diff --git a/lims_account/README.rst b/lims_account/README.rst new file mode 100644 index 0000000..cd2a4a4 --- /dev/null +++ b/lims_account/README.rst @@ -0,0 +1,154 @@ +======================================================= +Laboratory Information Management System (LIMS) Account +======================================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ba316928464662c1a5ea05c80f1da795b848da8896e05e3f1384cb2e6ccb4f28 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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_account + :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_account + :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| + +The **lims_account** module provides a bridge between the **LIMS +(Laboratory Information Management System)** and **Odoo Accounting**. + +It introduces a bi-directional link between **LIMS Orders** and +**Invoices**, enabling users to: + +- Associate one or multiple invoices (``account.move``) with one or + multiple LIMS orders (``lims.order``). +- Quickly navigate between LIMS Orders and their corresponding Invoices + using smart buttons. +- View related records directly in each form without leaving the current + screen. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Before installing this module: + +1. Ensure both **account** and **lims** modules are installed and + working. +2. The user must have access rights to both Accounting and LIMS modules. + +Usage +===== + +From an Invoice (Customer/Vendor Bill) +====================================== + +1. Go to **Accounting → Customers → Invoices** (or Vendor Bills). +2. Open any invoice record. +3. In the **LIMS Integration** section, click **Add a line** in the + *LIMS Orders* field. +4. Select one or more **LIMS Orders** from the list. +5. Save the record. + +| ✅ The invoice is now linked to those LIMS Orders. +| A **“LIMS Orders”** smart button appears in the header showing the + total count of linked orders. + +-------------- + +From a LIMS Order +================= + +1. Go to **LIMS → Orders**. +2. Open any LIMS Order record. +3. Use the **Invoices** smart button in the header. +4. Add or view linked invoices in the *Account Moves* field. + +✅ The LIMS Order will now show all related invoices. + +-------------- + +👁️ Viewing Linked Records +========================= + +- On an **Invoice**, click the **LIMS Orders** smart button to open all + linked LIMS Orders. +- On a **LIMS Order**, click the **Invoices** smart button to open all + linked invoices. + +You can navigate back and forth between records easily. + +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 +------- + +* Open Source Integrators + +Contributors +------------ + +- Rodrigo Madrid rmadrid@opensourceintegrators.com +- Adriana Alpizar aalpizar@opensourceintegrators.com +- Maxime Chambreuil mchambreuil@opensourceintegrators.com +- Nikul Chaudhary nchaudhary@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. + +.. |maintainer-max3903| image:: https://github.com/max3903.png?size=40px + :target: https://github.com/max3903 + :alt: max3903 +.. |maintainer-jasiel-osi| image:: https://github.com/jasiel-osi.png?size=40px + :target: https://github.com/jasiel-osi + :alt: jasiel-osi +.. |maintainer-Nikul-OSI| image:: https://github.com/Nikul-OSI.png?size=40px + :target: https://github.com/Nikul-OSI + :alt: Nikul-OSI + +Current `maintainers `__: + +|maintainer-max3903| |maintainer-jasiel-osi| |maintainer-Nikul-OSI| + +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_account/__init__.py b/lims_account/__init__.py new file mode 100644 index 0000000..17a0e65 --- /dev/null +++ b/lims_account/__init__.py @@ -0,0 +1,3 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from . import models diff --git a/lims_account/__manifest__.py b/lims_account/__manifest__.py new file mode 100644 index 0000000..4524b00 --- /dev/null +++ b/lims_account/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Laboratory Information Management System (LIMS) Account", + "summary": "Allows invoicing LIMS orders and linking invoices to LIMS orders", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "category": "Accounting", + "author": "Open Source Integrators, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/connector-lims", + "depends": ["lims", "account"], + "data": [ + "views/account_move_views.xml", + "views/lims_order_views.xml", + ], + "application": False, + "development_status": "Beta", + "maintainers": ["max3903", "jasiel-osi", "Nikul-OSI"], +} diff --git a/lims_account/models/__init__.py b/lims_account/models/__init__.py new file mode 100644 index 0000000..a9cfcde --- /dev/null +++ b/lims_account/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_move +from . import lims_order diff --git a/lims_account/models/account_move.py b/lims_account/models/account_move.py new file mode 100644 index 0000000..79a1ce5 --- /dev/null +++ b/lims_account/models/account_move.py @@ -0,0 +1,34 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class AccountMove(models.Model): + _inherit = "account.move" + + lims_order_ids = fields.Many2many( + comodel_name="lims.order", + relation="lims_order_account_move_rel", + column1="move_id", + column2="lims_order_id", + string="LIMS Orders", + ) + lims_order_count = fields.Integer( + compute="_compute_lims_order_count", string="LIMS Orders Count" + ) + + @api.depends("lims_order_ids") + def _compute_lims_order_count(self): + for rec in self: + rec.lims_order_count = len(rec.lims_order_ids) + + def action_open_lims_orders(self): + self.ensure_one() + return { + "name": _("LIMS Orders"), + "type": "ir.actions.act_window", + "res_model": "lims.order", + "view_mode": "list,form", + "domain": [("id", "in", self.lims_order_ids.ids)], + } diff --git a/lims_account/models/lims_order.py b/lims_account/models/lims_order.py new file mode 100644 index 0000000..4d09e5f --- /dev/null +++ b/lims_account/models/lims_order.py @@ -0,0 +1,34 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class LimsOrder(models.Model): + _inherit = "lims.order" + + account_move_ids = fields.Many2many( + comodel_name="account.move", + relation="lims_order_account_move_rel", + column1="lims_order_id", + column2="move_id", + string="Account Moves", + ) + account_move_count = fields.Integer( + compute="_compute_account_move_count", string="Invoices Count" + ) + + @api.depends("account_move_ids") + def _compute_account_move_count(self): + for rec in self: + rec.account_move_count = len(rec.account_move_ids) + + def action_open_account_moves(self): + self.ensure_one() + return { + "name": _("Invoices"), + "type": "ir.actions.act_window", + "res_model": "account.move", + "view_mode": "list,form", + "domain": [("id", "in", self.account_move_ids.ids)], + } diff --git a/lims_account/pyproject.toml b/lims_account/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/lims_account/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/lims_account/readme/CONFIGURE.md b/lims_account/readme/CONFIGURE.md new file mode 100644 index 0000000..e202471 --- /dev/null +++ b/lims_account/readme/CONFIGURE.md @@ -0,0 +1,3 @@ +Before installing this module: +1. Ensure both **account** and **lims** modules are installed and working. +2. The user must have access rights to both Accounting and LIMS modules. diff --git a/lims_account/readme/CONTRIBUTORS.md b/lims_account/readme/CONTRIBUTORS.md new file mode 100644 index 0000000..d6c5d53 --- /dev/null +++ b/lims_account/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ + * Rodrigo Madrid + * Adriana Alpizar + * Maxime Chambreuil + * Nikul Chaudhary diff --git a/lims_account/readme/DESCRIPTION.md b/lims_account/readme/DESCRIPTION.md new file mode 100644 index 0000000..029997e --- /dev/null +++ b/lims_account/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +The **lims_account** module provides a bridge between the **LIMS (Laboratory Information Management System)** and **Odoo Accounting**. + +It introduces a bi-directional link between **LIMS Orders** and **Invoices**, enabling users to: + +- Associate one or multiple invoices (`account.move`) with one or multiple LIMS orders (`lims.order`). +- Quickly navigate between LIMS Orders and their corresponding Invoices using smart buttons. +- View related records directly in each form without leaving the current screen. diff --git a/lims_account/readme/USAGE.md b/lims_account/readme/USAGE.md new file mode 100644 index 0000000..5e233f3 --- /dev/null +++ b/lims_account/readme/USAGE.md @@ -0,0 +1,27 @@ +# From an Invoice (Customer/Vendor Bill) +1. Go to **Accounting → Customers → Invoices** (or Vendor Bills). +2. Open any invoice record. +3. In the **LIMS Integration** section, click **Add a line** in the *LIMS Orders* field. +4. Select one or more **LIMS Orders** from the list. +5. Save the record. + +✅ The invoice is now linked to those LIMS Orders. +A **“LIMS Orders”** smart button appears in the header showing the total count of linked orders. + +--- + +# From a LIMS Order +1. Go to **LIMS → Orders**. +2. Open any LIMS Order record. +3. Use the **Invoices** smart button in the header. +4. Add or view linked invoices in the *Account Moves* field. + +✅ The LIMS Order will now show all related invoices. + +--- + +# 👁️ Viewing Linked Records +- On an **Invoice**, click the **LIMS Orders** smart button to open all linked LIMS Orders. +- On a **LIMS Order**, click the **Invoices** smart button to open all linked invoices. + +You can navigate back and forth between records easily. diff --git a/lims_account/static/description/index.html b/lims_account/static/description/index.html new file mode 100644 index 0000000..55cc837 --- /dev/null +++ b/lims_account/static/description/index.html @@ -0,0 +1,494 @@ + + + + + +Laboratory Information Management System (LIMS) Account + + + +
+

