From 1a40e4e4e8ba3e0a995443c731df439c1cdc4f44 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Thu, 9 Jan 2025 12:27:07 +0100 Subject: [PATCH 1/8] [ADD] contract_sale_generation_prevent_loop --- .../README.rst | 59 +++ .../__init__.py | 1 + .../__manifest__.py | 15 + .../models/__init__.py | 4 + .../models/contract.py | 20 + .../models/sale_order.py | 17 + .../readme/DESCRIPTION.rst | 5 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 410 ++++++++++++++++++ .../contract_sale_generation_prevent_loop | 1 + .../setup.py | 6 + 11 files changed, 538 insertions(+) create mode 100644 contract_sale_generation_prevent_loop/README.rst create mode 100644 contract_sale_generation_prevent_loop/__init__.py create mode 100644 contract_sale_generation_prevent_loop/__manifest__.py create mode 100644 contract_sale_generation_prevent_loop/models/__init__.py create mode 100644 contract_sale_generation_prevent_loop/models/contract.py create mode 100644 contract_sale_generation_prevent_loop/models/sale_order.py create mode 100644 contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst create mode 100644 contract_sale_generation_prevent_loop/static/description/icon.png create mode 100644 contract_sale_generation_prevent_loop/static/description/index.html create mode 120000 setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop create mode 100644 setup/contract_sale_generation_prevent_loop/setup.py diff --git a/contract_sale_generation_prevent_loop/README.rst b/contract_sale_generation_prevent_loop/README.rst new file mode 100644 index 000000000..39e7fd110 --- /dev/null +++ b/contract_sale_generation_prevent_loop/README.rst @@ -0,0 +1,59 @@ +====================================== +Contracts Sale Generation Prevent Loop +====================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f86ca92372fb642d644f7a98d63c9db3ed81232c8ad02ef4afa66bddc64ec2f6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-coopiteasy%2Faddons-lightgray.png?logo=github + :target: https://github.com/coopiteasy/addons/tree/16.0/contract_sale_generation_prevent_loop + :alt: coopiteasy/addons + +|badge1| |badge2| |badge3| + +When using both product_contract and contract_sale_generation, the sale order generated from the contract will create another contract on confirmation : + +SO with a is_contract product, when confirmed, creates a contract. This contract contains the same is_contract product. If this contract is set to generate SO, then this contract will generate SOs with the same is_contract module. On confirmation these SOs will create a contract, and so on. + +We break this loop by preventing the creation on contracts if the origin of the SO is a contract. + +**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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Coop IT Easy SC + +Maintainers +~~~~~~~~~~~ + +This module is part of the `coopiteasy/addons `_ project on GitHub. + +You are welcome to contribute. diff --git a/contract_sale_generation_prevent_loop/__init__.py b/contract_sale_generation_prevent_loop/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/contract_sale_generation_prevent_loop/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/contract_sale_generation_prevent_loop/__manifest__.py b/contract_sale_generation_prevent_loop/__manifest__.py new file mode 100644 index 000000000..a5c20d235 --- /dev/null +++ b/contract_sale_generation_prevent_loop/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2017 Pesol () +# Copyright 2017 Angel Moya +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + + +{ + "name": "Contracts Sale Generation Prevent Loop", + "version": "16.0.1.0.0", + "category": "Contract Management", + "license": "AGPL-3", + "author": "Coop IT Easy SC", + "website": "https://github.com/coopiteasy/addons", + "depends": ["product_contract", "contract_sale_generation"], + "installable": True, +} diff --git a/contract_sale_generation_prevent_loop/models/__init__.py b/contract_sale_generation_prevent_loop/models/__init__.py new file mode 100644 index 000000000..a39950e1c --- /dev/null +++ b/contract_sale_generation_prevent_loop/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import sale_order +from . import contract diff --git a/contract_sale_generation_prevent_loop/models/contract.py b/contract_sale_generation_prevent_loop/models/contract.py new file mode 100644 index 000000000..79bf00261 --- /dev/null +++ b/contract_sale_generation_prevent_loop/models/contract.py @@ -0,0 +1,20 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, models +from odoo.exceptions import UserError + + +class ContractContract(models.Model): + _inherit = "contract.contract" + + def write(self, vals): + if "name" in vals and self.generation_type == "sale": + raise UserError( + _( + "Contracts generating sales should not be renamed. " + "In case this contracts contains a product-generating " + "contract, this will cause a loop of contract creation." + ) + ) + return super().write(vals) diff --git a/contract_sale_generation_prevent_loop/models/sale_order.py b/contract_sale_generation_prevent_loop/models/sale_order.py new file mode 100644 index 000000000..275d87a86 --- /dev/null +++ b/contract_sale_generation_prevent_loop/models/sale_order.py @@ -0,0 +1,17 @@ +# Copyright 2021 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + def action_create_contract(self): + source_contract = self.env["contract.contract"].search( + [("name", "=", self.origin)] + ) + if source_contract: + return False + else: + return super().action_create_contract() diff --git a/contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst b/contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst new file mode 100644 index 000000000..efe93f4fc --- /dev/null +++ b/contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +When using both product_contract and contract_sale_generation, the sale order generated from the contract will create another contract on confirmation : + +SO with a is_contract product, when confirmed, creates a contract. This contract contains the same is_contract product. If this contract is set to generate SO, then this contract will generate SOs with the same is_contract module. On confirmation these SOs will create a contract, and so on. + +We break this loop by preventing the creation on contracts if the origin of the SO is a contract. diff --git a/contract_sale_generation_prevent_loop/static/description/icon.png b/contract_sale_generation_prevent_loop/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/contract_sale_generation_prevent_loop/static/description/index.html b/contract_sale_generation_prevent_loop/static/description/index.html new file mode 100644 index 000000000..7efdcb055 --- /dev/null +++ b/contract_sale_generation_prevent_loop/static/description/index.html @@ -0,0 +1,410 @@ + + + + + +Contracts Sale Generation Prevent Loop + + + +
+

