315 lines
13 KiB
Python
315 lines
13 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import requests
|
|
import json
|
|
|
|
from unittest.mock import patch
|
|
from contextlib import contextmanager
|
|
from odoo import api
|
|
from odoo.addons.website_sale.controllers.delivery import Delivery
|
|
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
|
from odoo.addons.website.tools import MockRequest
|
|
from odoo.tests import TransactionCase, tagged
|
|
|
|
|
|
@contextmanager
|
|
def _mock_call():
|
|
def _mock_request(*args, **kwargs):
|
|
method = kwargs.get('method') or args[0]
|
|
url = kwargs.get('url') or args[1]
|
|
responses = {
|
|
'get': {
|
|
'service-points': [{
|
|
'id': 11238037,
|
|
'name': 'STATION AVIA',
|
|
'formatted_opening_times': {
|
|
'0': ['07:00 - 18:30'],
|
|
'1': ['07:00 - 18:30'],
|
|
'2': ['07:00 - 18:30'],
|
|
'3': ['07:00 - 18:30'],
|
|
'4': ['08:00 - 14:00', '15:00 - 18:00'],
|
|
'5': ['09:00 - 16:00'],
|
|
'6': [],
|
|
},
|
|
'street': 'CHAUSSEE DE NAMUR',
|
|
'house_number': '67',
|
|
'city': 'RAMILLIES',
|
|
'postal_code': '1367',
|
|
'country': 'BE',
|
|
'latitude': '50.634529',
|
|
'longitude': '4.864696',
|
|
}],
|
|
},
|
|
'post': {
|
|
}
|
|
}
|
|
|
|
for endpoint, content in responses[method].items():
|
|
if endpoint in url:
|
|
response = requests.Response()
|
|
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 TestWebsiteDeliverySendcloudLocationsController(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.WebsiteSaleController = WebsiteSale()
|
|
cls.website = cls.env.ref('website.default_website')
|
|
cls.your_company = cls.env.ref("base.main_partner")
|
|
cls.warehouse_id = cls.env['stock.warehouse'].search([('company_id', '=', cls.your_company.id)], limit=1)
|
|
cls.your_company.write({'name': 'Odoo SA',
|
|
'country_id': cls.env.ref('base.be').id,
|
|
'street': 'Chaussée de Namur 40',
|
|
'street2': False,
|
|
'state_id': False,
|
|
'city': 'Ramillies',
|
|
'zip': 1367,
|
|
'email': 'odoo@example.com',
|
|
'phone': '081813700',
|
|
})
|
|
# partner will be in europe
|
|
cls.eu_partner = cls.env['res.partner'].create({
|
|
'name': 'newPartner',
|
|
'country_id': cls.env.ref('base.be').id,
|
|
'zip': '1367',
|
|
'state_id': False,
|
|
'country_code': 'BE',
|
|
'street': 'Rue des Bourlottes 9',
|
|
'city': 'Ramillies'
|
|
})
|
|
|
|
cls.product_to_ship1 = cls.env["product.product"].create({
|
|
'name': 'Door with wings',
|
|
'type': 'consu',
|
|
'weight': 10.0,
|
|
'sale_ok': True,
|
|
'website_published': True,
|
|
'lst_price': 1000.0,
|
|
'standard_price': 800.0,
|
|
})
|
|
|
|
shipping_product = cls.env['product.product'].create({
|
|
'name': 'SendCloud Delivery',
|
|
'type': 'service'
|
|
})
|
|
|
|
uom = cls.env.ref('uom.product_uom_meter')
|
|
|
|
# Allow customization of 'sendcloud_use_locations' on the delivery_carrier
|
|
cls.sendcloud_shipping = cls.env['sendcloud.shipping.product'].create({
|
|
'name': 'Test product',
|
|
'sendcloud_code': 'test',
|
|
'carrier': 'Test',
|
|
'min_weight': 1,
|
|
'max_weight': 50001,
|
|
'functionalities': {
|
|
'bool_func': [],
|
|
'detail_func': {},
|
|
'customizable': {
|
|
'last_mile': [
|
|
'service_point',
|
|
'home_delivery',
|
|
]
|
|
},
|
|
},
|
|
})
|
|
|
|
cls.sendcloud = cls.env['delivery.carrier'].create({
|
|
'delivery_type': 'sendcloud',
|
|
'product_id': shipping_product.id,
|
|
'sendcloud_public_key': 'mock_key',
|
|
'sendcloud_secret_key': 'mock_key',
|
|
'name': 'SendCloud',
|
|
'sendcloud_locations_radius_value': 1000,
|
|
'sendcloud_locations_radius_unit': uom.id,
|
|
'sendcloud_locations_id': 1,
|
|
'sendcloud_shipping_id': cls.sendcloud_shipping.id,
|
|
})
|
|
|
|
cls.sendcloud.sendcloud_use_locations = True
|
|
cls.payment_provider = cls.env['payment.provider'].create({'name': 'test'})
|
|
|
|
cls.payment_method_id = cls.env.ref('payment.payment_method_unknown').id
|
|
|
|
cls.partner = cls.env['res.partner'].create({'name': 'testestset'})
|
|
|
|
cls.currency = cls.env['res.currency'].create({'name': 'testestset', 'symbol': '€'})
|
|
|
|
cls.transaction = cls.env['payment.transaction'].create({
|
|
'state': 'draft',
|
|
'provider_id': cls.payment_provider.id,
|
|
'payment_method_id': cls.payment_method_id,
|
|
'partner_id': cls.partner.id,
|
|
'currency_id': cls.currency.id,
|
|
'amount': 42
|
|
})
|
|
|
|
cls.order = cls.env['sale.order'].create({
|
|
'carrier_id': cls.sendcloud.id,
|
|
'partner_id': cls.env.user.partner_id.id,
|
|
'partner_shipping_id': cls.eu_partner.id,
|
|
'transaction_ids': [cls.transaction.id]
|
|
})
|
|
|
|
def test_controller_pickup_location(self):
|
|
with MockRequest(self.env, website=self.website, sale_order_id=self.order.id):
|
|
with _mock_call():
|
|
response = Delivery().website_sale_get_pickup_locations()
|
|
self.assertNotEqual({},
|
|
Delivery().website_sale_set_pickup_location(
|
|
pickup_location_data=json.dumps(response['pickup_locations'][0])
|
|
)
|
|
)
|
|
self.assertEqual({
|
|
'id': 11238037,
|
|
'name': 'Station Avia',
|
|
'opening_hours': {
|
|
'0': ['07:00 - 18:30'],
|
|
'1': ['07:00 - 18:30'],
|
|
'2': ['07:00 - 18:30'],
|
|
'3': ['07:00 - 18:30'],
|
|
'4': ['08:00 - 14:00', '15:00 - 18:00'],
|
|
'5': ['09:00 - 16:00'],
|
|
'6': [],
|
|
},
|
|
'street': 'Chaussee De Namur 67',
|
|
'city': 'Ramillies',
|
|
'zip_code': '1367',
|
|
'country_code': 'BE',
|
|
'latitude': '50.634529',
|
|
'longitude': '4.864696',
|
|
}, self.order.pickup_location_data)
|
|
|
|
def test_sendcloud_delivery_partner(self):
|
|
"""
|
|
Test that the delivery associated to a website sale using a sendcloud
|
|
pickup point is associated with a partner of `delivery` type.
|
|
"""
|
|
product = self.product_to_ship1
|
|
public_user = self.env.ref('base.public_user')
|
|
website = self.website.with_user(public_user)
|
|
with MockRequest(product.with_user(public_user).env, website=website):
|
|
self.WebsiteSaleController.cart_update_json(product_id=product.id, add_qty=1)
|
|
sale_order = website.sale_get_order()
|
|
partner_address = {
|
|
'name': 'Bob',
|
|
'email': 'bob@email.com',
|
|
'phone': '+1 555-555-555',
|
|
'street': 'Chaussee De Namur 65',
|
|
'city': 'Ramillies',
|
|
'zip': '1367',
|
|
'country_id': self.ref('base.be'),
|
|
}
|
|
env = api.Environment(self.env.cr, public_user.id, {})
|
|
with MockRequest(self.env, website=website.with_user(public_user).with_env(env), sale_order_id=sale_order.id) as req:
|
|
req.httprequest.method = "POST"
|
|
self.WebsiteSaleController.shop_address_submit(**partner_address)
|
|
sale_order.write({
|
|
'carrier_id': self.sendcloud.id,
|
|
'transaction_ids': [self.transaction.id],
|
|
})
|
|
with MockRequest(self.env, website=website, sale_order_id=sale_order.id):
|
|
with _mock_call():
|
|
response = Delivery().website_sale_get_pickup_locations()
|
|
Delivery().website_sale_set_pickup_location(
|
|
pickup_location_data=json.dumps(response['pickup_locations'][0])
|
|
)
|
|
sale_order.action_confirm()
|
|
# the delivery adress of the SO and the delivery should have been updated
|
|
# to gather the mail and phon number of the partner but the pickup point address
|
|
delivery = sale_order.picking_ids
|
|
self.assertEqual(sale_order.partner_shipping_id, delivery.partner_id)
|
|
self.assertRecordValues(delivery.partner_id, [{
|
|
'type': 'delivery',
|
|
'name': 'Station Avia',
|
|
'contact_address_complete': 'Chaussee De Namur 67, 1367 Ramillies, Belgium',
|
|
'email': 'bob@email.com',
|
|
'phone': '+1 555-555-555',
|
|
}])
|
|
sendcloud_class = 'odoo.addons.delivery_sendcloud.models.sendcloud_service.SendCloud'
|
|
|
|
def _prepare_fake_parcel(self, *args, **kwargs):
|
|
res = {
|
|
'id': 420277401,
|
|
'reference': '0',
|
|
'status': {'id': 1000, 'message': 'Ready to send'},
|
|
'tracking_number': '323211588559959039950037',
|
|
'weight': '10.0',
|
|
'order_number': 'S00404',
|
|
'total_insured_value': 0,
|
|
'parcel_items': [{}],
|
|
'documents': [],
|
|
'external_reference': None,
|
|
'is_return': False,
|
|
'note': '',
|
|
'total_order_value': '1210',
|
|
'total_order_value_currency': 'EUR',
|
|
'length': '0.00',
|
|
'width': '0.00',
|
|
'height': '0.00',
|
|
'contract': 519,
|
|
'address_divided': {'street': 'Chaussee De Namur', 'house_number': '65'},
|
|
'shipment': {'id': 95, 'name': 'bpost @bpack 0-10kg'},
|
|
'shipping_method': 95,
|
|
'shipping_method_checkout_name': 'bpost @bpack',
|
|
'insured_value': 0,
|
|
'shipment_uuid': None,
|
|
'data': {},
|
|
'type': 'parcel',
|
|
'external_order_id': '420277401',
|
|
'external_shipment_id': '',
|
|
'colli_uuid': '925023d1-d4cc-4774-9ea3-c1ecb152a6e0',
|
|
'collo_nr': 0, 'collo_count': 1,
|
|
'label': {'normal_printer': [], 'label_printer': 'https://panel.sendcloud.sc/api/v2/labels/label_printer/420277401'},
|
|
'customs_declaration': {},
|
|
'to_state': None,
|
|
'date_created': '07-10-2024 14:12:12',
|
|
'date_announced': '07-10-2024 14:12:13',
|
|
'date_updated': '07-10-2024 14:12:13',
|
|
'customs_shipment_type': 2,
|
|
'address': 'Chaussee De Namur 65',
|
|
'address_2': '',
|
|
'city': 'Ramillies',
|
|
'company_name': '',
|
|
'country': {'iso_2': 'BE', 'iso_3': 'BEL', 'name': 'Belgium'},
|
|
'email': 'bob@email.com',
|
|
'name': 'Bob',
|
|
'postal_code': '1367',
|
|
'telephone': '+1 555-555-555',
|
|
'to_post_number': '',
|
|
'to_service_point': 11238037,
|
|
'errors': {},
|
|
'carrier': {'code': 'bpost'},
|
|
'tracking_url': 'https://tracking.eu-central-1-0.sendcloud.sc/fake',
|
|
}
|
|
parcel_common = self._prepare_parcel_common_data(picking=delivery, is_return=False, sender_id=False)
|
|
for key, value in parcel_common.items():
|
|
if key in res and value:
|
|
res[key] = value
|
|
return [res]
|
|
|
|
def _get_fake_shipping_rate(*args, **kwargs):
|
|
return [5.0]
|
|
|
|
def _fake_cancel_shipment(*args, **kwargs):
|
|
return {'status': 'queued', 'message': 'Parcel cancellation has been queued'}
|
|
|
|
with (
|
|
patch(sendcloud_class + '._send_shipment', new=_prepare_fake_parcel),
|
|
patch(sendcloud_class + '._get_shipping_rate', new=_get_fake_shipping_rate),
|
|
patch(sendcloud_class + '._cancel_shipment', new=_fake_cancel_shipment),
|
|
):
|
|
delivery.button_validate()
|
|
self.assertEqual(delivery.state, 'done')
|