From 63a87cf6848defc3c36f09bc003037d3ef29c09a Mon Sep 17 00:00:00 2001 From: Hardik Suthar Date: Wed, 29 Oct 2025 12:29:14 +0530 Subject: [PATCH 1/2] [18.0][ADD] Lims Purchase --- lims_purchase/README.rst | 105 +++++ lims_purchase/__init__.py | 1 + lims_purchase/__manifest__.py | 16 + lims_purchase/models/__init__.py | 2 + lims_purchase/models/lims_order.py | 63 +++ lims_purchase/models/purchase_order.py | 32 ++ lims_purchase/pyproject.toml | 3 + lims_purchase/readme/CONFIGURE.md | 10 + lims_purchase/readme/CONTRIBUTORS.md | 1 + lims_purchase/readme/DESCRIPTION.md | 10 + lims_purchase/readme/USAGE.md | 5 + lims_purchase/static/description/index.html | 432 +++++++++++++++++++ lims_purchase/views/lims_order_views.xml | 53 +++ lims_purchase/views/purchase_order_views.xml | 26 ++ 14 files changed, 759 insertions(+) create mode 100644 lims_purchase/README.rst create mode 100644 lims_purchase/__init__.py create mode 100644 lims_purchase/__manifest__.py create mode 100644 lims_purchase/models/__init__.py create mode 100644 lims_purchase/models/lims_order.py create mode 100644 lims_purchase/models/purchase_order.py create mode 100644 lims_purchase/pyproject.toml create mode 100644 lims_purchase/readme/CONFIGURE.md create mode 100644 lims_purchase/readme/CONTRIBUTORS.md create mode 100644 lims_purchase/readme/DESCRIPTION.md create mode 100644 lims_purchase/readme/USAGE.md create mode 100644 lims_purchase/static/description/index.html create mode 100644 lims_purchase/views/lims_order_views.xml create mode 100644 lims_purchase/views/purchase_order_views.xml diff --git a/lims_purchase/README.rst b/lims_purchase/README.rst new file mode 100644 index 0000000..e0af18d --- /dev/null +++ b/lims_purchase/README.rst @@ -0,0 +1,105 @@ +========================= +LIMS Purchase Integration +========================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7f9de5ed863d2f67657f763651bbb8e1770c27dcf8e277c0ef707c03cc054f43 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fconnector--lims-lightgray.png?logo=github + :target: https://github.com/OCA/connector-lims/tree/18.0/lims_purchase + :alt: OCA/connector-lims +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/connector-lims-18-0/connector-lims-18-0-lims_purchase + :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/connector-lims&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +========================== LIMS Purchase Integration +==================================================== + +This module integrates **Odoo LIMS** with **Purchase Orders**, allowing +laboratories to sell LIMS services directly as products. + +Link a LIMS order to a purchase order + +This module extends the ``lims`` and ``purchase`` modules. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +========================== LIMS Purchase Integration +==================================================== + +This module integrates **Odoo LIMS** with **Purchase Orders**, allowing +laboratories to sell LIMS services directly as products. + +Link a LIMS order to a purchase order + +This module extends the ``lims`` and ``purchase`` modules. + +Usage +===== + +Usage +===== + +Link a LIMS order to a purchase order + +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 +------- + +* Hardik-OSI + +Contributors +------------ + +- Hardik-OSI hsuthar@opensourceintegrators.com + +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/connector-lims `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/lims_purchase/__init__.py b/lims_purchase/__init__.py new file mode 100644 index 0000000..9a7e03e --- /dev/null +++ b/lims_purchase/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/lims_purchase/__manifest__.py b/lims_purchase/__manifest__.py new file mode 100644 index 0000000..426b540 --- /dev/null +++ b/lims_purchase/__manifest__.py @@ -0,0 +1,16 @@ +{ + "name": "LIMS Purchase Integration", + "version": "18.0.1.0.0", + "depends": ["purchase", "lims"], + "author": "Hardik-OSI", + "website": "https://github.com/OCA/connector-lims", + "category": "LIMS", + "summary": "Link LIMS orders and Purchase Orders; Smart buttons for navigation", + "license": "AGPL-3", + "data": [ + "views/purchase_order_views.xml", + "views/lims_order_views.xml", + ], + "installable": True, + "application": False, +} diff --git a/lims_purchase/models/__init__.py b/lims_purchase/models/__init__.py new file mode 100644 index 0000000..9726b47 --- /dev/null +++ b/lims_purchase/models/__init__.py @@ -0,0 +1,2 @@ +from . import purchase_order +from . import lims_order diff --git a/lims_purchase/models/lims_order.py b/lims_purchase/models/lims_order.py new file mode 100644 index 0000000..9072ca2 --- /dev/null +++ b/lims_purchase/models/lims_order.py @@ -0,0 +1,63 @@ +from odoo import api, fields, models + + +class LIMSOrder(models.Model): + _inherit = "lims.order" + + purchase_order_ids = fields.One2many( + "purchase.order", + "lims_order_id", + string="Purchase Orders", + help="Purchase Orders created/linked for this LIMS Order", + ) + + purchase_order_count = fields.Integer( + string="PO Count", + compute="_compute_purchase_order_count", + ) + + purchase_order_m2m_ids = fields.Many2many( + "purchase.order", + "lims_order_purchase_rel", + "lims_order_id", + "purchase_order_id", + string="Linked Purchase Orders (M2M)", + help="Attach existing Purchase Orders that relate to this LIMS Order.", + ) + + def _compute_purchase_order_count(self): + for rec in self: + # read_group is faster in bulk but simple search_count is fine here + rec.purchase_order_count = self.env["purchase.order"].search_count( + [("lims_order_id", "=", rec.id)] + ) + + def action_view_purchase_orders(self): + """Open purchase orders linked to this LIMS order.""" + self.ensure_one() + purchase_orders = self.purchase_order_ids + + # Use the standard Purchase action (the one that lists RFQs/POs) + action = self.env.ref("purchase.purchase_rfq").read()[0] + + # If no POs, open the empty list + if not purchase_orders: + action["domain"] = [("id", "in", [])] + return action + + # If only one PO → open form view directly + if len(purchase_orders) == 1: + form_view = self.env.ref("purchase.purchase_order_form", False) + action.update( + { + "view_mode": "form", + "views": [(form_view.id, "form")] if form_view else [], + "res_id": purchase_orders.id, + "domain": [], + } + ) + return action + + # Multiple → show list view filtered + action["domain"] = [("id", "in", purchase_orders.ids)] + return action diff --git a/lims_purchase/models/purchase_order.py b/lims_purchase/models/purchase_order.py new file mode 100644 index 0000000..6590747 --- /dev/null +++ b/lims_purchase/models/purchase_order.py @@ -0,0 +1,32 @@ +from odoo import api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + lims_order_id = fields.Many2one( + "lims.order", string="LIMS Order", ondelete="set null", + help="Link to the LIMS Order related to this Purchase Order" + ) + + def action_open_linked_lims_order(self): + """ + Smart-button action: open the related LIMS Order. + If no lims_order_id is set, return an action to search for none (or raise). + """ + self.ensure_one() + if not self.lims_order_id: + # Best UX: return an empty tree view filtered to nothing + action = self.env.ref("lims.action_lims_operation_order").read()[0] + action["domain"] = [("id", "in", [])] + return action + + # If you want to open the form directly: + action = self.env.ref("lims.action_lims_operation_order").read()[0] + # If the action supports views, prefer to open the form for the single record + action.update({ + "views": [(self.env.ref("lims.lims_order_form").id, "form")] if self.env.ref("lims.lims_order_form", False) else action.get("views"), + "res_id": self.lims_order_id.id, + "target": "current", + }) + return action diff --git a/lims_purchase/pyproject.toml b/lims_purchase/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/lims_purchase/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/lims_purchase/readme/CONFIGURE.md b/lims_purchase/readme/CONFIGURE.md new file mode 100644 index 0000000..3e7cb31 --- /dev/null +++ b/lims_purchase/readme/CONFIGURE.md @@ -0,0 +1,10 @@ +========================== +LIMS Purchase Integration +========================== + +This module integrates **Odoo LIMS** with **Purchase Orders**, allowing laboratories +to sell LIMS services directly as products. + +Link a LIMS order to a purchase order + +This module extends the `lims` and `purchase` modules. diff --git a/lims_purchase/readme/CONTRIBUTORS.md b/lims_purchase/readme/CONTRIBUTORS.md new file mode 100644 index 0000000..e04d19d --- /dev/null +++ b/lims_purchase/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +* Hardik-OSI \ No newline at end of file diff --git a/lims_purchase/readme/DESCRIPTION.md b/lims_purchase/readme/DESCRIPTION.md new file mode 100644 index 0000000..3e7cb31 --- /dev/null +++ b/lims_purchase/readme/DESCRIPTION.md @@ -0,0 +1,10 @@ +========================== +LIMS Purchase Integration +========================== + +This module integrates **Odoo LIMS** with **Purchase Orders**, allowing laboratories +to sell LIMS services directly as products. + +Link a LIMS order to a purchase order + +This module extends the `lims` and `purchase` modules. diff --git a/lims_purchase/readme/USAGE.md b/lims_purchase/readme/USAGE.md new file mode 100644 index 0000000..5067610 --- /dev/null +++ b/lims_purchase/readme/USAGE.md @@ -0,0 +1,5 @@ +Usage +===== + +Link a LIMS order to a purchase order + diff --git a/lims_purchase/static/description/index.html b/lims_purchase/static/description/index.html new file mode 100644 index 0000000..15e57ec --- /dev/null +++ b/lims_purchase/static/description/index.html @@ -0,0 +1,432 @@ + + + + + +LIMS Purchase Integration + + + +
+

