67 lines
3.3 KiB
Python
67 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Quick regen CSV + summary from ledger JSON, then git commit and push."""
|
|
import json, csv, subprocess
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
LEDGER = ROOT / 'truck_freight_ledger.json'
|
|
CSV = ROOT / 'truck_freight_ledger.csv'
|
|
SUMMARY = ROOT / 'truck_freight_summary.md'
|
|
|
|
ledger = json.loads(LEDGER.read_text())
|
|
records = ledger['records']
|
|
|
|
FIELDNAMES = ['id','date','status','vehicle','from','via','to','shipper','load_type','item','deliveries','freight_charged','advance_received','paid_to_driver','commission','driver_freight','pending_from_shipper','pending_to_driver','notes']
|
|
|
|
def jl(v):
|
|
if v is None: return ''
|
|
if isinstance(v, list): return ' | '.join(str(x) for x in v)
|
|
return str(v)
|
|
|
|
with CSV.open('w', newline='') as f:
|
|
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
|
|
writer.writeheader()
|
|
for r in records:
|
|
row = {k: '' for k in FIELDNAMES}
|
|
for k in ['id','date','status','vehicle','from','to','shipper','load_type','item','freight_charged','advance_received','paid_to_driver','commission','driver_freight','pending_from_shipper','pending_to_driver','notes']:
|
|
row[k] = r.get(k, '') if r.get(k, '') is not None else ''
|
|
row['via'] = jl(r.get('via'))
|
|
row['deliveries'] = jl(r.get('deliveries'))
|
|
writer.writerow(row)
|
|
|
|
def total(key):
|
|
return sum(r[key] for r in records if isinstance(r.get(key), (int, float)))
|
|
|
|
nr = len(records)
|
|
st = sum(1 for r in records if r.get('status') == 'settled')
|
|
|
|
lines = [
|
|
'# Truck Freight Ledger Summary', '',
|
|
'Overview',
|
|
f'- Records: {nr}',
|
|
f'- Settled loads: {st}',
|
|
'',
|
|
'Totals',
|
|
f'- Freight charged: {total("freight_charged")}',
|
|
f'- Advance received: {total("advance_received")}',
|
|
f'- Paid to driver: {total("paid_to_driver")}',
|
|
f'- Commission: {total("commission")}',
|
|
f'- Pending from shipper: {total("pending_from_shipper")}',
|
|
f'- Pending to driver: {total("pending_to_driver")}',
|
|
'',
|
|
'Record snapshot',
|
|
'| Date | Vehicle | Shipper | Route | Freight | Advance | Paid driver | Commission | Pending shipper | Status |',
|
|
'|---|---|---|---|---:|---:|---:|---:|---:|---|',
|
|
]
|
|
for r in sorted(records, key=lambda x: (x.get('date') or '', x.get('vehicle') or '', x.get('id') or '')):
|
|
route = ' → '.join([p for p in [r.get('from'), r.get('to')] if p])
|
|
if r.get('via'): route = f"{r.get('from')} via {jl(r.get('via'))} → {r.get('to')}"
|
|
lines.append(f"| {r.get('date','')} | {r.get('vehicle','') or '-'} | {r.get('shipper','') or '-'} | {route or '-'} | {r.get('freight_charged','') if r.get('freight_charged') is not None else '-'} | {r.get('advance_received','') if r.get('advance_received') is not None else '-'} | {r.get('paid_to_driver','') if r.get('paid_to_driver') is not None else '-'} | {r.get('commission','') if r.get('commission') is not None else '-'} | {r.get('pending_from_shipper','') if r.get('pending_from_shipper') is not None else '-'} | {r.get('status','') or '-'} |")
|
|
|
|
SUMMARY.write_text('\n'.join(lines) + '\n')
|
|
|
|
# Git commit and push
|
|
subprocess.run(['git', 'add', '-A'], check=True, cwd=ROOT)
|
|
subprocess.run(['git', 'commit', '-m', 'Regen CSV and summary'], check=True, cwd=ROOT)
|
|
subprocess.run(['git', 'push'], check=True, cwd=ROOT)
|
|
print(f'Done. Total records: {nr}')
|