Laboratory Information Management System (LIMS) Account

+ + +

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

+

The lims_account module provides a bridge between the LIMS +(Laboratory Information Management System) and Odoo Accounting.

+

It introduces a bi-directional link between LIMS Orders and +Invoices, enabling users to:

+
    +
  • Associate one or multiple invoices (account.move) with one or +multiple LIMS orders (lims.order).
  • +
  • Quickly navigate between LIMS Orders and their corresponding Invoices +using smart buttons.
  • +
  • View related records directly in each form without leaving the current +screen.
  • +
+

Table of contents

+ +
+

Configuration

+

Before installing this module:

+
    +
  1. Ensure both account and lims modules are installed and +working.
  2. +
  3. The user must have access rights to both Accounting and LIMS modules.
  4. +
+
+
+

Usage

+
+
+

From an Invoice (Customer/Vendor Bill)

+
    +
  1. Go to Accounting → Customers → Invoices (or Vendor Bills).
  2. +
  3. Open any invoice record.
  4. +
  5. In the LIMS Integration section, click Add a line in the +LIMS Orders field.
  6. +
  7. Select one or more LIMS Orders from the list.
  8. +
  9. Save the record.
  10. +
+
+
✅ The invoice is now linked to those LIMS Orders.
+
A “LIMS Orders” smart button appears in the header showing the +total count of linked orders.
+
+
+
+
+

