diff --git a/barcodes_regex_group/README.rst b/barcodes_regex_group/README.rst new file mode 100644 index 00000000000..5b88559000e --- /dev/null +++ b/barcodes_regex_group/README.rst @@ -0,0 +1,89 @@ +======================= +Barcodes - Regex groups +======================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fstock--logistics--barcode-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-barcode/tree/10.0/barcodes_regex_groups + :alt: OCA/stock-logistics-barcode +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-barcode-10-0/stock-logistics-barcode-10-0-barcodes_regex_groups + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/150/10.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows barcode nomenclatures to use regex groups to capture a part of a barcode. + +Odoo's default ``barcodes`` module uses regex to match the barcode against the nomenclature rules, but in case of a match, it passes the full string to the ``on_barcode_scanned`` method. + +With this module, we can use regex groups to specify which part of the barcode we want. For example, when a barcode looks like this: + +:: + + PRODUCT X1234 SERIAL 12345 + +We can define a regex to capture the serial number only, looking like this: + +:: + + PRODUCT [a-zA-Z0-9-]* SERIAL ([a-zA-Z0-9]*) + +As an added feature, we can specify the Odoo models that a certain rule should apply to. Let us say that in the above case, we make a rule for product, but also for serial. We want the 'serial' rule to fire for ``stock.pack.operation`` operations, but the 'product' rule to fire for ``stock.picking`` operations, while scanning the same barcode, so, we make two rules, and configure a different model for each. + +**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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Sunflower IT + +Contributors +~~~~~~~~~~~~ + +* Tom Blauwendraat + +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/stock-logistics-barcode `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/barcodes_regex_group/__init__.py b/barcodes_regex_group/__init__.py new file mode 100644 index 00000000000..a0fdc10fe11 --- /dev/null +++ b/barcodes_regex_group/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/barcodes_regex_group/__manifest__.py b/barcodes_regex_group/__manifest__.py new file mode 100644 index 00000000000..0ea49a51d99 --- /dev/null +++ b/barcodes_regex_group/__manifest__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Sunflower IT +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Barcodes - Regex groups", + "summary": "Partial barcode capture, using regex groups in nomenclatures.", + "version": "14.0.1.0.0", + "author": "Sunflower IT, " + "Odoo Community Association (OCA)", + "website": "https://odoo-community.org/", + "license": "AGPL-3", + "category": "Extra Tools", + "depends": [ + 'barcodes', + ], + "data": [ + "views/assets_backend.xml", + "views/barcode_rule.xml" + ], + 'installable': True, +} diff --git a/barcodes_regex_group/models/__init__.py b/barcodes_regex_group/models/__init__.py new file mode 100644 index 00000000000..f453c7ca251 --- /dev/null +++ b/barcodes_regex_group/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import barcode_events_mixin +from . import barcode_rule +from . import barcode_nomenclature diff --git a/barcodes_regex_group/models/barcode_events_mixin.py b/barcodes_regex_group/models/barcode_events_mixin.py new file mode 100644 index 00000000000..3b52dcc47f7 --- /dev/null +++ b/barcodes_regex_group/models/barcode_events_mixin.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from odoo import models, api + + +class BarcodeEventsMixin(models.AbstractModel): + _inherit = 'barcodes.barcode_events_mixin' + + @api.onchange('_barcode_scanned') + def _on_barcode_scanned(self): + #self.env.cache['_barcode_active_model'] = self._name + return super(BarcodeEventsMixin, self)._on_barcode_scanned() diff --git a/barcodes_regex_group/models/barcode_nomenclature.py b/barcodes_regex_group/models/barcode_nomenclature.py new file mode 100644 index 00000000000..286226cc299 --- /dev/null +++ b/barcodes_regex_group/models/barcode_nomenclature.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Sunflower IT +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import re +from typing import Match + +from odoo import models + + +class BarcodeNomenclature(models.Model): + _inherit = 'barcode.nomenclature' + + def match_pattern(self, barcode, pattern): + match = super(BarcodeNomenclature, self).match_pattern( + barcode, pattern) + print("AAAAAAA") + + # We cannot use numerical content and matching groups at the same time + import pdb; pdb.set_trace() + numerical_content = re.search("[{][N]*[D]*[}]", pattern) + if numerical_content: + return match + + # If there are no regex groups in pattern, use normal matching + has_regex_groups = re.search("[(].*[)]", pattern) + if not has_regex_groups: + return match + + # Perform pattern matching using 'search' instead of 'match' + # And don't truncate barcode on search pattern length + match['match'] = re.search(pattern, match['base_code']) + + # Abuse 'value' to store the result, since it goes to 'parsed_result' + if match['match'] and self.env.context.get('barcodes_regex_groups'): + match['value'] = match['match'] + return match + + def parse_barcode(self, barcode): + model = self.env.cache['_barcode_active_model'] + this = self.with_context(barcodes_regex_groups=True) + + # filter rules by their applicability to the currently active model + if model: + rule_ids_filtered = this.rule_ids.filtered( + lambda r: (not r.model_ids) + or model in r.model_ids.mapped('model')).ids + rule_ids_backup = this._cache['rule_ids'] + this._cache['rule_ids'] = rule_ids_filtered + + parsed_result = super(BarcodeNomenclature, this).parse_barcode(barcode) + + # restore rule_ids + if model: + this._cache['rule_ids'] = rule_ids_backup + + # Post-process any result of group-matching + if isinstance(parsed_result['value'], Match): + match = parsed_result['value'] + parsed_result['value'] = 0 + parsed_result['code'] = match.group(1) + + return parsed_result diff --git a/barcodes_regex_group/models/barcode_rule.py b/barcodes_regex_group/models/barcode_rule.py new file mode 100644 index 00000000000..330302a1429 --- /dev/null +++ b/barcodes_regex_group/models/barcode_rule.py @@ -0,0 +1,15 @@ +import logging +import re + +from odoo import tools, models, fields, api, _ +from odoo.exceptions import ValidationError + + +class BarcodeRule(models.Model): + _inherit = 'barcode.rule' + + model_ids = fields.Many2many( + string="Applicable models", + comodel_name="ir.model", + domain=[('field_id.name', '=', '_barcode_scanned')]) + pattern = fields.Char(size=64) \ No newline at end of file diff --git a/barcodes_regex_group/readme/CONTRIBUTORS.rst b/barcodes_regex_group/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..68c0876aa4b --- /dev/null +++ b/barcodes_regex_group/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Tom Blauwendraat diff --git a/barcodes_regex_group/readme/DESCRIPTION.rst b/barcodes_regex_group/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..908f5cf263c --- /dev/null +++ b/barcodes_regex_group/readme/DESCRIPTION.rst @@ -0,0 +1,17 @@ +This module allows barcode nomenclatures to use regex groups to capture a part of a barcode. + +Odoo's default ``barcodes`` module uses regex to match the barcode against the nomenclature rules, but in case of a match, it passes the full string to the ``on_barcode_scanned`` method. + +With this module, we can use regex groups to specify which part of the barcode we want. For example, when a barcode looks like this: + +:: + + PRODUCT X1234 SERIAL 12345 + +We can define a regex to capture the serial number only, looking like this: + +:: + + PRODUCT [a-zA-Z0-9-]* SERIAL ([a-zA-Z0-9]*) + +As an added feature, we can specify the Odoo models that a certain rule should apply to. Let us say that in the above case, we make a rule for product, but also for serial. We want the 'serial' rule to fire for ``stock.pack.operation`` operations, but the 'product' rule to fire for ``stock.picking`` operations, while scanning the same barcode, so, we make two rules, and configure a different model for each. diff --git a/barcodes_regex_group/static/description/icon.png b/barcodes_regex_group/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/barcodes_regex_group/static/description/icon.png differ diff --git a/barcodes_regex_group/static/description/index.html b/barcodes_regex_group/static/description/index.html new file mode 100644 index 00000000000..24b56691b3e --- /dev/null +++ b/barcodes_regex_group/static/description/index.html @@ -0,0 +1,429 @@ + + + + + + +Barcodes - Regex groups + + + +
+

