Odoo18-Base/extra-addons/website_delivery_sendcloud/tests/test_pickup_location_controller.py

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')