[FIX] account: Allow a Billing user to create an invoice/credit note

Purpose
=======

When validation his first invoice/credit note, a billing user can choose which number will be the first on the invoice sequencing but it will raise a access right issue

Specification
=============

We want to allow a billing user to do it, but we can't give him the right to write on the ir_sequence.

For that reason, we won't modify the ir.sequence field on the journal and skip this part. The field won't be displayed too on the form.

Additional Point:
~~~~~~~~~~~~~~~~~

A cleaning of the code has been made to avoid raise conditions even when the first invoice has been created (2 users creating 2 invoices before having one validated).
This commit is contained in:
Yannick Tivisse
2017-08-11 13:57:31 +02:00
parent 1ab8f7c9e3
commit 6ac7b55869
2 changed files with 33 additions and 20 deletions
+31 -18
View File
@@ -353,44 +353,57 @@ class AccountInvoice(models.Model):
('number_uniq', 'unique(number, company_id, journal_id, type)', 'Invoice Number must be unique per Company!'),
]
def _no_existing_validated_invoice(self):
self.ensure_one()
if self.journal_id.refund_sequence:
domain = [('type', '=', self.type)]
elif self.type in ['in_invoice', 'in_refund']:
domain = [('type', 'in', ['in_invoice', 'in_refund'])]
else:
domain = [('type', 'in', ['out_invoice', 'out_refund'])]
if self.id:
domain += [('id', '<>', self.id)]
domain += [('journal_id', '=', self.journal_id.id), ('state', 'not in', ['draft', 'cancel'])]
return not self.search(domain, limit=1)
@api.depends('state', 'journal_id', 'date_invoice')
def _get_sequence_prefix(self):
""" computes the number that will be assigned to the first invoice/bill/refund of a journal, in order to
let the user manually change it.
"""
if not self.env.user._is_admin():
for invoice in self:
invoice.sequence_number_next_prefix = False
invoice.sequence_number_next = ''
return
for invoice in self:
journal_sequence = invoice.journal_id.sequence_id
if invoice.journal_id.refund_sequence:
domain = [('type', '=', invoice.type)]
journal_sequence = invoice.type in ['in_refund', 'out_refund'] and invoice.journal_id.refund_sequence_id or invoice.journal_id.sequence_id
elif invoice.type in ['in_invoice', 'in_refund']:
domain = [('type', 'in', ['in_invoice', 'in_refund'])]
else:
domain = [('type', 'in', ['out_invoice', 'out_refund'])]
if invoice.id:
domain += [('id', '<>', invoice.id)]
domain += [('journal_id', '=', invoice.journal_id.id), ('state', 'not in', ['draft', 'cancel'])]
journal_sequence = invoice.journal_id.sequence_id
if (invoice.state == 'draft') and not self.search(domain, limit=1):
if (invoice.state == 'draft') and self._no_existing_validated_invoice():
prefix, dummy = journal_sequence.with_context(ir_sequence_date=invoice.date_invoice)._get_prefix_suffix()
invoice.sequence_number_next_prefix = prefix
number_next = journal_sequence._get_current_sequence().number_next_actual
invoice.sequence_number_next = '%%0%sd' % journal_sequence.padding % number_next
else:
invoice.sequence_number_next_prefix = False
invoice.sequence_number_next = 'no'
invoice.sequence_number_next = ''
@api.multi
def _set_sequence_next(self):
''' Set the number_next on the sequence related to the invoice/bill/refund'''
for invoice in self:
nxt = re.sub("[^0-9]", '', invoice.sequence_number_next or '1')
result = re.match("(0*)([0-9]+)", nxt)
journal_sequence = invoice.journal_id.refund_sequence and invoice.journal_id.refund_sequence_id or invoice.journal_id.sequence_id
if result and journal_sequence:
#use _get_current_sequence to manage the date range sequences
sequence = journal_sequence._get_current_sequence()
sequence.number_next = int(result.group(2))
self.ensure_one()
if not self.env.user._is_admin() or not self.sequence_number_next or not self._no_existing_validated_invoice():
return
nxt = re.sub("[^0-9]", '', self.sequence_number_next)
result = re.match("(0*)([0-9]+)", nxt)
journal_sequence = self.journal_id.refund_sequence and self.journal_id.refund_sequence_id or self.journal_id.sequence_id
if result and journal_sequence:
#use _get_current_sequence to manage the date range sequences
sequence = journal_sequence._get_current_sequence()
sequence.number_next = int(result.group(2))
@api.model
def create(self, vals):
@@ -238,7 +238,7 @@
<field name="number" class="oe_inline" attrs="{'invisible': [('state', '=', 'draft')]}"/>
<div attrs="{'invisible': [('sequence_number_next_prefix','=',False)]}">
<field name="sequence_number_next_prefix" class="oe_inline"/>
<field name="sequence_number_next" class="oe_inline" required="1" style="width: 80px !important;"/>
<field name="sequence_number_next" class="oe_inline" style="width: 80px !important;"/>
</div>
</h1>
</div>
@@ -378,7 +378,7 @@
<div attrs="{'invisible': [('sequence_number_next_prefix','=',False)]}">
<label string="Invoice Number:"/><br/>
<field name="sequence_number_next_prefix" class="oe_inline"/>
<field name="sequence_number_next" class="oe_inline" required="1" style="width: 80px !important;"/>
<field name="sequence_number_next" class="oe_inline" style="width: 80px !important;"/>
</div>
</h1>
<field name="type" invisible="1"/>