forked from Mapan/odoo17e
284 lines
13 KiB
Python
284 lines
13 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
import json
|
|
from contextlib import contextmanager
|
|
from unittest.mock import patch
|
|
|
|
import requests
|
|
|
|
from odoo.tests import Form, TransactionCase, tagged
|
|
|
|
|
|
@contextmanager
|
|
def _mock_request_call():
|
|
def _mock_request(*args, **kwargs):
|
|
url = kwargs.get('url', args[2])
|
|
responses = {
|
|
'token': {'access_token': 'mock_token'},
|
|
'rate': {'output': {
|
|
"alerts": [{"code": "string", "message": "string"}],
|
|
'rateReplyDetails': [{
|
|
'ratedShipmentDetails': [{'currency': 'USD', 'totalNetChargeWithDutiesAndTaxes': 5.5}]
|
|
}],
|
|
}},
|
|
'cancel': {'output': {'cancelledShipment': True}},
|
|
'ship': {
|
|
'output': {
|
|
'transactionShipments': [{
|
|
'completedShipmentDetail': {
|
|
'shipmentRating': {
|
|
'actualRateType': 'TEST',
|
|
'shipmentRateDetails': [{
|
|
'rateType': 'TEST',
|
|
"totalNetChargeWithDutiesAndTaxes": 5.5
|
|
}]
|
|
},
|
|
'completedPackageDetails': [{'trackingIds': [{'trackingNumber': 'TEST'}]}]
|
|
},
|
|
'pieceResponses': [{
|
|
'trackingNumber': '123',
|
|
'packageDocuments': [{'contentType': 'LABEL', 'encodedLabel': 'TEST'}]
|
|
}]
|
|
}]
|
|
}
|
|
},
|
|
}
|
|
|
|
for endpoint, content in responses.items():
|
|
if endpoint in url:
|
|
response = requests.Response()
|
|
response.request = requests.Request(kwargs.get('method'), url, kwargs.get('headers'))
|
|
response.request.body = str(kwargs.get('json')).encode('utf-8')
|
|
response._content = json.dumps(content).encode()
|
|
response.status_code = 200
|
|
return response
|
|
|
|
raise Exception('unhandled request url %s' % url)
|
|
|
|
with patch.object(requests.Session, 'request', _mock_request):
|
|
yield
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestDeliveryFedex(TransactionCase):
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.iPadMini = self.env['product.product'].create({
|
|
'name': 'Ipad Mini',
|
|
'weight': 0.01,
|
|
})
|
|
self.large_desk = self.env['product.product'].create({
|
|
'name': 'Large Desk',
|
|
'weight': 0.01,
|
|
})
|
|
self.uom_unit = self.env.ref('uom.product_uom_unit')
|
|
|
|
self.your_company = self.env.ref('base.main_partner')
|
|
self.your_company.write({'country_id': self.env.ref('base.us').id,
|
|
'state_id': self.env.ref('base.state_us_5').id,
|
|
'city': 'San Francisco',
|
|
'street': '51 Federal Street',
|
|
'zip': '94107',
|
|
'phone': 9874582356})
|
|
|
|
self.agrolait = self.env['res.partner'].create({
|
|
'name': 'Agrolait',
|
|
'phone': '(603)-996-3829',
|
|
'street': "rue des Bourlottes, 9",
|
|
'street2': "",
|
|
'city': "Ramillies",
|
|
'zip': 1367,
|
|
'state_id': False,
|
|
'country_id': self.env.ref('base.be').id,
|
|
})
|
|
self.delta_pc = self.env['res.partner'].create({
|
|
'name': 'Delta PC',
|
|
'phone': '(803)-873-6126',
|
|
'street': "1515 Main Street",
|
|
'street2': "",
|
|
'city': "Columbia",
|
|
'zip': 29201,
|
|
'state_id': self.env.ref('base.state_us_41').id,
|
|
'country_id': self.env.ref('base.us').id,
|
|
})
|
|
self.stock_location = self.env.ref('stock.stock_location_stock')
|
|
self.customer_location = self.env.ref('stock.stock_location_customers')
|
|
|
|
def wiz_put_in_pack(self, picking):
|
|
""" Helper to use the 'choose.delivery.package' wizard
|
|
in order to call the 'action_put_in_pack' method.
|
|
"""
|
|
wiz_action = picking.action_put_in_pack()
|
|
self.assertEqual(wiz_action['res_model'], 'choose.delivery.package', 'Wrong wizard returned')
|
|
wiz = Form(self.env[wiz_action['res_model']].with_context(wiz_action['context']).create({
|
|
'delivery_package_type_id': picking.carrier_id.fedex_rest_default_package_type_id.id
|
|
}))
|
|
choose_delivery_carrier = wiz.save()
|
|
choose_delivery_carrier.action_put_in_pack()
|
|
|
|
def test_01_fedex_basic_us_domestic_flow(self):
|
|
SaleOrder = self.env['sale.order']
|
|
|
|
sol_vals = {'product_id': self.iPadMini.id,
|
|
'name': "[A1232] iPad Mini",
|
|
'product_uom': self.uom_unit.id,
|
|
'product_uom_qty': 1.0,
|
|
'price_unit': self.iPadMini.lst_price}
|
|
|
|
so_vals = {'partner_id': self.delta_pc.id,
|
|
'order_line': [(0, None, sol_vals)]}
|
|
|
|
sale_order = SaleOrder.create(so_vals)
|
|
# I add delivery cost in Sales order
|
|
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
|
'default_order_id': sale_order.id,
|
|
'default_carrier_id': self.env.ref('delivery_fedex_rest.delivery_carrier_fedex_us').id
|
|
}))
|
|
choose_delivery_carrier = delivery_wizard.save()
|
|
with _mock_request_call():
|
|
choose_delivery_carrier.update_price()
|
|
self.assertGreater(choose_delivery_carrier.delivery_price, 0.0, "FedEx delivery cost for this SO has not been correctly estimated.")
|
|
choose_delivery_carrier.button_confirm()
|
|
|
|
sale_order.action_confirm()
|
|
self.assertEqual(len(sale_order.picking_ids), 1, "The Sales Order did not generate a picking.")
|
|
|
|
picking = sale_order.picking_ids[0]
|
|
self.assertEqual(picking.carrier_id.id, sale_order.carrier_id.id, "Carrier is not the same on Picking and on SO.")
|
|
|
|
picking.move_line_ids[0].quantity = 1.0
|
|
self.assertGreater(picking.shipping_weight, 0.0, "Picking weight should be positive.")
|
|
|
|
picking._action_done()
|
|
self.assertIsNot(picking.carrier_tracking_ref, False, "FedEx did not return any tracking number")
|
|
self.assertGreater(picking.carrier_price, 0.0, "FedEx carrying price is probably incorrect")
|
|
|
|
picking.cancel_shipment()
|
|
self.assertFalse(picking.carrier_tracking_ref, "Carrier Tracking code has not been properly deleted")
|
|
self.assertEqual(picking.carrier_price, 0.0, "Carrier price has not been properly deleted")
|
|
|
|
def test_02_fedex_basic_international_flow(self):
|
|
SaleOrder = self.env['sale.order']
|
|
|
|
sol_vals = {'product_id': self.iPadMini.id,
|
|
'name': "[A1232] Large Cabinet",
|
|
'product_uom': self.uom_unit.id,
|
|
'product_uom_qty': 1.0,
|
|
'price_unit': self.iPadMini.lst_price}
|
|
|
|
so_vals = {'partner_id': self.agrolait.id,
|
|
'order_line': [(0, None, sol_vals)]}
|
|
|
|
sale_order = SaleOrder.create(so_vals)
|
|
# I add delivery cost in Sales order
|
|
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
|
'default_order_id': sale_order.id,
|
|
'default_carrier_id': self.env.ref('delivery_fedex_rest.delivery_carrier_fedex_inter').id,
|
|
}))
|
|
choose_delivery_carrier = delivery_wizard.save()
|
|
with _mock_request_call():
|
|
choose_delivery_carrier.update_price()
|
|
self.assertGreater(choose_delivery_carrier.delivery_price, 0.0, "FedEx delivery cost for this SO has not been correctly estimated.")
|
|
choose_delivery_carrier.button_confirm()
|
|
|
|
sale_order.action_confirm()
|
|
self.assertEqual(len(sale_order.picking_ids), 1, "The Sales Order did not generate a picking.")
|
|
|
|
picking = sale_order.picking_ids[0]
|
|
self.assertEqual(picking.carrier_id.id, sale_order.carrier_id.id, "Carrier is not the same on Picking and on SO.")
|
|
|
|
picking.move_line_ids[0].quantity = 1.0
|
|
self.assertGreater(picking.shipping_weight, 0.0, "Picking weight should be positive.")
|
|
|
|
picking._action_done()
|
|
self.assertIsNot(picking.carrier_tracking_ref, False, "FedEx did not return any tracking number")
|
|
self.assertGreater(picking.carrier_price, 0.0, "FedEx carrying price is probably incorrect")
|
|
|
|
picking.cancel_shipment()
|
|
self.assertFalse(picking.carrier_tracking_ref, "Carrier Tracking code has not been properly deleted")
|
|
self.assertEqual(picking.carrier_price, 0.0, "Carrier price has not been properly deleted")
|
|
|
|
def test_03_fedex_multipackage_international_flow(self):
|
|
SaleOrder = self.env['sale.order']
|
|
|
|
sol_1_vals = {'product_id': self.iPadMini.id,
|
|
'name': "[A1232] iPad Mini",
|
|
'product_uom': self.uom_unit.id,
|
|
'product_uom_qty': 1.0,
|
|
'price_unit': self.iPadMini.lst_price}
|
|
sol_2_vals = {'product_id': self.large_desk.id,
|
|
'name': "[A1090] Large Desk",
|
|
'product_uom': self.uom_unit.id,
|
|
'product_uom_qty': 1.0,
|
|
'price_unit': self.large_desk.lst_price}
|
|
|
|
so_vals = {'partner_id': self.agrolait.id,
|
|
'order_line': [(0, None, sol_1_vals), (0, None, sol_2_vals)]}
|
|
|
|
sale_order = SaleOrder.create(so_vals)
|
|
# I add delivery cost in Sales order
|
|
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
|
'default_order_id': sale_order.id,
|
|
'default_carrier_id': self.env.ref('delivery_fedex_rest.delivery_carrier_fedex_inter').id
|
|
}))
|
|
choose_delivery_carrier = delivery_wizard.save()
|
|
with _mock_request_call():
|
|
choose_delivery_carrier.update_price()
|
|
self.assertGreater(choose_delivery_carrier.delivery_price, 0.0, "FedEx delivery cost for this SO has not been correctly estimated.")
|
|
choose_delivery_carrier.button_confirm()
|
|
|
|
sale_order.action_confirm()
|
|
self.assertEqual(len(sale_order.picking_ids), 1, "The Sales Order did not generate a picking.")
|
|
|
|
picking = sale_order.picking_ids[0]
|
|
self.assertEqual(picking.carrier_id.id, sale_order.carrier_id.id, "Carrier is not the same on Picking and on SO.")
|
|
|
|
move0 = picking.move_line_ids[0]
|
|
move0.quantity = 1.0
|
|
move0.picked = True
|
|
self.wiz_put_in_pack(picking)
|
|
move1 = picking.move_line_ids[1]
|
|
move1.quantity = 1.0
|
|
move1.picked = True
|
|
self.wiz_put_in_pack(picking)
|
|
self.assertEqual(len(picking.move_line_ids.mapped('result_package_id')), 2, "2 Packages should have been created at this point")
|
|
self.assertGreater(picking.shipping_weight, 0.0, "Picking weight should be positive.")
|
|
|
|
picking._action_done()
|
|
self.assertIsNot(picking.carrier_tracking_ref, False, "FedEx did not return any tracking number")
|
|
self.assertGreater(picking.carrier_price, 0.0, "FedEx carrying price is probably incorrect")
|
|
|
|
picking.cancel_shipment()
|
|
self.assertFalse(picking.carrier_tracking_ref, "Carrier Tracking code has not been properly deleted")
|
|
self.assertEqual(picking.carrier_price, 0.0, "Carrier price has not been properly deleted")
|
|
|
|
def test_04_fedex_international_delivery_from_delivery_order(self):
|
|
StockPicking = self.env['stock.picking']
|
|
|
|
order1_vals = {
|
|
'product_id': self.iPadMini.id,
|
|
'name': "[A1232] iPad Mini",
|
|
'product_uom': self.uom_unit.id,
|
|
'product_uom_qty': 1.0,
|
|
'location_id': self.stock_location.id,
|
|
'location_dest_id': self.customer_location.id}
|
|
|
|
do_vals = {'partner_id': self.agrolait.id,
|
|
'carrier_id': self.env.ref('delivery_fedex_rest.delivery_carrier_fedex_inter').id,
|
|
'location_id': self.stock_location.id,
|
|
'location_dest_id': self.customer_location.id,
|
|
'picking_type_id': self.env.ref('stock.picking_type_out').id,
|
|
'state': 'draft',
|
|
'move_ids_without_package': [(0, None, order1_vals)]}
|
|
|
|
delivery_order = StockPicking.create(do_vals)
|
|
self.assertEqual(delivery_order.state, 'draft', 'Shipment state should be draft.')
|
|
|
|
delivery_order.action_confirm()
|
|
self.assertEqual(delivery_order.state, 'assigned', 'Shipment state should be ready(assigned).')
|
|
delivery_order.move_ids_without_package.quantity = 1.0
|
|
with _mock_request_call():
|
|
delivery_order.button_validate()
|
|
self.assertEqual(delivery_order.state, 'done', 'Shipment state should be done.')
|