@@ -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
615636def guess_po_details (pi_data ):
0 commit comments