|
4 | 4 |
|
5 | 5 | from datetime import datetime
|
6 | 6 |
|
7 |
| -from odoo import api, fields, models |
| 7 | +from odoo import _, api, fields, models |
8 | 8 | from odoo.exceptions import UserError
|
9 | 9 | from odoo.tools import float_compare, html2plaintext
|
10 | 10 |
|
@@ -408,6 +408,7 @@ def _l10n_it_edi_get_extra_info(
|
408 | 408 | )
|
409 | 409 | self.l10n_it_edi_amount_tax += get_float(element_summary, ".//Imposta")
|
410 | 410 |
|
| 411 | + extra_info["l10n_it_edi_ext_body_tree"] = body_tree |
411 | 412 | return extra_info, message_to_log
|
412 | 413 |
|
413 | 414 | def _l10n_it_edi_create_partner(
|
@@ -578,68 +579,160 @@ def _l10n_it_edi_search_partner(self, company, vat, codice_fiscale, email):
|
578 | 579 |
|
579 | 580 | return partner
|
580 | 581 |
|
581 |
| - def _l10n_it_edi_import_line(self, element, move_line, extra_info=None): |
582 |
| - # Admin. ref. |
583 |
| - if admin_ref := get_text(element, ".//RiferimentoAmministrazione"): |
584 |
| - move_line.l10n_it_edi_admin_ref = admin_ref |
585 |
| - |
586 |
| - vals = { |
587 |
| - "line_number": int(get_text(element, ".//NumeroLinea")), |
588 |
| - "service_type": get_text(element, ".//TipoCessionePrestazione"), |
589 |
| - "name": " ".join(get_text(element, ".//Descrizione").split()), |
590 |
| - "qty": float(get_text(element, ".//Quantita") or 0), |
591 |
| - "uom": get_text(element, ".//UnitaMisura"), |
592 |
| - "period_start_date": get_date(element, ".//DataInizioPeriodo"), |
593 |
| - "period_end_date": get_date(element, ".//DataFinePeriodo"), |
594 |
| - "unit_price": get_float(element, ".//PrezzoUnitario"), |
595 |
| - "total_price": get_float(element, ".//PrezzoTotale"), |
596 |
| - "tax_amount": get_float(element, ".//AliquotaIVA"), |
597 |
| - "wt_amount": get_text(element, ".//Ritenuta"), |
598 |
| - "tax_kind": get_text(element, ".//Natura").upper(), |
599 |
| - "admin_ref": get_text(element, ".//RiferimentoAmministrazione"), |
600 |
| - "invoice_line_id": move_line.id, |
601 |
| - "invoice_id": move_line.move_id.id, |
602 |
| - } |
603 |
| - einvoice_line = self.env["l10n_it_edi.line"].create(vals) |
604 |
| - |
605 |
| - if elements_code := element.xpath(".//CodiceArticolo"): |
606 |
| - for element_code in elements_code: |
607 |
| - self.env["l10n_it_edi.article_code"].create( |
608 |
| - { |
609 |
| - "name": get_text(element_code, ".//CodiceTipo"), |
610 |
| - "code_val": get_text(element_code, ".//CodiceValore"), |
611 |
| - "l10n_it_edi_line_id": einvoice_line.id, |
612 |
| - } |
| 582 | + def _l10n_it_edi_ext_import_summary_line(self, element, extra_info=None): |
| 583 | + messages_to_log = [] |
| 584 | + company = self.company_id |
| 585 | + percentage = get_float(element, ".//AliquotaIVA") |
| 586 | + extra_domain = extra_info.get( |
| 587 | + "type_tax_use_domain", [("type_tax_use", "=", "purchase")] |
| 588 | + ) |
| 589 | + l10n_it_exempt_reason = get_text(element, ".//Natura").upper() or False |
| 590 | + tax = self._l10n_it_edi_search_tax_for_import( |
| 591 | + company, |
| 592 | + percentage, |
| 593 | + extra_domain, |
| 594 | + l10n_it_exempt_reason=l10n_it_exempt_reason, |
| 595 | + ) |
| 596 | + if tax: |
| 597 | + self.invoice_line_ids += self.env["account.move.line"].create( |
| 598 | + { |
| 599 | + "move_id": self.id, |
| 600 | + "name": _( |
| 601 | + "Summary for tax amount %(percentage)s", |
| 602 | + percentage=percentage, |
| 603 | + ), |
| 604 | + "price_unit": get_float(element, ".//ImponibileImporto"), |
| 605 | + "tax_ids": tax.ids, |
| 606 | + } |
| 607 | + ) |
| 608 | + else: |
| 609 | + messages_to_log.append( |
| 610 | + Markup("<br/>").join( |
| 611 | + ( |
| 612 | + _( |
| 613 | + "Tax not found for summary line " |
| 614 | + "with percentage %(percentage)s.", |
| 615 | + percentage=percentage, |
| 616 | + ), |
| 617 | + self._compose_info_message(element, "."), |
| 618 | + ) |
613 | 619 | )
|
| 620 | + ) |
614 | 621 |
|
615 |
| - if elements_discount := element.xpath(".//ScontoMaggiorazione"): |
616 |
| - for element_discount in elements_discount: |
617 |
| - self.env["l10n_it_edi.discount_rise_price"].create( |
618 |
| - { |
619 |
| - "name": get_text(element_discount, ".//Tipo"), |
620 |
| - "percentage": get_float(element_discount, ".//Percentuale"), |
621 |
| - "amount": get_float(element_discount, ".//Importo"), |
622 |
| - "l10n_it_edi_line_id": einvoice_line.id, |
623 |
| - } |
624 |
| - ) |
| 622 | + return messages_to_log |
625 | 623 |
|
626 |
| - if elements_other_data := element.xpath(".//AltriDatiGestionali"): |
627 |
| - for element_other_data in elements_other_data: |
628 |
| - self.env["l10n_it_edi.line_other_data"].create( |
629 |
| - { |
630 |
| - "name": get_text(element_other_data, ".//TipoDato"), |
631 |
| - "text_ref": get_text(element_other_data, ".//RiferimentoTesto"), |
632 |
| - "num_ref": get_float( |
633 |
| - element_other_data, ".//RiferimentoNumero" |
| 624 | + def _l10n_it_edi_import_line(self, element, move_line, extra_info=None): |
| 625 | + if extra_info is None: |
| 626 | + extra_info = dict() |
| 627 | + messages_to_log = [] |
| 628 | + company = move_line.company_id |
| 629 | + import_detail_level = ( |
| 630 | + move_line.partner_id.l10n_it_edi_import_detail_level |
| 631 | + or company.l10n_it_edi_import_detail_level |
| 632 | + ) |
| 633 | + if import_detail_level == "min": |
| 634 | + move_line.unlink() |
| 635 | + line_description = " ".join(get_text(element, ".//Descrizione").split()) |
| 636 | + messages_to_log.append( |
| 637 | + Markup("<br/>").join( |
| 638 | + ( |
| 639 | + _( |
| 640 | + "Line with description %(line_description)s " |
| 641 | + "has been skipped " |
| 642 | + "because import detail level is minimum.", |
| 643 | + line_description=line_description, |
634 | 644 | ),
|
635 |
| - "date_ref": get_date(element_other_data, ".//RiferimentoData"), |
636 |
| - "l10n_it_edi_line_id": einvoice_line.id, |
637 |
| - } |
| 645 | + self._compose_info_message(element, "."), |
| 646 | + ) |
638 | 647 | )
|
| 648 | + ) |
| 649 | + elif ( |
| 650 | + body_tree := extra_info.get("l10n_it_edi_ext_body_tree") |
| 651 | + ) is not None and import_detail_level == "tax": |
| 652 | + move_line.unlink() |
| 653 | + tax_level_imported = extra_info.get("l10n_it_edi_ext_tax_level_imported") |
| 654 | + if not tax_level_imported: |
| 655 | + for summary_line in body_tree.xpath(".//DatiBeniServizi/DatiRiepilogo"): |
| 656 | + messages_to_log += self._l10n_it_edi_ext_import_summary_line( |
| 657 | + summary_line, extra_info=extra_info |
| 658 | + ) |
| 659 | + extra_info["l10n_it_edi_ext_tax_level_imported"] = True |
| 660 | + elif import_detail_level == "max": |
| 661 | + # Admin. ref. |
| 662 | + if admin_ref := get_text(element, ".//RiferimentoAmministrazione"): |
| 663 | + move_line.l10n_it_edi_admin_ref = admin_ref |
| 664 | + |
| 665 | + vals = { |
| 666 | + "line_number": int(get_text(element, ".//NumeroLinea")), |
| 667 | + "service_type": get_text(element, ".//TipoCessionePrestazione"), |
| 668 | + "name": " ".join(get_text(element, ".//Descrizione").split()), |
| 669 | + "qty": float(get_text(element, ".//Quantita") or 0), |
| 670 | + "uom": get_text(element, ".//UnitaMisura"), |
| 671 | + "period_start_date": get_date(element, ".//DataInizioPeriodo"), |
| 672 | + "period_end_date": get_date(element, ".//DataFinePeriodo"), |
| 673 | + "unit_price": get_float(element, ".//PrezzoUnitario"), |
| 674 | + "total_price": get_float(element, ".//PrezzoTotale"), |
| 675 | + "tax_amount": get_float(element, ".//AliquotaIVA"), |
| 676 | + "wt_amount": get_text(element, ".//Ritenuta"), |
| 677 | + "tax_kind": get_text(element, ".//Natura").upper(), |
| 678 | + "admin_ref": get_text(element, ".//RiferimentoAmministrazione"), |
| 679 | + "invoice_line_id": move_line.id, |
| 680 | + "invoice_id": move_line.move_id.id, |
| 681 | + } |
| 682 | + einvoice_line = self.env["l10n_it_edi.line"].create(vals) |
| 683 | + |
| 684 | + if elements_code := element.xpath(".//CodiceArticolo"): |
| 685 | + for element_code in elements_code: |
| 686 | + self.env["l10n_it_edi.article_code"].create( |
| 687 | + { |
| 688 | + "name": get_text(element_code, ".//CodiceTipo"), |
| 689 | + "code_val": get_text(element_code, ".//CodiceValore"), |
| 690 | + "l10n_it_edi_line_id": einvoice_line.id, |
| 691 | + } |
| 692 | + ) |
639 | 693 |
|
640 |
| - return super()._l10n_it_edi_import_line( |
641 |
| - element, move_line, extra_info=extra_info |
642 |
| - ) |
| 694 | + if elements_discount := element.xpath(".//ScontoMaggiorazione"): |
| 695 | + for element_discount in elements_discount: |
| 696 | + self.env["l10n_it_edi.discount_rise_price"].create( |
| 697 | + { |
| 698 | + "name": get_text(element_discount, ".//Tipo"), |
| 699 | + "percentage": get_float(element_discount, ".//Percentuale"), |
| 700 | + "amount": get_float(element_discount, ".//Importo"), |
| 701 | + "l10n_it_edi_line_id": einvoice_line.id, |
| 702 | + } |
| 703 | + ) |
| 704 | + |
| 705 | + if elements_other_data := element.xpath(".//AltriDatiGestionali"): |
| 706 | + for element_other_data in elements_other_data: |
| 707 | + self.env["l10n_it_edi.line_other_data"].create( |
| 708 | + { |
| 709 | + "name": get_text(element_other_data, ".//TipoDato"), |
| 710 | + "text_ref": get_text( |
| 711 | + element_other_data, ".//RiferimentoTesto" |
| 712 | + ), |
| 713 | + "num_ref": get_float( |
| 714 | + element_other_data, ".//RiferimentoNumero" |
| 715 | + ), |
| 716 | + "date_ref": get_date( |
| 717 | + element_other_data, ".//RiferimentoData" |
| 718 | + ), |
| 719 | + "l10n_it_edi_line_id": einvoice_line.id, |
| 720 | + } |
| 721 | + ) |
| 722 | + |
| 723 | + messages_to_log += super()._l10n_it_edi_import_line( |
| 724 | + element, move_line, extra_info=extra_info |
| 725 | + ) |
| 726 | + else: |
| 727 | + raise UserError( |
| 728 | + _( |
| 729 | + "Import detail level %(import_detail_level)s not supported.\n" |
| 730 | + "Please set an import detail level in company %(company)s.", |
| 731 | + import_detail_level=import_detail_level, |
| 732 | + company=company, |
| 733 | + ) |
| 734 | + ) |
| 735 | + return messages_to_log |
643 | 736 |
|
644 | 737 | def _l10n_it_edi_check_amount_untaxed(self):
|
645 | 738 | error_message = ""
|
|
0 commit comments