- /fedex: batch create, document upload/replace/delete, save shipment, imported list
- /api/orders, /api/invoices, /api/pb-file, /api/pb/refresh-token, /api/stock-codes
- /api/payments/bundle: generate + download-all remittance bundles
- shared app/components/DocCell.tsx and app/lib/{invoice-docs,pb-fetch,pb-token}.ts
- recon: invoice reconciliation reports and PowerShell fix-plan scripts
- .gitignore: exclude one-off scripts/_* debugging artefacts, recon/pdfs+txts, data backups
60 lines
No EOL
1.9 KiB
Python
60 lines
No EOL
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Categorize the recon CSV into clear buckets and write a human-readable summary."""
|
|
import csv, json
|
|
from pathlib import Path
|
|
|
|
RECON = Path(__file__).parent
|
|
src = RECON / 'recon_report.csv'
|
|
|
|
rows = []
|
|
with open(src, encoding='utf-8-sig') as f:
|
|
rows = list(csv.DictReader(f))
|
|
|
|
IMAGE_PDFS = {'149943','157610','157611','157925','157926','158876','162154','165709'}
|
|
|
|
buckets = {
|
|
'OK': [],
|
|
'MISSING_LINE_IN_DB': [],
|
|
'DUPLICATE_LINE_RECORDS': [],
|
|
'IMAGE_PDF_NEEDS_OCR': [],
|
|
'NO_PDF_ATTACHED': [],
|
|
'OTHER': [],
|
|
}
|
|
|
|
for r in rows:
|
|
inv = r['invoice_no']
|
|
notes = r['notes']
|
|
pdf_status = r['pdf_status']
|
|
pdf_lc = int(r['pdf_line_count']) if r['pdf_line_count'] else 0
|
|
db_lc = int(r['db_distinct_lines'])
|
|
db_rec = int(r['db_line_records'])
|
|
sum_net = float(r['db_sum_net_lines'].replace(',', '.'))
|
|
pdf_net = float(r['pdf_total_net']) if r['pdf_total_net'] else None
|
|
|
|
if pdf_status == 'no-pdf':
|
|
buckets['NO_PDF_ATTACHED'].append(r); continue
|
|
if inv in IMAGE_PDFS:
|
|
buckets['IMAGE_PDF_NEEDS_OCR'].append(r); continue
|
|
if not notes:
|
|
buckets['OK'].append(r); continue
|
|
# Bucket the rest
|
|
if 'LINE_COUNT' in notes and 'pdf=' in notes:
|
|
buckets['MISSING_LINE_IN_DB'].append(r)
|
|
elif 'SUM_LINE_NETS' in notes:
|
|
buckets['DUPLICATE_LINE_RECORDS'].append(r)
|
|
else:
|
|
buckets['OTHER'].append(r)
|
|
|
|
# Print summary
|
|
print(f"Total invoices recon'd: {len(rows)}")
|
|
print()
|
|
for name, lst in buckets.items():
|
|
print(f"== {name} ({len(lst)}) ==")
|
|
for r in lst:
|
|
print(f" {r['invoice_no']:8} {r['document_type']:8} "
|
|
f"db_total_net={r['db_total_net']:>10} "
|
|
f"db_distinct_lines={r['db_distinct_lines']:>3} "
|
|
f"db_records={r['db_line_records']:>3} "
|
|
f"pdf_lines={r['pdf_line_count']:>3} "
|
|
f"notes={r['notes']}")
|
|
print() |