diff --git a/sale_cart/README.rst b/sale_cart/README.rst index 62c67b624b..ad9286f503 100644 --- a/sale_cart/README.rst +++ b/sale_cart/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ========= Sale Cart ========= @@ -13,7 +17,7 @@ Sale Cart .. |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 +.. |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-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github @@ -22,7 +26,7 @@ Sale Cart |badge1| |badge2| |badge3| -This addon add a typology on sale.order to distinguish the sale orders that are +This addon adds a "cart" typology on sale.order to distinguish the sale orders that are in the process of being written (cart) and those that are quotations ready to be confirmed. @@ -56,6 +60,7 @@ Contributors ~~~~~~~~~~~~ * Laurent Mignon +* Nicolas DELBOVIER Maintainers ~~~~~~~~~~~ diff --git a/sale_cart/__manifest__.py b/sale_cart/__manifest__.py index 6fe431db48..7ffca856ae 100644 --- a/sale_cart/__manifest__.py +++ b/sale_cart/__manifest__.py @@ -10,7 +10,7 @@ "license": "AGPL-3", "author": "ACSONE SA/NV", "website": "https://github.com/shopinvader/odoo-shopinvader", - "depends": ["sale", "sales_team"], + "depends": ["sale", "sales_team", "sale_typology"], "data": ["views/sale_order.xml"], "demo": [], "external_dependencies": {"python": ["openupgradelib"]}, diff --git a/sale_cart/models/sale_order.py b/sale_cart/models/sale_order.py index 390faeb5e7..f1a00cd835 100644 --- a/sale_cart/models/sale_order.py +++ b/sale_cart/models/sale_order.py @@ -7,7 +7,12 @@ class SaleOrder(models.Model): _inherit = "sale.order" - typology = fields.Selection([("sale", "Sale"), ("cart", "Cart")], default="sale") + typology = fields.Selection( + selection_add=[("cart", "Cart")], + ondelete={ + "cart": "cascade", + }, + ) def _confirm_cart(self): self.ensure_one() diff --git a/sale_cart/readme/CONTRIBUTORS.rst b/sale_cart/readme/CONTRIBUTORS.rst index 172b2d223c..a455b581a9 100644 --- a/sale_cart/readme/CONTRIBUTORS.rst +++ b/sale_cart/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Laurent Mignon +* Nicolas DELBOVIER \ No newline at end of file diff --git a/sale_cart/readme/DESCRIPTION.rst b/sale_cart/readme/DESCRIPTION.rst index 7f6c5b3950..c0964e8344 100644 --- a/sale_cart/readme/DESCRIPTION.rst +++ b/sale_cart/readme/DESCRIPTION.rst @@ -1,4 +1,4 @@ -This addon add a typology on sale.order to distinguish the sale orders that are +This addon adds a "cart" typology on sale.order to distinguish the sale orders that are in the process of being written (cart) and those that are quotations ready to be confirmed. diff --git a/sale_cart/static/description/index.html b/sale_cart/static/description/index.html index 7e461a4cdb..ac74cbd74e 100644 --- a/sale_cart/static/description/index.html +++ b/sale_cart/static/description/index.html @@ -3,7 +3,7 @@ -Sale Cart +README.rst -
-

Sale Cart

+
+ + +Odoo Community Association + +
+

Sale Cart

-

Beta License: AGPL-3 shopinvader/odoo-shopinvader

-

This addon add a typology on sale.order to distinguish the sale orders that are +

Beta License: AGPL-3 shopinvader/odoo-shopinvader

+

This addon adds a “cart” typology on sale.order to distinguish the sale orders that are in the process of being written (cart) and those that are quotations ready to be confirmed.

It also automatically converts the cart into a sale when the payment is @@ -388,7 +393,7 @@

Sale Cart

-

Bug Tracker

+

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 @@ -396,25 +401,27 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Maintainers

+

Maintainers

This module is part of the shopinvader/odoo-shopinvader project on GitHub.

You are welcome to contribute.

