parent
03ebb4f02f
commit
010ea4b065
25
invoice.py
25
invoice.py
|
@ -9,6 +9,7 @@ import random
|
|||
import xmlsig
|
||||
import hashlib
|
||||
import datetime
|
||||
import math
|
||||
from decimal import Decimal
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from lxml import etree
|
||||
|
@ -256,6 +257,7 @@ class Invoice(metaclass=PoolMeta):
|
|||
"""Return the content to render in factura-e XML file"""
|
||||
pool = Pool()
|
||||
Currency = pool.get('currency.currency')
|
||||
Invoice = pool.get('account.invoice')
|
||||
Date = pool.get('ir.date')
|
||||
Rate = pool.get('currency.currency.rate')
|
||||
|
||||
|
@ -395,15 +397,12 @@ class Invoice(metaclass=PoolMeta):
|
|||
'invoice': self,
|
||||
'Decimal': Decimal,
|
||||
'Currency': Currency,
|
||||
'Invoice': Invoice,
|
||||
'euro': euro,
|
||||
'exchange_rate': exchange_rate,
|
||||
'exchange_rate_date': exchange_rate_date,
|
||||
'invoice': self,
|
||||
'Decimal': Decimal,
|
||||
'Currency': Currency,
|
||||
'euro': euro,
|
||||
'exchange_rate': exchange_rate,
|
||||
'exchange_rate_date': exchange_rate_date,
|
||||
'UOM_CODE2TYPE': UOM_CODE2TYPE,
|
||||
}
|
||||
|
||||
|
@ -676,6 +675,24 @@ class Invoice(metaclass=PoolMeta):
|
|||
|
||||
return signed_file_content
|
||||
|
||||
@classmethod
|
||||
def double_up_to_eight(cls, value):
|
||||
# return max 8 digits in DoubleUpToEightDecimalType
|
||||
_TOTAL_DIGITS = 8
|
||||
def digits_decimal(value):
|
||||
num_str = str(value)
|
||||
if '.' in num_str:
|
||||
num_digits = num_str[::-1].find('.')
|
||||
else:
|
||||
num_digits = 0
|
||||
|
||||
return num_digits
|
||||
|
||||
if digits_decimal(value) > _TOTAL_DIGITS:
|
||||
precision = 10 ** -_TOTAL_DIGITS
|
||||
return math.floor(float(value) / precision) * precision
|
||||
return value
|
||||
|
||||
|
||||
class InvoiceLine(metaclass=PoolMeta):
|
||||
__name__ = 'account.invoice.line'
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
<StartDate>{{ invoice.credited_invoices[0].move.period.start_date.isoformat() }}</StartDate>
|
||||
<EndDate>{{ invoice.credited_invoices[0].move.period.end_date.isoformat() }}</EndDate>
|
||||
</TaxPeriod>
|
||||
{# TODO: Methods not supported:
|
||||
{# TODO: Methods not supported:
|
||||
- 02 (solo se anotan los detalles ya rectificados)
|
||||
- 03 (Rectificación por descuento por volumen de operaciones durante un periodo)
|
||||
- 04 (Autorizadas por la Agencia Tributaria)
|
||||
|
@ -161,7 +161,7 @@
|
|||
<InvoiceCurrencyCode>{{ invoice.currency.code.upper() }}</InvoiceCurrencyCode>
|
||||
{% if invoice.currency != euro %}
|
||||
<ExchangeRateDetails>
|
||||
<ExchangeRate>{{ Currency.compute(invoice.currency, exchange_rate, euro) }}</ExchangeRate>
|
||||
<ExchangeRate>{{ Invoice.double_up_to_eight(exchange_rate) }}</ExchangeRate>
|
||||
<ExchangeRateDate>{{ exchange_rate_date }}</ExchangeRateDate>
|
||||
</ExchangeRateDetails>
|
||||
{% endif %}
|
||||
|
@ -172,15 +172,15 @@
|
|||
{% for invoice_tax in invoice.taxes_outputs %}
|
||||
<Tax>
|
||||
<TaxTypeCode>{{ invoice_tax.tax.report_type }}</TaxTypeCode>
|
||||
<TaxRate>{{ Currency.compute(invoice.currency, invoice_tax.tax.rate * 100, euro) }}</TaxRate>
|
||||
<TaxRate>{{ Invoice.double_up_to_eight(invoice_tax.tax.rate * 100) }}</TaxRate>
|
||||
<TaxableBase>
|
||||
<TotalAmount>{{ Currency.compute(invoice.currency, invoice_tax.base, euro) }}</TotalAmount>
|
||||
<TotalAmount>{{ Invoice.double_up_to_eight(invoice_tax.base) }}</TotalAmount>
|
||||
{% if invoice.currency != euro %}
|
||||
<EquivalentInEuros>{{ Currency.compute(invoice.currency, invoice_tax.base, euro) }}</EquivalentInEuros>
|
||||
<EquivalentInEuros>{{ Invoice.double_up_to_eight(invoice_tax.base) }}</EquivalentInEuros>
|
||||
{% endif %}
|
||||
</TaxableBase>
|
||||
<TaxAmount>
|
||||
<TotalAmount>{{ Currency.compute(invoice.currency, invoice_tax.amount, euro) }}</TotalAmount>
|
||||
<TotalAmount>{{ Invoice.double_up_to_eight(invoice_tax.amount) }}</TotalAmount>
|
||||
{% if invoice.currency != euro %}
|
||||
<EquivalentInEuros>{{ Currency.compute(invoice.currency, invoice_tax.amount, euro) }}</EquivalentInEuros>
|
||||
{% endif %}
|
||||
|
@ -207,7 +207,7 @@
|
|||
{% for invoice_tax in invoice.taxes_withheld %}
|
||||
<Tax>
|
||||
<TaxTypeCode>{{ invoice_tax.tax.report_type }}</TaxTypeCode>
|
||||
<TaxRate>{{ Currency.compute(invoice.currency, invoice_tax.tax.rate * 100, euro) }}</TaxRate>
|
||||
<TaxRate>{{ Invoice.double_up_to_eight(invoice_tax.tax.rate * 100) }}</TaxRate>
|
||||
<TaxableBase>
|
||||
<TotalAmount>{{ Currency.compute(invoice.currency, invoice_tax.base, euro) }}</TotalAmount>
|
||||
{% if invoice.currency != euro %}
|
||||
|
@ -225,13 +225,13 @@
|
|||
</TaxesWithheld>
|
||||
{% endif %}
|
||||
<InvoiceTotals>
|
||||
<TotalGrossAmount>{{ Currency.compute(invoice.currency, invoice.untaxed_amount, euro) }}</TotalGrossAmount>
|
||||
<TotalGrossAmount>{{ Invoice.double_up_to_eight(invoice.untaxed_amount) }}</TotalGrossAmount>
|
||||
{# TODO: GeneralDiscounts and TotalGeneralDiscounts (account_invoice_discount_global) not supported #}
|
||||
{# TODO: GeneralSurcharges and TotalGeneralSurcharges not supported #}
|
||||
<TotalGrossAmountBeforeTaxes>{{ Currency.compute(invoice.currency, invoice.untaxed_amount, euro) }}</TotalGrossAmountBeforeTaxes>
|
||||
<TotalTaxOutputs>{{ Currency.compute(invoice.currency, invoice.taxes_outputs | sum(attribute='amount', start=Decimal(0)), euro) }}</TotalTaxOutputs>
|
||||
<TotalTaxesWithheld>{{ Currency.compute(invoice.currency, invoice.taxes_withheld | sum(attribute='amount', start=Decimal(0)), euro) }}</TotalTaxesWithheld>
|
||||
<InvoiceTotal>{{ Currency.compute(invoice.currency, invoice.total_amount, euro) }}</InvoiceTotal>
|
||||
<TotalGrossAmountBeforeTaxes>{{ Invoice.double_up_to_eight(invoice.untaxed_amount) }}</TotalGrossAmountBeforeTaxes>
|
||||
<TotalTaxOutputs>{{ Invoice.double_up_to_eight(invoice.taxes_outputs | sum(attribute='amount', start=Decimal(0))) }}</TotalTaxOutputs>
|
||||
<TotalTaxesWithheld>{{ Invoice.double_up_to_eight(invoice.taxes_withheld | sum(attribute='amount', start=Decimal(0))) }}</TotalTaxesWithheld>
|
||||
<InvoiceTotal>{{ Invoice.double_up_to_eight(invoice.total_amount) }}</InvoiceTotal>
|
||||
{# TODO: optional, not supported
|
||||
- Subsidies
|
||||
- PaymentsOnAccount, TotalPaymentsOnAccount
|
||||
|
@ -239,8 +239,8 @@
|
|||
- TotalFinancialExpenses (account_payment_type_cost?)
|
||||
- AmountsWithheld
|
||||
#}
|
||||
<TotalOutstandingAmount>{{ Currency.compute(invoice.currency, invoice.total_amount, euro) }}</TotalOutstandingAmount>
|
||||
<TotalExecutableAmount>{{ Currency.compute(invoice.currency, invoice.total_amount, euro) }}</TotalExecutableAmount>
|
||||
<TotalOutstandingAmount>{{ Invoice.double_up_to_eight(invoice.total_amount) }}</TotalOutstandingAmount>
|
||||
<TotalExecutableAmount>{{ Invoice.double_up_to_eight(invoice.total_amount) }}</TotalExecutableAmount>
|
||||
</InvoiceTotals>
|
||||
<Items>
|
||||
{% for line in invoice.lines if line.type == 'line' %}
|
||||
|
@ -257,19 +257,19 @@
|
|||
<ItemDescription>{{ (line.description and line.description[:2500]) or (line.product and line.product.rec_name[:2500]) or '#'+line.id|string }}</ItemDescription>
|
||||
<Quantity>{{ line.quantity }}</Quantity>
|
||||
<UnitOfMeasure>{{ UOM_CODE2TYPE.get(line.unit.symbol, '05') if line.unit else '05' }}</UnitOfMeasure>
|
||||
<UnitPriceWithoutTax>{{ Currency.compute(invoice.currency, line.unit_price, euro) }}</UnitPriceWithoutTax>
|
||||
<TotalCost>{{ Currency.compute(invoice.currency, line.amount, euro) }}</TotalCost>
|
||||
<UnitPriceWithoutTax>{{ Invoice.double_up_to_eight(line.unit_price) }}</UnitPriceWithoutTax>
|
||||
<TotalCost>{{ Invoice.double_up_to_eight(line.amount) }}</TotalCost>
|
||||
{# TODO: optional, not supported
|
||||
- DiscountsAndRebates (account_invoice_discount)
|
||||
- Charges
|
||||
#}
|
||||
<GrossAmount>{{ Currency.compute(invoice.currency, line.amount, euro) }}</GrossAmount>
|
||||
<GrossAmount>{{ Invoice.double_up_to_eight(line.amount) }}</GrossAmount>
|
||||
{% if line.taxes_withheld %}
|
||||
<TaxesWithheld>
|
||||
{% for line_tax in invoice.taxes_withheld %}
|
||||
<Tax>
|
||||
<TaxTypeCode>{{ line_tax.tax.report_type }}</TaxTypeCode>
|
||||
<TaxRate>{{ Currency.compute(invoice.currency, line_tax.tax.rate * 100, euro) }}</TaxRate>
|
||||
<TaxRate>{{ Invoice.double_up_to_eight(line_tax.tax.rate * 100) }}</TaxRate>
|
||||
<TaxableBase>
|
||||
<TotalAmount>{{ Currency.compute(invoice.currency, line.amount, euro) }}</TotalAmount>
|
||||
{% if invoice.currency != euro %}
|
||||
|
|
Loading…
Reference in New Issue