From 994b6235906d63e408950fb87359dc906ce107a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Bernardi?= Date: Mon, 4 Nov 2019 19:13:51 -0300 Subject: [PATCH] issue #124 #170 add currency rate to invoice (for foreign currencies) --- currency.py | 34 +++++++++++++++++++++++++++++- invoice.py | 48 ++++++++++++++++++++++++++++--------------- locale/es.po | 4 ++++ view/invoice_form.xml | 6 ++++++ 4 files changed, 75 insertions(+), 17 deletions(-) diff --git a/currency.py b/currency.py index 258ca2d..d9c1778 100644 --- a/currency.py +++ b/currency.py @@ -1,5 +1,6 @@ # The COPYRIGHT file at the top level of this repository contains # the full copyright notices and license terms. +from decimal import Decimal import datetime from pyafipws.wsfev1 import WSFEv1 from pyafipws.wsfexv1 import WSFEXv1 @@ -7,16 +8,47 @@ from trytond.model import fields from trytond.pyson import Eval, If, In -from trytond.pool import PoolMeta +from trytond.pool import Pool, PoolMeta +from trytond.transaction import Transaction __all__ = ['Currency', 'Rate'] class Currency(metaclass=PoolMeta): __name__ = 'currency.currency' + afip_code = fields.Char('AFIP Code', size=3, help="The 3 digits AFIP currency code.") + @classmethod + def compute(cls, from_currency, amount, to_currency, round=True): + pool = Pool() + Company = pool.get('company.company') + + currency_rate = Transaction().context.get('currency_rate') + if not currency_rate: + return super(Currency, cls).compute(from_currency, amount, + to_currency, round) + + if to_currency == from_currency: + if round: + return to_currency.round(amount) + else: + return amount + + company = Company(Transaction().context['company']) + if from_currency == company.currency: + from_currency_rate = currency_rate + currency_rate = Decimal('1.0') + else: + from_currency_rate = Decimal('1.0') + + if round: + return to_currency.round( + amount * currency_rate / from_currency_rate) + else: + return amount * currency_rate / from_currency_rate + class Rate(metaclass=PoolMeta): __name__ = 'currency.currency.rate' diff --git a/invoice.py b/invoice.py index e0fb44d..1bb97ec 100644 --- a/invoice.py +++ b/invoice.py @@ -340,6 +340,8 @@ class Invoice(metaclass=PoolMeta): depends=_DEPENDS + ['company_party']) pyafipws_anulacion = fields.Boolean('FCE AnulaciĆ³n', states=_STATES, depends=_DEPENDS) + currency_rate = fields.Numeric('Currency rate', digits=(12, 6), + states={'readonly': Eval('state') != 'draft'}, depends=['state']) @classmethod def __setup__(cls): @@ -445,6 +447,12 @@ def on_change_party(self): if self.party and self.party.iva_condition: self.party_iva_condition = self.party.iva_condition + @fields.depends('company', 'currency') + def on_change_currency(self): + if self.company and self.currency: + if self.company.currency != self.currency: + self.currency_rate = self.currency.rate + @fields.depends('pos') def on_change_with_pos_pos_daily_report(self, name=None): if self.pos: @@ -742,6 +750,7 @@ def _credit(self): Date = pool.get('ir.date') credit = super(Invoice, self)._credit() + credit.currency_rate = self.currency_rate if self.type == 'in': invoice_type, invoice_type_desc = INVOICE_CREDIT_AFIP_CODE[ str(int(self.tipo_comprobante)) @@ -838,6 +847,10 @@ def get_next_number(self, pattern=None): return '%05d-%08d' % (self.pos.number, int(number)) return SequenceStrict.get_id(sequence.id) + def get_move(self): + with Transaction().set_context(currency_rate=self.currency_rate): + return super(Invoice, self).get_move() + def _get_move_line(self, date, amount): line = super(Invoice, self)._get_move_line(date, amount) ref_number = self.number if self.type == 'out' else self.reference @@ -1315,28 +1328,31 @@ def strip_accents(text): imp_neto = str('%.2f' % imp_neto) imp_tot_conc = str('%.2f' % imp_tot_conc) - if self.company.currency.rate == Decimal('0'): - if self.party.vat_number_afip_foreign: - if batch: - logger.error('missing_currency_rate: Invoice: %s, ' - 'rate is not setted.' % self.id) - return (ws, True) - self.raise_user_error('missing_currency_rate') - else: - ctz = 1 - elif self.company.currency.rate == Decimal('1'): - ctz = 1 / self.currency.rate - else: - ctz = self.company.currency.rate / self.currency.rate - - if not self.currency.afip_code: + # currency and rate + moneda_id = self.currency.afip_code + if not moneda_id: if batch: logger.error('missing_currency_afip_code: Invoice: %s, ' 'currency afip code is not setted.' % self.id) return (ws, True) self.raise_user_error('missing_currency_afip_code') - moneda_id = self.currency.afip_code + if moneda_id != "PES": + ctz = self.currency_rate + else: + if self.company.currency.rate == Decimal('0'): + if self.party.vat_number_afip_foreign: + if batch: + logger.error('missing_currency_rate: Invoice: %s, ' + 'rate is not setted.' % self.id) + return (ws, True) + self.raise_user_error('missing_currency_rate') + else: + ctz = 1 + elif self.company.currency.rate == Decimal('1'): + ctz = 1 / self.currency.rate + else: + ctz = self.company.currency.rate / self.currency.rate moneda_ctz = "{:.{}f}".format(ctz, 6) # foreign trade data: export permit, country code, etc.: diff --git a/locale/es.po b/locale/es.po index fbb8236..9631496 100644 --- a/locale/es.po +++ b/locale/es.po @@ -110,6 +110,10 @@ msgctxt "field:account.invoice,annulled:" msgid "Annulled" msgstr "Anulada" +msgctxt "field:account.invoice,currency_rate:" +msgid "Currency rate" +msgstr "Tasa de cambio" + msgctxt "field:account.invoice,invoice_type:" msgid "Comprobante" msgstr "Tipo de factura" diff --git a/view/invoice_form.xml b/view/invoice_form.xml index 1d5dc2c..582b87b 100644 --- a/view/invoice_form.xml +++ b/view/invoice_form.xml @@ -60,4 +60,10 @@ + +