From 99732b588ad40e8517960b2d51fce9859db6f99f Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Tue, 27 Sep 2022 15:12:33 +0200 Subject: [PATCH 01/30] [MIG] rename account_invoice_mode_at_shipping --- partner_invoicing_mode_at_shipping/README.rst | 0 .../__init__.py | 2 + .../__manifest__.py | 15 + .../data/queue_job_data.xml | 15 + .../models/__init__.py | 3 + .../models/res_partner.py | 13 + .../models/stock_move.py | 19 + .../models/stock_picking.py | 49 ++ .../readme/CONTRIBUTORS.rst | 5 + .../readme/CREDITS.rst | 3 + .../readme/DESCRIPTION.rst | 4 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 438 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_invoice_mode_at_shipping.py | 57 +++ 15 files changed, 624 insertions(+) create mode 100644 partner_invoicing_mode_at_shipping/README.rst create mode 100644 partner_invoicing_mode_at_shipping/__init__.py create mode 100644 partner_invoicing_mode_at_shipping/__manifest__.py create mode 100644 partner_invoicing_mode_at_shipping/data/queue_job_data.xml create mode 100644 partner_invoicing_mode_at_shipping/models/__init__.py create mode 100644 partner_invoicing_mode_at_shipping/models/res_partner.py create mode 100644 partner_invoicing_mode_at_shipping/models/stock_move.py create mode 100644 partner_invoicing_mode_at_shipping/models/stock_picking.py create mode 100644 partner_invoicing_mode_at_shipping/readme/CONTRIBUTORS.rst create mode 100644 partner_invoicing_mode_at_shipping/readme/CREDITS.rst create mode 100644 partner_invoicing_mode_at_shipping/readme/DESCRIPTION.rst create mode 100644 partner_invoicing_mode_at_shipping/static/description/icon.png create mode 100644 partner_invoicing_mode_at_shipping/static/description/index.html create mode 100644 partner_invoicing_mode_at_shipping/tests/__init__.py create mode 100644 partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py diff --git a/partner_invoicing_mode_at_shipping/README.rst b/partner_invoicing_mode_at_shipping/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/partner_invoicing_mode_at_shipping/__init__.py b/partner_invoicing_mode_at_shipping/__init__.py new file mode 100644 index 00000000000..0ee8b5073e2 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import tests diff --git a/partner_invoicing_mode_at_shipping/__manifest__.py b/partner_invoicing_mode_at_shipping/__manifest__.py new file mode 100644 index 00000000000..7815728e342 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2020 Camptocamp +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Partner Invoicing Mode At Shipping", + "version": "15.0.1.0.0", + "summary": "Create invoices automatically when goods are shipped.", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-invoicing", + "license": "AGPL-3", + "category": "Accounting & Finance", + "data": [ + "data/queue_job_data.xml", + ], + "depends": ["account", "partner_invoicing_mode", "queue_job", "stock"], +} diff --git a/partner_invoicing_mode_at_shipping/data/queue_job_data.xml b/partner_invoicing_mode_at_shipping/data/queue_job_data.xml new file mode 100644 index 00000000000..b5f70b53f5c --- /dev/null +++ b/partner_invoicing_mode_at_shipping/data/queue_job_data.xml @@ -0,0 +1,15 @@ + + + + + invoice_at_shipping + + + + + + + _invoicing_at_shipping + + + diff --git a/partner_invoicing_mode_at_shipping/models/__init__.py b/partner_invoicing_mode_at_shipping/models/__init__.py new file mode 100644 index 00000000000..b87ddbd73f5 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/models/__init__.py @@ -0,0 +1,3 @@ +from . import res_partner +from . import stock_move +from . import stock_picking diff --git a/partner_invoicing_mode_at_shipping/models/res_partner.py b/partner_invoicing_mode_at_shipping/models/res_partner.py new file mode 100644 index 00000000000..f9a1327e249 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/models/res_partner.py @@ -0,0 +1,13 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + invoicing_mode = fields.Selection( + selection_add=[("at_shipping", "At Shipping")], + ondelete={"at_shipping": "set default"}, + ) diff --git a/partner_invoicing_mode_at_shipping/models/stock_move.py b/partner_invoicing_mode_at_shipping/models/stock_move.py new file mode 100644 index 00000000000..3870a990091 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/models/stock_move.py @@ -0,0 +1,19 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import models + + +class StockMove(models.Model): + _inherit = "stock.move" + + def _get_related_invoices(self): + """Overridden from stock_account to return the customer invoices + related to this stock move. + """ + invoices = super()._get_related_invoices() + line_invoices = self.mapped("sale_line_id.order_id.invoice_ids").filtered( + lambda x: x.state == "posted" + ) + invoices |= line_invoices + return invoices diff --git a/partner_invoicing_mode_at_shipping/models/stock_picking.py b/partner_invoicing_mode_at_shipping/models/stock_picking.py new file mode 100644 index 00000000000..1dd7e24ac40 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/models/stock_picking.py @@ -0,0 +1,49 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import _, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + def _action_done(self): + res = super()._action_done() + for picking in self: + if picking._invoice_at_shipping(): + picking.with_delay()._invoicing_at_shipping() + return res + + def _invoice_at_shipping(self): + """Check if picking must be invoiced at shipping.""" + self.ensure_one() + return ( + self.picking_type_code == "outgoing" + and self.sale_id.partner_invoice_id.invoicing_mode == "at_shipping" + ) + + def _invoicing_at_shipping(self): + self.ensure_one() + sales = self.env["sale.order"].browse() + # Filter out non invoicable sales order + for sale in self._get_sales_order_to_invoice(): + if sale._get_invoiceable_lines(): + sales |= sale + # Split invoice creation on partner sales grouping on invoice settings + sales_one_invoice_per_order = sales.filtered( + "partner_invoice_id.one_invoice_per_order" + ) + invoices = self.env["account.move"].browse() + if sales_one_invoice_per_order: + invoices |= sales_one_invoice_per_order._create_invoices(grouped=True) + sales_many_invoice_per_order = sales - sales_one_invoice_per_order + if sales_many_invoice_per_order: + invoices |= sales_many_invoice_per_order._create_invoices(grouped=False) + for invoice in invoices: + invoice.with_delay()._validate_invoice() + return invoices or _("Nothing to invoice.") + + def _get_sales_order_to_invoice(self): + return self.mapped("move_lines.sale_line_id.order_id").filtered( + lambda r: r._get_invoiceable_lines() + ) diff --git a/partner_invoicing_mode_at_shipping/readme/CONTRIBUTORS.rst b/partner_invoicing_mode_at_shipping/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..ecddfcde7f4 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* `Camptocamp `_: + + * Thierry Ducrest + +* Phuc (Tran Thanh) diff --git a/partner_invoicing_mode_at_shipping/readme/CREDITS.rst b/partner_invoicing_mode_at_shipping/readme/CREDITS.rst new file mode 100644 index 00000000000..f5cc070c78e --- /dev/null +++ b/partner_invoicing_mode_at_shipping/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* Camptocamp diff --git a/partner_invoicing_mode_at_shipping/readme/DESCRIPTION.rst b/partner_invoicing_mode_at_shipping/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..9a3d5a02e2d --- /dev/null +++ b/partner_invoicing_mode_at_shipping/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This module allows to select a `At shipping` invoicing mode for a customer. +It is based on `partner_invoicing_mode`. +When this mode is selected the customer will be invoiced automatically on +delivery of the goods. diff --git a/partner_invoicing_mode_at_shipping/static/description/icon.png b/partner_invoicing_mode_at_shipping/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/partner_invoicing_mode_at_shipping/static/description/index.html b/partner_invoicing_mode_at_shipping/static/description/index.html new file mode 100644 index 00000000000..e5585743373 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/static/description/index.html @@ -0,0 +1,438 @@ + + + + + + +Account Invoice Mode At Shipping + + + +
+

