summaryrefslogtreecommitdiff
path: root/addons/l10n_latam_invoice_document
diff options
context:
space:
mode:
authorwan <wan@odoo.com>2019-11-27 15:57:42 +0000
committerwan <wan@odoo.com>2020-02-05 13:59:43 +0000
commitdfd01b8c5c7e1177f37bf199790a0732a61eed78 (patch)
tree6ebb7f50ba554fb4138954c958f799836aae91a7 /addons/l10n_latam_invoice_document
parenta6d7c7b04a48669037e6568849a26571602386f6 (diff)
[IMP] account: rework name sequences
Task 2146469 Rework the name computation: * It doesn't use ir.sequence anymore * It is an editable computed field * Add a renaming tool This allows the user to tweak the sequences more easily than having to get through the ir.sequence settings. The sequence depends on a parameter of the journal: continuous, montly and yearly restart of the sequence. Everytime a new period is started, try to make a pattern form another period. The incrementing is done by taking the previous name, ordered lexicographically, splitting it by taking the digits at the end, adding 1 and re contstruct with the prefix. ** This means there could be cases where the prefix has a big importance on the next number. For instance, if you have INVOICE/2019/0001 INVOICE/2019/0002 and then rename the last one to INV/2019/0002, don't expect the next number to be INV/2019/0003. It will be INVOICE/2019/0002 (again) because the highest number was INVOICE/2019/0001. You will then end up with INVOICE/2019/0001 INV/2019/0002 INVOICE/2019/0002 closes odoo/odoo#41485 Related: odoo/enterprise#7189 Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
Diffstat (limited to 'addons/l10n_latam_invoice_document')
-rw-r--r--addons/l10n_latam_invoice_document/models/account_move.py84
-rw-r--r--addons/l10n_latam_invoice_document/views/account_move_view.xml3
-rw-r--r--addons/l10n_latam_invoice_document/views/report_invoice.xml1
-rw-r--r--addons/l10n_latam_invoice_document/wizards/account_move_reversal.py80
-rw-r--r--addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml2
5 files changed, 51 insertions, 119 deletions
diff --git a/addons/l10n_latam_invoice_document/models/account_move.py b/addons/l10n_latam_invoice_document/models/account_move.py
index fb6d8b0541b..52b8f960a74 100644
--- a/addons/l10n_latam_invoice_document/models/account_move.py
+++ b/addons/l10n_latam_invoice_document/models/account_move.py
@@ -3,6 +3,7 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from functools import partial
+import re
from odoo.tools.misc import formatLang
@@ -16,48 +17,27 @@ class AccountMove(models.Model):
l10n_latam_document_type_id = fields.Many2one(
'l10n_latam.document.type', string='Document Type', copy=False, readonly=False, auto_join=True, index=True,
states={'posted': [('readonly', True)]}, compute='_compute_l10n_latam_document_type', store=True)
- l10n_latam_sequence_id = fields.Many2one('ir.sequence', compute='_compute_l10n_latam_sequence')
- l10n_latam_document_number = fields.Char(
- compute='_compute_l10n_latam_document_number', inverse='_inverse_l10n_latam_document_number',
- string='Document Number', readonly=True, states={'draft': [('readonly', False)]})
l10n_latam_use_documents = fields.Boolean(related='journal_id.l10n_latam_use_documents')
l10n_latam_country_code = fields.Char(
related='company_id.country_id.code', help='Technical field used to hide/show fields regarding the localization')
- def _get_sequence_prefix(self):
- """ If we use documents we update sequences only from journal """
- return super(AccountMove, self.filtered(lambda x: not x.l10n_latam_use_documents))._get_sequence_prefix()
-
- @api.depends('name')
- def _compute_l10n_latam_document_number(self):
- recs_with_name = self.filtered(lambda x: x.name != '/')
- for rec in recs_with_name:
- name = rec.name
- doc_code_prefix = rec.l10n_latam_document_type_id.doc_code_prefix
- if doc_code_prefix and name:
- name = name.split(" ", 1)[-1]
- rec.l10n_latam_document_number = name
- remaining = self - recs_with_name
- remaining.l10n_latam_document_number = False
-
- @api.onchange('l10n_latam_document_type_id', 'l10n_latam_document_number')
- def _inverse_l10n_latam_document_number(self):
- for rec in self.filtered('l10n_latam_document_type_id'):
- if not rec.l10n_latam_document_number:
- rec.name = '/'
- else:
- l10n_latam_document_number = rec.l10n_latam_document_type_id._format_document_number(rec.l10n_latam_document_number)
- if rec.l10n_latam_document_number != l10n_latam_document_number:
- rec.l10n_latam_document_number = l10n_latam_document_number
- rec.name = "%s %s" % (rec.l10n_latam_document_type_id.doc_code_prefix, l10n_latam_document_number)
-
- @api.depends('l10n_latam_document_type_id', 'journal_id')
- def _compute_l10n_latam_sequence(self):
- recs_with_journal_id = self.filtered('journal_id')
- for rec in recs_with_journal_id:
- rec.l10n_latam_sequence_id = rec._get_document_type_sequence()
- remaining = self - recs_with_journal_id
- remaining.l10n_latam_sequence_id = False
+ @api.model
+ def _deduce_sequence_number_reset(self, name):
+ if self.l10n_latam_use_documents:
+ return 'never'
+ return super(AccountMove, self)._deduce_sequence_number_reset(name)
+
+ def _get_last_sequence_domain(self, relaxed=False):
+ where_string, param = super(AccountMove, self)._get_last_sequence_domain(relaxed)
+ if self.l10n_latam_use_documents:
+ where_string += " AND l10n_latam_document_type_id = %(l10n_latam_document_type_id)s "
+ param['l10n_latam_document_type_id'] = self.l10n_latam_document_type_id.id or 0
+ return where_string, param
+
+ def _get_starting_sequence(self):
+ if self.l10n_latam_use_documents:
+ return "%s 0001-00000000" % (self.l10n_latam_document_type_id.doc_code_prefix)
+ return super(AccountMove, self)._get_starting_sequence()
def _compute_l10n_latam_amount_and_taxes(self):
recs_invoice = self.filtered(lambda x: x.is_invoice())
@@ -82,20 +62,10 @@ class AccountMove(models.Model):
remaining.l10n_latam_amount_untaxed = False
remaining.l10n_latam_tax_ids = [(5, 0)]
- def _compute_invoice_sequence_number_next(self):
- """ If journal use documents disable the next number header"""
- with_latam_document_number = self.filtered('l10n_latam_use_documents')
- with_latam_document_number.invoice_sequence_number_next_prefix = False
- with_latam_document_number.invoice_sequence_number_next = False
- return super(AccountMove, self - with_latam_document_number)._compute_invoice_sequence_number_next()
-
def post(self):
for rec in self.filtered(lambda x: x.l10n_latam_use_documents and (not x.name or x.name == '/')):
- if not rec.l10n_latam_sequence_id:
- raise UserError(_('No sequence or document number linked to invoice id %s') % rec.id)
if rec.type in ('in_receipt', 'out_receipt'):
raise UserError(_('We do not accept the usage of document types on receipts yet. '))
- rec.l10n_latam_document_number = rec.l10n_latam_sequence_id.next_by_id()
return super().post()
@api.constrains('name', 'journal_id', 'state')
@@ -122,10 +92,10 @@ class AccountMove(models.Model):
raise ValidationError(_(
'The journal require a document type but not document type has been selected on invoices %s.' % (
without_doc_type.ids)))
- without_number = validated_invoices.filtered(
- lambda x: not x.l10n_latam_document_number and not x.l10n_latam_sequence_id)
+ valid = re.compile(r'[A-Z\-]+\s*\d{1,5}\-\d{1,8}')
+ without_number = validated_invoices.filtered(lambda x: not valid.match(x.name))
if without_number:
- raise ValidationError(_('Please set the document number on the following invoices %s.' % (
+ raise ValidationError(_('The document number on the following invoices is not correct %s.' % (
without_number.ids)))
@api.constrains('type', 'l10n_latam_document_type_id')
@@ -193,24 +163,20 @@ class AccountMove(models.Model):
) for group, amounts in res]
super(AccountMove, self - move_with_doc_type)._compute_invoice_taxes_by_group()
- def _get_document_type_sequence(self):
- """ Method to be inherited by different localizations. """
- self.ensure_one()
- return self.env['ir.sequence']
-
@api.constrains('name', 'partner_id', 'company_id')
def _check_unique_vendor_number(self):
""" The constraint _check_unique_sequence_number is valid for customer bills but not valid for us on vendor
bills because the uniqueness must be per partner and also because we want to validate on entry creation and
not on entry validation """
- for rec in self.filtered(lambda x: x.is_purchase_document() and x.l10n_latam_use_documents and x.l10n_latam_document_number):
+ for rec in self.filtered(lambda x: x.is_purchase_document() and x.l10n_latam_use_documents):
domain = [
('type', '=', rec.type),
- # by validating name we validate l10n_latam_document_number and l10n_latam_document_type_id
+ # by validating name we validate l10n_latam_document_type_id
('name', '=', rec.name),
('company_id', '=', rec.company_id.id),
('id', '!=', rec.id),
- ('commercial_partner_id', '=', rec.commercial_partner_id.id)
+ ('commercial_partner_id', '=', rec.commercial_partner_id.id),
+ ('posted_before', '=', True),
]
if rec.search(domain):
raise ValidationError(_('Vendor bill number must be unique per vendor and company.'))
diff --git a/addons/l10n_latam_invoice_document/views/account_move_view.xml b/addons/l10n_latam_invoice_document/views/account_move_view.xml
index a8df0d65233..32dd56279da 100644
--- a/addons/l10n_latam_invoice_document/views/account_move_view.xml
+++ b/addons/l10n_latam_invoice_document/views/account_move_view.xml
@@ -38,15 +38,12 @@
<field name="l10n_latam_available_document_type_ids" invisible="1"/>
<field name="l10n_latam_use_documents" invisible="1"/>
<field name="l10n_latam_country_code" invisible="1"/>
- <field name="l10n_latam_sequence_id" invisible="1"/>
</form>
<field name="journal_id" position="after">
<field name="l10n_latam_document_type_id"
attrs="{'invisible': [('l10n_latam_use_documents', '=', False)], 'required': [('l10n_latam_use_documents', '=', True)], 'readonly': [('state', '!=', 'draft')]}"
domain="[('id', 'in', l10n_latam_available_document_type_ids)]" options="{'no_open': True, 'no_create': True}"/>
- <field name="l10n_latam_document_number"
- attrs="{'invisible': ['|', ('l10n_latam_sequence_id', '!=', False), ('l10n_latam_use_documents', '=', False)], 'required': [('l10n_latam_sequence_id', '=', False), ('l10n_latam_use_documents', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
</field>
</field>
</record>
diff --git a/addons/l10n_latam_invoice_document/views/report_invoice.xml b/addons/l10n_latam_invoice_document/views/report_invoice.xml
index fc2784bb033..f1a775f8888 100644
--- a/addons/l10n_latam_invoice_document/views/report_invoice.xml
+++ b/addons/l10n_latam_invoice_document/views/report_invoice.xml
@@ -13,7 +13,6 @@
<xpath expr="//h2" position="after">
<h2 t-if="o.l10n_latam_document_type_id.report_name">
<span t-field="o.l10n_latam_document_type_id.report_name"/>
- <span t-field="o.l10n_latam_document_number"/>
</h2>
</xpath>
diff --git a/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py b/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py
index de81b3c6ba7..0169859a098 100644
--- a/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py
+++ b/addons/l10n_latam_invoice_document/wizards/account_move_reversal.py
@@ -5,27 +5,11 @@ from odoo.exceptions import UserError
class AccountMoveReversal(models.TransientModel):
-
_inherit = "account.move.reversal"
- l10n_latam_use_documents = fields.Boolean(readonly=True)
- l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type', ondelete='cascade', domain="[('id', 'in', l10n_latam_available_document_type_ids)]")
- l10n_latam_available_document_type_ids = fields.Many2many('l10n_latam.document.type', store=False)
- l10n_latam_sequence_id = fields.Many2one('ir.sequence', compute='_compute_l10n_latam_sequence')
- l10n_latam_document_number = fields.Char(string='Document Number')
-
- @api.model
- def default_get(self, fields):
- res = super(AccountMoveReversal, self).default_get(fields)
- move_ids = self.env['account.move'].browse(self.env.context['active_ids']) if self.env.context.get('active_model') == 'account.move' else self.env['account.move']
- if len(move_ids) > 1:
- move_ids_use_document = move_ids.filtered(lambda move: move.l10n_latam_use_documents)
- if move_ids_use_document:
- raise UserError(_('You can only reverse documents with legal invoicing documents from Latin America one at a time.\nProblematic documents: %s') % ", ".join(move_ids_use_document.mapped('name')))
- else:
- res['l10n_latam_use_documents'] = move_ids.journal_id.l10n_latam_use_documents
-
- return res
+ l10n_latam_use_documents = fields.Boolean(compute='_compute_document_type')
+ l10n_latam_document_type_id = fields.Many2one('l10n_latam.document.type', 'Document Type', ondelete='cascade', domain="[('id', 'in', l10n_latam_available_document_type_ids)]", compute='_compute_document_type', readonly=False)
+ l10n_latam_available_document_type_ids = fields.Many2many('l10n_latam.document.type', compute='_compute_document_type')
@api.model
def _reverse_type_map(self, move_type):
@@ -38,41 +22,29 @@ class AccountMoveReversal(models.TransientModel):
'in_receipt': 'out_receipt'}
return match.get(move_type)
- @api.onchange('move_ids')
- def _onchange_move_id(self):
- if self.l10n_latam_use_documents:
- refund = self.env['account.move'].new({
- 'type': self._reverse_type_map(self.move_ids.type),
- 'journal_id': self.move_ids.journal_id.id,
- 'partner_id': self.move_ids.partner_id.id,
- 'company_id': self.move_ids.company_id.id,
- })
- self.l10n_latam_document_type_id = refund.l10n_latam_document_type_id
- self.l10n_latam_available_document_type_ids = refund.l10n_latam_available_document_type_ids
+ @api.depends('move_ids')
+ def _compute_document_type(self):
+ self.l10n_latam_available_document_type_ids = False
+ self.l10n_latam_document_type_id = False
+ self.l10n_latam_use_documents = False
+ for record in self:
+ if len(record.move_ids) > 1:
+ move_ids_use_document = record.move_ids._origin.filtered(lambda move: move.l10n_latam_use_documents)
+ if move_ids_use_document:
+ raise UserError(_('You can only reverse documents with legal invoicing documents from Latin America one at a time.\nProblematic documents: %s') % ", ".join(move_ids_use_document.mapped('name')))
+ else:
+ record.l10n_latam_use_documents = record.move_ids.journal_id.l10n_latam_use_documents
+
+ if record.l10n_latam_use_documents:
+ refund = record.env['account.move'].new({
+ 'type': record._reverse_type_map(record.move_ids.type),
+ 'journal_id': record.move_ids.journal_id.id,
+ 'partner_id': record.move_ids.partner_id.id,
+ 'company_id': record.move_ids.company_id.id,
+ })
+ record.l10n_latam_document_type_id = refund.l10n_latam_document_type_id
+ record.l10n_latam_available_document_type_ids = refund.l10n_latam_available_document_type_ids
def reverse_moves(self):
return super(AccountMoveReversal, self.with_context(
- default_l10n_latam_document_type_id=self.l10n_latam_document_type_id.id,
- default_l10n_latam_document_number=self.l10n_latam_document_number)).reverse_moves()
-
- @api.depends('l10n_latam_document_type_id')
- def _compute_l10n_latam_sequence(self):
- for rec in self:
- rec.l10n_latam_sequence_id = False
- if len(rec.move_ids) <= 1:
- refund = rec.env['account.move'].new({
- 'type': self._reverse_type_map(rec.move_ids.type),
- 'journal_id': rec.move_ids.journal_id.id,
- 'partner_id': rec.move_ids.partner_id.id,
- 'company_id': rec.move_ids.company_id.id,
- 'l10n_latam_document_type_id': rec.l10n_latam_document_type_id.id,
- })
- rec.l10n_latam_sequence_id = refund._get_document_type_sequence()
-
- @api.onchange('l10n_latam_document_number', 'l10n_latam_document_type_id')
- def _onchange_l10n_latam_document_number(self):
- if self.l10n_latam_document_type_id:
- l10n_latam_document_number = self.l10n_latam_document_type_id._format_document_number(
- self.l10n_latam_document_number)
- if self.l10n_latam_document_number != l10n_latam_document_number:
- self.l10n_latam_document_number = l10n_latam_document_number
+ default_l10n_latam_document_type_id=self.l10n_latam_document_type_id.id)).reverse_moves()
diff --git a/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml
index 9022fbd86ee..f2d8b96527a 100644
--- a/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml
+++ b/addons/l10n_latam_invoice_document/wizards/account_move_reversal_view.xml
@@ -8,12 +8,10 @@
<field name="arch" type="xml">
<form>
<field name="l10n_latam_use_documents" invisible="1"/>
- <field name="l10n_latam_sequence_id" invisible="1"/>
</form>
<field name="date" position="before">
<field name="l10n_latam_available_document_type_ids" invisible="1"/>
<field name="l10n_latam_document_type_id" attrs="{'invisible': ['|', ('l10n_latam_use_documents', '=', False), ('refund_method', '=', 'refund')], 'required': [('l10n_latam_use_documents', '=', True), ('refund_method', '!=', 'refund')]}" options="{'no_open': True, 'no_create': True}"/>
- <field name="l10n_latam_document_number" attrs="{'invisible': ['|', ('l10n_latam_sequence_id', '!=', False), ('refund_method', '=', 'refund')], 'required': [('l10n_latam_sequence_id', '=', True), ('refund_method', '!=', 'refund')]}"/>
</field>
</field>
</record>