Files
Implementation_ITSA/Reference Data/python_project/scripts/update_estimated_bl_dates.py
AzureAD\SylvainDUVERNAY 32b13838f2 Commit
2026-03-28 17:11:52 +01:00

180 lines
6.5 KiB
Python

import sys
import csv
from pathlib import Path
# Add parent directory to Python path so we can import helpers
parent_dir = Path(__file__).parent.parent
sys.path.insert(0, str(parent_dir))
from helpers.config import get_db_connection
CSV_PATH = parent_dir / "loaders" / "Contract_Update.csv"
def check_contract_number_format(cur):
"""Show sample contract numbers from DB to confirm expected format."""
cur.execute("SELECT number FROM purchase_purchase ORDER BY id LIMIT 3")
pur_samples = [r[0] for r in cur.fetchall()]
cur.execute("SELECT number FROM sale_sale ORDER BY id LIMIT 3")
sale_samples = [r[0] for r in cur.fetchall()]
print(f" Sample purchase numbers : {pur_samples}")
print(f" Sample sale numbers : {sale_samples}")
print()
def update_estimated_bl_dates(dry_run=False):
conn = get_db_connection()
cur = conn.cursor()
print("=== Contract BL Date Update ===")
print(f"CSV : {CSV_PATH}")
print(f"Mode : {'DRY RUN (no changes will be saved)' if dry_run else 'LIVE UPDATE'}\n")
print("DB contract number format check:")
check_contract_number_format(cur)
# Read CSV
rows = []
with open(CSV_PATH, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
contract_type = row["ContractType"].strip().upper()
contract_number = row["ContractNumber"].strip()
bl_date = row["EstimatedBlDate"].strip()
if contract_type and contract_number and bl_date:
rows.append((contract_type, contract_number, bl_date))
print(f"Rows loaded from CSV: {len(rows)}\n")
updated_count = 0
skipped_count = 0
not_found_count = 0
for contract_type, contract_number, bl_date in rows:
if contract_type == "P":
# Resolve purchase_line IDs for this purchase number
# Try both raw number (e.g. "2086") and P- prefix (e.g. "P-2086")
cur.execute(
"""
SELECT pl.id
FROM purchase_line pl
JOIN purchase_purchase pp ON pp.id = pl.purchase
WHERE pp.number IN (%s, %s)
AND pl.type = 'line'
ORDER BY pl.id
""",
(contract_number, f"P-{contract_number}"),
)
line_ids = [r[0] for r in cur.fetchall()]
if not line_ids:
print(f" [NOT FOUND] Purchase {contract_number} — no matching purchase_line rows")
not_found_count += 1
continue
# Update pricing_estimated rows linked to those lines with trigger = bldate
cur.execute(
"""
UPDATE pricing_estimated
SET estimated_date = %s,
write_date = NOW(),
write_uid = 1
WHERE line = ANY(%s)
AND trigger = 'bldate'
RETURNING id, line, estimated_date
""",
(bl_date, line_ids),
)
updated_rows = cur.fetchall()
if updated_rows:
for pe_id, line_id, new_date in updated_rows:
print(
f" [{'DRY' if dry_run else 'OK '}] Purchase {contract_number}"
f" | purchase_line={line_id} | pricing_estimated.id={pe_id}"
f" | estimated_date -> {new_date}"
)
updated_count += len(updated_rows)
else:
print(
f" [SKIP] Purchase {contract_number} — lines {line_ids} found"
f" but no pricing_estimated row with trigger='bldate'"
)
skipped_count += 1
elif contract_type == "S":
# Resolve sale_line IDs for this sale number
# Try both raw number (e.g. "2086") and S- prefix (e.g. "S-2086")
cur.execute(
"""
SELECT sl.id
FROM sale_line sl
JOIN sale_sale ss ON ss.id = sl.sale
WHERE ss.number IN (%s, %s)
AND sl.type = 'line'
ORDER BY sl.id
""",
(contract_number, f"S-{contract_number}"),
)
line_ids = [r[0] for r in cur.fetchall()]
if not line_ids:
print(f" [NOT FOUND] Sale {contract_number} — no matching sale_line rows")
not_found_count += 1
continue
# Update pricing_estimated rows linked to those sale lines with trigger = bldate
cur.execute(
"""
UPDATE pricing_estimated
SET estimated_date = %s,
write_date = NOW(),
write_uid = 1
WHERE sale_line = ANY(%s)
AND trigger = 'bldate'
RETURNING id, sale_line, estimated_date
""",
(bl_date, line_ids),
)
updated_rows = cur.fetchall()
if updated_rows:
for pe_id, sale_line_id, new_date in updated_rows:
print(
f" [{'DRY' if dry_run else 'OK '}] Sale {contract_number}"
f" | sale_line={sale_line_id} | pricing_estimated.id={pe_id}"
f" | estimated_date -> {new_date}"
)
updated_count += len(updated_rows)
else:
print(
f" [SKIP] Sale {contract_number} — lines {line_ids} found"
f" but no pricing_estimated row with trigger='bldate'"
)
skipped_count += 1
else:
print(f" [WARN] Unknown ContractType '{contract_type}' for contract {contract_number} — skipped")
skipped_count += 1
print("\n--- Summary ---")
print(f" Updated : {updated_count} pricing_estimated rows")
print(f" Skipped : {skipped_count} contracts (no bldate row in pricing_estimated)")
print(f" Not found: {not_found_count} contracts (contract number not in DB)")
if dry_run:
conn.rollback()
print("\nDry run — all changes rolled back, nothing saved.")
else:
conn.commit()
print("\nAll changes committed to database.")
cur.close()
conn.close()
if __name__ == "__main__":
dry_run = "--dry-run" in sys.argv
update_estimated_bl_dates(dry_run=dry_run)