182 lines
6.2 KiB
Python
182 lines
6.2 KiB
Python
"""
|
|
Import Enquiry.xlsx data → generates enquiry_import.sql
|
|
Run locally, then copy the .sql file to the server and execute with:
|
|
psql -U admin -d logistics -p 5433 -f enquiry_import.sql
|
|
|
|
Usage:
|
|
python cmd/import_enquiry/import.py
|
|
"""
|
|
|
|
import openpyxl
|
|
import os
|
|
import sys
|
|
|
|
XLSX = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "Enquiry.xlsx")
|
|
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "enquiry_import.sql")
|
|
|
|
|
|
def esc(v):
|
|
"""Escape a value for SQL single-quote string."""
|
|
if v is None:
|
|
return "NULL"
|
|
s = str(v).strip()
|
|
if s.endswith(".0") and s[:-2].isdigit():
|
|
s = s[:-2] # strip Excel float suffix from phone numbers
|
|
s = s.replace("'", "''")
|
|
return f"'{s}'"
|
|
|
|
|
|
def clean(v):
|
|
if v is None:
|
|
return ""
|
|
s = str(v).strip()
|
|
if s.endswith(".0") and s[:-2].isdigit():
|
|
s = s[:-2]
|
|
return s
|
|
|
|
|
|
def build_branches(ws):
|
|
lines = []
|
|
current_company = None
|
|
count = 0
|
|
for row in ws.iter_rows(min_row=2, values_only=True):
|
|
if not any(v is not None for v in row):
|
|
continue
|
|
company = clean(row[6])
|
|
if company:
|
|
if company == "Company":
|
|
continue
|
|
current_company = company
|
|
if not current_company:
|
|
continue
|
|
|
|
area = esc(clean(row[7]))
|
|
phone = esc(clean(row[8]))
|
|
plus_code = esc(clean(row[9]))
|
|
address = esc(clean(row[10]))
|
|
rate = esc(clean(row[1]))
|
|
pickup = esc(clean(row[2]))
|
|
drop = esc(clean(row[3]))
|
|
days = esc(clean(row[4]))
|
|
packing = esc(clean(row[5]))
|
|
co = esc(current_company)
|
|
|
|
lines.append(
|
|
f"INSERT INTO competitor_branches "
|
|
f"(company,area,phone,plus_code,address,rate_per_kg,offers_pickup,offers_drop,time_in_days,packing_charge,created_at,updated_at) "
|
|
f"VALUES ({co},{area},{phone},{plus_code},{address},{rate},{pickup},{drop},{days},{packing},NOW(),NOW());"
|
|
)
|
|
count += 1
|
|
return lines, count
|
|
|
|
|
|
def build_pricing(ws):
|
|
lines = []
|
|
|
|
all_cells = {}
|
|
for row in ws.iter_rows():
|
|
for cell in row:
|
|
if cell.value is not None:
|
|
all_cells[(cell.row, cell.column)] = cell.value
|
|
|
|
company_row = {col: val for (r, col), val in all_cells.items() if r == 5}
|
|
header_row = {col: val for (r, col), val in all_cells.items() if r == 6}
|
|
company_cols = sorted(company_row.items())
|
|
|
|
ranges = []
|
|
for i, (col, name) in enumerate(company_cols):
|
|
end = company_cols[i + 1][0] - 1 if i + 1 < len(company_cols) else max(header_row.keys())
|
|
ranges.append((name, col, end))
|
|
|
|
geo_keywords = {"local", "city", "state", "metro", "national", "zonal",
|
|
"regional", "south", "rest", "inter", "remote", "kerala",
|
|
"karnataka", "priority", "surface", "air", "express",
|
|
"standard", "within", "nearby", "international"}
|
|
|
|
count = 0
|
|
for company, col_start, col_end in ranges:
|
|
sub_hdrs = {col: val for col, val in header_row.items()
|
|
if col_start <= col <= col_end}
|
|
if not sub_hdrs:
|
|
continue
|
|
|
|
cols_sorted = sorted(sub_hdrs.keys())
|
|
weight_col = cols_sorted[0]
|
|
zone_cols = cols_sorted[1:]
|
|
|
|
has_delivery_time = any("delivery time" in str(v).lower()
|
|
for v in sub_hdrs.values())
|
|
|
|
data_rows_by_row = {}
|
|
for (r, col), val in all_cells.items():
|
|
if r >= 7 and col_start <= col <= col_end:
|
|
data_rows_by_row.setdefault(r, {})[col] = val
|
|
|
|
for r in sorted(data_rows_by_row.keys()):
|
|
row_data = data_rows_by_row[r]
|
|
weight_slab = clean(row_data.get(weight_col, ""))
|
|
if not weight_slab:
|
|
continue
|
|
|
|
delivery_time = ""
|
|
zone_value_cols = zone_cols
|
|
|
|
if has_delivery_time and zone_cols:
|
|
delivery_time = clean(row_data.get(zone_cols[0], ""))
|
|
zone_value_cols = zone_cols[1:]
|
|
|
|
for zc in zone_value_cols:
|
|
zone_label = clean(sub_hdrs.get(zc, ""))
|
|
rate_val = clean(row_data.get(zc, ""))
|
|
if not rate_val:
|
|
continue
|
|
|
|
zone_words = set(zone_label.lower().split())
|
|
if geo_keywords & zone_words:
|
|
zone = zone_label
|
|
service_type = ""
|
|
else:
|
|
service_type = zone_label
|
|
zone = ""
|
|
|
|
lines.append(
|
|
f"INSERT INTO carrier_pricing "
|
|
f"(company,weight_slab,service_type,zone,rate,delivery_time,created_at,updated_at) "
|
|
f"VALUES ({esc(company)},{esc(weight_slab)},{esc(service_type)},{esc(zone)},{esc(rate_val)},{esc(delivery_time)},NOW(),NOW());"
|
|
)
|
|
count += 1
|
|
|
|
return lines, count
|
|
|
|
|
|
def main():
|
|
print(f"Reading {XLSX} …")
|
|
wb = openpyxl.load_workbook(XLSX)
|
|
|
|
branch_lines, b_count = build_branches(wb["Enquiry"])
|
|
pricing_lines, p_count = build_pricing(wb["Price per Kilometer"])
|
|
|
|
total = b_count + p_count
|
|
print(f" competitor_branches : {b_count} rows")
|
|
print(f" carrier_pricing : {p_count} rows")
|
|
print(f" total : {total} INSERT statements")
|
|
|
|
with open(OUT, "w", encoding="utf-8") as f:
|
|
f.write("-- Doormile Enquiry import — generated by import.py\n")
|
|
f.write("BEGIN;\n\n")
|
|
f.write("-- ── Sheet 1: Competitor Branches ───────────────────────────\n")
|
|
for line in branch_lines:
|
|
f.write(line + "\n")
|
|
f.write("\n-- ── Sheet 2: Carrier Pricing ──────────────────────────────\n")
|
|
for line in pricing_lines:
|
|
f.write(line + "\n")
|
|
f.write("\nCOMMIT;\n")
|
|
|
|
print(f"\nDone. Written to: {OUT}")
|
|
print("\nTo import on the server:")
|
|
print(" psql -U admin -d logistics -p 5433 -f enquiry_import.sql")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|