LIMS Purchase Integration

+ + +

Beta License: AGPL-3 OCA/connector-lims Translate me on Weblate Try me on Runboat

+
+

========================== LIMS Purchase Integration

+

This module integrates Odoo LIMS with Purchase Orders, allowing +laboratories to sell LIMS services directly as products.

+

Link a LIMS order to a purchase order

+

This module extends the lims and purchase modules.

+

Table of contents

+
+
+

Configuration

+
+
+

========================== LIMS Purchase Integration

+

This module integrates Odoo LIMS with Purchase Orders, allowing +laboratories to sell LIMS services directly as products.

+

Link a LIMS order to a purchase order

+

This module extends the lims and purchase modules.

+
+
+

Usage

+
+
+

Usage

+

Link a LIMS order to a purchase order

+
+
+

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

+
    +
  • Hardik-OSI
  • +
+
+
+

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/connector-lims project on GitHub.

+

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

+
+
+
+ + diff --git a/lims_purchase/views/lims_order_views.xml b/lims_purchase/views/lims_order_views.xml new file mode 100644 index 0000000..6f77b6f --- /dev/null +++ b/lims_purchase/views/lims_order_views.xml @@ -0,0 +1,53 @@ + + + + lims.order.form.purchase.button + lims.order + + + + + + + + + + + lims.order.form.add.purchase.tab + lims.order + + + + + + + + + + + + +
+ + + + + + + + +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/lims_purchase/views/purchase_order_views.xml b/lims_purchase/views/purchase_order_views.xml new file mode 100644 index 0000000..9d39a7c --- /dev/null +++ b/lims_purchase/views/purchase_order_views.xml @@ -0,0 +1,26 @@ + + + + purchase.order.form.lims + purchase.order + + + + + + + + + + + + + + From 0aa178c52c858d33eb32c4914aff9c6a7cab89ef Mon Sep 17 00:00:00 2001 From: Nikul-OSI Date: Fri, 14 Nov 2025 14:35:51 +0530 Subject: [PATCH 2/2] [IMP] Improved code with UT --- lims_purchase/README.rst | 4 +- lims_purchase/__init__.py | 2 +- lims_purchase/__manifest__.py | 2 +- lims_purchase/models/lims_order.py | 2 +- lims_purchase/models/purchase_order.py | 22 +++-- lims_purchase/static/description/index.html | 25 +++--- lims_purchase/tests/__init__.py | 4 + lims_purchase/tests/test_purchase_order.py | 86 ++++++++++++++++++++ lims_purchase/views/lims_order_views.xml | 12 ++- lims_purchase/views/purchase_order_views.xml | 23 ++++-- test-requirements.txt | 1 + 11 files changed, 146 insertions(+), 37 deletions(-) create mode 100644 lims_purchase/tests/__init__.py create mode 100644 lims_purchase/tests/test_purchase_order.py create mode 100644 test-requirements.txt diff --git a/lims_purchase/README.rst b/lims_purchase/README.rst index e0af18d..550fd73 100644 --- a/lims_purchase/README.rst +++ b/lims_purchase/README.rst @@ -80,12 +80,12 @@ Credits Authors ------- -* Hardik-OSI +* Open Source Integrators Contributors ------------ -- Hardik-OSI hsuthar@opensourceintegrators.com +- Hardik-OSI hsuthar@opensourceintegrators.com Maintainers ----------- diff --git a/lims_purchase/__init__.py b/lims_purchase/__init__.py index 9a7e03e..0650744 100644 --- a/lims_purchase/__init__.py +++ b/lims_purchase/__init__.py @@ -1 +1 @@ -from . import models \ No newline at end of file +from . import models diff --git a/lims_purchase/__manifest__.py b/lims_purchase/__manifest__.py index 426b540..226e4e8 100644 --- a/lims_purchase/__manifest__.py +++ b/lims_purchase/__manifest__.py @@ -2,7 +2,7 @@ "name": "LIMS Purchase Integration", "version": "18.0.1.0.0", "depends": ["purchase", "lims"], - "author": "Hardik-OSI", + "author": "Open Source Integrators, Odoo Community Association (OCA)", "website": "https://github.com/OCA/connector-lims", "category": "LIMS", "summary": "Link LIMS orders and Purchase Orders; Smart buttons for navigation", diff --git a/lims_purchase/models/lims_order.py b/lims_purchase/models/lims_order.py index 9072ca2..a16e005 100644 --- a/lims_purchase/models/lims_order.py +++ b/lims_purchase/models/lims_order.py @@ -1,4 +1,4 @@ -from odoo import api, fields, models +from odoo import fields, models class LIMSOrder(models.Model): diff --git a/lims_purchase/models/purchase_order.py b/lims_purchase/models/purchase_order.py index 6590747..9c71d39 100644 --- a/lims_purchase/models/purchase_order.py +++ b/lims_purchase/models/purchase_order.py @@ -1,12 +1,14 @@ -from odoo import api, fields, models +from odoo import fields, models class PurchaseOrder(models.Model): _inherit = "purchase.order" lims_order_id = fields.Many2one( - "lims.order", string="LIMS Order", ondelete="set null", - help="Link to the LIMS Order related to this Purchase Order" + "lims.order", + string="LIMS Order", + ondelete="set null", + help="Link to the LIMS Order related to this Purchase Order", ) def action_open_linked_lims_order(self): @@ -24,9 +26,13 @@ def action_open_linked_lims_order(self): # If you want to open the form directly: action = self.env.ref("lims.action_lims_operation_order").read()[0] # If the action supports views, prefer to open the form for the single record - action.update({ - "views": [(self.env.ref("lims.lims_order_form").id, "form")] if self.env.ref("lims.lims_order_form", False) else action.get("views"), - "res_id": self.lims_order_id.id, - "target": "current", - }) + action.update( + { + "views": [(self.env.ref("lims.lims_order_form").id, "form")] + if self.env.ref("lims.lims_order_form", False) + else action.get("views"), + "res_id": self.lims_order_id.id, + "target": "current", + } + ) return action diff --git a/lims_purchase/static/description/index.html b/lims_purchase/static/description/index.html index 15e57ec..b18b585 100644 --- a/lims_purchase/static/description/index.html +++ b/lims_purchase/static/description/index.html @@ -2,18 +2,19 @@ - + LIMS Purchase Integration