Skip to content

Commit f38d7a3

Browse files
authored
Merge pull request #38 from maasanto/fix/peppol-parser-missing-values
fix: resolve missing item, tax account and payment schedule in PEPPOL parser
2 parents 2838814 + 9562017 commit f38d7a3

1 file changed

Lines changed: 35 additions & 14 deletions

File tree

edocument/edocument/profiles/peppol/parser.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ def parse_peppol_taxes(root, namespaces):
409409

410410
# Tax account (try to find from tax category)
411411
# This is a simplified approach - you may need to map tax categories to accounts
412-
tax["account_head"] = None # Will need to be set based on your tax setup
412+
tax["account_head"] = None # Resolved later by guess_missing_values
413413

414414
# Tax amount
415415
tax_amount = get_xml_text(tax_subtotal, ".//cbc:TaxAmount", namespaces)
@@ -470,9 +470,9 @@ def parse_peppol_payment_terms(root, namespaces, default_due_date=None):
470470

471471
payment_schedule.append(schedule_item)
472472

473-
# If no payment terms found, add default one
474-
if not payment_schedule and default_due_date:
475-
payment_schedule.append({"doctype": "Payment Schedule", "due_date": default_due_date})
473+
# Don't add a default payment_schedule entry with only due_date.
474+
# ERPNext will compute the schedule from payment_terms_template (set via supplier defaults)
475+
# or the user can add it manually. Adding an entry without payment_amount causes errors.
476476

477477
return payment_schedule
478478

@@ -584,6 +584,17 @@ def guess_missing_values(pi_data):
584584
except Exception:
585585
pass
586586

587+
# Last resort: match by item name. Since item_name is not unique,
588+
# this may match the wrong item when duplicates exist.
589+
if not item.get("item_code") and item.get("item_name"):
590+
item_name = item["item_name"]
591+
if frappe.db.exists("Item", item_name):
592+
item["item_code"] = item_name
593+
else:
594+
item_code = frappe.db.get_value("Item", {"item_name": item_name}, "name")
595+
if item_code:
596+
item["item_code"] = item_code
597+
587598
# Remove temporary fields (if they exist)
588599
if "seller_product_id" in item:
589600
item.pop("seller_product_id")
@@ -599,17 +610,27 @@ def guess_missing_values(pi_data):
599610
if not item.get("purchase_order"):
600611
item["purchase_order"] = pi_data["purchase_order"]
601612

602-
# Guess tax accounts for taxes (simplified - you may need to map based on your tax setup)
613+
# Guess tax accounts for taxes from existing Purchase Taxes templates
614+
company = pi_data.get("company")
603615
for tax in pi_data.get("taxes", []):
604-
if not tax.get("account_head") and tax.get("rate"):
605-
# Try to find a default tax account based on rate
606-
# This is a simplified approach - you may need to customize this
607-
try:
608-
# Get default tax account from company settings or tax template
609-
# For now, leave it empty - user will need to set it manually
610-
pass
611-
except Exception:
612-
pass
616+
if not tax.get("account_head") and tax.get("rate") and company:
617+
tax_rate = tax["rate"]
618+
account_head = frappe.db.sql(
619+
"""SELECT child.account_head
620+
FROM `tabPurchase Taxes and Charges` child
621+
JOIN `tabPurchase Taxes and Charges Template` parent ON child.parent = parent.name
622+
WHERE child.rate = %s AND parent.company = %s AND parent.disabled = 0
623+
ORDER BY parent.is_default DESC
624+
LIMIT 1""",
625+
(tax_rate, company),
626+
)
627+
if account_head:
628+
tax["account_head"] = account_head[0][0]
629+
if not tax.get("description"):
630+
if tax.get("rate"):
631+
tax["description"] = _("VAT {0}%").format(tax["rate"])
632+
else:
633+
tax["description"] = _("Tax")
613634

614635

615636
def guess_po_details(pi_data):

0 commit comments

Comments
 (0)