diff --git a/modules/edocument_ubl/edocument.py b/modules/edocument_ubl/edocument.py index e5cb9a915f..45dfe1af78 100644 --- a/modules/edocument_ubl/edocument.py +++ b/modules/edocument_ubl/edocument.py @@ -323,11 +323,21 @@ class Invoice(Model): invoice.payment_term_date = cls._parse_2_payment_term_date( root.findall('./{*}PaymentTerms')) - invoice.lines = [ + lines = [ cls._parse_invoice_2_line( - line, company=invoice.company, currency=invoice.currency, + line, + company=invoice.company, + currency=invoice.currency, supplier=supplier) for line in root.iterfind('./{*}InvoiceLine')] + lines += [ + cls._parse_invoice_2_allowance_charge( + allowance_charge, + company=invoice.company, + currency=invoice.currency, + supplier=supplier) + for allowance_charge in root.iterfind('./{*}AllowanceCharge')] + invoice.lines = lines invoice.taxes = [ cls._parse_2_tax( tax, company=invoice.company) @@ -457,6 +467,51 @@ class Invoice(Model): line.taxes = taxes return line + @classmethod + def _parse_invoice_2_allowance_charge( + cls, allowance_charge, company, currency, supplier=None): + pool = Pool() + AccountConfiguration = pool.get('account.configuration') + Line = pool.get('account.invoice.line') + Tax = pool.get('account.tax') + + account_configuration = AccountConfiguration(1) + + line = Line( + type='line', company=company, currency=currency, invoice_type='in') + + indicator = allowance_charge.findtext('./{*}ChargeIndicator') + line.quantity = {'true': 1, 'false': -1}[indicator] + line.account = account_configuration.get_multivalue( + 'default_category_account_expense', + company=company.id) + line.description = allowance_charge.findtext( + './{*}AllowanceChargeReason') + line.unit_price = round_price(Decimal(allowance_charge.findtext( + './{*}Amount'))) + + taxes = [] + tax_categories = allowance_charge.iterfind('./{*}TaxCategory') + for tax_category in tax_categories: + domain = cls._parse_2_tax_category(tax_category) + domain.extend([ + ['OR', + ('group', '=', None), + ('group.kind', 'in', ['purchase', 'both']), + ], + ('company', '=', company.id), + ]) + try: + tax, = Tax.search(domain, limit=1) + except ValueError: + raise InvoiceError(gettext( + 'edocument_ubl.msg_tax_not_found', + tax_category=etree.tostring( + tax_category, pretty_print=True).decode())) + taxes.append(tax) + line.taxes = taxes + return line + @classmethod def _parse_credit_note_2(cls, root): pool = Pool() @@ -504,11 +559,19 @@ class Invoice(Model): code=currency_code)) invoice.payment_term_date = cls._parse_2_payment_term_date( root.findall('./{*}PaymentTerms')) - invoice.lines = [ + lines = [ cls._parse_credit_note_2_line( line, company=invoice.company, currency=invoice.currency, supplier=supplier) for line in root.iterfind('./{*}CreditNoteLine')] + lines += [ + cls._parse_credit_note_2_allowance_charge( + allowance_charge, + company=invoice.company, + currency=invoice.currency, + supplier=supplier) + for allowance_charge in root.iterfind('./{*}AllowanceCharge')] + invoice.lines = lines invoice.taxes = [ cls._parse_2_tax( tax, company=invoice.company) @@ -640,6 +703,51 @@ class Invoice(Model): line.taxes = taxes return line + @classmethod + def _parse_credit_note_2_allowance_charge( + cls, allowance_charge, company, currency, supplier=None): + pool = Pool() + AccountConfiguration = pool.get('account.configuration') + Line = pool.get('account.invoice.line') + Tax = pool.get('account.tax') + + account_configuration = AccountConfiguration(1) + + line = Line( + type='line', company=company, currency=currency, invoice_type='in') + + indicator = allowance_charge.findtext('./{*}ChargeIndicator') + line.quantity = {'true': -1, 'false': 1}[indicator] + line.account = account_configuration.get_multivalue( + 'default_category_account_expense', + company=company.id) + line.description = allowance_charge.findtext( + './{*}AllowanceChargeReason') + line.unit_price = round_price(Decimal(allowance_charge.findtext( + './{*}Amount'))) + + taxes = [] + tax_categories = allowance_charge.iterfind('./{*}TaxCategory') + for tax_category in tax_categories: + domain = cls._parse_2_tax_category(tax_category) + domain.extend([ + ['OR', + ('group', '=', None), + ('group.kind', 'in', ['purchase', 'both']), + ], + ('company', '=', company.id), + ]) + try: + tax, = Tax.search(domain, limit=1) + except ValueError: + raise InvoiceError(gettext( + 'edocument_ubl.msg_tax_not_found', + tax_category=etree.tostring( + tax_category, pretty_print=True).decode())) + taxes.append(tax) + line.taxes = taxes + return line + @classmethod def _parse_2_supplier(cls, supplier_party, create=False): pool = Pool() diff --git a/modules/edocument_ubl/tests/scenario_ubl_2_credit_note_parse.rst b/modules/edocument_ubl/tests/scenario_ubl_2_credit_note_parse.rst index 1a07094b76..d894612953 100644 --- a/modules/edocument_ubl/tests/scenario_ubl_2_credit_note_parse.rst +++ b/modules/edocument_ubl/tests/scenario_ubl_2_credit_note_parse.rst @@ -80,7 +80,7 @@ Parse the UBL invoice:: >>> invoice.tax_amount Decimal('-292.20') >>> len(invoice.lines) - 5 + 7 >>> attachments = Attachment.find([]) >>> len(attachments) diff --git a/modules/edocument_ubl/tests/scenario_ubl_2_invoice_parse.rst b/modules/edocument_ubl/tests/scenario_ubl_2_invoice_parse.rst index ed6250046f..95e4ec0765 100644 --- a/modules/edocument_ubl/tests/scenario_ubl_2_invoice_parse.rst +++ b/modules/edocument_ubl/tests/scenario_ubl_2_invoice_parse.rst @@ -80,7 +80,7 @@ Parse the UBL invoice:: >>> invoice.tax_amount Decimal('292.20') >>> len(invoice.lines) - 5 + 7 >>> attachments = Attachment.find([]) >>> len(attachments)