+
diff --git a/sale_cart/views/sale_order.xml b/sale_cart/views/sale_order.xml index fb4f7a69ca..2fc2cb0ff7 100644 --- a/sale_cart/views/sale_order.xml +++ b/sale_cart/views/sale_order.xml @@ -33,7 +33,7 @@ - [('typology', '=', 'sale'), + [('typology', '!=', 'cart'), ('state','in',('draft','sent','cancel'))] diff --git a/sale_cart_quotation/README.rst b/sale_cart_quotation/README.rst new file mode 100644 index 0000000000..6f081426ff --- /dev/null +++ b/sale_cart_quotation/README.rst @@ -0,0 +1,64 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +=================== +Sale Cart Quotation +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:092764e34a3532b13b87a0b07712f405be8de3df4ce5265a1c4f0640ea1f44f8 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github + :target: https://github.com/shopinvader/odoo-shopinvader/tree/16.0/sale_cart_quotation + :alt: shopinvader/odoo-shopinvader + +|badge1| |badge2| |badge3| + +Glue module between sale_quotation and sale_cart, allowing users to request a quotation directly from a cart. + +**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 +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Nicolas DELBOVIER + +Maintainers +~~~~~~~~~~~ + +This module is part of the `shopinvader/odoo-shopinvader `_ project on GitHub. + +You are welcome to contribute. diff --git a/sale_cart_quotation/__init__.py b/sale_cart_quotation/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/sale_cart_quotation/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_cart_quotation/__manifest__.py b/sale_cart_quotation/__manifest__.py new file mode 100644 index 0000000000..8e29bed16f --- /dev/null +++ b/sale_cart_quotation/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Cart Quotation", + "summary": """Glue module between sale_quotation and sale_cart, + allowing users to request a quotation directly from a cart.""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV", + "website": "https://github.com/shopinvader/odoo-shopinvader", + "depends": ["sale_quotation", "sale_cart"], + "data": [ + "views/sale_order.xml", + ], + "demo": [], +} diff --git a/sale_cart_quotation/models/__init__.py b/sale_cart_quotation/models/__init__.py new file mode 100644 index 0000000000..6aacb75313 --- /dev/null +++ b/sale_cart_quotation/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/sale_cart_quotation/models/sale_order.py b/sale_cart_quotation/models/sale_order.py new file mode 100644 index 0000000000..6ddcefe945 --- /dev/null +++ b/sale_cart_quotation/models/sale_order.py @@ -0,0 +1,21 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, models +from odoo.exceptions import UserError + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + def action_cart_request_quotation(self): + if any(rec.state != "draft" or rec.typology != "cart" for rec in self): + raise UserError( + _( + "Only orders of cart typology in draft state " + "can be converted to quotation" + ) + ) + self.write({"use_customer_quotation_workflow": True}) + self.action_customer_request_quotation() + return True diff --git a/sale_cart_quotation/readme/CONTRIBUTORS.rst b/sale_cart_quotation/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..5341bc4906 --- /dev/null +++ b/sale_cart_quotation/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Nicolas DELBOVIER \ No newline at end of file diff --git a/sale_cart_quotation/readme/DESCRIPTION.rst b/sale_cart_quotation/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..9021b4ab73 --- /dev/null +++ b/sale_cart_quotation/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Glue module between sale_quotation and sale_cart, allowing users to request a quotation directly from a cart. \ No newline at end of file diff --git a/sale_cart_quotation/static/description/index.html b/sale_cart_quotation/static/description/index.html new file mode 100644 index 0000000000..8068db88da --- /dev/null +++ b/sale_cart_quotation/static/description/index.html @@ -0,0 +1,422 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Sale Cart Quotation

+ +

Beta License: AGPL-3 shopinvader/odoo-shopinvader

+

Glue module between sale_quotation and sale_cart, allowing users to request a quotation directly from a cart.

+

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

+
    +
  • ACSONE SA/NV
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the shopinvader/odoo-shopinvader project on GitHub.

+

You are welcome to contribute.

+
+
+
+
+ + diff --git a/sale_cart_quotation/tests/__init__.py b/sale_cart_quotation/tests/__init__.py new file mode 100644 index 0000000000..43ae815229 --- /dev/null +++ b/sale_cart_quotation/tests/__init__.py @@ -0,0 +1 @@ +from . import test_quotation diff --git a/sale_cart_quotation/tests/test_quotation.py b/sale_cart_quotation/tests/test_quotation.py new file mode 100644 index 0000000000..7c4357ff78 --- /dev/null +++ b/sale_cart_quotation/tests/test_quotation.py @@ -0,0 +1,49 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + +from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT + + +class TestQuotation(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT)) + product = cls.env["product.product"].create({"name": "Test Product"}) + partner = cls.env["res.partner"].create({"name": "John"}) + cls.so = cls.env["sale.order"].create( + { + "partner_id": partner.id, + "order_line": [(0, 0, {"product_id": product.id})], + } + ) + + def test_request_quotation(self): + self.so.typology = "cart" + self.so.action_cart_request_quotation() + self.assertRecordValues( + self.so, + [ + { + "quotation_state": "customer_request", + "typology": "quote", + } + ], + ) + + def test_send_requested_quotation(self): + self.so.typology = "cart" + self.so.action_cart_request_quotation() + self.so.action_quotation_sent() + self.assertRecordValues( + self.so, + [ + { + "quotation_state": "waiting_acceptation", + "typology": "quote", + } + ], + ) + self.assertEqual(self.so.quotation_state, "waiting_acceptation") diff --git a/sale_cart_quotation/views/sale_order.xml b/sale_cart_quotation/views/sale_order.xml new file mode 100644 index 0000000000..0fedb28780 --- /dev/null +++ b/sale_cart_quotation/views/sale_order.xml @@ -0,0 +1,23 @@ + + + + + + sale.cart.quotation.sale.order.form + sale.order + + + +