Barcodes - Regex groups

+ + +

Beta License: AGPL-3 OCA/stock-logistics-barcode Translate me on Weblate Try me on Runbot

+

This module allows barcode nomenclatures to use regex groups to capture a part of a barcode.

+

Odoo’s default barcodes module uses regex to match the barcode against the nomenclature rules, but in case of a match, it passes the full string to the on_barcode_scanned method.

+

With this module, we can use regex groups to specify which part of the barcode we want. For example, when a barcode looks like this:

+
+PRODUCT X1234 SERIAL 12345
+
+

We can define a regex to capture the serial number only, looking like this:

+
+PRODUCT [a-zA-Z0-9-]* SERIAL ([a-zA-Z0-9]*)
+
+

As an added feature, we can specify the Odoo models that a certain rule should apply to. Let us say that in the above case, we make a rule for product, but also for serial. We want the ‘serial’ rule to fire for stock.pack.operation operations, but the ‘product’ rule to fire for stock.picking operations, while scanning the same barcode, so, we make two rules, and configure a different model for each.

+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Sunflower IT
  • +
+
+
+

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/stock-logistics-barcode project on GitHub.

+

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

+
+
+
+ + diff --git a/barcodes_regex_group/static/src/js/barcode_events.js b/barcodes_regex_group/static/src/js/barcode_events.js new file mode 100644 index 00000000000..6a0197d0343 --- /dev/null +++ b/barcodes_regex_group/static/src/js/barcode_events.js @@ -0,0 +1,8 @@ +odoo.define('barcodes_regex_group.BarcodeEvents', function (require) { + "use strict"; + + var BarcodeEvents = require('barcodes.BarcodeEvents').BarcodeEvents; + + BarcodeEvents.regexp = /(.{3,})/s; + BarcodeEvents.suffix = /[\0]/; +}); diff --git a/barcodes_regex_group/static/src/js/barcode_parser.js b/barcodes_regex_group/static/src/js/barcode_parser.js new file mode 100644 index 00000000000..5972e28240a --- /dev/null +++ b/barcodes_regex_group/static/src/js/barcode_parser.js @@ -0,0 +1,51 @@ +odoo.define('barcodes_regex_group.BarcodeParser', function (require) { + "use strict"; + + var BarcodeParser = require('barcodes.BarcodeParser'); + + BarcodeParser.include({ + init: function(attributes) { + return this._super(attributes); + }, + + match_pattern: function(barcode, pattern, encoding) { + var match = this._super(barcode, pattern, encoding); + // Abuse 'value' to store the result, since it goes to 'parsed_result' + if ((match.match != null) && (match.match.length > 1)) + match.value = { + value_copy: match.value, + match_copy: match.match + }; + return match; + }, + + parse_barcode: function(barcode) { + // TODO: filter rules by their applicability to the currently active model + // model = self.env.cache['_barcode_active_model'] + // if model: + // rule_ids_filtered = this.rule_ids.filtered( + // lambda r: (not r.model_ids) + // or model in r.model_ids.mapped('model')).ids + // rule_ids_backup = this._cache['rule_ids'] + // this._cache['rule_ids'] = rule_ids_filtered + + var parsed_result = this._super(barcode); + // TODO: restore rule_ids + // if model: + // this._cache['rule_ids'] = rule_ids_backup + + // Post-process any result of group-matching + if (parsed_result.value.match_copy !== undefined) { + var match = parsed_result.value.match_copy; + parsed_result.value = parsed_result.value.value_copy; + parsed_result.code = match[1]; + parsed_result.base_code = match[1]; + if (match.length > 2) + parsed_result.extra_codes = match.slice(2); + } + + return parsed_result; + }, + }); + +}); diff --git a/barcodes_regex_group/views/assets_backend.xml b/barcodes_regex_group/views/assets_backend.xml new file mode 100644 index 00000000000..565fd9dd16d --- /dev/null +++ b/barcodes_regex_group/views/assets_backend.xml @@ -0,0 +1,19 @@ + + + +