From f7d564bb10783179c734a9d864dfe1871d705df4 Mon Sep 17 00:00:00 2001 From: Tran Anh Tuan Date: Tue, 31 Oct 2023 09:43:24 +0000 Subject: [PATCH] [ADD] base_wamas: Add new module --- base_wamas/README.rst | 89 ++ base_wamas/__init__.py | 1 + base_wamas/__manifest__.py | 29 + base_wamas/data/ir_config_parameter_data.xml | 29 + .../wamas_document_default_field_data.xml | 55 ++ ...s_document_default_field_template_data.xml | 76 ++ .../data/wamas_document_element_data.xml | 146 ++++ base_wamas/data/wamas_document_field_data.xml | 799 ++++++++++++++++++ .../data/wamas_document_template_data.xml | 28 + base_wamas/models/__init__.py | 7 + .../models/wamas_document_default_field.py | 11 + .../wamas_document_default_field_template.py | 18 + ...as_document_default_field_template_line.py | 16 + base_wamas/models/wamas_document_element.py | 129 +++ base_wamas/models/wamas_document_field.py | 279 ++++++ base_wamas/models/wamas_document_template.py | 84 ++ .../models/wamas_document_template_line.py | 14 + base_wamas/readme/CONTRIBUTORS.rst | 2 + base_wamas/readme/CREDITS.rst | 1 + base_wamas/readme/DESCRIPTION.rst | 7 + base_wamas/security/ir_model_access.xml | 96 +++ base_wamas/static/description/index.html | 435 ++++++++++ base_wamas/tests/__init__.py | 1 + base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt | 6 + base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt | 6 + base_wamas/tests/test_base_wamas.py | 68 ++ ..._document_default_field_template_views.xml | 64 ++ .../wamas_document_default_field_views.xml | 71 ++ .../views/wamas_document_element_views.xml | 67 ++ .../views/wamas_document_field_views.xml | 86 ++ .../views/wamas_document_template_views.xml | 60 ++ base_wamas/views/wamas_menus.xml | 79 ++ setup/base_wamas/base_wamas | 1 + setup/base_wamas/odoo/addons/base_wamas | 1 + setup/base_wamas/setup.py | 6 + 35 files changed, 2867 insertions(+) create mode 100644 base_wamas/README.rst create mode 100644 base_wamas/__init__.py create mode 100644 base_wamas/__manifest__.py create mode 100644 base_wamas/data/ir_config_parameter_data.xml create mode 100644 base_wamas/data/wamas_document_default_field_data.xml create mode 100644 base_wamas/data/wamas_document_default_field_template_data.xml create mode 100644 base_wamas/data/wamas_document_element_data.xml create mode 100644 base_wamas/data/wamas_document_field_data.xml create mode 100644 base_wamas/data/wamas_document_template_data.xml create mode 100644 base_wamas/models/__init__.py create mode 100644 base_wamas/models/wamas_document_default_field.py create mode 100644 base_wamas/models/wamas_document_default_field_template.py create mode 100644 base_wamas/models/wamas_document_default_field_template_line.py create mode 100644 base_wamas/models/wamas_document_element.py create mode 100644 base_wamas/models/wamas_document_field.py create mode 100644 base_wamas/models/wamas_document_template.py create mode 100644 base_wamas/models/wamas_document_template_line.py create mode 100644 base_wamas/readme/CONTRIBUTORS.rst create mode 100644 base_wamas/readme/CREDITS.rst create mode 100644 base_wamas/readme/DESCRIPTION.rst create mode 100644 base_wamas/security/ir_model_access.xml create mode 100644 base_wamas/static/description/index.html create mode 100644 base_wamas/tests/__init__.py create mode 100644 base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt create mode 100644 base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt create mode 100644 base_wamas/tests/test_base_wamas.py create mode 100644 base_wamas/views/wamas_document_default_field_template_views.xml create mode 100644 base_wamas/views/wamas_document_default_field_views.xml create mode 100644 base_wamas/views/wamas_document_element_views.xml create mode 100644 base_wamas/views/wamas_document_field_views.xml create mode 100644 base_wamas/views/wamas_document_template_views.xml create mode 100644 base_wamas/views/wamas_menus.xml create mode 120000 setup/base_wamas/base_wamas create mode 120000 setup/base_wamas/odoo/addons/base_wamas create mode 100644 setup/base_wamas/setup.py diff --git a/base_wamas/README.rst b/base_wamas/README.rst new file mode 100644 index 00000000000..ec0d6086424 --- /dev/null +++ b/base_wamas/README.rst @@ -0,0 +1,89 @@ +========== +Base WAMAS +========== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6161db39eaa16938cd82cb49477c6fbffecebc8c59d08cde376b59d6624b22c7 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fedi-lightgray.png?logo=github + :target: https://github.com/OCA/edi/tree/16.0/base_wamas + :alt: OCA/edi +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/edi-16-0/edi-16-0-base_wamas + :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/edi&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Provides following models: + +* WAMAS Document Template, to define WAMAS document, it includes WAMAS document elements. +* WAMAS Document Element, to define elements in WAMAS document, such as: WEAK, WEAP... +* WAMAS Document Field, to define fields that WAMAS elment has, there are a lot of fields in a WAMAS element. +* WAMAS Document Default Field, to define default fields of WAMAS document has. +* WAMAS Document Default Field Template, to define the template of default fields of the elements. + +**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 +~~~~~~~ + +* BCIM +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Jacques-Etienne Baudoux +* Tuan Tran + +Other credits +~~~~~~~~~~~~~ + +The creation of this module was financially supported by Camptocamp. + +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/edi `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_wamas/__init__.py b/base_wamas/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/base_wamas/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/base_wamas/__manifest__.py b/base_wamas/__manifest__.py new file mode 100644 index 00000000000..c42dd092c41 --- /dev/null +++ b/base_wamas/__manifest__.py @@ -0,0 +1,29 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Base WAMAS", + "summary": """Base module to aggregate WAMAS features.""", + "version": "16.0.1.0.0", + "development_status": "Beta", + "website": "https://github.com/OCA/edi", + "license": "AGPL-3", + "author": "BCIM,Camptocamp,Odoo Community Association (OCA)", + "depends": ["base_edi"], + "data": [ + "security/ir_model_access.xml", + "data/ir_config_parameter_data.xml", + "data/wamas_document_field_data.xml", + "data/wamas_document_default_field_data.xml", + "data/wamas_document_default_field_template_data.xml", + "data/wamas_document_element_data.xml", + "data/wamas_document_template_data.xml", + "views/wamas_document_template_views.xml", + "views/wamas_document_element_views.xml", + "views/wamas_document_field_views.xml", + "views/wamas_document_default_field_views.xml", + "views/wamas_document_default_field_template_views.xml", + "views/wamas_menus.xml", + ], +} diff --git a/base_wamas/data/ir_config_parameter_data.xml b/base_wamas/data/ir_config_parameter_data.xml new file mode 100644 index 00000000000..9a7f03598f2 --- /dev/null +++ b/base_wamas/data/ir_config_parameter_data.xml @@ -0,0 +1,29 @@ + + + + + wamas_document_default_field_type + Sentence Type + + + + wamas_document_list_false_value + ["n", "nein", "non", "no", "none", "f", "false"] + + + + wamas_document_list_true_value + ["j", "ja", "o", "oui", "t", "true", "y", "yes"] + + + + wamas_document_default_false_value + "N" + + + + wamas_document_default_true_value + "J" + + + diff --git a/base_wamas/data/wamas_document_default_field_data.xml b/base_wamas/data/wamas_document_default_field_data.xml new file mode 100644 index 00000000000..e6a194cfbab --- /dev/null +++ b/base_wamas/data/wamas_document_default_field_data.xml @@ -0,0 +1,55 @@ + + + + + Source + Source + str + 10 + + + + Destination + Destination + str + 10 + + + + Telegram Sequence + Telegram Sequence + int + 6 + 30 + + + + Creation Time + Creation Time + datetime + 14 + + + + Sentence Type + Sentence Type + str + 9 + + + diff --git a/base_wamas/data/wamas_document_default_field_template_data.xml b/base_wamas/data/wamas_document_default_field_template_data.xml new file mode 100644 index 00000000000..124fd36d491 --- /dev/null +++ b/base_wamas/data/wamas_document_default_field_template_data.xml @@ -0,0 +1,76 @@ + + + + + Default Field Template - WEAK + Default Field Template - WEAK + + + + + Default Field Template - WEAP + Default Field Template - WEAP + + + + + Default Field Template - WEAKQ + Default Field Template - WEAKQ + + + + + Default Field Template - WEAPQ + Default Field Template - WEAPQ + + + + diff --git a/base_wamas/data/wamas_document_element_data.xml b/base_wamas/data/wamas_document_element_data.xml new file mode 100644 index 00000000000..0c0528926bf --- /dev/null +++ b/base_wamas/data/wamas_document_element_data.xml @@ -0,0 +1,146 @@ + + + + + WEAK + WEAK + + + + + + WEAP + WEAP + + + + + + WEAKQ + WEAKQ + + + + + + WEAPQ + WEAPQ + + + + + diff --git a/base_wamas/data/wamas_document_field_data.xml b/base_wamas/data/wamas_document_field_data.xml new file mode 100644 index 00000000000..141d0a18eba --- /dev/null +++ b/base_wamas/data/wamas_document_field_data.xml @@ -0,0 +1,799 @@ + + + + + + + Client + Client + str + 3 + 60 + + + + EM Notice Number + EM Notice Number + str + 20 + 70 + + + + EM Host Review Code + EM Host Review Code + str + 5 + 80 + + + + External Reference + External Reference + str + 20 + 90 + + + + EM Notice Type + EM Notice Type + str + 6 + 100 + + + + Mand. Supplier + Mand. Supplier + str + 3 + 110 + + + + Supplier Number + Supplier Number + str + 13 + 120 + + + + Name + Name + str + 40 + 130 + + + + Name 2 + Name 2 + str + 40 + 140 + + + + Name 3 + Name 3 + str + 40 + 150 + + + + Name 4 + Name 4 + str + 40 + 160 + + + + Call Form + Call Form + str + 15 + 170 + + + + Address + Address + str + 40 + 180 + + + + Address 2 + Address 2 + str + 40 + 190 + + + + Postal Code + Postal Code + str + 10 + 200 + + + + Location + Location + str + 40 + 210 + + + + District + District + str + 40 + 220 + + + + Country + Country + str + 4 + 230 + + + + Phone Number + Phone Number + str + 35 + 240 + + + + Fax Number + Fax Number + str + 35 + 250 + + + + Email + Email + str + 40 + 260 + + + + Home Page + Home Page + str + 35 + 270 + + + + ILN/GLN + ILN/GLN + str + 13 + 280 + + + + Order Date + Order Date + datetime + 14 + 290 + + + + Information for WAMAS + Information for WAMAS + str + 77 + 300 + + + + + + Client + Client + str + 3 + 60 + + + + EM Notice Number + EM Notice Number + str + 20 + 70 + + + + EM Host Review Code + EM Host Review Code + str + 5 + 80 + + + + External Reference + External Reference + str + 20 + 90 + + + + HOST-PosNr + HOST-PosNr + str + 6 + 100 + + + + Client 2 + Client 2 + str + 3 + 110 + + + + Item Number + Item Number + str + 20 + 120 + + + + Variant + Variant + str + 5 + 130 + + + + Batch + Batch + str + 20 + 140 + + + + DLC + DLC + date + 8 + 150 + + + + Booking Number + Booking Number + str + 20 + 160 + + + + KZ Transport Assistance + KZ Transport Assistance + bool + 1 + 170 + + + + Material Qualifier 1 + Material Qualifier 1 + str + 20 + 180 + + + + Material Qualifier 2 + Material Qualifier 2 + str + 20 + 190 + + + + Material Qualifier 3 + Material Qualifier 3 + str + 20 + 200 + + + + Ordered Quantity + Ordered Quantity + float + 12 + 3 + 210 + + + + Order Unit + Order Unit + str + 5 + 220 + + + + TypePos-EM + TypePos-EM + str + 7 + 230 + + + + Notified Delivery Date + Notified Delivery Date + datetime + 14 + 240 + + + + Notified Delivery Note Number + Notified Delivery Note Number + str + 20 + 250 + + + + Notified Delivery Note Date + Notified Delivery Note Date + datetime + 14 + 260 + + + + Supplier Item Number + Supplier Item Number + str + 20 + 270 + + + + Sentence ID + Sentence ID + str + 1 + 280 + + + + Position Finished + Position Finished + bool + 1 + 290 + + + + Feedback + Feedback + str + 3 + 300 + + + + Serial Number + Serial Number + str + 20 + 310 + + + + Information for WAMAS + Information for WAMAS + str + 77 + 320 + + + + + + Client + Client + str + 3 + 60 + + + + EM Transaction Number + EM Transaction Number + str + 20 + 70 + + + + EM Notice ID for Host + EM Notice ID for Host + str + 5 + 80 + + + + Delivery Date + Delivery Date + datetime + 14 + 90 + + + + Truck Driver + Truck Driver + str + 40 + 100 + + + + Truck License Plate + Truck License Plate + str + 10 + 110 + + + + Truck Entry Time + Truck Entry Time + datetime + 14 + 120 + + + + Start Time + Start Time + datetime + 14 + 130 + + + + Finish Time + Finish Time + datetime + 14 + 140 + + + + Registration Time + Registration Time + datetime + 14 + 150 + + + + Host Information + Host Information + str + 77 + 160 + + + + Mand. Supplier + Mand. Supplier + str + 3 + 170 + + + + Vendor Code + Vendor Code + str + 13 + 180 + + + + + + Client + Client + str + 3 + 60 + + + + EM Transaction Number + EM Transaction Number + str + 20 + 70 + + + + Client 2 + Client 2 + str + 3 + 80 + + + + EM Notice Number + EM Notice Number + str + 20 + 90 + + + + EM Notice ID for Host + EM Notice ID for Host + str + 5 + 100 + + + + External Reference + External Reference + str + 20 + 110 + + + + HOST-PosNr + HOST-PosNr + str + 6 + 120 + + + + Delivery Note Number + Delivery Note Number + str + 20 + 130 + + + + Client 3 + Client 3 + str + 3 + 140 + + + + Item Number + Item Number + str + 20 + 150 + + + + Variant + Variant + str + 5 + 160 + + + + Host Material Qualification ID + Host Material Qualification ID + str + 20 + 170 + + + + Quantity + Quantity + float + 12 + 3 + 180 + + + + Weight + Weight + float + 12 + 3 + 190 + + + + HOST Weight Unit + HOST Weight Unit + str + 5 + 200 + + + + Stock Unit + Stock Unit + str + 5 + 210 + + + + Batch + Batch + str + 20 + 220 + + + + DLC + DLC + date + 8 + 230 + + + + Booking Number + Booking Number + str + 20 + 240 + + + + EM Number + EM Number + str + 20 + 250 + + + + KZ Transport Assistance + KZ Transport Assistance + bool + 1 + 260 + + + diff --git a/base_wamas/data/wamas_document_template_data.xml b/base_wamas/data/wamas_document_template_data.xml new file mode 100644 index 00000000000..30a779e627d --- /dev/null +++ b/base_wamas/data/wamas_document_template_data.xml @@ -0,0 +1,28 @@ + + + + + WEAK - WEAP + WEAK - WEAP + + + + + WEAKQ - WEAPQ + WEAKQ - WEAPQ + + + + diff --git a/base_wamas/models/__init__.py b/base_wamas/models/__init__.py new file mode 100644 index 00000000000..b2bb5f862ff --- /dev/null +++ b/base_wamas/models/__init__.py @@ -0,0 +1,7 @@ +from . import wamas_document_field +from . import wamas_document_default_field +from . import wamas_document_default_field_template +from . import wamas_document_default_field_template_line +from . import wamas_document_element +from . import wamas_document_template +from . import wamas_document_template_line diff --git a/base_wamas/models/wamas_document_default_field.py b/base_wamas/models/wamas_document_default_field.py new file mode 100644 index 00000000000..5dcae2749c5 --- /dev/null +++ b/base_wamas/models/wamas_document_default_field.py @@ -0,0 +1,11 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class WamasDocumentDefaultField(models.Model): + _name = "wamas.document.default.field" + _inherit = "wamas.document.field" + _description = "WAMAS Document Default Field" diff --git a/base_wamas/models/wamas_document_default_field_template.py b/base_wamas/models/wamas_document_default_field_template.py new file mode 100644 index 00000000000..af9199b1609 --- /dev/null +++ b/base_wamas/models/wamas_document_default_field_template.py @@ -0,0 +1,18 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class WamasDocumentDefaultField(models.Model): + _name = "wamas.document.default.field.template" + _description = "WAMAS Document Default Field Template" + + name = fields.Char(required=True) + code = fields.Char(required=True) + line_ids = fields.One2many( + "wamas.document.default.field.template.line", + "template_id", + "Lines of Default Fields", + ) diff --git a/base_wamas/models/wamas_document_default_field_template_line.py b/base_wamas/models/wamas_document_default_field_template_line.py new file mode 100644 index 00000000000..88c42409df5 --- /dev/null +++ b/base_wamas/models/wamas_document_default_field_template_line.py @@ -0,0 +1,16 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class WamasDocumentDefaultFieldLine(models.Model): + _name = "wamas.document.default.field.template.line" + _description = "WAMAS Document Default Field Template Line" + + df_field_id = fields.Many2one( + "wamas.document.default.field", "Default Field", required=True + ) + sequence = fields.Integer(required=True, default=10) + template_id = fields.Many2one("wamas.document.default.field.template", "Template") diff --git a/base_wamas/models/wamas_document_element.py b/base_wamas/models/wamas_document_element.py new file mode 100644 index 00000000000..c184271b52d --- /dev/null +++ b/base_wamas/models/wamas_document_element.py @@ -0,0 +1,129 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from collections import OrderedDict + +from odoo import _, fields, models +from odoo.exceptions import UserError + +from ..models.wamas_document_template import check_type_of_item + + +def get_item(recordset_field, row, idx_start, res, convert_type): + for field in recordset_field: + if field._name == "wamas.document.default.field.template.line": + field = field.df_field_id + + idx_end = idx_start + field.len_field + + val = row[idx_start:idx_end] + if convert_type: + val = field.get_value_from_string(val) + + if isinstance(res, OrderedDict): + res[field.code] = val + elif isinstance(res, list): + res.append((field.code, val)) + + idx_start = idx_end + + return res, idx_start + + +class WamasDocumentElement(models.Model): + _name = "wamas.document.element" + _description = "WAMAS Document Element" + + name = fields.Char(required=True) + code = fields.Char(required=True) + df_field_template_id = fields.Many2one( + "wamas.document.default.field.template", "Default Field Template", required=True + ) + field_ids = fields.One2many("wamas.document.field", "element_id", "Fields") + + def get_values_from_element( + self, row, convert_type=False, result_type="ordered_dict" + ): + self.ensure_one() + + res = False + + if result_type == "list_tuple": + res = [] + elif result_type == "ordered_dict": + res = OrderedDict() + idx = 0 + + # Get value from `row` for `default fields` + sorted_fields = self.df_field_template_id.line_ids.sorted( + key=lambda r: r.sequence + ) + res, idx = get_item(sorted_fields, row, idx, res, convert_type) + + # Get value from `row` for `fields` + sorted_fields = self.field_ids.sorted(key=lambda r: r.sequence) + res, idx = get_item(sorted_fields, row, idx, res, convert_type) + + return res + + def set_values_to_element(self, items): + self.ensure_one() + + res = "" + + item_type = check_type_of_item(items) + if not item_type: + raise UserError( + _( + "The input must be the list of tuples OR " + "the the list of ordered dictionary!" + ) + ) + + for item in items: + if item_type == "list_tuple": + _key = item[0] + _value = item[1] + elif item_type == "ordered_dict": + _key = item + _value = items[_key] + + for line in self.df_field_template_id.line_ids: + df_field = line.df_field_id + + if _key == df_field.code: + res += df_field.set_value_to_string(_value) + + for field in self.field_ids: + if _key == field.code: + a1 = field.set_value_to_string(_value) + res += a1 + + return res + + def get_index_of_field_type(self): + self.ensure_one() + + idx_start = False + idx_end = False + + default_field_type = self.env["ir.config_parameter"].get_param( + "wamas_document_default_field_type", "Sentence Type" + ) + line_of_field_type = self.df_field_template_id.line_ids.filtered( + lambda r: r.df_field_id.code == default_field_type + ) + + if line_of_field_type: + field_type = line_of_field_type.df_field_id + + filtered_lines = self.df_field_template_id.line_ids.filtered( + lambda r: r.sequence < line_of_field_type.sequence + ) + + if filtered_lines: + idx_start = sum([line.df_field_id.len_field for line in filtered_lines]) + idx_end = idx_start + field_type.len_field + + return idx_start, idx_end diff --git a/base_wamas/models/wamas_document_field.py b/base_wamas/models/wamas_document_field.py new file mode 100644 index 00000000000..9f226c00555 --- /dev/null +++ b/base_wamas/models/wamas_document_field.py @@ -0,0 +1,279 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from datetime import date, datetime + +from dateutil.parser import parse + +from odoo import _, fields, models +from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval + +FIELD_TYPES = [ + ("str", "String"), + ("int", "Integer"), + ("float", "Float"), + ("date", "Date"), + ("datetime", "Datetime"), + ("bool", "Boolean"), +] + + +def is_date(string, fuzzy=False): + """ + Return whether the string can be interpreted as a date. + + :param string: str, string to check for date + :param fuzzy: bool, ignore unknown tokens in string if True + """ + try: + parse(string, fuzzy=fuzzy) + return True + + except ValueError: + return False + + +class WamasDocumentField(models.Model): + _name = "wamas.document.field" + _description = "WAMAS Document Field" + + name = fields.Char(required=True) + code = fields.Char(required=True) + ttype = fields.Selection(FIELD_TYPES, "Type", required=True) + len_field = fields.Integer("Length", required=True) + decimal_place = fields.Integer() + sequence = fields.Integer(required=True, default=10) + element_id = fields.Many2one("wamas.document.element", "Element") + + def get_value_from_string(self, value): + self.ensure_one() + + res = value + + if self.ttype == "str": + res = self._get_string(value) + elif self.ttype == "int": + res = self._get_int(value) + elif self.ttype == "float": + res = self._get_float(value) + elif self.ttype == "date": + res = self._get_date(value) + elif self.ttype == "datetime": + res = self._get_datetime(value) + elif self.ttype == "bool": + res = self._get_bool(value) + + return res + + def set_value_to_string(self, value): + self.ensure_one() + + res = value + + if self.ttype == "str": + res = self._set_from_string(value) + elif self.ttype == "int": + res = self._set_from_int(value) + elif self.ttype == "float": + res = self._set_from_float(value) + elif self.ttype == "date": + res = self._set_from_date(value) + elif self.ttype == "datetime": + res = self._set_from_datetime(value) + elif self.ttype == "bool": + res = self._set_from_bool(value) + + return res + + def _get_string(self, value): + self.ensure_one() + + res = value.strip() + + return res + + def _get_int(self, value): + self.ensure_one() + + res = value.strip() + + try: + res = int(res) + except TypeError: # pylint: disable=except-pass + pass + + return res + + def _get_float(self, value): + self.ensure_one() + + res = value.strip() + + try: + if len(res) >= self.len_field: + str_whole_number = res[: self.len_field - self.decimal_place] + str_decimal_portion = res[self.decimal_place * -1 :] + + res = str_whole_number + "." + str_decimal_portion + + res = float(res.strip()) + except TypeError: # pylint: disable=except-pass + pass + + return res + + def _get_date(self, value): + self.ensure_one() + + res = value.strip() + + try: + if res: + res = parse(res).date() + except TypeError: # pylint: disable=except-pass + pass + + return res + + def _get_datetime(self, value): + self.ensure_one() + + res = value.strip() + + try: + if res: + res = parse(res) + except TypeError: # pylint: disable=except-pass + pass + + return res + + def _get_bool(self, value): + self.ensure_one() + + res = value.strip() + + ICP = self.env["ir.config_parameter"] + lst_false = safe_eval(ICP.get_param("wamas_document_list_false_value", ["f"])) + lst_true = safe_eval(ICP.get_param("wamas_document_list_true_value", ["t"])) + + try: + if value.lower() in lst_false: + res = False + elif value.lower() in lst_true: + res = True + except TypeError: # pylint: disable=except-pass + pass + + return res + + def _set_from_string(self, value): + self.ensure_one() + + res = str(value).ljust(self.len_field)[: self.len_field] + + return res + + def _set_from_int(self, value): + self.ensure_one() + + res = str(value).rjust(self.len_field, "0")[: self.len_field] + + return res + + def _set_from_float(self, value): + self.ensure_one() + + res = str(float(value)) + + # Check if it is int / float or not + if not res.replace(".", "", 1).isdigit(): + raise UserError( + _( + "The value '%s' is not the float type. " + "Please check it again!" % res + ) + ) + + str_whole_number, str_decimal_portion = res.split(".") + + str_whole_number = str_whole_number.rjust( + self.len_field - self.decimal_place, "0" + ) + str_decimal_portion = str_decimal_portion.ljust(self.decimal_place, "0") + + res = (str_whole_number + str_decimal_portion)[: self.len_field] + + return res + + def _set_from_date(self, value): + self.ensure_one() + + res = value + + if isinstance(res, date): + res = res.strftime("%Y%m%d") + elif isinstance(res, datetime): + res = res.date().strftime("%Y%m%d") + elif isinstance(res, str): + if res == "": + res = res.ljust(self.len_field) + elif not is_date(res): + raise UserError( + _( + "The value '%s' is not the date type. " + "Please check it again!" % value + ) + ) + else: + res = str(value).ljust(self.len_field) + + res = res[: self.len_field] + + return res + + def _set_from_datetime(self, value): + self.ensure_one() + + res = value + + if isinstance(res, (date, datetime)): + res = res.strftime("%Y%m%d%H%M%S") + elif isinstance(res, str): + if res == "": + res = res.ljust(self.len_field) + elif not is_date(res): + raise UserError( + _( + "The value '%s' is not the datetime type. " + "Please check it again!" % value + ) + ) + else: + res = str(value).ljust(self.len_field) + + res = res[: self.len_field] + + return res + + def _set_from_bool(self, value): + self.ensure_one() + + ICP = self.env["ir.config_parameter"] + default_false_value = safe_eval( + ICP.get_param("wamas_document_default_false_value", "F") + ) + default_true_value = safe_eval( + ICP.get_param("wamas_document_default_true_value", "T") + ) + + res = default_false_value + + if value: + res = default_true_value + + res = res[: self.len_field] + + return res diff --git a/base_wamas/models/wamas_document_template.py b/base_wamas/models/wamas_document_template.py new file mode 100644 index 00000000000..087e2bcdd5b --- /dev/null +++ b/base_wamas/models/wamas_document_template.py @@ -0,0 +1,84 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from collections import OrderedDict + +from odoo import _, fields, models +from odoo.exceptions import UserError + + +def check_type_of_item(items): + res = False + + if isinstance(items, list): + res = "list_tuple" + elif isinstance(items, OrderedDict): + res = "ordered_dict" + + return res + + +class WamasDocumentTemplate(models.Model): + _name = "wamas.document.template" + _description = "WAMAS Document Template" + + name = fields.Char(required=True) + code = fields.Char(required=True) + line_ids = fields.One2many( + "wamas.document.template.line", "template_id", "Lines of Elements" + ) + + def get_proper_element_from_row(self, row): + self.ensure_one() + res = False + + for line in self.line_ids: + element = line.element_id + + idx_start, idx_end = element.get_index_of_field_type() + + if idx_start and idx_end: + str_row_type = row[idx_start:idx_end] + + if str_row_type and element.code in str_row_type: + res = element + break + + return res + + def get_proper_element_from_items(self, items): + self.ensure_one() + + res = False + + item_type = check_type_of_item(items) + if not item_type: + raise UserError( + _( + "The input must be the list of tuples OR " + "the the list of ordered dictionary!" + ) + ) + + default_field_type = self.env["ir.config_parameter"].get_param( + "wamas_document_default_field_type", "Sentence Type" + ) + + for item in items: + if item_type == "list_tuple": + _key = item[0] + _value = item[1] + elif item_type == "ordered_dict": + _key = item + _value = items[_key] + + if _key == default_field_type: + found_line = self.line_ids.filtered( + lambda r: r.element_id.code in _value + ) + + if found_line: + res = found_line.element_id + + return res diff --git a/base_wamas/models/wamas_document_template_line.py b/base_wamas/models/wamas_document_template_line.py new file mode 100644 index 00000000000..b06d019ae6d --- /dev/null +++ b/base_wamas/models/wamas_document_template_line.py @@ -0,0 +1,14 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class WamasDocumentTemplateLine(models.Model): + _name = "wamas.document.template.line" + _description = "WAMAS Document Template Line" + + element_id = fields.Many2one("wamas.document.element", required=True) + sequence = fields.Integer(required=True, default=10) + template_id = fields.Many2one("wamas.document.template", "Template") diff --git a/base_wamas/readme/CONTRIBUTORS.rst b/base_wamas/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..0ab51a38a22 --- /dev/null +++ b/base_wamas/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Jacques-Etienne Baudoux +* Tuan Tran diff --git a/base_wamas/readme/CREDITS.rst b/base_wamas/readme/CREDITS.rst new file mode 100644 index 00000000000..ac19123b04a --- /dev/null +++ b/base_wamas/readme/CREDITS.rst @@ -0,0 +1 @@ +The creation of this module was financially supported by Camptocamp. diff --git a/base_wamas/readme/DESCRIPTION.rst b/base_wamas/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..f34d7d0ae2e --- /dev/null +++ b/base_wamas/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +Provides following models: + +* WAMAS Document Template, to define WAMAS document, it includes WAMAS document elements. +* WAMAS Document Element, to define elements in WAMAS document, such as: WEAK, WEAP... +* WAMAS Document Field, to define fields that WAMAS elment has, there are a lot of fields in a WAMAS element. +* WAMAS Document Default Field, to define default fields of WAMAS document has. +* WAMAS Document Default Field Template, to define the template of default fields of the elements. diff --git a/base_wamas/security/ir_model_access.xml b/base_wamas/security/ir_model_access.xml new file mode 100644 index 00000000000..93964731029 --- /dev/null +++ b/base_wamas/security/ir_model_access.xml @@ -0,0 +1,96 @@ + + + + + Access WAMAS Document Template - EDI Manager + + + + + + + + + + Access WAMAS Document Template Line - EDI Manager + + + + + + + + + + Access WAMAS Document Element - EDI Manager + + + + + + + + + + Access WAMAS Document Field - EDI Manager + + + + + + + + + + Access WAMAS Document Default Field - EDI Manager + + + + + + + + + + Access WAMAS Document Default Field Template Line - EDI Manager + + + + + + + + + + Access WAMAS Document Default Field Template - EDI Manager + + + + + + + + + diff --git a/base_wamas/static/description/index.html b/base_wamas/static/description/index.html new file mode 100644 index 00000000000..8f9d59a549c --- /dev/null +++ b/base_wamas/static/description/index.html @@ -0,0 +1,435 @@ + + + + + + +Base WAMAS + + + +
+

Base WAMAS

+ + +

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

+

Provides following models:

+
    +
  • WAMAS Document Template, to define WAMAS document, it includes WAMAS document elements.
  • +
  • WAMAS Document Element, to define elements in WAMAS document, such as: WEAK, WEAP…
  • +
  • WAMAS Document Field, to define fields that WAMAS elment has, there are a lot of fields in a WAMAS element.
  • +
  • WAMAS Document Default Field, to define default fields of WAMAS document has.
  • +
  • WAMAS Document Default Field Template, to define the template of default fields of the elements.
  • +
+

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

+
    +
  • BCIM
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The creation of this module was financially supported by Camptocamp.

+
+
+

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

+

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

+
+
+
+ + diff --git a/base_wamas/tests/__init__.py b/base_wamas/tests/__init__.py new file mode 100644 index 00000000000..97ff99b3027 --- /dev/null +++ b/base_wamas/tests/__init__.py @@ -0,0 +1 @@ +from . import test_base_wamas diff --git a/base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt b/base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt new file mode 100644 index 00000000000..943e40db565 --- /dev/null +++ b/base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt @@ -0,0 +1,6 @@ +WAMAS SYSTEM1 00000120230501065723WEAKQ0051000196241 HOST 20230501060217 19700101010000202305010609112023050106433920230501060221 0001040 +WAMAS SYSTEM1 00000220230501065723WEAPQ0050000196241 000123477 HOST 00002045415 0001111 00000DISPONIBLE 000001536000000000000000 BOUT 19700101 12 eCAM 018090 N +WAMAS SYSTEM1 00000320230501065723WEAPQ0050000196241 000123477 HOST 00003045415 0001112 00000DISPONIBLE 000005184000000000000000 PET 19700101 12 eCAM 018090 N +WAMAS SYSTEM1 00000420230501065723WEAPQ0050000196241 000123477 HOST 00004045415 0001113 00000DISPONIBLE 000003840000000000000000 BOUT 19700101 12 eCAM 018090 N +WAMAS SYSTEM1 00000520230501065723WEAPQ0050000196241 000123477 HOST 00005045415 0001114 00000DISPONIBLE 000003072000000000000000 PET 19700101 12 eCAM 018090 N +WAMAS SYSTEM1 00000620230501065723WEAPQ0050000196241 000123477 HOST 00006045415 0001115 00000DISPONIBLE 000003024000000000000000 PET 19700101 12 eCAM 018090 N diff --git a/base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt b/base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt new file mode 100644 index 00000000000..bcffe47aa61 --- /dev/null +++ b/base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt @@ -0,0 +1,6 @@ +SYSTEM1 WAMAS 00000120231031100930WEAK00050000123477 HOST STDMAN0001040 New Company 1 1th Ave S 55406 Minneapolis Minnesota Unit+41 111 222 333 +41 11 222 33 44 customerservice@new.company.com 20231028000000 +SYSTEM1 WAMAS 00002020231031100930WEAP00045000123477 HOST 0000200001111 00000 20231031 NDISPONIBLE 000001536000BOUT NORMAL 20231031000000 202310310000007910063 NNLG +SYSTEM1 WAMAS 00003020231031100930WEAP00045000123477 HOST 0000300001112 00000 20231031 NDISPONIBLE 000005184000PET NORMAL 20231031000000 202310310000007910105 NNLG +SYSTEM1 WAMAS 00004020231031100930WEAP00045000123477 HOST 0000400001113 00000 20231031 NDISPONIBLE 000003840000BOUT NORMAL 20231031000000 202310310000007910004 NNLG +SYSTEM1 WAMAS 00005020231031100930WEAP00045000123477 HOST 0000500001114 00000 20231031 NDISPONIBLE 000003072000PET NORMAL 20231031000000 2023103100000012156876 NNLG +SYSTEM1 WAMAS 00006020231031100930WEAP00045000123477 HOST 0000600001115 00000 20231031 NDISPONIBLE 000003024000PET NORMAL 20231031000000 202310310000007910044 NNLG diff --git a/base_wamas/tests/test_base_wamas.py b/base_wamas/tests/test_base_wamas.py new file mode 100644 index 00000000000..d4d9247e8e4 --- /dev/null +++ b/base_wamas/tests/test_base_wamas.py @@ -0,0 +1,68 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import filecmp +import os +import tempfile + +from odoo.tests.common import TransactionCase +from odoo.tools import file_open, file_path + + +class TestBaseWamas(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.weak_weap = cls.env.ref("base_wamas.wamas_document_template_weak_weap") + cls.weakq_weapq = cls.env.ref("base_wamas.wamas_document_template_weakq_weapq") + cls.tmpfile_path = tempfile.mkstemp(suffix=".txt")[1] + + @classmethod + def tearDownClass(cls): + if os.path.exists(cls.tmpfile_path): + os.remove(cls.tmpfile_path) + return super().tearDownClass() + + def test_weak_weap(self): + path = "base_wamas/tests/files/SAMPLE_WEAK_WEAP.txt" + self._run_full_workflow(path, self.weak_weap) + + def test_weakq_weapq(self): + path = "base_wamas/tests/files/SAMPLE_WEAKQ_WEAPQ.txt" + self._run_full_workflow(path, self.weakq_weapq) + + def _run_full_workflow(self, path, template_rec): + # Get the data from XML file + result = [] + + with file_open(path) as f: + for row in f: + found_element = template_rec.get_proper_element_from_row(row) + + if not found_element: + continue + + values = found_element.get_values_from_element( + row, convert_type=True, result_type="list_tuple" + ) + result.append(values) + + # Generate XML file from the `result` above + lst_lines = [] + + for items in result: + found_element = template_rec.get_proper_element_from_items(items) + if not found_element: + continue + + str_line = found_element.set_values_to_element(items) + if str_line: + lst_lines.append(str_line + "\n") + + if lst_lines: + with open(self.tmpfile_path, "w") as f: + f.writelines(lst_lines) + + # Compare 2 files + self.assertTrue(filecmp.cmp(file_path(path), self.tmpfile_path)) diff --git a/base_wamas/views/wamas_document_default_field_template_views.xml b/base_wamas/views/wamas_document_default_field_template_views.xml new file mode 100644 index 00000000000..13aff47ef46 --- /dev/null +++ b/base_wamas/views/wamas_document_default_field_template_views.xml @@ -0,0 +1,64 @@ + + + + + wamas.document.default.field.template.view.tree + wamas.document.default.field.template + + + + + + + + + + wamas.document.default.field.template.view.form + wamas.document.default.field.template + +
+ + + + + + + + + + + + + + +
+
+
+ + + wamas.document.default.field.template.view.search + wamas.document.default.field.template + + + + + + + + + + WAMAS Document Default Field Template + ir.actions.act_window + wamas.document.default.field.template + tree,form + + {} + + +
diff --git a/base_wamas/views/wamas_document_default_field_views.xml b/base_wamas/views/wamas_document_default_field_views.xml new file mode 100644 index 00000000000..9df41888c1e --- /dev/null +++ b/base_wamas/views/wamas_document_default_field_views.xml @@ -0,0 +1,71 @@ + + + + + wamas.document.default.field.view.tree + wamas.document.default.field + + + + + + + + + + + + + wamas.document.default.field.view.form + wamas.document.default.field + +
+ + + + + + + + + + + + + +
+
+
+ + + wamas.document.default.field.view.search + wamas.document.default.field + + + + + + + + + + + + + + + + + WAMAS Document Default Field + ir.actions.act_window + wamas.document.default.field + tree,form + + {} + + +
diff --git a/base_wamas/views/wamas_document_element_views.xml b/base_wamas/views/wamas_document_element_views.xml new file mode 100644 index 00000000000..a3a9ae2ca6f --- /dev/null +++ b/base_wamas/views/wamas_document_element_views.xml @@ -0,0 +1,67 @@ + + + + + wamas.document.element.view.tree + wamas.document.element + + + + + + + + + + + wamas.document.element.view.form + wamas.document.element + +
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + wamas.document.element.view.search + wamas.document.element + + + + + + + + + + + WAMAS Document Element + ir.actions.act_window + wamas.document.element + tree,form + + {} + + +
diff --git a/base_wamas/views/wamas_document_field_views.xml b/base_wamas/views/wamas_document_field_views.xml new file mode 100644 index 00000000000..b2da58910d1 --- /dev/null +++ b/base_wamas/views/wamas_document_field_views.xml @@ -0,0 +1,86 @@ + + + + + wamas.document.field.view.tree + wamas.document.field + + + + + + + + + + + + + + wamas.document.field.view.form + wamas.document.field + +
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + wamas.document.field.view.search + wamas.document.field + + + + + + + + + + + + + + + + + + + WAMAS Document Field + ir.actions.act_window + wamas.document.field + tree,form + + {'search_default_gb_element_id': 1} + + +
diff --git a/base_wamas/views/wamas_document_template_views.xml b/base_wamas/views/wamas_document_template_views.xml new file mode 100644 index 00000000000..6cfda7ca07d --- /dev/null +++ b/base_wamas/views/wamas_document_template_views.xml @@ -0,0 +1,60 @@ + + + + + wamas.document.template.view.tree + wamas.document.template + + + + + + + + + + wamas.document.template.view.form + wamas.document.template + +
+ + + + + + + + + + + + + + + + +
+
+
+ + + wamas.document.template.view.search + wamas.document.template + + + + + + + + + + WAMAS Document Template + ir.actions.act_window + wamas.document.template + tree,form + + {} + + +
diff --git a/base_wamas/views/wamas_menus.xml b/base_wamas/views/wamas_menus.xml new file mode 100644 index 00000000000..fc8dc9903e0 --- /dev/null +++ b/base_wamas/views/wamas_menus.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup/base_wamas/base_wamas b/setup/base_wamas/base_wamas new file mode 120000 index 00000000000..67481d55077 --- /dev/null +++ b/setup/base_wamas/base_wamas @@ -0,0 +1 @@ +../../../../base_wamas \ No newline at end of file diff --git a/setup/base_wamas/odoo/addons/base_wamas b/setup/base_wamas/odoo/addons/base_wamas new file mode 120000 index 00000000000..67481d55077 --- /dev/null +++ b/setup/base_wamas/odoo/addons/base_wamas @@ -0,0 +1 @@ +../../../../base_wamas \ No newline at end of file diff --git a/setup/base_wamas/setup.py b/setup/base_wamas/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/base_wamas/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)