diff --git a/CHANGELOG b/CHANGELOG index 98a7c51aff..cbb0fafb0f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add tax identifier on invoice * Rename Invoice.create_move to get_move * Rename InvoiceLine and InvoiceTax get_move_line to get_move_lines * Change Invoice.set_number into classmethod diff --git a/doc/index.rst b/doc/index.rst index 6d10cd4065..527e814754 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -11,6 +11,8 @@ There are 4 types of invoice: *Invoice*, *Supplier Invoice*, *Credit Note* and *Paid* or *Canceled*. - Company: The company for which the invoice is created. +- Tax Identifier: The tax identifier that will be printed on the invoice + (By default the first tax identifier of the company). - Number: The invoice number set on validation for supplier invoices and on posting for others using the sequence defined on the period or fiscal year. - Reference: The internal reference of the invoice. diff --git a/invoice.odt b/invoice.odt index 5e68c5a490..b6c2ff62da 100644 Binary files a/invoice.odt and b/invoice.odt differ diff --git a/invoice.py b/invoice.py index a67f7e3641..b723642ff8 100644 --- a/invoice.py +++ b/invoice.py @@ -75,6 +75,16 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): Eval('context', {}).get('company', -1)), ], depends=_DEPENDS) + company_party = fields.Function( + fields.Many2One('party.party', "Company Party"), + 'on_change_with_company_party') + tax_identifier = fields.Many2One( + 'party.identifier', "Tax Identifier", + states=_STATES, + domain=[ + ('party', '=', Eval('company_party', -1)), + ], + depends=_DEPENDS + ['company_party']) type = fields.Selection(_TYPE, 'Type', select=True, required=True, states={ 'readonly': ((Eval('state') != 'draft') @@ -192,6 +202,10 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): ('number', 'DESC'), ('id', 'DESC'), ] + cls.tax_identifier.domain = [ + cls.tax_identifier.domain, + ('type', 'in', cls._tax_identifier_types()), + ] cls._error_messages.update({ 'missing_tax_line': ('Invoice "%s" has taxes defined but not ' 'on invoice lines.\nRe-compute the invoice.'), @@ -399,6 +413,11 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): def default_company(): return Transaction().context.get('company') + @fields.depends('company') + def on_change_with_company_party(self, name=None): + if self.company: + return self.company.party.id + @classmethod def default_payment_term(cls): PaymentTerm = Pool().get('account.invoice.payment_term') @@ -970,6 +989,9 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): Date = pool.get('ir.date') for invoice in invoices: + if not invoice.tax_identifier: + invoice.tax_identifier = invoice.get_tax_identifier() + if invoice.number: continue @@ -1000,6 +1022,17 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): invoice.invoice_date = Transaction().context['date'] cls.save(invoices) + @classmethod + def _tax_identifier_types(cls): + return ['eu_vat'] + + def get_tax_identifier(self): + "Return the default computed tax identifier" + types = self._tax_identifier_types() + for identifier in self.company.party.identifiers: + if identifier.type in types: + return identifier.id + @classmethod def check_modify(cls, invoices): ''' diff --git a/tests/scenario_invoice.rst b/tests/scenario_invoice.rst index fe01d53e98..db8b1370f4 100644 --- a/tests/scenario_invoice.rst +++ b/tests/scenario_invoice.rst @@ -25,6 +25,10 @@ Create company:: >>> _ = create_company() >>> company = get_company() + >>> tax_identifier = company.party.identifiers.new() + >>> tax_identifier.type = 'eu_vat' + >>> tax_identifier.code = 'BE0897290877' + >>> company.party.save() Create fiscal year:: @@ -144,6 +148,8 @@ Post invoice:: >>> invoice.click('post') >>> invoice.state u'posted' + >>> invoice.tax_identifier.code + u'BE0897290877' >>> invoice.untaxed_amount Decimal('220.00') >>> invoice.tax_amount diff --git a/view/invoice_form.xml b/view/invoice_form.xml index 5d1cfc0f6e..53546ec395 100644 --- a/view/invoice_form.xml +++ b/view/invoice_form.xml @@ -64,7 +64,8 @@ this repository contains the full copyright notices and license terms. -->