diff --git a/joint_buying_base/tests/test_abstract.py b/joint_buying_base/tests/test_abstract.py index e94eb8a3..a063092b 100644 --- a/joint_buying_base/tests/test_abstract.py +++ b/joint_buying_base/tests/test_abstract.py @@ -16,10 +16,12 @@ def setUp(self): self.user_3PP = self.env.ref("joint_buying_base.user_joint_buying_user_3PP") + self.company_1GG = self.env.ref("joint_buying_base.company_1GG") self.company_3PP = self.env.ref("joint_buying_base.company_3PP") self.company_CDA = self.env.ref("joint_buying_base.company_CDA") self.company_CHE = self.env.ref("joint_buying_base.company_CHE") self.company_ELD = self.env.ref("joint_buying_base.company_ELD") + self.company_LSE = self.env.ref("joint_buying_base.company_LSE") self.company_VEV = self.env.ref("joint_buying_base.company_VEV") # Custom Functions diff --git a/joint_buying_product/__manifest__.py b/joint_buying_product/__manifest__.py index 55b68cb3..dea5ae55 100644 --- a/joint_buying_product/__manifest__.py +++ b/joint_buying_product/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Joint Buying - Products", - "version": "12.0.4.0.2", + "version": "12.0.5.0.0", "category": "GRAP - Logistics", "author": "GRAP", "website": "https://github.com/grap/odoo-addons-logistics", diff --git a/joint_buying_product/demo/joint_buying_purchase_order_grouped.xml b/joint_buying_product/demo/joint_buying_purchase_order_grouped.xml index de4de3ca..64e7876e 100644 --- a/joint_buying_product/demo/joint_buying_purchase_order_grouped.xml +++ b/joint_buying_product/demo/joint_buying_purchase_order_grouped.xml @@ -22,6 +22,7 @@ + @@ -56,6 +57,7 @@ + @@ -89,6 +91,7 @@ + @@ -122,6 +125,7 @@ + @@ -155,6 +159,7 @@ + diff --git a/joint_buying_product/i18n/fr.po b/joint_buying_product/i18n/fr.po index d4b5d112..dec6b995 100644 --- a/joint_buying_product/i18n/fr.po +++ b/joint_buying_product/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-13 20:31+0000\n" -"PO-Revision-Date: 2023-12-13 20:31+0000\n" +"POT-Creation-Date: 2024-01-26 19:54+0000\n" +"PO-Revision-Date: 2024-01-26 19:54+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -499,8 +499,8 @@ msgid "Companies" msgstr "Sociétés" #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:542 -#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:583 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:546 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:587 #, python-format msgid "Compose Email" msgstr "Rédiger un courriel" @@ -633,6 +633,11 @@ msgstr "Supprimer la copie du message" msgid "Delete sent emails (mass mailing only)" msgstr "Supprimer les courriels envoyés (seulement publipostage)" +#. module: joint_buying_product +#: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order__delivery_partner_id +msgid "Delivery Place" +msgstr "Lieu de livraison" + #. module: joint_buying_product #: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order__deposit_date #: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order_grouped__deposit_date @@ -819,8 +824,8 @@ msgid "Gingembrette Sachet 200gr @ Three Peas" msgstr "" #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:530 -#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:573 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:534 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:577 #: model:ir.actions.report,name:joint_buying_product.action_report_joint_buying_purchase_order_grouped #: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order__grouped_order_id #: model:ir.model.fields,field_description:joint_buying_product.field_mail_compose_message_purchase_order_grouped__grouped_order_id @@ -1969,11 +1974,6 @@ msgstr "Responsable" msgid "Rillette (500gr) (Global)" msgstr "" -#. module: joint_buying_product -#: selection:joint.buying.transport.request,request_type:0 -msgid "Sale Order" -msgstr "Commande de vente" - #. module: joint_buying_product #: model:product.product,name:joint_buying_product.product_devidal_saucisson #: model:product.template,name:joint_buying_product.product_devidal_saucisson_product_template @@ -2189,7 +2189,7 @@ msgid "Technical field, used to know if the joint buying purchase order has a re msgstr "Champ technique, utilisé pour savoir si la commande groupée a une demande de transport associée. Il peut seulement contenir 0 ou une demande de transport." #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:636 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order_grouped.py:640 #, python-format msgid "The company '%s' has been subscribed to the supplier '%s'." msgstr "La société '%s' a été abonnée au fournisseur '%s'." @@ -2453,20 +2453,6 @@ msgstr "Utiliser un modèle" msgid "Users" msgstr "Utilisateurs" -#. module: joint_buying_product -#: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_category__website_message_ids -#: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order__website_message_ids -#: model:ir.model.fields,field_description:joint_buying_product.field_joint_buying_purchase_order_grouped__website_message_ids -msgid "Website Messages" -msgstr "Messages du site web" - -#. module: joint_buying_product -#: model:ir.model.fields,help:joint_buying_product.field_joint_buying_category__website_message_ids -#: model:ir.model.fields,help:joint_buying_product.field_joint_buying_purchase_order__website_message_ids -#: model:ir.model.fields,help:joint_buying_product.field_joint_buying_purchase_order_grouped__website_message_ids -msgid "Website communication history" -msgstr "Historique de communication du site web" - #. module: joint_buying_product #: model:ir.model.fields,help:joint_buying_product.field_mail_compose_message_purchase_order_grouped__is_log msgid "Whether the message is an internal note (comment mode only)" @@ -2484,13 +2470,13 @@ msgid "You can not change the value of the Joint buying partner." msgstr "Vous ne pouvez pas changer la valeur de partenaire de commande groupée" #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:372 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:403 #, python-format msgid "You can not confirm an order with null amount." msgstr "Vous ne pouvez pas confirmer une commande avec un montant nul." #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:368 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:399 #, python-format msgid "You can not confirm an order without any lines." msgstr "Vous ne pouvez pas confirmer une commande sans lignes." @@ -2518,13 +2504,13 @@ msgid "You can not set a negative quantity in the 'Purchase Quantity' field !" msgstr "Vous ne pouvez pas saisir de quantité négative dans le champ 'quantité à commander' !" #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:376 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:407 #, python-format msgid "You cannot confirm an order for which you have not reached the minimum purchase amount." msgstr "Vous ne pouvez pas confirmer une commande pour laquelle le franco de port n'est pas atteint." #. module: joint_buying_product -#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:383 +#: code:addons/joint_buying_product/models/joint_buying_purchase_order.py:414 #, python-format msgid "You cannot confirm an order for which you have not reached the minimum weight." msgstr "Vous ne pouvez pas confirmer une commande pour laquelle le franco de port n'est pas atteint." @@ -2619,3 +2605,8 @@ msgstr "" msgid "or" msgstr "ou" +#. module: joint_buying_product +#: model:ir.model.fields,help:joint_buying_product.field_joint_buying_purchase_order__delivery_partner_id +msgid "the place where the goods are to be delivered. Defined by default as the customer's address, the location may be different in some cases, if the customer collects the goods from another location." +msgstr "Le lieu ou la marchandise doit être livrée. Par défaut, il s'agit de l'adresse du client qui commande, mais l'emplacement peut être différent dans certains cas, si le client récupère la marchandise à un autre endroit." + diff --git a/joint_buying_product/migrations/12.0.5.0.0/pre-migration.py b/joint_buying_product/migrations/12.0.5.0.0/pre-migration.py new file mode 100644 index 00000000..75461826 --- /dev/null +++ b/joint_buying_product/migrations/12.0.5.0.0/pre-migration.py @@ -0,0 +1,31 @@ +# Copyright (C) 2024-Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +from openupgradelib import openupgrade + +_logger = logging.getLogger(__name__) + + +@openupgrade.migrate() +def migrate(env, version): + # Configure Correctly new 'Delivery Place' Field + if not openupgrade.column_exists( + env.cr, "joint_buying_purchase_order", "delivery_partner_id" + ): + openupgrade.logged_query( + env.cr, + """ + ALTER TABLE joint_buying_purchase_order + ADD COLUMN delivery_partner_id int; + """, + ) + openupgrade.logged_query( + env.cr, + """ + UPDATE joint_buying_purchase_order jbpo + SET delivery_partner_id = jbpo.customer_id; + """, + ) diff --git a/joint_buying_product/models/joint_buying_purchase_order.py b/joint_buying_product/models/joint_buying_purchase_order.py index e16393e5..7ac62091 100644 --- a/joint_buying_product/models/joint_buying_purchase_order.py +++ b/joint_buying_product/models/joint_buying_purchase_order.py @@ -87,6 +87,20 @@ class JointBuyingPurchaseOrder(models.Model): context=_JOINT_BUYING_PARTNER_CONTEXT, ) + delivery_partner_id = fields.Many2one( + comodel_name="res.partner", + string="Delivery Place", + required=True, + track_visibility=True, + context=_JOINT_BUYING_PARTNER_CONTEXT, + help="the place where the goods are" + " to be delivered. Defined by default" + " as the customer's address," + " the location may be different in some cases," + " if the customer collects the goods" + " from another location.", + ) + state = fields.Selection( related="grouped_order_id.state", string="State", store=True ) @@ -316,7 +330,11 @@ def _compute_total_weight(self): @api.model def _prepare_order_vals(self, supplier, customer, categories): OrderLine = self.env["joint.buying.purchase.order.line"] - res = {"customer_id": customer.id, "line_ids": []} + res = { + "customer_id": customer.id, + "delivery_partner_id": customer.id, + "line_ids": [], + } for product in supplier._get_joint_buying_products(categories): vals = OrderLine._prepare_line_vals(product) res["line_ids"].append((0, 0, vals)) @@ -327,7 +345,7 @@ def _hook_state_changed(self): Create transport requests: - if not exists, - if state != closed / deposited or is not null - - if deposit place != customer_id + - if deposit_partner_id != delivery_partner_id Unlink transport requests: - if exists @@ -340,21 +358,34 @@ def _hook_state_changed(self): or (x.total_weight or x.amount_untaxed) ) and not x.transport_request_id - and x.deposit_partner_id != x.customer_id + and x.deposit_partner_id != x.delivery_partner_id ) if orders_request_to_create: vals_list = [{"order_id": x.id} for x in orders_request_to_create] self.env["joint.buying.transport.request"].create(vals_list) - # for (order, request) in zip(orders_request_to_create, requests): - # order.write({"transport_request_id": request.id}) orders_request_to_unlink = self.filtered( - lambda x: x.state in ["closed", "deposited"] - and not (x.total_weight or x.amount_untaxed) + lambda x: ( + x.state in ["closed", "deposited"] + and not (x.total_weight or x.amount_untaxed) + ) + or x.deposit_partner_id == x.delivery_partner_id ) if orders_request_to_unlink: orders_request_to_unlink.mapped("transport_request_ids").unlink() + def write(self, vals): + res = super().write(vals) + if "delivery_partner_id" in vals: + # Maybe some transport request are now required, or now obsolete + # depending if deposit_partner_id is equal or not to delivery_partner_id + self._hook_state_changed() + # Anyway, as destination changed, invalidate transport request + self.mapped("transport_request_ids").filtered( + lambda x: x.state != "to_compute" + )._invalidate() + return res + @api.model_create_multi def create(self, vals_list): orders = super().create(vals_list) diff --git a/joint_buying_product/models/joint_buying_purchase_order_grouped.py b/joint_buying_product/models/joint_buying_purchase_order_grouped.py index 1e12f6a7..f639b681 100644 --- a/joint_buying_product/models/joint_buying_purchase_order_grouped.py +++ b/joint_buying_product/models/joint_buying_purchase_order_grouped.py @@ -307,6 +307,10 @@ def write(self, vals): res = super().write(vals) if not self.env.context.get("update_state_value"): self.update_state_value() + if "deposit_partner_id" in vals.keys(): + # Maybe some transport request are now required, or now obsolete + # depending if deposit_partner_id is equal or not to delivery_partner_id + self.mapped("order_ids")._hook_state_changed() if {"deposit_date", "deposit_partner_id"}.intersection(set(vals.keys())): self.mapped("order_ids.transport_request_id")._invalidate() return res diff --git a/joint_buying_product/models/joint_buying_transport_request.py b/joint_buying_product/models/joint_buying_transport_request.py index a2ee3cd7..093ffcb0 100644 --- a/joint_buying_product/models/joint_buying_transport_request.py +++ b/joint_buying_product/models/joint_buying_transport_request.py @@ -41,7 +41,7 @@ def _get_depends_start_partner_id(self): def _get_depends_arrival_partner_id(self): res = super()._get_depends_arrival_partner_id() - res.append("order_id.deposit_partner_id") + res.append("order_id.delivery_partner_id") return res def _get_depends_amount_untaxed(self): @@ -106,7 +106,7 @@ def _compute_arrival_partner_id(self): )._compute_arrival_partner_id() for request in self.filtered(lambda x: x.order_id): - request.arrival_partner_id = request.order_id.customer_id + request.arrival_partner_id = request.order_id.delivery_partner_id def _compute_amount_untaxed(self): super( diff --git a/joint_buying_product/tests/test_joint_buying_transport_request_compute.py b/joint_buying_product/tests/test_joint_buying_transport_request_compute.py index 6eed32be..73a7eb58 100644 --- a/joint_buying_product/tests/test_joint_buying_transport_request_compute.py +++ b/joint_buying_product/tests/test_joint_buying_transport_request_compute.py @@ -60,3 +60,63 @@ def test_create_transport_request_joint_buying(self): self.assertEqual(request.amount_untaxed, order_VEV.amount_untaxed) self.assertEqual(request.total_weight, order_VEV.total_weight) + + def test_joint_buying_order_change_delivery_partner(self): + # This demo grouped order is delivered in 1GG + order_VEV = self.env.ref("joint_buying_product.order_ronzon_VEV_past") + + self.assertTrue(order_VEV.transport_request_id) + request = order_VEV.transport_request_id + self.assertEqual(request.start_partner_id.joint_buying_code, "1GG") + self.assertEqual(request.arrival_partner_id.joint_buying_code, "VEV") + + # check initial computation + request.button_compute_tour() + self.assertEqual(request.state, "computed") + self.assertEqual(len(request.line_ids), 2) + self.assertEqual(request.line_ids[0].starting_point_id.joint_buying_code, "1GG") + self.assertEqual(request.line_ids[0].arrival_point_id.joint_buying_code, "LSE") + self.assertEqual(request.line_ids[1].starting_point_id.joint_buying_code, "LSE") + self.assertEqual(request.line_ids[1].arrival_point_id.joint_buying_code, "VEV") + + # Change delivery_partner_id to the deposit_partner_id + # should delete the transport request + order_VEV.delivery_partner_id = self.company_1GG.joint_buying_partner_id + self.assertFalse(order_VEV.transport_request_id) + + # Change delivery_partner_id to a third partner + # should recrate the transport request + order_VEV.delivery_partner_id = self.company_CDA.joint_buying_partner_id + self.assertTrue(order_VEV.transport_request_id) + request = order_VEV.transport_request_id + self.assertEqual(request.start_partner_id.joint_buying_code, "1GG") + self.assertEqual(request.arrival_partner_id.joint_buying_code, "CDA") + self.assertEqual(request.state, "to_compute") + + request.button_compute_tour() + self.assertEqual(request.state, "computed") + self.assertEqual(len(request.line_ids), 3) + self.assertEqual(request.line_ids[0].starting_point_id.joint_buying_code, "1GG") + self.assertEqual(request.line_ids[0].arrival_point_id.joint_buying_code, "LSE") + self.assertEqual(request.line_ids[1].starting_point_id.joint_buying_code, "LSE") + self.assertEqual(request.line_ids[1].arrival_point_id.joint_buying_code, "VEV") + self.assertEqual(request.line_ids[2].starting_point_id.joint_buying_code, "VEV") + self.assertEqual(request.line_ids[2].arrival_point_id.joint_buying_code, "CDA") + + def test_joint_buying_order_grouped_change_deposit_partner(self): + + grouped_order = self.env.ref("joint_buying_product.grouped_order_ronzon_past") + order_LSE = grouped_order.order_ids.filtered( + lambda x: x.customer_id.joint_buying_code == "LSE" + ) + self.assertTrue(order_LSE.transport_request_id) + + # Change the deposit partner should delete the order + # of the customer which is in the deposit place + grouped_order.deposit_partner_id = self.company_LSE.joint_buying_partner_id + self.assertFalse(order_LSE.transport_request_id) + + # Change the deposit partner should create the order + # of the customer which is not in the deposit place + grouped_order.deposit_partner_id = self.company_1GG.joint_buying_partner_id + self.assertTrue(order_LSE.transport_request_id) diff --git a/joint_buying_product/views/view_joint_buying_purchase_order.xml b/joint_buying_product/views/view_joint_buying_purchase_order.xml index a8970ccc..e3c912ef 100644 --- a/joint_buying_product/views/view_joint_buying_purchase_order.xml +++ b/joint_buying_product/views/view_joint_buying_purchase_order.xml @@ -104,6 +104,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +