import os
import sys
import ctypes
import csv
from datetime import datetime
from pyrfc import Connection
# ============================================================
# SAP NW RFC SDK – Load DLLs
# ============================================================
sap_sdk_path = r"C:\nwrfcsdk\lib"
if sap_sdk_path not in [Link]["PATH"]:
[Link]["PATH"] = sap_sdk_path + ";" + [Link]["PATH"]
try:
[Link]([Link](sap_sdk_path, "[Link]"))
[Link]([Link](sap_sdk_path, "[Link]"))
except OSError as e:
print(f"❌ Could not load RFC DLLs: {e}")
[Link](1)
# ============================================================
# SAP CONNECTION DETAILS
# ============================================================
SAP_CONFIG = {
"ashost": "[Link]", # Hostname
"sysnr": "58", # Instance Number
"client": "500", # DEFAULT (update if required)
"user": "MM01",
"passwd": "sap@4545",
"lang": "EN"
# ============================================================
# >>> PO INVOICE INPUT <<<
# ============================================================
PO_NUMBER = "4500000009" # ENTER PO NUMBER
PO_ITEM = "000010" # ENTER PO ITEM NUMBER
invoice_header = {
"INVOICE_IND":"X",
"DOC_TYPE":"RE",
"DOC_DATE": "20251213",
"PSTNG_DATE": "20251213",
"COMP_CODE": "BEE1",
"CURRENCY": "INR",
"PO_REF_NO": "4500000009",
"BUSINESS_PLACE": "BEE1",
"GROSS_AMOUNT": 600.00
#"CALC_TAX_IND":"X"
#"INVOICE_IND":"x"
#"COMP_CODE": "BEE1",
#"DOC_DATE": "20251213",
#"PSTNG_DATE": "20251213",
#"PO_REF_NO": "4500000006",
#"CURRENCY": "INR"
#"GROSS_AMOUNT": "600"
}
#INVOICESTATUS = {
# "INVOICESTATUS": "5"
# }
invoice_item = [
{
"INVOICE_DOC_ITEM": "000010",
"PO_NUMBER": PO_NUMBER,
"PO_ITEM": PO_ITEM,
"TAX_CODE": "I3",
"ITEM_AMOUNT": 30.00,
"QUANTITY": 20.0,
"PO_UNIT": "EA",
"ITEM_TEXT": "TEST BAPI"
}
]
tax_data = [
{
"TAX_CODE": "I3",
"TAX_AMOUNT": 108.00,
"TAX_BASE_AMOUNT": 600.00,
"ITEMNO_TAX": PO_ITEM,
"TAX_COUNTRY":"IN"
#"COND_TYPE": "MWST"
#"Tax_code":"",
#"Tax_base_amount":"",
}
]
# ============================================================
# CHECK PO EXISTS
# ============================================================
def check_po_exists(conn, po_number):
print(f"\n🔍 Checking PO {po_number}...")
try:
response = [Link]("BAPI_PO_GETDETAIL", PURCHASEORDER=po_number)
for msg in [Link]("RETURN", []):
print(f"{msg['TYPE']} - {msg['MESSAGE']}")
has_error = any(m["TYPE"] in ("E", "A") for m in [Link]("RETURN",
[]))
if has_error:
print("❌ Invalid PO. Cannot continue.\n")
return False
print("✅ PO is valid.\n")
return True
except Exception as e:
print(f"❌ Error checking PO: {e}")
return False
# ============================================================
# POST PO-BASED INVOICE
# ============================================================
def post_po_invoice():
try:
print("🔗 Connecting to SAP...")
conn = Connection(**SAP_CONFIG)
print("✅ Connected.\n")
# Validate PO
if not check_po_exists(conn, PO_NUMBER):
print("⛔ Stopping due to invalid PO.")
return None
print("📄 Posting PO-based invoice (MIRO)...")
response = [Link](
"BAPI_INCOMINGINVOICE_CREATE1",
HEADERDATA=invoice_header,
ITEMDATA=invoice_item,
ACCOUNTINGDATA=[], # Always empty for PO
TAXDATA=tax_data
)
print("\n=== SAP RETURN MESSAGES ===")
for msg in [Link]("RETURN", []):
print(f"{msg['TYPE']} - {msg['MESSAGE']}")
has_error = any(m["TYPE"] in ("E", "A") for m in [Link]("RETURN",
[]))
if not has_error:
print("\n💾 Committing...")
[Link]("BAPI_TRANSACTION_COMMIT", WAIT="X")
print("✅ PO Invoice posted successfully!")
else:
print("\n⛔ Errors found. Rolling back...")
[Link]("BAPI_TRANSACTION_ROLLBACK")
print("❌ Posting failed.")
[Link]()
return response
except Exception as e:
print(f"❌ SAP Error: {e}")
return None
# ============================================================
# LOG TO CSV
# ============================================================
def log_results(result):
log_file = f"po_invoice_log_{[Link]().strftime('%Y%m%d_%H%M%S')}.csv"
with open(log_file, "w", newline="", encoding="utf-8-sig") as f:
writer = [Link](f)
[Link](["TYPE", "ID", "NUMBER", "MESSAGE"])
if result:
for msg in [Link]("RETURN", []):
[Link]([msg["TYPE"], msg["ID"], msg["NUMBER"],
msg["MESSAGE"]])
print(f"\n📄 Log saved → {log_file}")
# ============================================================
# MAIN
# ============================================================
if __name__ == "__main__":
result = post_po_invoice()
if result:
log_results(result)