diff --git a/setup/shopinvader_delivery_instruction/odoo/__init__.py b/setup/shopinvader_delivery_instruction/odoo/__init__.py new file mode 100644 index 0000000000..de40ea7ca0 --- /dev/null +++ b/setup/shopinvader_delivery_instruction/odoo/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/shopinvader_delivery_instruction/odoo/addons/__init__.py b/setup/shopinvader_delivery_instruction/odoo/addons/__init__.py new file mode 100644 index 0000000000..de40ea7ca0 --- /dev/null +++ b/setup/shopinvader_delivery_instruction/odoo/addons/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/shopinvader_delivery_instruction/odoo/addons/shopinvader_delivery_instruction b/setup/shopinvader_delivery_instruction/odoo/addons/shopinvader_delivery_instruction new file mode 120000 index 0000000000..d374f88d7e --- /dev/null +++ b/setup/shopinvader_delivery_instruction/odoo/addons/shopinvader_delivery_instruction @@ -0,0 +1 @@ +../../../../shopinvader_delivery_instruction \ No newline at end of file diff --git a/setup/shopinvader_delivery_instruction/setup.py b/setup/shopinvader_delivery_instruction/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/shopinvader_delivery_instruction/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopinvader_delivery_instruction/__init__.py b/shopinvader_delivery_instruction/__init__.py new file mode 100644 index 0000000000..35cebfd836 --- /dev/null +++ b/shopinvader_delivery_instruction/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import services diff --git a/shopinvader_delivery_instruction/__manifest__.py b/shopinvader_delivery_instruction/__manifest__.py new file mode 100644 index 0000000000..d5d83ef8ec --- /dev/null +++ b/shopinvader_delivery_instruction/__manifest__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Shopinvader delivery instruction", + "description": """Shopinvader addons to let user define delivery + instructions""", + "author": "ACSONE SA/NV", + "website": "http://shopinvader.com/", + "category": "e-commerce", + "version": "10.0.1.0.0", + "license": "AGPL-3", + "depends": [ + "shopinvader", + # OCA/sale-workflow + "sale_stock_picking_note", + ], +} diff --git a/shopinvader_delivery_instruction/services/__init__.py b/shopinvader_delivery_instruction/services/__init__.py new file mode 100644 index 0000000000..2dc57e84b7 --- /dev/null +++ b/shopinvader_delivery_instruction/services/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import abstract_sale +from . import cart diff --git a/shopinvader_delivery_instruction/services/abstract_sale.py b/shopinvader_delivery_instruction/services/abstract_sale.py new file mode 100644 index 0000000000..4dcb910b8a --- /dev/null +++ b/shopinvader_delivery_instruction/services/abstract_sale.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.addons.component.core import AbstractComponent + + +class AbstractSaleService(AbstractComponent): + _inherit = "shopinvader.abstract.sale.service" + + def _convert_one_sale(self, sale): + """ + Inherit to add the picking note into the result + :param sale: sale.order recordset + :return: dict + """ + values = super(AbstractSaleService, self)._convert_one_sale(sale) + values.update({"delivery_instruction": sale.picking_note}) + return values diff --git a/shopinvader_delivery_instruction/services/cart.py b/shopinvader_delivery_instruction/services/cart.py new file mode 100644 index 0000000000..a6bfcb4d68 --- /dev/null +++ b/shopinvader_delivery_instruction/services/cart.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.addons.component.core import Component + + +class CartService(Component): + _inherit = "shopinvader.cart.service" + + def _validator_update(self): + """ + Inherit to add the delivery_instruction validator + :return: dict + """ + validator = super(CartService, self)._validator_update() + validator.update({"delivery_instruction": {"type": "string"}}) + return validator + + def _prepare_delivery_instruction(self, delivery_instruction, params): + """ + Put the given delivery note into params dict (used to create the + sale.order). + :param delivery_instruction: str or bool + :param params: dict + :return: bool + """ + # If the user try to remove the value, we'll have an empty string + if delivery_instruction or isinstance( + delivery_instruction, (str, unicode) + ): + params.update({"picking_note": delivery_instruction}) + return True + + def _prepare_update(self, cart, params): + """ + Inherit to add the picking note into the cart + :param cart: sale.order recordset + :param params: dict + :return: dict + """ + params = super(CartService, self)._prepare_update(cart, params) + self._prepare_delivery_instruction( + params.pop("delivery_instruction", False), params + ) + return params diff --git a/shopinvader_delivery_instruction/tests/__init__.py b/shopinvader_delivery_instruction/tests/__init__.py new file mode 100644 index 0000000000..cdbbed93a2 --- /dev/null +++ b/shopinvader_delivery_instruction/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import test_sale_order_picking_note diff --git a/shopinvader_delivery_instruction/tests/test_sale_order_picking_note.py b/shopinvader_delivery_instruction/tests/test_sale_order_picking_note.py new file mode 100644 index 0000000000..de295bb7f3 --- /dev/null +++ b/shopinvader_delivery_instruction/tests/test_sale_order_picking_note.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from uuid import uuid4 + +from odoo.addons.shopinvader.tests.common import CommonCase + + +class TestSaleOrderDeliveryNote(CommonCase): + """ + Tests about the delivery note provided by the customer. + This field should by passed into the related picking. + """ + + def setUp(self): + super(TestSaleOrderDeliveryNote, self).setUp() + self.cart = self.env.ref("shopinvader.sale_order_2") + self.shopinvader_session = {"cart_id": self.cart.id} + self.partner = self.env.ref("shopinvader.partner_1") + self.address = self.env.ref("shopinvader.partner_1_address_1") + with self.work_on_services( + partner=self.partner, shopinvader_session=self.shopinvader_session + ) as work: + self.service = work.component(usage="cart") + + def test_update_picking_note1(self): + """ + Execute some update on existing cart (update many times the + delivery_instruction) then confirm it to check if the + delivery_instruction is passed to related pickings. + :return: + """ + delivery_instructions = [ + str(uuid4()), + str(uuid4()), + "", + "", + str(uuid4()), + str(uuid4()), + ] + for delivery_instruction in delivery_instructions: + params = {"delivery_instruction": delivery_instruction} + self.service.dispatch("update", params=params) + self.assertEquals(self.cart.picking_note, delivery_instruction) + result = self.service.dispatch("update") + data = result.get("data", {}) + self.assertEquals( + data.get("delivery_instruction"), delivery_instruction + ) + self.cart.action_confirm() + pickings = self.cart.picking_ids + self.assertTrue(pickings) + for picking in pickings: + # Should be equals to the last delivery_instruction set on the cart + self.assertEquals(picking.note, delivery_instruction) + return