Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10.0][IMP] barcodes_generator_abstract: Add automated generator #77

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions barcodes_generator_abstract/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Generate Barcodes for any Models (Abstract)
This module expends Odoo functionality, allowing user to generate barcode
depending on a given barcode rule for any Model.

For exemple, a typical pattern for products is "20.....{NNNDD}" that means
For example, a typical pattern for products is "20.....{NNNDD}" that means
that:
* the EAN13 code will begin by '20'
* followed by 5 digits (named Barcode Base in this module)
Expand Down Expand Up @@ -109,7 +109,9 @@ Known issues / Roadmap
======================

1. On barcode.rule model, constraint and domain system could be set between
'type' and 'generate_model' fields.
'type' and 'generate_model' fields.
1. Cache is being cleared in a constraint in `barcode.rule`. Mutating in a
constraint is bad practice & should be moved somewhere.

Bug Tracker
===========
Expand Down
5 changes: 3 additions & 2 deletions barcodes_generator_abstract/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
'version': '10.0.1.0.0',
'category': 'Tools',
'author':
'GRAP,'
'La Louve,'
'GRAP, '
'La Louve, '
'LasLabs, '
'Odoo Community Association (OCA)',
'website': 'https://www.odoo-community.org',
'license': 'AGPL-3',
Expand Down
25 changes: 20 additions & 5 deletions barcodes_generator_abstract/models/barcode_generate_mixin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-Today GRAP (http://www.grap.coop)
# Copyright (C) 2016-Today La Louve (http://www.lalouve.net)
# Copyright (C) 2014-TODAY GRAP (http://www.grap.coop)
# Copyright (C) 2016-TODAY La Louve (http://www.lalouve.net)
# Copyright 2017 LasLabs Inc.
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import logging

from odoo import models, fields, api, exceptions, _
from odoo import _, api, exceptions, fields, models

from .barcode_rule import _GENERATE_TYPE

Expand All @@ -15,7 +16,7 @@
try:
import barcode
except ImportError:
_logger.debug("Cannot import 'barcode' python library.")
_logger.debug("Cannot import 'viivakoodi' python library.")
barcode = None


Expand All @@ -32,6 +33,20 @@ class BarcodeGenerateMixin(models.AbstractModel):
string='Generate Type', selection=_GENERATE_TYPE, readonly=True,
related='barcode_rule_id.generate_type')

@api.model
def create(self, vals):
""" It creates a new barcode if automation is active. """
barcode_rule = self.env['barcode.rule'].get_automatic_rule(self._name)
if barcode_rule.exists():
vals.update({
'barcode_rule_id': barcode_rule.id,
})
record = super(BarcodeGenerateMixin, self).create(vals)
if barcode_rule:
record.generate_base()
record.generate_barcode()
return record

# View Section
@api.multi
def generate_base(self):
Expand Down Expand Up @@ -66,7 +81,7 @@ def _get_custom_barcode(self, item):
instead that replace 'N' and 'D' char.
"""
if not item.barcode_rule_id:
return False
return False

# Define barcode
custom_code = item.barcode_rule_id.pattern
Expand Down
56 changes: 54 additions & 2 deletions barcodes_generator_abstract/models/barcode_rule.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-Today GRAP (http://www.grap.coop)
# Copyright (C) 2016-Today La Louve (http://www.lalouve.net)
# Copyright 2017 LasLabs Inc.
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import _, api, exceptions, fields, models
from odoo import _, api, exceptions, fields, models, tools

_GENERATE_TYPE = [
('no', 'No generation'),
Expand All @@ -29,7 +30,7 @@ class BarcodeRule(models.Model):

generate_model = fields.Selection(
string='Generate Model', selection=[],
help="if 'Generate Type' is set, mention the model related to this"
help="If 'Generate Type' is set, mention the model related to this"
" rule.")

padding = fields.Integer(
Expand All @@ -39,6 +40,12 @@ class BarcodeRule(models.Model):
sequence_id = fields.Many2one(
string='Sequence', comodel_name='ir.sequence')

generate_automate = fields.Boolean(
string='Automatic Generation',
help='Check this to automatically generate a barcode upon creation of '
'a new record in the mixed model.',
)

# Compute Section
@api.depends('pattern')
@api.multi
Expand All @@ -54,6 +61,33 @@ def onchange_generate_type(self):
if rule.generate_type == 'no':
rule.generate_model = False

# Constrains Section
@api.multi
@api.constrains('generate_model', 'generate_automate')
def _check_generate_model_automate(self):
""" It should not allow two automated barcode generators per model.

It also clears the cache of automated rules if necessary.
"""
should_clear = False
for record in self:
if not record.generate_automate:
continue
# This query is duplicated, but necessary because the other
# method is cached & we need a completely current result.
domain = [
('generate_model', '=', record.generate_model),
('generate_automate', '=', True),
]
if len(self.search(domain)) > 1:
raise exceptions.ValidationError(_(
'Only one rule per model can be used for automatic '
'barcode generation.'
))
should_clear = True
if should_clear:
self.clear_caches()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you clear this on create/write when vals contains 'generate_automate' value?

Copy link
Contributor Author

@lasley lasley Feb 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm yeah that would work too, although then we'd be splitting the logic into two spots & it would need to be a conjoined if - because this is also clearing cache if generate_model is changed too.

I could remove the somewhat ghetto should_clear as if len(self) instead though, which would remove two lines and be the same level of efficiency.

I do somewhat take reservation to a mutating operation in a constraint though, so it might still be best to bite the bullet and move into the two spots. Any additional thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For keeping the same logic, just create a new method that is called from both write/create methods. I still miss the wanted @onwrite decorator: odoo/odoo#11042

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow I love this @onwrite idea. It also reminded me that I needed to create the API lib from OCA/server-tools#615. I think I'll try to tackle that this weekend.

Also, yeah cool a helper method seems almost excessive, but it is better than code duplication. It's also better than a mutation in a constraint, even if the mutation is just a cache deletion.


# View Section
@api.multi
def generate_sequence(self):
Expand All @@ -73,3 +107,21 @@ def _prepare_sequence(self, rule):
'name': _('Sequence - %s') % rule.name,
'padding': rule.padding,
}

@api.model
@tools.ormcache('model')
def get_automatic_rule(self, model):
""" It provides a cached indicator for barcode automation.

Note that this cache needs to be explicitly cleared when
`generate_automate` is changed on an associated `barcode.rule`.

Args:
model (str): Name of model to search for.
Returns:
BarcodeRule: Recordset of automated barcode rules for model.
"""
return self.search([
('generate_model', '=', model),
('generate_automate', '=', True),
])
2 changes: 2 additions & 0 deletions barcodes_generator_abstract/views/view_barcode_rule.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<!--
Copyright (C) 2016-Today: GRAP (http://www.grap.coop)
Copyright (C) 2016-Today La Louve (http://www.lalouve.net)
Copyright 2017 LasLabs Inc.
@author Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
Expand All @@ -20,6 +21,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
<field name="generate_type"/>
<field name="padding" attrs="{'invisible': [('generate_type', '=', 'no')]}"/>
<field name="generate_model" attrs="{'invisible': [('generate_type', '=', 'no')]}"/>
<field name="generate_automate" attrs="{'invisible': [('generate_type', '=', 'no')]}"/>
<vbnewline />
<button name="generate_sequence" type="object" string="Generate Sequence" colspan="2"
attrs="{'invisible': [('generate_type', '!=', 'sequence')]}"/>
Expand Down