You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

102 lines
3.7 KiB

# -*- 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 import models, fields, api, exceptions
class barcode_generate_mixin(models.AbstractModel):
_name = 'barcode.generate.mixin'
# 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'))
@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'
char, present in the pattern of the barcode_rule_id
"""
return '0'