diff --git a/purchase_reception_notify/README.rst b/purchase_reception_notify/README.rst new file mode 100644 index 00000000000..b80651fbbb8 --- /dev/null +++ b/purchase_reception_notify/README.rst @@ -0,0 +1,102 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +========================= +Purchase Reception Notify +========================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:56ebe85de4be40127c1f520b1cc3bd4d19e178630d7b83bfc896b95d8c1c6995 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/purchase-workflow/tree/19.0/purchase_reception_notify + :alt: OCA/purchase-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/purchase-workflow-19-0/purchase-workflow-19-0-purchase_reception_notify + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/purchase-workflow&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module automatically notifies the employees following a purchase +order as soon as the associated products have been received into stock. + +It also introduces a new message subtype specifically created for those +notifications. This subtype is set to internal by default when +subscribing. The old purchase orders will be updated to assign this new +subtype to the existing followers, as long as they are still active +employees. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Integrated in the normal flow. + +Create a Purchase Order with at least one product with a specified +quantity and confirm th purchase order to generate the corresponding +incoming shipment. Once the purchase order is confirmed, go to Inventory +-> Operations -> Receipts. Open the generated receipt and click on +"Validate". The message will be automatically generated. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ForgeFlow + +Contributors +------------ + +- Aaron Henriquez +- Jordi Ballester +- `Heliconia Solutions Pvt. Ltd. `__ + + - Bhavesh Heliconia + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/purchase-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_reception_notify/__init__.py b/purchase_reception_notify/__init__.py new file mode 100644 index 00000000000..cc6b6354ad8 --- /dev/null +++ b/purchase_reception_notify/__init__.py @@ -0,0 +1,2 @@ +from . import models +from .hooks import post_init_hook diff --git a/purchase_reception_notify/__manifest__.py b/purchase_reception_notify/__manifest__.py new file mode 100644 index 00000000000..9944af4f015 --- /dev/null +++ b/purchase_reception_notify/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2019-2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3.0). + +{ + "name": "Purchase Reception Notify", + "version": "19.0.1.0.0", + "category": "Purchase Management", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/purchase-workflow", + "license": "AGPL-3", + "depends": ["purchase_stock"], + "data": ["data/mail_data.xml"], + "installable": True, + "post_init_hook": "post_init_hook", +} diff --git a/purchase_reception_notify/data/mail_data.xml b/purchase_reception_notify/data/mail_data.xml new file mode 100644 index 00000000000..8c287cc1974 --- /dev/null +++ b/purchase_reception_notify/data/mail_data.xml @@ -0,0 +1,9 @@ + + + + Purchase Receptions + purchase.order + + + + diff --git a/purchase_reception_notify/hooks.py b/purchase_reception_notify/hooks.py new file mode 100644 index 00000000000..e79ad51ec13 --- /dev/null +++ b/purchase_reception_notify/hooks.py @@ -0,0 +1,32 @@ +# Copyright 2019-2024 ForgeFlow S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import logging + +_logger = logging.getLogger(__name__) + + +def post_init_hook(env): + """Existing employees should be subscribed to the new subtype for all + existing purchase orders. + """ + _logger.info( + "Starting task to update internal followers for " + "existing purchase orders to assign the new subtype " + "Purchase Receptions." + ) + users = env["res.users"].search([]) + followers = env["mail.followers"].search( + [ + ("res_model", "=", "purchase.order"), + ("partner_id", "in", users.mapped("partner_id").ids), + ] + ) + for follower in followers: + follower.subtype_ids += env.ref( + "purchase_reception_notify.mt_purchase_reception" + ) + _logger.info( + "Finalized task to update internal followers for " + "existing purchase orders to assign the new subtype " + "Purchase Receptions." + ) diff --git a/purchase_reception_notify/i18n/es.po b/purchase_reception_notify/i18n/es.po new file mode 100644 index 00000000000..de2432e8c22 --- /dev/null +++ b/purchase_reception_notify/i18n/es.po @@ -0,0 +1,47 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_reception_notify +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-15 21:38+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "" +"
  • %(display_name)s: Received quantity %(product_qty)s %(uom)s
  • " +msgstr "" +"
  • %(display_name)s: Cantidad recibida %(product_qty)s %(uom)s
  • " + +#. module: purchase_reception_notify +#: model:mail.message.subtype,name:purchase_reception_notify.mt_purchase_reception +msgid "Purchase Receptions" +msgstr "Recepción de Compras" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "Receipt confirmation %s" +msgstr "Confirmación de recepción %s" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "The following items have now been received in Incoming Shipment %s:" +msgstr "Los siguientes artículos ya se han recibido en %s de envío entrante:" + +#. module: purchase_reception_notify +#: model:ir.model,name:purchase_reception_notify.model_stock_picking +msgid "Transfer" +msgstr "Transferencia" diff --git a/purchase_reception_notify/i18n/it.po b/purchase_reception_notify/i18n/it.po new file mode 100644 index 00000000000..5d6566821f5 --- /dev/null +++ b/purchase_reception_notify/i18n/it.po @@ -0,0 +1,52 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_reception_notify +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-05-08 08:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "" +"
  • %(display_name)s: Received quantity %(product_qty)s %(uom)s
  • " +msgstr "" +"
  • %(display_name)s: quantità ricevuta %(product_qty)s %(uom)s
  • " + +#. module: purchase_reception_notify +#: model:mail.message.subtype,name:purchase_reception_notify.mt_purchase_reception +msgid "Purchase Receptions" +msgstr "Ricezioni Acquisti" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "Receipt confirmation %s" +msgstr "Conferma di ricezione %s" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "The following items have now been received in Incoming Shipment %s:" +msgstr "" +"I seguenti oggetti sono stati ricevuti nella spedizioni in ingresso %s:" + +#. module: purchase_reception_notify +#: model:ir.model,name:purchase_reception_notify.model_stock_picking +msgid "Transfer" +msgstr "Trasferimento" + +#, python-format +#~ msgid "
  • %s: Received quantity %s %s
  • " +#~ msgstr "
  • %s: Quantità ricevuta %s %s
  • " diff --git a/purchase_reception_notify/i18n/pt_BR.po b/purchase_reception_notify/i18n/pt_BR.po new file mode 100644 index 00000000000..77c0759f944 --- /dev/null +++ b/purchase_reception_notify/i18n/pt_BR.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_reception_notify +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "" +"
  • %(display_name)s: Received quantity %(product_qty)s %(uom)s
  • " +msgstr "" + +#. module: purchase_reception_notify +#: model:mail.message.subtype,name:purchase_reception_notify.mt_purchase_reception +msgid "Purchase Receptions" +msgstr "" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "Receipt confirmation {}" +msgstr "" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "The following items have now been received in Incoming Shipment {}:" +msgstr "" + +#. module: purchase_reception_notify +#: model:ir.model,name:purchase_reception_notify.model_stock_picking +msgid "Transfer" +msgstr "" diff --git a/purchase_reception_notify/i18n/purchase_reception_notify.pot b/purchase_reception_notify/i18n/purchase_reception_notify.pot new file mode 100644 index 00000000000..714abe3cbb3 --- /dev/null +++ b/purchase_reception_notify/i18n/purchase_reception_notify.pot @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_reception_notify +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "" +"
  • %(display_name)s: Received quantity %(product_qty)s %(uom)s
  • " +msgstr "" + +#. module: purchase_reception_notify +#: model:mail.message.subtype,name:purchase_reception_notify.mt_purchase_reception +msgid "Purchase Receptions" +msgstr "" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "Receipt confirmation {}" +msgstr "" + +#. module: purchase_reception_notify +#. odoo-python +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +msgid "The following items have now been received in Incoming Shipment {}:" +msgstr "" + +#. module: purchase_reception_notify +#: model:ir.model,name:purchase_reception_notify.model_stock_picking +msgid "Transfer" +msgstr "" diff --git a/purchase_reception_notify/i18n/zh_CN.po b/purchase_reception_notify/i18n/zh_CN.po new file mode 100644 index 00000000000..6eadc1df1c9 --- /dev/null +++ b/purchase_reception_notify/i18n/zh_CN.po @@ -0,0 +1,50 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_reception_notify +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-03-23 13:13+0000\n" +"Last-Translator: Dong \n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.10\n" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "" +"
  • %(display_name)s: Received quantity %(product_qty)s %(uom)s
  • " +msgstr "" + +#. module: purchase_reception_notify +#: model:mail.message.subtype,name:purchase_reception_notify.mt_purchase_reception +msgid "Purchase Receptions" +msgstr "采购收货" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "Receipt confirmation %s" +msgstr "收货确认 %s" + +#. module: purchase_reception_notify +#: code:addons/purchase_reception_notify/models/stock_picking.py:0 +#, python-format +msgid "The following items have now been received in Incoming Shipment %s:" +msgstr "已在收货单 %s 中收到下列产品:" + +#. module: purchase_reception_notify +#: model:ir.model,name:purchase_reception_notify.model_stock_picking +msgid "Transfer" +msgstr "调拨" + +#, python-format +#~ msgid "
  • %s: Received quantity %s %s
  • " +#~ msgstr "
  • %s:已收货数量 %s %s
  • " diff --git a/purchase_reception_notify/models/__init__.py b/purchase_reception_notify/models/__init__.py new file mode 100644 index 00000000000..ae4c27227f1 --- /dev/null +++ b/purchase_reception_notify/models/__init__.py @@ -0,0 +1 @@ +from . import stock_picking diff --git a/purchase_reception_notify/models/stock_picking.py b/purchase_reception_notify/models/stock_picking.py new file mode 100644 index 00000000000..2dc4f5d395d --- /dev/null +++ b/purchase_reception_notify/models/stock_picking.py @@ -0,0 +1,62 @@ +# Copyright 2019-2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). + +from markupsafe import Markup, escape + +from odoo import api, models + + +class Picking(models.Model): + _inherit = "stock.picking" + + @api.model + def _purchase_order_picking_confirm_message_content(self, picking, purchase_dict): + if not purchase_dict: + purchase_dict = {} + title = self.env._("Receipt confirmation %s", picking.name) + message = f"

    {title}

    " + message += self.env._( + "The following items have now been received in Incoming Shipment %s", + picking.name, + ) + + message += "
      " + for purchase_line_id in purchase_dict.values(): + display_name = purchase_line_id["purchase_line"].product_id.display_name + product_qty = purchase_line_id["stock_move"].product_qty + uom = purchase_line_id["stock_move"].product_uom.name + + message += self.env._( + "
    • %(display_name)s: Received quantity " + "%(product_qty)s %(uom)s
    • ", + display_name=escape(display_name), + product_qty=product_qty, + uom=escape(uom), + ) + message += "
    " + return Markup(message) + + def _action_done(self): + res = super()._action_done() + for picking in self.filtered(lambda p: p.picking_type_id.code == "incoming"): + purchase_dict = {} + for move in picking.move_ids.filtered("purchase_line_id"): + pol_id = move.purchase_line_id + if pol_id.order_id not in purchase_dict.keys(): + purchase_dict[pol_id.order_id] = {} + if pol_id.id not in purchase_dict[pol_id.order_id].keys(): + purchase_dict[pol_id.order_id][pol_id.id] = {} + data = {"purchase_line": pol_id, "stock_move": move} + purchase_dict[pol_id.order_id][pol_id.id] = data + for po in purchase_dict.keys(): + message = self._purchase_order_picking_confirm_message_content( + picking, purchase_dict[po] + ) + po.sudo().message_post( + body=message, + subtype_id=self.env.ref( + "purchase_reception_notify.mt_purchase_reception" + ).id, + author_id=self.env.user.partner_id.id, + ) + return res diff --git a/purchase_reception_notify/pyproject.toml b/purchase_reception_notify/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/purchase_reception_notify/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/purchase_reception_notify/readme/CONTRIBUTORS.md b/purchase_reception_notify/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..48e4da05621 --- /dev/null +++ b/purchase_reception_notify/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Aaron Henriquez \<\> +- Jordi Ballester \<\> +- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io) + - Bhavesh Heliconia diff --git a/purchase_reception_notify/readme/DESCRIPTION.md b/purchase_reception_notify/readme/DESCRIPTION.md new file mode 100644 index 00000000000..8223e1b5c15 --- /dev/null +++ b/purchase_reception_notify/readme/DESCRIPTION.md @@ -0,0 +1,8 @@ +This module automatically notifies the employees following a purchase order +as soon as the associated products have been received into stock. + +It also introduces a new message subtype specifically created for those +notifications. This subtype is set to internal by default when +subscribing. The old purchase orders will be updated to assign this new +subtype to the existing followers, as long as they are still active +employees. diff --git a/purchase_reception_notify/readme/USAGE.md b/purchase_reception_notify/readme/USAGE.md new file mode 100644 index 00000000000..bcef1b57ad6 --- /dev/null +++ b/purchase_reception_notify/readme/USAGE.md @@ -0,0 +1,6 @@ +Integrated in the normal flow. + +Create a Purchase Order with at least one product with a specified quantity and confirm th purchase order +to generate the corresponding incoming shipment. Once the purchase order is confirmed, +go to Inventory -> Operations -> Receipts. Open the generated receipt and click on "Validate". +The message will be automatically generated. diff --git a/purchase_reception_notify/static/description/icon.png b/purchase_reception_notify/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/purchase_reception_notify/static/description/icon.png differ diff --git a/purchase_reception_notify/static/description/index.html b/purchase_reception_notify/static/description/index.html new file mode 100644 index 00000000000..e85989e04e8 --- /dev/null +++ b/purchase_reception_notify/static/description/index.html @@ -0,0 +1,450 @@ + + + + + +README.rst + + + +
    + + + +Odoo Community Association + +
    +

    Purchase Reception Notify

    + +

    Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

    +

    This module automatically notifies the employees following a purchase +order as soon as the associated products have been received into stock.

    +

    It also introduces a new message subtype specifically created for those +notifications. This subtype is set to internal by default when +subscribing. The old purchase orders will be updated to assign this new +subtype to the existing followers, as long as they are still active +employees.

    +

    Table of contents

    + +
    +

    Usage

    +

    Integrated in the normal flow.

    +

    Create a Purchase Order with at least one product with a specified +quantity and confirm th purchase order to generate the corresponding +incoming shipment. Once the purchase order is confirmed, go to Inventory +-> Operations -> Receipts. Open the generated receipt and click on +“Validate”. The message will be automatically generated.

    +
    +
    +

    Bug Tracker

    +

    Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

    +

    Do not contact contributors directly about support or help with technical issues.

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • ForgeFlow
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

    OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

    +

    This module is part of the OCA/purchase-workflow project on GitHub.

    +

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    +
    +
    +
    +
    + + diff --git a/purchase_reception_notify/tests/__init__.py b/purchase_reception_notify/tests/__init__.py new file mode 100644 index 00000000000..c973f1c733f --- /dev/null +++ b/purchase_reception_notify/tests/__init__.py @@ -0,0 +1 @@ +from . import test_purchase_reception_notify diff --git a/purchase_reception_notify/tests/test_purchase_reception_notify.py b/purchase_reception_notify/tests/test_purchase_reception_notify.py new file mode 100644 index 00000000000..becf18ebb87 --- /dev/null +++ b/purchase_reception_notify/tests/test_purchase_reception_notify.py @@ -0,0 +1,125 @@ +from odoo.fields import Datetime + +from odoo.addons.base.tests.common import BaseCommon + + +class TestPurchaseReceptionNotify(BaseCommon): + @classmethod + def default_env_context(cls): + return {} + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.purchase_order_model = cls.env["purchase.order"] + cls.purchase_order_line_model = cls.env["purchase.order.line"] + cls.product_model = cls.env["product.product"] + cls.uom_model = cls.env["uom.uom"] + cls.stock_picking_model = cls.env["stock.picking"] + # UOM + cls.uom_unit = cls.env.ref("uom.product_uom_unit") + + # Product + cls.product = cls.product_model.sudo().create( + { + "name": "Product Test", + "uom_id": cls.uom_unit.id, + "purchase_method": "purchase", + } + ) + + # Purchase Order + cls.purchase_order = cls.purchase_order_model.create( + {"partner_id": cls.partner.id} + ) + cls.purchase_order_line = cls.purchase_order_line_model.sudo().create( + { + "date_planned": Datetime.now(), + "name": "PO01", + "order_id": cls.purchase_order.id, + "product_id": cls.product.id, + "product_uom_id": cls.uom_unit.id, + "price_unit": 1.0, + "product_qty": 5.0, + } + ) + cls.purchase_order.button_confirm() + + def test_action_done_message_post(self): + """Test that the _action_done method posts the correct message.""" + # Validate picking to trigger `_action_done` + picking = self.purchase_order.picking_ids + for move in picking.move_ids: + move.quantity = move.product_uom_qty # Set quantity as done + picking.button_validate() + + # Assert that a message was posted on the Purchase Order + self.assertTrue( + self.purchase_order.message_ids, + "No message was posted on the Purchase Order.", + ) + + # Check the last message content + last_message = self.purchase_order.message_ids[0] + self.assertIn( + "Receipt confirmation", + last_message.body, + "The confirmation message is not correctly posted.", + ) + self.assertIn( + "The following items have now been received", + last_message.body, + "The detailed message content is missing.", + ) + + # Check that the product name and quantity are in the message + self.assertIn( + self.product.display_name, + last_message.body, + "The product name is not included in the message.", + ) + self.assertIn( + str(self.purchase_order_line.product_qty), + last_message.body, + "The product quantity is not included in the message.", + ) + self.assertIn( + self.uom_unit.name, + last_message.body, + "The unit of measure is not included in the message.", + ) + + def test_action_done_empty_purchase_dict(self): + """Test that _action_done handles the case when purchase_dict is empty.""" + # Get the picking related to the purchase order + picking = self.purchase_order.picking_ids + + # Simulate a case where no moves are linked to purchase lines + for move in picking.move_ids: + move.write({"purchase_line_id": None}) + + # Validate the picking to trigger _action_done + for move in picking.move_ids: + move.quantity = move.product_uom_qty + picking.button_validate() + + # Ensure the purchase_dict line is covered by asserting no crash occurred + self.assertTrue( + picking.state == "done", + "Picking should be completed successfully " + "even with an empty purchase_dict.", + ) + + # Check that no custom message was posted for receipt confirmation + last_message = self.purchase_order.message_ids[0] + self.assertNotIn( + "Receipt confirmation", + last_message.body, + "A receipt confirmation message should not be posted " + "when purchase_dict is empty.", + ) + self.assertIn( + "Purchase Order created", + last_message.body, + "The default Purchase Order creation message should still exist.", + )