From a LIMS Order

+
    +
  1. Go to LIMS → Orders.
  2. +
  3. Open any LIMS Order record.
  4. +
  5. Use the Invoices smart button in the header.
  6. +
  7. Add or view linked invoices in the Account Moves field.
  8. +
+

✅ The LIMS Order will now show all related invoices.

+
+
+
+

👁️ Viewing Linked Records

+
    +
  • On an Invoice, click the LIMS Orders smart button to open all +linked LIMS Orders.
  • +
  • On a LIMS Order, click the Invoices smart button to open all +linked invoices.
  • +
+

You can navigate back and forth between records easily.

+
+
+

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

+
    +
  • Open Source Integrators
  • +
+
+ +
+

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.

+

Current maintainers:

+

max3903 jasiel-osi Nikul-OSI

+

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_account/tests/__init__.py b/lims_account/tests/__init__.py new file mode 100644 index 0000000..eff8641 --- /dev/null +++ b/lims_account/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_account_move diff --git a/lims_account/tests/test_account_move.py b/lims_account/tests/test_account_move.py new file mode 100644 index 0000000..f1a1f70 --- /dev/null +++ b/lims_account/tests/test_account_move.py @@ -0,0 +1,91 @@ +# Copyright (C) 2025 Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields +from odoo.fields import Command + +from odoo.addons.lims.tests.common import LIMSCommon + + +class TestAccountMove(LIMSCommon): + """Tests for LIMS order and account move integration.""" + + def setUp(self): + """Set up reusable records for all test methods.""" + super().setUp() + self.LimsOrder = self.env["lims.order"] + + self.partner_id = self.env.ref("base.res_partner_12", raise_if_not_found=False) + self.stage_new = self.env.ref( + "lims.lims_stage_order_new", raise_if_not_found=False + ) + self.service_product = self.env["product.product"].search([], limit=1) + + # Create a LIMS Order with related account move and test lines + self.lims_order = self.LimsOrder.create( + { + "name": "Test Order", + "stage_id": self.stage_new.id, + "company_id": self.env.company.id, + "laboratory_id": self.partner_laboratory.id, + "team_id": self.lims_team.id, + "partner_id": self.partner_id.id, + "tag_ids": [(6, 0, [self.lims_tag.id])], + "description": "Unit test for Account Move linkage", + "operator_id": self.partner_operator.id, + "physician_id": self.partner_physician.id, + "specimen_id": self.lims_specimen.id, + "scheduled_date": fields.Date.today(), + "date": fields.Date.today(), + "test_ids": [ + Command.create( + { + "test_id": self.test_id.id, + "operator_id": self.partner_operator.id, + "scheduled_date": fields.Date.today(), + "date": fields.Date.today(), + "todo": "Test TODO", + } + ) + ], + "account_move_ids": [ + Command.create( + { + "partner_id": self.partner_id.id, + "move_type": "out_invoice", + "invoice_line_ids": [ + Command.create( + { + "name": "Test Invoice Line", + "quantity": 1.0, + "price_unit": 1000.0, + } + ) + ], + } + ) + ], + } + ) + + def test_01_compute_and_open_account_moves(self): + """Test that LIMS order correctly computes and opens related account moves.""" + lims_order = self.lims_order + lims_order._compute_account_move_count() + lims_order.action_open_account_moves() + + self.assertTrue( + lims_order.account_move_count, + "LIMS order should have at least one linked account move.", + ) + + def test_02_compute_and_open_lims_orders_from_account_move(self): + """Test that account moves correctly compute and open related LIMS orders.""" + account_move = self.lims_order.account_move_ids + account_move._compute_lims_order_count() + account_move.action_open_lims_orders() + + self.assertTrue( + account_move.lims_order_count, + "Account move should be linked to at least one LIMS order.", + ) diff --git a/lims_account/views/account_move_views.xml b/lims_account/views/account_move_views.xml new file mode 100644 index 0000000..78d40fd --- /dev/null +++ b/lims_account/views/account_move_views.xml @@ -0,0 +1,31 @@ + + + account.move.form.inherit + account.move + + + + + + + + + + + + + + diff --git a/lims_account/views/lims_order_views.xml b/lims_account/views/lims_order_views.xml new file mode 100644 index 0000000..cfe4cb3 --- /dev/null +++ b/lims_account/views/lims_order_views.xml @@ -0,0 +1,31 @@ + + + lims.order.form.inherit + lims.order + + +
+ +
+ + + + + + + +
+
+
diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..fef89ce --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-lims @ git+https://github.com/OCA/connector-lims.git@refs/pull/20/head#subdirectory=lims