diff --git a/ai_oca_bridge_mrp/README.rst b/ai_oca_bridge_mrp/README.rst index b7dc45e..7d1c614 100644 --- a/ai_oca_bridge_mrp/README.rst +++ b/ai_oca_bridge_mrp/README.rst @@ -1,9 +1,5 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ================= -Ai Oca Bridge MRP +AI OCA Bridge MRP ================= .. @@ -17,7 +13,7 @@ Ai Oca Bridge MRP .. |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 +.. |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%2Fai-lightgray.png?logo=github diff --git a/ai_oca_bridge_mrp/__manifest__.py b/ai_oca_bridge_mrp/__manifest__.py index 06e70ae..9f90c3a 100644 --- a/ai_oca_bridge_mrp/__manifest__.py +++ b/ai_oca_bridge_mrp/__manifest__.py @@ -2,12 +2,13 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - "name": "Ai Oca Bridge MRP", + "name": "AI OCA Bridge MRP", "summary": """Adds MRP triggers for AI Bridges""", "version": "16.0.1.0.0", "license": "AGPL-3", "author": "Escodoo,Odoo Community Association (OCA)", "maintainers": ["marcelsavegnago"], + "category": "AI", "website": "https://github.com/OCA/ai", "depends": [ "ai_oca_bridge", diff --git a/ai_oca_bridge_mrp/static/description/icon.png b/ai_oca_bridge_mrp/static/description/icon.png index 3a0328b..4adee3c 100644 Binary files a/ai_oca_bridge_mrp/static/description/icon.png and b/ai_oca_bridge_mrp/static/description/icon.png differ diff --git a/ai_oca_bridge_mrp/static/description/index.html b/ai_oca_bridge_mrp/static/description/index.html index 1b3dc28..2c88bdb 100644 --- a/ai_oca_bridge_mrp/static/description/index.html +++ b/ai_oca_bridge_mrp/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +AI OCA Bridge MRP -
+
+

AI OCA Bridge MRP

- - -Odoo Community Association - -
-

Ai Oca Bridge MRP

-

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

+

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

This module is intended to allow external AI systems to perform actions with the correct context, based on triggers related to MRP.

Table of contents

@@ -392,7 +387,7 @@

Ai Oca Bridge MRP

-

Configuration

+

Configuration

  • Bridge with ``Usage = “AI Thread Create”`` Processes new MRP workorder in the external system for AI-enhanced actions like lead @@ -416,13 +411,13 @@

    Configuration

-

Usage

+

Usage

Depending on the bridges you have created, create, update or delete a MRP record matching the bridge domain. You should see the execution on the AI Bridge Execution menu.

-

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 @@ -430,15 +425,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Escodoo
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -462,6 +457,5 @@

Maintainers

-
diff --git a/ai_oca_bridge_mrp/tests/test_mrp_workorder_ai_bridge.py b/ai_oca_bridge_mrp/tests/test_mrp_workorder_ai_bridge.py deleted file mode 100644 index b557a3d..0000000 --- a/ai_oca_bridge_mrp/tests/test_mrp_workorder_ai_bridge.py +++ /dev/null @@ -1,262 +0,0 @@ -# Copyright 2025 Escodoo -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from unittest import mock - -from odoo.tests.common import TransactionCase - - -class TestMrpAiBridge(TransactionCase): - @classmethod - def setUpClass(cls): - super().setUpClass() - - # Create necessary MRP data - cls.product = cls.env["product.product"].create( - { - "name": "Test Product", - "type": "product", - } - ) - - cls.bom = cls.env["mrp.bom"].create( - { - "product_tmpl_id": cls.product.product_tmpl_id.id, - "product_qty": 1, - } - ) - - cls.workcenter = cls.env["mrp.workcenter"].create( - { - "name": "Test Workcenter", - } - ) - - cls.operation = cls.env["mrp.routing.workcenter"].create( - { - "name": "Test Operation", - "bom_id": cls.bom.id, - "workcenter_id": cls.workcenter.id, - } - ) - - # Create a production order - cls.production = cls.env["mrp.production"].create( - { - "name": "Test Production", - "product_id": cls.product.id, - "product_qty": 1, - "bom_id": cls.bom.id, - } - ) - - cls.bridge_create = cls.env["ai.bridge"].create( - { - "name": "MRP Workorder AI Bridge - Create", - "description": "

Test bridge for MRP workorder creation

", - "model_id": cls.env.ref("mrp.model_mrp_workorder").id, - "usage": "ai_thread_create", - "url": "https://api.example.com/ai/mrp/create", - "auth_type": "none", - "payload_type": "record", - "result_type": "none", - "result_kind": "immediate", - "field_ids": [ - ( - 6, - 0, - [ - cls.env.ref("mrp.field_mrp_workorder__name").id, - cls.env.ref("mrp.field_mrp_workorder__state").id, - ], - ) - ], - } - ) - - cls.bridge_write = cls.env["ai.bridge"].create( - { - "name": "MRP Workorder AI Bridge - Update", - "description": "

Test bridge for MRP workorder updates

", - "model_id": cls.env.ref("mrp.model_mrp_workorder").id, - "usage": "ai_thread_write", - "url": "https://api.example.com/ai/mrp/update", - "auth_type": "none", - "payload_type": "record", - "result_type": "none", - "result_kind": "immediate", - "field_ids": [ - ( - 6, - 0, - [ - cls.env.ref("mrp.field_mrp_workorder__name").id, - cls.env.ref("mrp.field_mrp_workorder__state").id, - ], - ) - ], - } - ) - - cls.bridge_unlink = cls.env["ai.bridge"].create( - { - "name": "MRP Workorder AI Bridge - Delete", - "description": "

Test bridge for MRP workorder deletion

", - "model_id": cls.env.ref("mrp.model_mrp_workorder").id, - "usage": "ai_thread_unlink", - "url": "https://api.example.com/ai/mrp/delete", - "auth_type": "none", - "payload_type": "none", - "result_type": "none", - "result_kind": "immediate", - } - ) - - def test_mrp_workorder_create_bridge(self): - with mock.patch("requests.post") as mock_post: - mock_post.return_value.status_code = 200 - mock_post.return_value.json.return_value = {"message": "Workorder created"} - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_create.id)] - ), - ) - workorder = self.env["mrp.workorder"].create( - { - "name": "Test Workorder", - "workcenter_id": self.workcenter.id, - "production_id": self.production.id, - "product_uom_id": self.product.uom_id.id, - } - ) - executions = self.env["ai.bridge.execution"].search( - [("ai_bridge_id", "=", self.bridge_create.id)] - ) - self.assertEqual(len(executions), 1) - args, kwargs = mock_post.call_args - self.assertEqual(args[0], "https://api.example.com/ai/mrp/create") - record = kwargs["json"].get("record", {}) - self.assertEqual(record.get("id"), workorder.id) - self.assertEqual(record.get("name"), "Test Workorder") - - def test_mrp_workorder_write_bridge(self): - self.bridge_create.active = False - workorder = self.env["mrp.workorder"].create( - { - "name": "Test Workorder for Update", - "workcenter_id": self.workcenter.id, - "production_id": self.production.id, - "product_uom_id": self.product.uom_id.id, - } - ) - self.bridge_create.active = True - with mock.patch("requests.post") as mock_post: - mock_post.return_value.status_code = 200 - mock_post.return_value.json.return_value = {"message": "Workorder updated"} - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_write.id)] - ), - ) - workorder.write( - { - "name": "Updated Workorder", - } - ) - executions = self.env["ai.bridge.execution"].search( - [("ai_bridge_id", "=", self.bridge_write.id)] - ) - self.assertEqual(len(executions), 1) - args, kwargs = mock_post.call_args - self.assertEqual(args[0], "https://api.example.com/ai/mrp/update") - record = kwargs["json"].get("record", {}) - self.assertEqual(record.get("id"), workorder.id) - self.assertEqual(record.get("name"), "Updated Workorder") - - def test_mrp_workorder_unlink_bridge(self): - self.bridge_create.active = False - workorder = self.env["mrp.workorder"].create( - { - "name": "Test Workorder for Deletion", - "workcenter_id": self.workcenter.id, - "production_id": self.production.id, - "product_uom_id": self.product.uom_id.id, - } - ) - self.bridge_create.active = True - workorder_id = workorder.id - with mock.patch("requests.post") as mock_post: - mock_post.return_value.status_code = 200 - mock_post.return_value.json.return_value = {"message": "Workorder deleted"} - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_unlink.id)] - ), - ) - workorder.unlink() - executions = self.env["ai.bridge.execution"].search( - [("ai_bridge_id", "=", self.bridge_unlink.id)] - ) - self.assertEqual(len(executions), 1) - args, kwargs = mock_post.call_args - self.assertEqual(args[0], "https://api.example.com/ai/mrp/delete") - self.assertEqual(kwargs["json"].get("_id", False), workorder_id) - - def test_all_bridges_together(self): - with mock.patch("requests.post") as mock_post: - mock_post.return_value.status_code = 200 - mock_post.return_value.json.return_value = {"message": "Success"} - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_create.id)] - ), - ) - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_write.id)] - ), - ) - self.assertEqual( - 0, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_unlink.id)] - ), - ) - workorder = self.env["mrp.workorder"].create( - { - "name": "Complete Test Workorder", - "workcenter_id": self.workcenter.id, - "production_id": self.production.id, - "product_uom_id": self.product.uom_id.id, - } - ) - workorder.write( - { - "name": "Updated Complete Test Workorder", - } - ) - workorder.unlink() - - self.assertEqual( - 1, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_create.id)] - ), - ) - self.assertEqual( - 1, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_write.id)] - ), - ) - self.assertEqual( - 1, - self.env["ai.bridge.execution"].search_count( - [("ai_bridge_id", "=", self.bridge_unlink.id)] - ), - )