Contracts Sale Generation Prevent Loop

+ + +

Beta License: AGPL-3 coopiteasy/addons

+

When using both product_contract and contract_sale_generation, the sale order generated from the contract will create another contract on confirmation :

+

SO with a is_contract product, when confirmed, creates a contract. This contract contains the same is_contract product. If this contract is set to generate SO, then this contract will generate SOs with the same is_contract module. On confirmation these SOs will create a contract, and so on.

+

We break this loop by preventing the creation on contracts if the origin of the SO is a contract.

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Coop IT Easy SC
  • +
+
+
+

Maintainers

+

This module is part of the coopiteasy/addons project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop b/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop new file mode 120000 index 000000000..d17da5969 --- /dev/null +++ b/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop @@ -0,0 +1 @@ +../../../../contract_sale_generation_prevent_loop \ No newline at end of file diff --git a/setup/contract_sale_generation_prevent_loop/setup.py b/setup/contract_sale_generation_prevent_loop/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/contract_sale_generation_prevent_loop/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 295dec28c57736ed8b5b1f71a4d29055d4debf39 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Sat, 11 Jan 2025 12:48:48 +0100 Subject: [PATCH 2/8] [IMP] reset quantity for SO created from contracts --- .../__manifest__.py | 3 ++ .../models/__init__.py | 1 + .../models/contract.py | 5 ++++ .../models/sale_order.py | 4 ++- .../models/sale_order_line.py | 17 +++++++++++ .../views/sale_order.xml | 28 +++++++++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 contract_sale_generation_prevent_loop/models/sale_order_line.py create mode 100644 contract_sale_generation_prevent_loop/views/sale_order.xml diff --git a/contract_sale_generation_prevent_loop/__manifest__.py b/contract_sale_generation_prevent_loop/__manifest__.py index a5c20d235..433f7319f 100644 --- a/contract_sale_generation_prevent_loop/__manifest__.py +++ b/contract_sale_generation_prevent_loop/__manifest__.py @@ -12,4 +12,7 @@ "website": "https://github.com/coopiteasy/addons", "depends": ["product_contract", "contract_sale_generation"], "installable": True, + "data": [ + "views/sale_order.xml", + ], } diff --git a/contract_sale_generation_prevent_loop/models/__init__.py b/contract_sale_generation_prevent_loop/models/__init__.py index a39950e1c..4badda9e8 100644 --- a/contract_sale_generation_prevent_loop/models/__init__.py +++ b/contract_sale_generation_prevent_loop/models/__init__.py @@ -1,4 +1,5 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import sale_order +from . import sale_order_line from . import contract diff --git a/contract_sale_generation_prevent_loop/models/contract.py b/contract_sale_generation_prevent_loop/models/contract.py index 79bf00261..87355084d 100644 --- a/contract_sale_generation_prevent_loop/models/contract.py +++ b/contract_sale_generation_prevent_loop/models/contract.py @@ -8,6 +8,11 @@ class ContractContract(models.Model): _inherit = "contract.contract" + def _recurring_create_sale(self, date_ref=False): + res = super()._recurring_create_sale(date_ref) + res.created_from_contract = True + return res + def write(self, vals): if "name" in vals and self.generation_type == "sale": raise UserError( diff --git a/contract_sale_generation_prevent_loop/models/sale_order.py b/contract_sale_generation_prevent_loop/models/sale_order.py index 275d87a86..ee9e8277f 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order.py +++ b/contract_sale_generation_prevent_loop/models/sale_order.py @@ -1,12 +1,14 @@ # Copyright 2021 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models +from odoo import fields, models class SaleOrder(models.Model): _inherit = "sale.order" + created_from_contract = fields.Boolean(default=False, readonly=True) + def action_create_contract(self): source_contract = self.env["contract.contract"].search( [("name", "=", self.origin)] diff --git a/contract_sale_generation_prevent_loop/models/sale_order_line.py b/contract_sale_generation_prevent_loop/models/sale_order_line.py new file mode 100644 index 000000000..0a8ee930c --- /dev/null +++ b/contract_sale_generation_prevent_loop/models/sale_order_line.py @@ -0,0 +1,17 @@ +# Copyright 2021 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class SaleOrder(models.Model): + _inherit = "sale.order.line" + + def _compute_qty_to_invoice(self): + res = super()._compute_qty_to_invoice() + if self.order_id.created_from_contract: + # put back the right quantity to invoice + self.filtered("product_id.is_contract").update( + {"qty_to_invoice": self.product_uom_qty} + ) + return res diff --git a/contract_sale_generation_prevent_loop/views/sale_order.xml b/contract_sale_generation_prevent_loop/views/sale_order.xml new file mode 100644 index 000000000..d2b584789 --- /dev/null +++ b/contract_sale_generation_prevent_loop/views/sale_order.xml @@ -0,0 +1,28 @@ + + + + + sale.order.form (in product_contract) + sale.order + + + + + + + + {'invisible':['|', ('created_from_contract', '=', True), + ('need_contract_creation', '=', False)]} + + + + + From 8c2d415c6adddb0fc5dff548ede6df13a88ed3e3 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Sat, 11 Jan 2025 12:51:19 +0100 Subject: [PATCH 3/8] [IMP] stop checking origin of SO with origin name --- .../models/contract.py | 20 ++++--------------- .../models/sale_order.py | 5 +---- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/contract_sale_generation_prevent_loop/models/contract.py b/contract_sale_generation_prevent_loop/models/contract.py index 87355084d..ea0119dae 100644 --- a/contract_sale_generation_prevent_loop/models/contract.py +++ b/contract_sale_generation_prevent_loop/models/contract.py @@ -1,25 +1,13 @@ # Copyright 2018 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, models -from odoo.exceptions import UserError +from odoo import models class ContractContract(models.Model): _inherit = "contract.contract" - def _recurring_create_sale(self, date_ref=False): - res = super()._recurring_create_sale(date_ref) - res.created_from_contract = True + def _prepare_recurring_sales_values(self, date_ref=False): + res = super()._prepare_recurring_sales_values(date_ref) + res[0]["created_from_contract"] = True return res - - def write(self, vals): - if "name" in vals and self.generation_type == "sale": - raise UserError( - _( - "Contracts generating sales should not be renamed. " - "In case this contracts contains a product-generating " - "contract, this will cause a loop of contract creation." - ) - ) - return super().write(vals) diff --git a/contract_sale_generation_prevent_loop/models/sale_order.py b/contract_sale_generation_prevent_loop/models/sale_order.py index ee9e8277f..673e6f024 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order.py +++ b/contract_sale_generation_prevent_loop/models/sale_order.py @@ -10,10 +10,7 @@ class SaleOrder(models.Model): created_from_contract = fields.Boolean(default=False, readonly=True) def action_create_contract(self): - source_contract = self.env["contract.contract"].search( - [("name", "=", self.origin)] - ) - if source_contract: + if self.created_from_contract: return False else: return super().action_create_contract() From fcad80127f0a9d41e10d796b44a9dac5c6104dfe Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Sat, 11 Jan 2025 16:11:53 +0100 Subject: [PATCH 4/8] fixups --- contract_sale_generation_prevent_loop/models/contract.py | 3 ++- .../models/sale_order_line.py | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/contract_sale_generation_prevent_loop/models/contract.py b/contract_sale_generation_prevent_loop/models/contract.py index ea0119dae..7257cc941 100644 --- a/contract_sale_generation_prevent_loop/models/contract.py +++ b/contract_sale_generation_prevent_loop/models/contract.py @@ -9,5 +9,6 @@ class ContractContract(models.Model): def _prepare_recurring_sales_values(self, date_ref=False): res = super()._prepare_recurring_sales_values(date_ref) - res[0]["created_from_contract"] = True + if res: + res[0]["created_from_contract"] = True return res diff --git a/contract_sale_generation_prevent_loop/models/sale_order_line.py b/contract_sale_generation_prevent_loop/models/sale_order_line.py index 0a8ee930c..52614176e 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order_line.py +++ b/contract_sale_generation_prevent_loop/models/sale_order_line.py @@ -10,8 +10,9 @@ class SaleOrder(models.Model): def _compute_qty_to_invoice(self): res = super()._compute_qty_to_invoice() if self.order_id.created_from_contract: - # put back the right quantity to invoice - self.filtered("product_id.is_contract").update( - {"qty_to_invoice": self.product_uom_qty} - ) + for line in self: + # put back the right quantity to invoice + line.filtered("product_id.is_contract").update( + {"qty_to_invoice": line.product_uom_qty} + ) return res From 98d5b05cd302a838fc411ba33e843e5bdd9a1187 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Tue, 14 Jan 2025 10:42:21 +0100 Subject: [PATCH 5/8] fixup --- .../models/sale_order_line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contract_sale_generation_prevent_loop/models/sale_order_line.py b/contract_sale_generation_prevent_loop/models/sale_order_line.py index 52614176e..d0c88075e 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order_line.py +++ b/contract_sale_generation_prevent_loop/models/sale_order_line.py @@ -9,8 +9,8 @@ class SaleOrder(models.Model): def _compute_qty_to_invoice(self): res = super()._compute_qty_to_invoice() - if self.order_id.created_from_contract: - for line in self: + for line in self: + if self.order_id.created_from_contract: # put back the right quantity to invoice line.filtered("product_id.is_contract").update( {"qty_to_invoice": line.product_uom_qty} From cac729fe0c37885cc90c4dab7c3911a06d78cd63 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Tue, 14 Jan 2025 11:13:41 +0100 Subject: [PATCH 6/8] fixup --- contract_sale_generation_prevent_loop/models/sale_order_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract_sale_generation_prevent_loop/models/sale_order_line.py b/contract_sale_generation_prevent_loop/models/sale_order_line.py index d0c88075e..efbad6757 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order_line.py +++ b/contract_sale_generation_prevent_loop/models/sale_order_line.py @@ -10,7 +10,7 @@ class SaleOrder(models.Model): def _compute_qty_to_invoice(self): res = super()._compute_qty_to_invoice() for line in self: - if self.order_id.created_from_contract: + if line.order_id.created_from_contract: # put back the right quantity to invoice line.filtered("product_id.is_contract").update( {"qty_to_invoice": line.product_uom_qty} From 795a2c2fa89176e71d086121d1e7459d9a20c896 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Wed, 15 Jan 2025 09:53:59 +0100 Subject: [PATCH 7/8] fixup --- .../models/sale_order.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contract_sale_generation_prevent_loop/models/sale_order.py b/contract_sale_generation_prevent_loop/models/sale_order.py index 673e6f024..30154f59c 100644 --- a/contract_sale_generation_prevent_loop/models/sale_order.py +++ b/contract_sale_generation_prevent_loop/models/sale_order.py @@ -10,7 +10,8 @@ class SaleOrder(models.Model): created_from_contract = fields.Boolean(default=False, readonly=True) def action_create_contract(self): - if self.created_from_contract: - return False - else: - return super().action_create_contract() + for order in self: + if order.created_from_contract: + return False + else: + return super().action_create_contract() From 6a7affedeb9abf69cc417af56116aa3098fe2270 Mon Sep 17 00:00:00 2001 From: Victor Champonnois Date: Wed, 15 Jan 2025 09:55:31 +0100 Subject: [PATCH 8/8] [REF] rename product_contract_sale_generation --- .../README.rst | 12 ++++++------ .../__init__.py | 0 .../__manifest__.py | 2 +- .../models/__init__.py | 0 .../models/contract.py | 0 .../models/sale_order.py | 0 .../models/sale_order_line.py | 0 .../readme/DESCRIPTION.rst | 0 .../static/description/icon.png | Bin .../static/description/index.html | 12 ++++++------ .../views/sale_order.xml | 0 .../addons/contract_sale_generation_prevent_loop | 1 - .../odoo/addons/product_contract_sale_generation | 1 + .../setup.py | 0 14 files changed, 14 insertions(+), 14 deletions(-) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/README.rst (81%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/__init__.py (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/__manifest__.py (90%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/models/__init__.py (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/models/contract.py (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/models/sale_order.py (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/models/sale_order_line.py (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/readme/DESCRIPTION.rst (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/static/description/icon.png (100%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/static/description/index.html (93%) rename {contract_sale_generation_prevent_loop => product_contract_sale_generation}/views/sale_order.xml (100%) delete mode 120000 setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop create mode 120000 setup/product_contract_sale_generation/odoo/addons/product_contract_sale_generation rename setup/{contract_sale_generation_prevent_loop => product_contract_sale_generation}/setup.py (100%) diff --git a/contract_sale_generation_prevent_loop/README.rst b/product_contract_sale_generation/README.rst similarity index 81% rename from contract_sale_generation_prevent_loop/README.rst rename to product_contract_sale_generation/README.rst index 39e7fd110..e35b49154 100644 --- a/contract_sale_generation_prevent_loop/README.rst +++ b/product_contract_sale_generation/README.rst @@ -1,6 +1,6 @@ -====================================== -Contracts Sale Generation Prevent Loop -====================================== +================================ +Product Contract Sale Generation +================================ .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -17,7 +17,7 @@ Contracts Sale Generation Prevent Loop :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github - :target: https://github.com/coopiteasy/addons/tree/16.0/contract_sale_generation_prevent_loop + :target: https://github.com/coopiteasy/addons/tree/16.0/product_contract_sale_generation :alt: coopiteasy/addons |badge1| |badge2| |badge3| @@ -39,7 +39,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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -54,6 +54,6 @@ Authors Maintainers ~~~~~~~~~~~ -This module is part of the `coopiteasy/addons `_ project on GitHub. +This module is part of the `coopiteasy/addons `_ project on GitHub. You are welcome to contribute. diff --git a/contract_sale_generation_prevent_loop/__init__.py b/product_contract_sale_generation/__init__.py similarity index 100% rename from contract_sale_generation_prevent_loop/__init__.py rename to product_contract_sale_generation/__init__.py diff --git a/contract_sale_generation_prevent_loop/__manifest__.py b/product_contract_sale_generation/__manifest__.py similarity index 90% rename from contract_sale_generation_prevent_loop/__manifest__.py rename to product_contract_sale_generation/__manifest__.py index 433f7319f..38f847235 100644 --- a/contract_sale_generation_prevent_loop/__manifest__.py +++ b/product_contract_sale_generation/__manifest__.py @@ -4,7 +4,7 @@ { - "name": "Contracts Sale Generation Prevent Loop", + "name": "Product Contract Sale Generation", "version": "16.0.1.0.0", "category": "Contract Management", "license": "AGPL-3", diff --git a/contract_sale_generation_prevent_loop/models/__init__.py b/product_contract_sale_generation/models/__init__.py similarity index 100% rename from contract_sale_generation_prevent_loop/models/__init__.py rename to product_contract_sale_generation/models/__init__.py diff --git a/contract_sale_generation_prevent_loop/models/contract.py b/product_contract_sale_generation/models/contract.py similarity index 100% rename from contract_sale_generation_prevent_loop/models/contract.py rename to product_contract_sale_generation/models/contract.py diff --git a/contract_sale_generation_prevent_loop/models/sale_order.py b/product_contract_sale_generation/models/sale_order.py similarity index 100% rename from contract_sale_generation_prevent_loop/models/sale_order.py rename to product_contract_sale_generation/models/sale_order.py diff --git a/contract_sale_generation_prevent_loop/models/sale_order_line.py b/product_contract_sale_generation/models/sale_order_line.py similarity index 100% rename from contract_sale_generation_prevent_loop/models/sale_order_line.py rename to product_contract_sale_generation/models/sale_order_line.py diff --git a/contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst b/product_contract_sale_generation/readme/DESCRIPTION.rst similarity index 100% rename from contract_sale_generation_prevent_loop/readme/DESCRIPTION.rst rename to product_contract_sale_generation/readme/DESCRIPTION.rst diff --git a/contract_sale_generation_prevent_loop/static/description/icon.png b/product_contract_sale_generation/static/description/icon.png similarity index 100% rename from contract_sale_generation_prevent_loop/static/description/icon.png rename to product_contract_sale_generation/static/description/icon.png diff --git a/contract_sale_generation_prevent_loop/static/description/index.html b/product_contract_sale_generation/static/description/index.html similarity index 93% rename from contract_sale_generation_prevent_loop/static/description/index.html rename to product_contract_sale_generation/static/description/index.html index 7efdcb055..b47f18e0d 100644 --- a/contract_sale_generation_prevent_loop/static/description/index.html +++ b/product_contract_sale_generation/static/description/index.html @@ -3,7 +3,7 @@ -Contracts Sale Generation Prevent Loop +Product Contract Sale Generation -
-

Contracts Sale Generation Prevent Loop

+
+

Product Contract Sale Generation

-

Beta License: AGPL-3 coopiteasy/addons

+

Beta License: AGPL-3 coopiteasy/addons

When using both product_contract and contract_sale_generation, the sale order generated from the contract will create another contract on confirmation :

SO with a is_contract product, when confirmed, creates a contract. This contract contains the same is_contract product. If this contract is set to generate SO, then this contract will generate SOs with the same is_contract module. On confirmation these SOs will create a contract, and so on.

We break this loop by preventing the creation on contracts if the origin of the SO is a contract.

@@ -388,7 +388,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 to smash it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -401,7 +401,7 @@

Authors

Maintainers

-

This module is part of the coopiteasy/addons project on GitHub.

+

This module is part of the coopiteasy/addons project on GitHub.

You are welcome to contribute.

diff --git a/contract_sale_generation_prevent_loop/views/sale_order.xml b/product_contract_sale_generation/views/sale_order.xml similarity index 100% rename from contract_sale_generation_prevent_loop/views/sale_order.xml rename to product_contract_sale_generation/views/sale_order.xml diff --git a/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop b/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop deleted file mode 120000 index d17da5969..000000000 --- a/setup/contract_sale_generation_prevent_loop/odoo/addons/contract_sale_generation_prevent_loop +++ /dev/null @@ -1 +0,0 @@ -../../../../contract_sale_generation_prevent_loop \ No newline at end of file diff --git a/setup/product_contract_sale_generation/odoo/addons/product_contract_sale_generation b/setup/product_contract_sale_generation/odoo/addons/product_contract_sale_generation new file mode 120000 index 000000000..90a287525 --- /dev/null +++ b/setup/product_contract_sale_generation/odoo/addons/product_contract_sale_generation @@ -0,0 +1 @@ +../../../../product_contract_sale_generation \ No newline at end of file diff --git a/setup/contract_sale_generation_prevent_loop/setup.py b/setup/product_contract_sale_generation/setup.py similarity index 100% rename from setup/contract_sale_generation_prevent_loop/setup.py rename to setup/product_contract_sale_generation/setup.py