Spaces:
Running on Zero
Running on Zero
Update parser_vapi_welspun.py
Browse files- parser_vapi_welspun.py +7 -100
parser_vapi_welspun.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import re
|
| 2 |
-
import streamlit as st
|
| 3 |
import pdfplumber
|
| 4 |
from io import BytesIO
|
| 5 |
from openpyxl.styles import Alignment
|
|
@@ -16,101 +15,11 @@ def extract_all_commodities_from_text(pdf_text):
|
|
| 16 |
|
| 17 |
def extract_vapi_welspun_items(pdf_lines, pdf_text=""):
|
| 18 |
parsed_items = []
|
| 19 |
-
box_commodities =
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
with pdfplumber.open(BytesIO(cached_bytes)) as pdf:
|
| 25 |
-
for page in pdf.pages:
|
| 26 |
-
tables = page.extract_tables()
|
| 27 |
-
for table in tables:
|
| 28 |
-
for row in table:
|
| 29 |
-
if row and len(row) >= 5:
|
| 30 |
-
clean_cells = [str(cell).strip() for cell in row if cell is not None and str(cell).strip() != ""]
|
| 31 |
-
if not clean_cells:
|
| 32 |
-
continue
|
| 33 |
-
|
| 34 |
-
hs_code = ""
|
| 35 |
-
hs_index = -1
|
| 36 |
-
for idx, cell in enumerate(clean_cells):
|
| 37 |
-
if re.fullmatch(r'\d{8}', cell.replace(",", "").strip()):
|
| 38 |
-
hs_code = cell.replace(",", "").strip()
|
| 39 |
-
hs_index = idx
|
| 40 |
-
break
|
| 41 |
-
|
| 42 |
-
if not hs_code:
|
| 43 |
-
continue
|
| 44 |
-
|
| 45 |
-
dbk_sr = clean_cells[hs_index - 1] if hs_index > 0 else ""
|
| 46 |
-
|
| 47 |
-
# डायनेमिक डिस्क्रिप्शन
|
| 48 |
-
description_text = ""
|
| 49 |
-
if hs_index != -1 and len(clean_cells) > hs_index + 1:
|
| 50 |
-
desc_parts = []
|
| 51 |
-
for idx in range(hs_index + 1, len(clean_cells)):
|
| 52 |
-
cell_val = clean_cells[idx]
|
| 53 |
-
if re.fullmatch(r'\d+\.\d+', cell_val) or re.fullmatch(r'\d+\s*[xX]\s*\d+', cell_val):
|
| 54 |
-
break
|
| 55 |
-
if cell_val.isdigit() and int(cell_val) > 99 and len(desc_parts) > 0:
|
| 56 |
-
break
|
| 57 |
-
desc_parts.append(cell_val)
|
| 58 |
-
description_text = " ".join(desc_parts).strip()
|
| 59 |
-
|
| 60 |
-
if not description_text and hs_index > 0:
|
| 61 |
-
desc_candidates = [clean_cells[i] for i in range(0, hs_index) if not clean_cells[i].isdigit()]
|
| 62 |
-
description_text = " ".join(desc_candidates).strip()
|
| 63 |
-
|
| 64 |
-
# 🚀 फिक्स: SQMTR और Net Wt को उनके क्रम (Order) से सेट करना ताकि कभी इंटरचेंज न हों
|
| 65 |
-
net_wt, qty, rate, amount_usd, taxable_inr, igst_per, igst_amt, sqmtr = "", "", "", "", "", "", "", ""
|
| 66 |
-
|
| 67 |
-
if len(clean_cells) >= 4:
|
| 68 |
-
igst_amt = clean_cells[-1]
|
| 69 |
-
igst_per = clean_cells[-2]
|
| 70 |
-
taxable_inr = clean_cells[-3]
|
| 71 |
-
amount_usd = clean_cells[-4]
|
| 72 |
-
|
| 73 |
-
decimal_3_values = []
|
| 74 |
-
for cell in clean_cells:
|
| 75 |
-
clean_c = cell.replace(",", "").strip()
|
| 76 |
-
if re.fullmatch(r'\d+\.\d{3}', clean_c):
|
| 77 |
-
decimal_3_values.append(cell)
|
| 78 |
-
elif re.fullmatch(r'\d+\.\d{5}', clean_c):
|
| 79 |
-
if not rate:
|
| 80 |
-
rate = cell
|
| 81 |
-
elif clean_c.isdigit() and int(clean_c) > 0 and cell != hs_code and cell != dbk_sr:
|
| 82 |
-
if not qty:
|
| 83 |
-
qty = cell
|
| 84 |
-
|
| 85 |
-
# यदि एक से ज्यादा 3-डेसिमल वैल्यू हैं (जैसे SQMTR और Net Wt दोनों)
|
| 86 |
-
if len(decimal_3_values) >= 2:
|
| 87 |
-
sqmtr = decimal_3_values[0] # पहली वैल्यू SQMTR बनेगी
|
| 88 |
-
net_wt = decimal_3_values[1] # दूसरी वैल्यू हमेशा Net Wt बनेगी
|
| 89 |
-
elif len(decimal_3_values) == 1:
|
| 90 |
-
net_wt = decimal_3_values[0] # अगर सिर्फ एक है तो वह Net Wt होगी
|
| 91 |
-
|
| 92 |
-
item_dict = {f"col_{i}": (str(row[i]).strip() if i < len(row) and row[i] else "") for i in range(len(row))}
|
| 93 |
-
item_dict.update({
|
| 94 |
-
"dbk_sr": dbk_sr,
|
| 95 |
-
"hs_code": hs_code,
|
| 96 |
-
"description_text": description_text,
|
| 97 |
-
"net_wt": net_wt,
|
| 98 |
-
"qty": qty,
|
| 99 |
-
"rate": rate,
|
| 100 |
-
"amount_usd": amount_usd,
|
| 101 |
-
"amount_inr": taxable_inr,
|
| 102 |
-
"igst_per": igst_per if igst_per else "5.00",
|
| 103 |
-
"igst_amt": igst_amt,
|
| 104 |
-
"sqmtr": sqmtr,
|
| 105 |
-
"box_commodities": box_commodities
|
| 106 |
-
})
|
| 107 |
-
parsed_items.append(item_dict)
|
| 108 |
-
except Exception as e:
|
| 109 |
-
st.error(f"Pattern Parser Error: {str(e)}")
|
| 110 |
-
|
| 111 |
-
if not parsed_items:
|
| 112 |
-
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": []})
|
| 113 |
-
|
| 114 |
return parsed_items
|
| 115 |
|
| 116 |
|
|
@@ -130,7 +39,6 @@ def map_vapi_welspun_items_to_excel_dynamic(ws, parsed_items, item_rules, inv_sr
|
|
| 130 |
v_column_value = "LUT" if matched_lut else ("P" if matched_paid else "LUT")
|
| 131 |
|
| 132 |
max_rows = len(parsed_items)
|
| 133 |
-
|
| 134 |
first_item = parsed_items[0] if parsed_items else {}
|
| 135 |
all_comms = first_item.get("box_commodities", [])
|
| 136 |
|
|
@@ -163,8 +71,7 @@ def map_vapi_welspun_items_to_excel_dynamic(ws, parsed_items, item_rules, inv_sr
|
|
| 163 |
continue
|
| 164 |
|
| 165 |
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"]:
|
| 166 |
-
|
| 167 |
-
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "📦 Extract Inside Box (डब्बे के अंदर का टेक्स्ट)", "Exact Word", "", "None", field_label=field_name, pdf_bytes=cached_bytes)
|
| 168 |
if not extracted_val or not extracted_val.strip():
|
| 169 |
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "Right (आगे)", "Exact Word", "", "None", field_label=field_name)
|
| 170 |
|
|
@@ -239,4 +146,4 @@ def map_vapi_welspun_items_to_excel_dynamic(ws, parsed_items, item_rules, inv_sr
|
|
| 239 |
curr_row += 1
|
| 240 |
overall_sr += 1
|
| 241 |
|
| 242 |
-
return ws, overall_sr, curr_row
|
|
|
|
| 1 |
import re
|
|
|
|
| 2 |
import pdfplumber
|
| 3 |
from io import BytesIO
|
| 4 |
from openpyxl.styles import Alignment
|
|
|
|
| 15 |
|
| 16 |
def extract_vapi_welspun_items(pdf_lines, pdf_text=""):
|
| 17 |
parsed_items = []
|
| 18 |
+
box_commodities = []
|
| 19 |
+
if pdf_text:
|
| 20 |
+
box_commodities = extract_all_commodities_from_text(pdf_text)
|
| 21 |
+
|
| 22 |
+
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})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
return parsed_items
|
| 24 |
|
| 25 |
|
|
|
|
| 39 |
v_column_value = "LUT" if matched_lut else ("P" if matched_paid else "LUT")
|
| 40 |
|
| 41 |
max_rows = len(parsed_items)
|
|
|
|
| 42 |
first_item = parsed_items[0] if parsed_items else {}
|
| 43 |
all_comms = first_item.get("box_commodities", [])
|
| 44 |
|
|
|
|
| 71 |
continue
|
| 72 |
|
| 73 |
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"]:
|
| 74 |
+
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "📦 Extract Inside Box (डब्बे के अंदर का टेक्स्ट)", "Exact Word", "", "None", field_label=field_name)
|
|
|
|
| 75 |
if not extracted_val or not extracted_val.strip():
|
| 76 |
extracted_val = extract_header_value(pdf_lines, pdf_text, rule_val, "Right (आगे)", "Exact Word", "", "None", field_label=field_name)
|
| 77 |
|
|
|
|
| 146 |
curr_row += 1
|
| 147 |
overall_sr += 1
|
| 148 |
|
| 149 |
+
return ws, overall_sr, curr_row
|