mirror of
http://forgejo-oa09toasww4dgii9cj3gpzda.187.127.164.61.sslip.io/iamcoolvivek007/data.git
synced 2026-06-11 00:06:51 +00:00
108 lines
4.6 KiB
Python
Executable file
108 lines
4.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""Append a new freight record and regenerate CSV/summary outputs.
|
|
|
|
Usage:
|
|
python3 append_load.py new_record.json
|
|
|
|
The input JSON should be a single record object with fields matching the ledger schema.
|
|
"""
|
|
import csv
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
LEDGER_PATH = ROOT / 'truck_freight_ledger.json'
|
|
CSV_PATH = ROOT / 'truck_freight_ledger.csv'
|
|
SUMMARY_PATH = ROOT / 'truck_freight_summary.md'
|
|
|
|
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 join_list(v):
|
|
if v is None:
|
|
return ''
|
|
if isinstance(v, list):
|
|
return ' | '.join(str(x) for x in v)
|
|
return str(v)
|
|
|
|
|
|
def load_ledger():
|
|
return json.loads(LEDGER_PATH.read_text())
|
|
|
|
|
|
def write_csv(records):
|
|
with CSV_PATH.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'] = join_list(r.get('via'))
|
|
row['deliveries'] = join_list(r.get('deliveries'))
|
|
writer.writerow(row)
|
|
|
|
|
|
def write_summary(records):
|
|
def total(key):
|
|
s = 0
|
|
for r in records:
|
|
v = r.get(key)
|
|
if isinstance(v, (int, float)):
|
|
s += v
|
|
return s
|
|
|
|
num_records = len(records)
|
|
settled = sum(1 for r in records if r.get('status') == 'settled')
|
|
pending_or_partial = sum(1 for r in records if 'pending' in (r.get('status') or '') or r.get('status') == 'partial')
|
|
|
|
lines = []
|
|
lines.append('# Truck Freight Ledger Summary')
|
|
lines.append('')
|
|
lines.append('Overview')
|
|
lines.append(f'- Records: {num_records}')
|
|
lines.append(f'- Settled loads: {settled}')
|
|
lines.append(f'- Pending/partial loads: {pending_or_partial}')
|
|
lines.append('')
|
|
lines.append('Totals')
|
|
lines.append(f'- Freight charged: {total("freight_charged")}')
|
|
lines.append(f'- Advance received: {total("advance_received")}')
|
|
lines.append(f'- Paid to driver: {total("paid_to_driver")}')
|
|
lines.append(f'- Commission: {total("commission")}')
|
|
lines.append(f'- Pending from shipper: {total("pending_from_shipper")}')
|
|
lines.append(f'- Pending to driver: {total("pending_to_driver")}')
|
|
lines.append('')
|
|
lines.append('Record snapshot')
|
|
lines.append('| Date | Vehicle | Shipper | Route | Freight | Advance | Paid driver | Commission | Pending shipper | Status |')
|
|
lines.append('|---|---|---|---|---:|---:|---:|---:|---:|---|')
|
|
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 {join_list(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_PATH.write_text('\n'.join(lines) + '\n')
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 2:
|
|
print('Usage: python3 append_load.py new_record.json', file=sys.stderr)
|
|
raise SystemExit(2)
|
|
new_record = json.loads(Path(sys.argv[1]).read_text())
|
|
ledger = load_ledger()
|
|
ledger.setdefault('records', []).append(new_record)
|
|
ledger['records'] = sorted(ledger['records'], key=lambda x: (x.get('date') or '', x.get('vehicle') or '', x.get('id') or ''))
|
|
LEDGER_PATH.write_text(json.dumps(ledger, indent=2, ensure_ascii=False) + '\n')
|
|
write_csv(ledger['records'])
|
|
write_summary(ledger['records'])
|
|
print(f"Appended record {new_record.get('id', '(no id)')} and regenerated CSV + summary.")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|