Account Invoice Mode At Shipping

+ + +

Beta License: AGPL-3 OCA/account-invoicing Translate me on Weblate Try me on Runbot

+

This module allows to select a At shipping invoicing mode for a customer. +It is based on account_invoice_base_invoicing_mode. +When this mode is selected the customer will be invoiced automatically on +delivery of the goods.

+

Table of contents

+ +
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been financially supported by:

+
    +
  • Camptocamp
  • +
+
+
+

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/account-invoicing project on GitHub.

+

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

+
+
+
+ + diff --git a/partner_invoicing_mode_at_shipping/tests/__init__.py b/partner_invoicing_mode_at_shipping/tests/__init__.py new file mode 100644 index 00000000000..094b649436f --- /dev/null +++ b/partner_invoicing_mode_at_shipping/tests/__init__.py @@ -0,0 +1 @@ +from . import test_invoice_mode_at_shipping diff --git a/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py b/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py new file mode 100644 index 00000000000..2caccae74f8 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py @@ -0,0 +1,57 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.tests.common import TransactionCase + + +class TestInvoiceModeAtShipping(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.partner = cls.env.ref("base.res_partner_1") + cls.product = cls.env.ref("product.product_delivery_01") + cls.so1 = cls.env["sale.order"].create( + { + "partner_id": cls.partner.id, + "partner_invoice_id": cls.partner.id, + "partner_shipping_id": cls.partner.id, + "order_line": [ + ( + 0, + 0, + { + "name": "Line one", + "product_id": cls.product.id, + "product_uom_qty": 4, + "product_uom": cls.product.uom_id.id, + "price_unit": 123, + }, + ) + ], + "pricelist_id": cls.env.ref("product.list0").id, + } + ) + + def test_invoice_created_at_shipping(self): + """Check that an invoice is created when goods are shipped.""" + self.partner.invoicing_mode = "at_shipping" + self.so1.action_confirm() + for picking in self.so1.picking_ids: + for line in picking.move_lines: + line.quantity_done = line.product_uom_qty + picking.action_assign() + picking.with_context(test_queue_job_no_delay=True).button_validate() + self.assertEqual(len(self.so1.invoice_ids), 1) + self.assertEqual(self.so1.invoice_ids.state, "posted") + + def test_invoice_not_created_at_shipping(self): + """Check that an invoice is not created when goods are shipped.""" + self.partner.invoicing_mode = "standard" + self.so1.action_confirm() + for picking in self.so1.picking_ids: + for line in picking.move_lines: + line.quantity_done = line.product_uom_qty + picking.action_assign() + picking.button_validate() + self.assertEqual(len(self.so1.invoice_ids), 0) From dcbed15abc0bd9d7868bffcdfbcf7a2c746b9ed8 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Wed, 30 Nov 2022 18:08:02 +0100 Subject: [PATCH 02/30] [MIG] partner_invoicing_mode_at_shipping: Migration to 16.0 --- partner_invoicing_mode_at_shipping/README.rst | 87 +++++++++++++++++++ .../__init__.py | 1 - .../__manifest__.py | 2 +- .../models/stock_move.py | 2 +- .../models/stock_picking.py | 10 +-- .../static/description/index.html | 16 ++-- .../tests/test_invoice_mode_at_shipping.py | 81 +++++++++++++++-- 7 files changed, 175 insertions(+), 24 deletions(-) diff --git a/partner_invoicing_mode_at_shipping/README.rst b/partner_invoicing_mode_at_shipping/README.rst index e69de29bb2d..94f493a81d1 100644 --- a/partner_invoicing_mode_at_shipping/README.rst +++ b/partner_invoicing_mode_at_shipping/README.rst @@ -0,0 +1,87 @@ +================================== +Partner Invoicing Mode At Shipping +================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/licence-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%2Faccount--invoicing-lightgray.png?logo=github + :target: https://github.com/OCA/account-invoicing/tree/16.0/partner_invoicing_mode_at_shipping + :alt: OCA/account-invoicing +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-invoicing-16-0/account-invoicing-16-0-partner_invoicing_mode_at_shipping + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/95/16.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to select a `At shipping` invoicing mode for a customer. +It is based on `partner_invoicing_mode`. +When this mode is selected the customer will be invoiced automatically on +delivery of the goods. + +**Table of contents** + +.. contents:: + :local: + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* `Camptocamp `_: + + * Thierry Ducrest + +* Phuc (Tran Thanh) + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* Camptocamp + +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/account-invoicing `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/partner_invoicing_mode_at_shipping/__init__.py b/partner_invoicing_mode_at_shipping/__init__.py index 0ee8b5073e2..0650744f6bc 100644 --- a/partner_invoicing_mode_at_shipping/__init__.py +++ b/partner_invoicing_mode_at_shipping/__init__.py @@ -1,2 +1 @@ from . import models -from . import tests diff --git a/partner_invoicing_mode_at_shipping/__manifest__.py b/partner_invoicing_mode_at_shipping/__manifest__.py index 7815728e342..f3bffecec92 100644 --- a/partner_invoicing_mode_at_shipping/__manifest__.py +++ b/partner_invoicing_mode_at_shipping/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Partner Invoicing Mode At Shipping", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "summary": "Create invoices automatically when goods are shipped.", "author": "Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-invoicing", diff --git a/partner_invoicing_mode_at_shipping/models/stock_move.py b/partner_invoicing_mode_at_shipping/models/stock_move.py index 3870a990091..7dc6546baed 100644 --- a/partner_invoicing_mode_at_shipping/models/stock_move.py +++ b/partner_invoicing_mode_at_shipping/models/stock_move.py @@ -12,7 +12,7 @@ def _get_related_invoices(self): related to this stock move. """ invoices = super()._get_related_invoices() - line_invoices = self.mapped("sale_line_id.order_id.invoice_ids").filtered( + line_invoices = self.sale_line_id.order_id.invoice_ids.filtered( lambda x: x.state == "posted" ) invoices |= line_invoices diff --git a/partner_invoicing_mode_at_shipping/models/stock_picking.py b/partner_invoicing_mode_at_shipping/models/stock_picking.py index 1dd7e24ac40..da62d0fbd7c 100644 --- a/partner_invoicing_mode_at_shipping/models/stock_picking.py +++ b/partner_invoicing_mode_at_shipping/models/stock_picking.py @@ -24,16 +24,12 @@ def _invoice_at_shipping(self): def _invoicing_at_shipping(self): self.ensure_one() - sales = self.env["sale.order"].browse() - # Filter out non invoicable sales order - for sale in self._get_sales_order_to_invoice(): - if sale._get_invoiceable_lines(): - sales |= sale + sales = self._get_sales_order_to_invoice() # Split invoice creation on partner sales grouping on invoice settings sales_one_invoice_per_order = sales.filtered( "partner_invoice_id.one_invoice_per_order" ) - invoices = self.env["account.move"].browse() + invoices = self.env["account.move"] if sales_one_invoice_per_order: invoices |= sales_one_invoice_per_order._create_invoices(grouped=True) sales_many_invoice_per_order = sales - sales_one_invoice_per_order @@ -44,6 +40,6 @@ def _invoicing_at_shipping(self): return invoices or _("Nothing to invoice.") def _get_sales_order_to_invoice(self): - return self.mapped("move_lines.sale_line_id.order_id").filtered( + return self.move_ids.sale_line_id.order_id.filtered( lambda r: r._get_invoiceable_lines() ) diff --git a/partner_invoicing_mode_at_shipping/static/description/index.html b/partner_invoicing_mode_at_shipping/static/description/index.html index e5585743373..3f86dbd697c 100644 --- a/partner_invoicing_mode_at_shipping/static/description/index.html +++ b/partner_invoicing_mode_at_shipping/static/description/index.html @@ -3,8 +3,8 @@ - -Account Invoice Mode At Shipping + +Partner Invoicing Mode At Shipping -
-

Account Invoice Mode At Shipping

+
+

Partner Invoicing Mode At Shipping

-

Beta License: AGPL-3 OCA/account-invoicing Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/account-invoicing Translate me on Weblate Try me on Runbot

This module allows to select a At shipping invoicing mode for a customer. -It is based on account_invoice_base_invoicing_mode. +It is based on partner_invoicing_mode. When this mode is selected the customer will be invoiced automatically on delivery of the goods.

Table of contents

@@ -390,7 +390,7 @@

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 smashing it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -429,7 +429,7 @@

Maintainers

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/account-invoicing project on GitHub.

+

This module is part of the OCA/account-invoicing project on GitHub.

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

diff --git a/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py b/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py index 2caccae74f8..b83563d9415 100644 --- a/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py +++ b/partner_invoicing_mode_at_shipping/tests/test_invoice_mode_at_shipping.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from odoo.tests.common import TransactionCase +from odoo.tools import mute_logger class TestInvoiceModeAtShipping(TransactionCase): @@ -38,9 +39,10 @@ def test_invoice_created_at_shipping(self): self.partner.invoicing_mode = "at_shipping" self.so1.action_confirm() for picking in self.so1.picking_ids: - for line in picking.move_lines: - line.quantity_done = line.product_uom_qty - picking.action_assign() + for move in picking.move_ids: + move.quantity_done = move.product_uom_qty + picking.action_assign() + with mute_logger("odoo.addons.queue_job.delay"): picking.with_context(test_queue_job_no_delay=True).button_validate() self.assertEqual(len(self.so1.invoice_ids), 1) self.assertEqual(self.so1.invoice_ids.state, "posted") @@ -50,8 +52,75 @@ def test_invoice_not_created_at_shipping(self): self.partner.invoicing_mode = "standard" self.so1.action_confirm() for picking in self.so1.picking_ids: - for line in picking.move_lines: - line.quantity_done = line.product_uom_qty + for move in picking.move_ids: + move.quantity_done = move.product_uom_qty picking.action_assign() - picking.button_validate() + with mute_logger("odoo.addons.queue_job.delay"): + picking.with_context(test_queue_job_no_delay=True).button_validate() self.assertEqual(len(self.so1.invoice_ids), 0) + + def test_picking_multi_order_single_invoice(self): + """A picking for more than one sale order creating a single invoice""" + self.partner.invoicing_mode = "at_shipping" + self.partner.one_invoice_per_order = False + so2 = self.so1.copy() + for order in self.so1, so2: + order.action_confirm() + # Effectively merge both pickings + picking = self.so1.picking_ids + so2.picking_ids.move_ids.picking_id = picking + # Transfer the remaining picking with moves + for move in picking.move_ids: + move.quantity_done = move.product_uom_qty + picking.action_assign() + with mute_logger("odoo.addons.queue_job.delay"): + picking.with_context(test_queue_job_no_delay=True).button_validate() + self.assertEqual(len(self.so1.invoice_ids), 1) + self.assertEqual(self.so1.invoice_ids.state, "posted") + self.assertEqual(self.so1.invoice_ids, so2.invoice_ids) + + def test_picking_multi_order_multi_invoice(self): + """A picking for more than one sale order creates more than one invoice""" + self.partner.invoicing_mode = "at_shipping" + self.partner.one_invoice_per_order = True + so2 = self.so1.copy() + for order in self.so1, so2: + order.action_confirm() + # Effectively merge both pickings + picking = self.so1.picking_ids + so2.picking_ids.move_ids.picking_id = picking + # Transfer the remaining picking with moves + for move in picking.move_ids: + move.quantity_done = move.product_uom_qty + picking.action_assign() + with mute_logger("odoo.addons.queue_job.delay"): + picking.with_context(test_queue_job_no_delay=True).button_validate() + self.assertEqual(len(self.so1.invoice_ids), 1) + self.assertEqual(self.so1.invoice_ids.state, "posted") + self.assertEqual(len(so2.invoice_ids), 1) + self.assertEqual(so2.invoice_ids.state, "posted") + self.assertNotEqual(self.so1.invoice_ids, so2.invoice_ids) + + def test_picking_backorder(self): + """In case of a backorder, another invoice is created""" + self.partner.invoicing_mode = "at_shipping" + self.so1.action_confirm() + picking = self.so1.picking_ids + picking.move_ids.quantity_done = 2 + picking.action_assign() + with mute_logger("odoo.addons.queue_job.delay"): + picking.with_context( + skip_backorder=True, test_queue_job_no_delay=True + ).button_validate() + self.assertEqual(len(self.so1.invoice_ids), 1) + self.assertEqual(self.so1.invoice_ids.state, "posted") + # Now process the backorder + backorder = self.so1.picking_ids - picking + backorder.move_ids.quantity_done = 2 + backorder.action_assign() + with mute_logger("odoo.addons.queue_job.delay"): + backorder.with_context(test_queue_job_no_delay=True).button_validate() + self.assertEqual(len(self.so1.invoice_ids), 2) + self.assertTrue( + all(invoice.state == "posted") for invoice in self.so1.invoice_ids + ) From eac108968a7215245834d07074d0dbb27d03c7f7 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 21 Apr 2023 00:44:03 +0000 Subject: [PATCH 03/30] [UPD] Update partner_invoicing_mode_at_shipping.pot --- .../partner_invoicing_mode_at_shipping.pot | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 partner_invoicing_mode_at_shipping/i18n/partner_invoicing_mode_at_shipping.pot diff --git a/partner_invoicing_mode_at_shipping/i18n/partner_invoicing_mode_at_shipping.pot b/partner_invoicing_mode_at_shipping/i18n/partner_invoicing_mode_at_shipping.pot new file mode 100644 index 00000000000..2a52ab4c717 --- /dev/null +++ b/partner_invoicing_mode_at_shipping/i18n/partner_invoicing_mode_at_shipping.pot @@ -0,0 +1,47 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_invoicing_mode_at_shipping +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: partner_invoicing_mode_at_shipping +#: model:ir.model.fields.selection,name:partner_invoicing_mode_at_shipping.selection__res_partner__invoicing_mode__at_shipping +msgid "At Shipping" +msgstr "" + +#. module: partner_invoicing_mode_at_shipping +#: model:ir.model,name:partner_invoicing_mode_at_shipping.model_res_partner +msgid "Contact" +msgstr "" + +#. module: partner_invoicing_mode_at_shipping +#: model:ir.model.fields,field_description:partner_invoicing_mode_at_shipping.field_res_partner__invoicing_mode +#: model:ir.model.fields,field_description:partner_invoicing_mode_at_shipping.field_res_users__invoicing_mode +msgid "Invoicing Mode" +msgstr "" + +#. module: partner_invoicing_mode_at_shipping +#. odoo-python +#: code:addons/partner_invoicing_mode_at_shipping/models/stock_picking.py:0 +#, python-format +msgid "Nothing to invoice." +msgstr "" + +#. module: partner_invoicing_mode_at_shipping +#: model:ir.model,name:partner_invoicing_mode_at_shipping.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: partner_invoicing_mode_at_shipping +#: model:ir.model,name:partner_invoicing_mode_at_shipping.model_stock_picking +msgid "Transfer" +msgstr "" From 19ce00ed8c8006f842e78a1cb78b5118d3c0bf60 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 21 Apr 2023 00:48:31 +0000 Subject: [PATCH 04/30] [UPD] README.rst --- .../static/description/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/partner_invoicing_mode_at_shipping/static/description/index.html b/partner_invoicing_mode_at_shipping/static/description/index.html index 3f86dbd697c..229a168ddc8 100644 --- a/partner_invoicing_mode_at_shipping/static/description/index.html +++ b/partner_invoicing_mode_at_shipping/static/description/index.html @@ -3,7 +3,7 @@ - + Partner Invoicing Mode At Shipping