CK-Export-Invoice-Processor / parser_vapi_welspun.py
joschetan's picture
Update parser_vapi_welspun.py
a8bf002 verified
Raw
History Blame Contribute Delete
7.53 kB
import re
import pdfplumber
from io import BytesIO
from openpyxl.styles import Alignment
from pdf_engine import apply_value_replacement, extract_header_value
def extract_all_commodities_from_text(pdf_text):
commodities = []
pattern = r'(\d{8})\s*[:\-]\s*(.+)'
matches = re.findall(pattern, pdf_text)
for hsn, desc in matches:
full_desc = f"{hsn}: {desc.strip()}"
commodities.append(full_desc)
return commodities
def extract_vapi_welspun_items(pdf_lines, pdf_text=""):
parsed_items = []
box_commodities = []
if pdf_text:
box_commodities = extract_all_commodities_from_text(pdf_text)
parsed_items.append({"dbk_sr": "", "hs_code": "", "description_text": "", "net_wt": "", "qty": "", "rate": "", "amount_usd": "", "amount_inr": "", "igst_per": "5.00", "igst_amt": "", "sqmtr": "", "box_commodities": box_commodities})
return parsed_items
def map_vapi_welspun_items_to_excel_dynamic(ws, parsed_items, item_rules, inv_sr_no=1, start_overall_sr=1, start_excel_row=2, default_invoice_no="", default_invoice_date="", pdf_text="", lut_kws="", paid_kws="", parser_rule=""):
curr_row = start_excel_row
overall_sr = start_overall_sr
pdf_text_upper = str(pdf_text).upper()
pdf_lines = str(pdf_text).split("\n")
l_keywords = [k.strip().upper() for k in str(lut_kws).split(",") if k.strip()]
p_keywords = [k.strip().upper() for k in str(paid_kws).split(",") if k.strip()]
matched_lut = any(kw.replace("NO.", "").replace(".", "").strip() in pdf_text_upper for kw in l_keywords if kw.strip())
matched_paid = any(kw.replace(".", "").strip() in pdf_text_upper for kw in p_keywords if kw.strip())
v_column_value = "LUT" if matched_lut else ("P" if matched_paid else "LUT")
max_rows = len(parsed_items)
first_item = parsed_items[0] if parsed_items else {}
all_comms = first_item.get("box_commodities", [])
for item_idx in range(max_rows):
item_sr_no = item_idx + 1
item = parsed_items[item_idx] if item_idx < len(parsed_items) else {}
ws[f"G{curr_row}"] = inv_sr_no
ws[f"H{curr_row}"] = item_sr_no
ws[f"V{curr_row}"] = v_column_value
ws[f"I{curr_row}"] = default_invoice_no
if default_invoice_date and not "ROSC" in str(default_invoice_date):
ws[f"J{curr_row}"] = default_invoice_date
if all_comms:
cell_ref_bs = f"BS{curr_row}"
if item_idx < len(all_comms):
ws[cell_ref_bs] = all_comms[item_idx]
else:
ws[cell_ref_bs] = ""
ws[cell_ref_bs].alignment = Alignment(wrap_text=True)
for field_name, r_info in item_rules.items():
col_letter = r_info.get("col", "").strip().upper()
rule_type_raw = str(r_info.get("type", "PDF Row Item")).strip()
rule_val = str(r_info.get("rule", "")).strip()
if not col_letter or col_letter in ["V", "BR", "BS", "S", "J"]:
continue
if "extract" in rule_type_raw.lower() or "box" in rule_type_raw.lower() or "header" in rule_type_raw.lower() or col_letter in ["BW", "BY"]:
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "📦 Extract Inside Box (डब्बे के अंदर का टेक्स्ट)", "Exact Word", "", "None", field_label=field_name)
if not extracted_val or not extracted_val.strip():
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "Right (आगे)", "Exact Word", "", "None", field_label=field_name)
if extracted_val and "\n" in str(extracted_val):
lines = [l.strip() for l in str(extracted_val).split("\n") if l.strip()]
ws[f"{col_letter}{curr_row}"] = lines[item_idx] if item_idx < len(lines) else ""
else:
ws[f"{col_letter}{curr_row}"] = extracted_val if item_idx == 0 else ""
for field_name, r_info in item_rules.items():
col_letter = r_info.get("col", "").strip().upper()
rule_type_raw = str(r_info.get("type", "PDF Row Item")).strip()
rule_val = str(r_info.get("rule", "")).strip()
rule_val_lower = rule_val.lower()
if not col_letter or col_letter in ["V", "I", "J", "G", "BR", "BS", "M"]:
continue
if "extract" in rule_type_raw.lower() or "box" in rule_type_raw.lower() or "header" in rule_type_raw.lower():
continue
cell_ref = f"{col_letter}{curr_row}"
raw_val = ""
clean_rule_val = rule_val_lower.replace("col_", "").strip()
if clean_rule_val.isdigit() and col_letter in ["K", "S", "BU"]:
col_idx = int(clean_rule_val)
raw_val = item.get(f"col_{col_idx}", "")
if col_letter == "S":
raw_val = f"{raw_val}B" if raw_val and not str(raw_val).upper().endswith("B") else raw_val
elif col_letter == "K" or "hs" in rule_val_lower or "ritc" in rule_val_lower:
raw_val = item.get("hs_code", "")
elif col_letter == "BU" or "desc" in rule_val_lower:
raw_val = item.get("description_text", "")
elif col_letter == "S" or "dbk" in rule_val_lower:
dbk = item.get("dbk_sr", "")
raw_val = f"{dbk}B" if dbk and not dbk.upper().endswith("B") else dbk
elif col_letter == "AB" or "wt" in rule_val_lower or "weight" in rule_val_lower:
raw_val = item.get("net_wt", "")
elif col_letter == "N" or "qty" in rule_val_lower or "quantity" in rule_val_lower:
raw_val = item.get("qty", "")
elif col_letter == "P" or "rate" in rule_val_lower:
raw_val = item.get("rate", "")
elif col_letter == "Q" or ("amount" in rule_val_lower and "usd" in rule_val_lower):
raw_val = item.get("amount_usd", "")
elif col_letter == "W" or "taxable" in rule_val_lower or "inr" in rule_val_lower:
raw_val = item.get("amount_inr", "")
elif col_letter == "X" or "igst%" in rule_val_lower or "igst per" in rule_val_lower:
raw_val = item.get("igst_per", "5.00")
elif col_letter == "Y" or "igst amount" in rule_val_lower:
raw_val = item.get("igst_amt", "")
elif col_letter == "Z" or "sqmtr" in rule_val_lower:
raw_val = item.get("sqmtr", "")
else:
if clean_rule_val.isdigit():
col_idx = int(clean_rule_val)
raw_val = item.get(f"col_{col_idx}", "")
if "=" in rule_val:
raw_val = apply_value_replacement(str(raw_val), rule_val)
try:
if col_letter in ["S", "K", "BU"]:
ws[cell_ref] = str(raw_val).replace("\n", " ")
else:
clean_num = str(raw_val).replace(",", "").replace("\n", "").strip()
ws[cell_ref] = float(clean_num) if clean_num else 0.0
except:
ws[cell_ref] = raw_val
curr_row += 1
overall_sr += 1
return ws, overall_sr, curr_row