From 3044bfe9e306a94fb8717e8059dc813f943ac9a9 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 10 Oct 2016 18:05:01 +0200 Subject: [PATCH] [WIP] --- barcodes_generate/README.rst | 115 +++++++++++++++++ barcodes_generate/__openerp__.py | 49 ++------ barcodes_generate/demo/barcode.rule.xml | 25 ++++ barcodes_generate/demo/barcode_rule.xml | 26 ++++ barcodes_generate/demo/res_users.xml | 12 +- .../models/barcode_generate_mixin.py | 118 ++++++++++++------ barcodes_generate/models/barcode_rule.py | 28 ++--- barcodes_generate/models/product_product.py | 5 +- barcodes_generate/models/res_partner.py | 4 +- barcodes_generate/security/res_groups.xml | 5 +- .../static/description/barcode_rule_form.png | Bin 0 -> 16095 bytes ...barcode_rule.png => barcode_rule_tree.png} | Bin .../product_product_form_empty.png | Bin 0 -> 11558 bytes .../product_product_form_generated.png | Bin 0 -> 8476 bytes barcodes_generate/views/view_barcode_rule.xml | 5 +- .../views/view_product_product.xml | 25 ++-- barcodes_generate/views/view_res_partner.xml | 25 ++-- 17 files changed, 324 insertions(+), 118 deletions(-) create mode 100644 barcodes_generate/README.rst create mode 100644 barcodes_generate/demo/barcode.rule.xml create mode 100644 barcodes_generate/demo/barcode_rule.xml create mode 100644 barcodes_generate/static/description/barcode_rule_form.png rename barcodes_generate/static/description/{barcode_rule.png => barcode_rule_tree.png} (100%) create mode 100644 barcodes_generate/static/description/product_product_form_empty.png create mode 100644 barcodes_generate/static/description/product_product_form_generated.png diff --git a/barcodes_generate/README.rst b/barcodes_generate/README.rst new file mode 100644 index 00000000..dc627758 --- /dev/null +++ b/barcodes_generate/README.rst @@ -0,0 +1,115 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +============== +{module_title} +============== + +============================================ +Generate Barcodes for Products and Customers +============================================ + +This module expends Odoo functionnality, allowing user to generate barcode +depending on a given barcode rule. + +For exemple, a typical pattern for products is "23.....{NNNDD}" that means +that: +* the EAN13 code will begin by '23' ; +* followed by 5 digits (named Barcode Base in this module, ) ; +* and after 5 others digits to define the variable price ; +* a 13 digit control + +With this module, it is possible to: + +* Affect a pattern (barcode.rule) to a product.product or a res.partner + +* Generate the next Barcode base of a pattern. (to avoid duplicate barcode) +* Generate a barcode, based on a pattern and a barcode base + +Configuration +============= + +To configure this module, you need to: + +* Go to Point Of Sale / Configuration / Barcode Nomenclatures and select +* Select a Nomenclature +* Create or select a rule +.. figure:: barcodes_generate/static/description/barcode_rule_tree.png + +* Check 'Available for Products', or 'Available for Partners' Checkbox. + +.. figure:: barcodes_generate/static/description/barcode_rule_form.png + +Usage +===== + +To use this module, you need to: + +* Go to a Product form (or a Partner Form): +* set a rule to the current object + +.. figure:: barcodes_generate/static/description/product_product_form_empty.png + +* Click on 'Generate Base and Barcode' + +.. figure:: barcodes_generate/static/description/product_product_form_generated.png + +Alternatively you can set manually a barcode base, and click only on Generate barcode. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/184/9.0 + +Known issues / Roadmap +====================== + +Dependency to point_of_sale is required because barcode field, defined in 'base' +module (in the res.partner model), is defined in a 'point_of_sale' view. +Furthermore, barcode nomenclature menu is available on Point Of Sale submenu. + +It's a relative problem, because product barcodes generation will occures +mostly in a Point of Sale context. + +You could comment 'point_of_sale' dependencies if you want to use this module +without point of sale installed. + +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. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +* Icon of the module is based on the Oxygen Team work and is under LGPL licence: + http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org.html + +Contributors +------------ + +* Sylvain LE GAL (https://twitter.com/legalsylvain) + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit https://odoo-community.org. + diff --git a/barcodes_generate/__openerp__.py b/barcodes_generate/__openerp__.py index cd84ded4..9b131278 100644 --- a/barcodes_generate/__openerp__.py +++ b/barcodes_generate/__openerp__.py @@ -1,51 +1,19 @@ # -*- coding: utf-8 -*- # Copyright (C) 2016-Today GRAP (http://www.grap.coop) +# Copyright (C) 2016-Today GRAP (http://www.lalouve.net) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - 'name': 'Barcodes - Generate', - 'summary': 'Generate Barcodes for Products and Customers', + 'name': 'Generate Barcodes', + 'summary': 'Generate Barcodes for Products and Partners', 'version': '1.0', 'category': 'Point Of Sale', - 'description': """ -============================================ -Generate Barcodes for Products and Customers -============================================ - -This module expends Odoo functionnality, allowing user to generate barcode -depending on a given barcode rule. - -For exemple, a typical pattern for products is "23.....{NNNDD}" that means -that the EAN13 code will begin by '23', followed by 5 digits and after 5 others -digits to define the variable price. (EAN13 has a third char for control). - -With this module, it is possible to: - -* Affect a pattern (barcode.rule) to a product.product or a res.partner -* To generate an EAN13 depending on the defined pattern and a custom ID - -Note ----- -Dependency to point_of_sale is required because barcode field, defined in 'base' -module (in the res.partner model), is defined in a 'point_of_sale' view. - -It's a relative problem, because product barcodes generation will occures -mostly in a Point of Sale context. - -You could comment 'point_of_sale' dependency if you want to use this module -without point of sale. - -Copyright Note --------------- -Icon of the module is based on the Oxygen Team work and is under LGPL licence: - -http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org.html - - -""", - 'author': 'GRAP', - 'website': 'http://www.grap.coop', + 'author': + 'GRAP,' + 'La Louve,' + 'Odoo Community Association (OCA)', + 'website': 'http://www.odoo-community.org', 'license': 'AGPL-3', 'depends': [ 'barcodes', @@ -59,6 +27,7 @@ http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org.html ], 'demo': [ 'demo/res_users.xml', + 'demo/barcode_rule.xml', ], 'images': [ 'static/description/barcode_rule.png' diff --git a/barcodes_generate/demo/barcode.rule.xml b/barcodes_generate/demo/barcode.rule.xml new file mode 100644 index 00000000..b37e4458 --- /dev/null +++ b/barcodes_generate/demo/barcode.rule.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + Partner (Generated Barcode) + + client + ean13 + 042......... + 999 + + + + diff --git a/barcodes_generate/demo/barcode_rule.xml b/barcodes_generate/demo/barcode_rule.xml new file mode 100644 index 00000000..f5f152db --- /dev/null +++ b/barcodes_generate/demo/barcode_rule.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + Partner (Generated Barcode) + + + client + ean13 + 042......... + 999 + + + + diff --git a/barcodes_generate/demo/res_users.xml b/barcodes_generate/demo/res_users.xml index bdf035f6..b90eb9d5 100644 --- a/barcodes_generate/demo/res_users.xml +++ b/barcodes_generate/demo/res_users.xml @@ -1,13 +1,19 @@ - + - + - + + diff --git a/barcodes_generate/models/barcode_generate_mixin.py b/barcodes_generate/models/barcode_generate_mixin.py index 10c544bf..266df28e 100644 --- a/barcodes_generate/models/barcode_generate_mixin.py +++ b/barcodes_generate/models/barcode_generate_mixin.py @@ -1,53 +1,99 @@ # -*- coding: utf-8 -*- # Copyright (C) 2014 GRAP (http://www.grap.coop) +# Copyright (C) 2016-Today GRAP (http://www.lalouve.net) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import barcode -from openerp.osv import fields -from openerp.osv.orm import AbstractModel +from openerp import models, fields, api, exceptions -class barcode_generate_mixin(AbstractModel): +class barcode_generate_mixin(models.AbstractModel): _name = 'barcode.generate.mixin' - _columns = { - 'barcode_rule_id': fields.many2one( - 'barcode.rule', 'Barcode Rule'), - 'barcode_base': fields.integer('Barcode Base'), - } - - def generate_barcode(self, cr, uid, ids, context=None): - vals = self._compute_custom_barcode(cr, uid, ids, context=context) - for id in vals.keys(): - self.write(cr, uid, id, {'ean13': vals[id]}, context=context) - return True - - def _compute_custom_barcode(self, cr, uid, ids, context=None): - res = {} - for item in self.browse(cr, uid, ids, context=context): - if item.barcode_rule_id and item.barcode_base: - pass - barcode_class = barcode.get_barcode_class( - item.barcode_rule_id.encoding) + # Column Section + barcode_rule_id = fields.Many2one( + string='Barcode Rule', comodel_name='barcode.rule') + + barcode_base = fields.Char(string='Barcode Base') + + # Constrains Section + @api.multi + @api.constrains('barcode_base') + def _constrains_barcode_base(self): + for item in self: + if item.barcode_base and not item.barcode_base.isdigit(): + raise exceptions.Warning(_("Barcode Base should be numeric")) + + # View Section + @api.multi + def generate_base(self): + for item in self: + padding = item.barcode_rule_id.pattern.count('.') + generic_code = self._get_custom_barcode(item) + if generic_code: + generic_code = generic_code.replace( + '.' * padding, '_' * padding) + reserved_barcodes = self.search([('barcode', 'ilike', generic_code)]).mapped('barcode') + next_base = str(self._get_next_integer_base( + item, generic_code, reserved_barcodes)).rjust(padding, '0') + item.barcode_base = next_base + + @api.multi + def generate_barcode(self): + for item in self: padding = item.barcode_rule_id.pattern.count('.') full_base = str(item.barcode_base).rjust(padding, '0') + custom_code = self._get_custom_barcode(item) + if custom_code: + custom_code = custom_code.replace('.' * padding, full_base) + barcode_class = barcode.get_barcode_class( + item.barcode_rule_id.encoding) + item.barcode = barcode_class(custom_code) + + @api.multi + def generate_base_barcode(self): + for item in self: + if not item.barcode_base: + item.generate_base() + item.generate_barcode() + + # Custom Section + @api.model + def _get_next_integer_base(self, item, generic_code, reserved_barcodes): + """Given a list of reserved_barcodes, This will return the next" + base barcode. By default, return the max barcode base + 1. + Overload / Overwrite this function to provide custom behaviour. + (specially, fill gaps functionnality). + generic_code should have the '_' pattern. + """ + if not reserved_barcodes: + return 1 + max_barcode = sorted(reserved_barcodes)[len(reserved_barcodes) - 1] + begin = generic_code.find('_') + end = begin + generic_code.count('_') + return int(max_barcode[begin:end]) + 1 + + @api.model + def _get_custom_barcode(self, item): + """ + if the pattern is '23.....{NNNDD}' + this function will return '23.....00000' + """ + if not item.barcode_rule_id: + return False + + # Define barcode + custom_code = item.barcode_rule_id.pattern + custom_code = custom_code.replace('{', '').replace('}', '') + custom_code = custom_code.replace( + 'D', self._get_replacement_char('D')) + return custom_code.replace( + 'N', self._get_replacement_char('N')) - # Define barcode - custom_code = item.barcode_rule_id.pattern - custom_code = custom_code.replace('{', '').replace('}', '') - custom_code = custom_code.replace( - 'D', self._get_barcode_replacement_char( - cr, uid, 'D', context=context)) - custom_code = custom_code.replace( - 'N', self._get_barcode_replacement_char( - cr, uid, 'N', context=context)) - custom_code = custom_code.replace('.' * padding, full_base) - res[item.id] = barcode_class(custom_code) - return res - - def _get_barcode_replacement_char(self, cr, uid, char, context=None): + @api.model + def _get_replacement_char(self, char): """ Can be overload by inheritance Define wich character will be used instead of the 'N' or the 'D' diff --git a/barcodes_generate/models/barcode_rule.py b/barcodes_generate/models/barcode_rule.py index 3a4a63f7..ef57c695 100644 --- a/barcodes_generate/models/barcode_rule.py +++ b/barcodes_generate/models/barcode_rule.py @@ -1,27 +1,21 @@ # -*- coding: utf-8 -*- # Copyright (C) 2014 GRAP (http://www.grap.coop) +# Copyright (C) 2016-Today GRAP (http://www.lalouve.net) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv import fields -from openerp.osv.orm import Model +from openerp import models, fields -class barcode_rule(Model): +class barcode_rule(models.Model): _inherit = 'barcode.rule' - _columns = { - 'is_product_available': fields.boolean( - string='Available for Products', help="If checked, users with" - " specific access right will have the possibility to generate" - " barcodes with this pattern for the products."), - 'is_partner_available': fields.boolean( - string='Available for Partners', help="If checked, users with" - " specific access right will have the possibility to generate" - " barcodes with this pattern for the partners."), - } + is_product_available = fields.Boolean( + string='Available for Products', help="If checked, users with" + " specific access right will have the possibility to generate" + " barcodes with this pattern for the products.") - # TODO set constraint - # is_product_available and is_partner_available: - # - should be possible only for ean13 barcode rule - # - should be possible only if pattern contains at leas one '.' char + is_partner_available = fields.Boolean( + string='Available for Partners', help="If checked, users with" + " specific access right will have the possibility to generate" + " barcodes with this pattern for the partners.") diff --git a/barcodes_generate/models/product_product.py b/barcodes_generate/models/product_product.py index c20f9475..6ec511d0 100644 --- a/barcodes_generate/models/product_product.py +++ b/barcodes_generate/models/product_product.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- # Copyright (C) 2014 GRAP (http://www.grap.coop) +# Copyright (C) 2016-Today GRAP (http://www.lalouve.net) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv.orm import Model +from openerp import models -class product_product(Model): +class ProductProduct(models.Model): _name = 'product.product' _inherit = ['product.product', 'barcode.generate.mixin'] diff --git a/barcodes_generate/models/res_partner.py b/barcodes_generate/models/res_partner.py index 9ae48017..8d3aee6b 100644 --- a/barcodes_generate/models/res_partner.py +++ b/barcodes_generate/models/res_partner.py @@ -3,9 +3,9 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.osv.orm import Model +from openerp import models -class res_partner(Model): +class ResPartner(models.Model): _name = 'res.partner' _inherit = ['res.partner', 'barcode.generate.mixin'] diff --git a/barcodes_generate/security/res_groups.xml b/barcodes_generate/security/res_groups.xml index 0d81da22..a9522bde 100644 --- a/barcodes_generate/security/res_groups.xml +++ b/barcodes_generate/security/res_groups.xml @@ -1,11 +1,12 @@ - + Generate Barcodes for Products @@ -17,4 +18,4 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + diff --git a/barcodes_generate/static/description/barcode_rule_form.png b/barcodes_generate/static/description/barcode_rule_form.png new file mode 100644 index 0000000000000000000000000000000000000000..f90c9bdc9c34312fa09167bd611ba6029c876a43 GIT binary patch literal 16095 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 Mkrl2K)c^TE08|H{0RR91 literal 0 HcmV?d00001 diff --git a/barcodes_generate/static/description/barcode_rule.png b/barcodes_generate/static/description/barcode_rule_tree.png similarity index 100% rename from barcodes_generate/static/description/barcode_rule.png rename to barcodes_generate/static/description/barcode_rule_tree.png diff --git a/barcodes_generate/static/description/product_product_form_empty.png b/barcodes_generate/static/description/product_product_form_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..8ed388be9c140dda810cfc9c7030d97003f388af GIT binary patch literal 11558 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 y8YTm7v6C7vEeNeUJMlJj - + barcode.rule @@ -18,4 +19,4 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + diff --git a/barcodes_generate/views/view_product_product.xml b/barcodes_generate/views/view_product_product.xml index 77df09cf..b45483e1 100644 --- a/barcodes_generate/views/view_product_product.xml +++ b/barcodes_generate/views/view_product_product.xml @@ -1,28 +1,39 @@ - + product.product - + - + + + +