Add CSV export and summary files

This commit is contained in:
Hermes Agent 2026-05-17 20:14:49 +00:00
parent 1bcd969bdd
commit ae37e3d550
4 changed files with 156 additions and 0 deletions

View file

@ -4,6 +4,9 @@ This repository stores structured truck freight forwarding records for future an
Files Files
- truck_freight_ledger.json: canonical structured ledger - truck_freight_ledger.json: canonical structured ledger
- truck_freight_ledger.csv: spreadsheet-friendly export
- truck_freight_summary.md: quick human-readable summary
- append_load.py: helper to append a new record and regenerate exports
Schema notes Schema notes
- currency: currency code - currency: currency code
@ -26,3 +29,5 @@ Usage
- Append new loads as new records. - Append new loads as new records.
- Keep corrections in notes when the user updates details. - Keep corrections in notes when the user updates details.
- Use the JSON file for future AI analysis and profit/pending calculations. - Use the JSON file for future AI analysis and profit/pending calculations.
- Use append_load.py to add a new record and automatically regenerate the CSV and summary files.

108
append_load.py Executable file
View file

@ -0,0 +1,108 @@
#!/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()

13
truck_freight_ledger.csv Normal file
View file

@ -0,0 +1,13 @@
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
2026-05-17-jinu-coin-trivandrum-shabarimala-chennai,2026-05-17,partial,,Trivandrum,Shabarimala,Chennai,Jinu Coin,,,,,,,,,,,"User first said shipper was Minutes Coin, then corrected to Jinu Coin. No amounts were provided."
2026-05-17-ka04ag7476-drs-agarwal,2026-05-17,pending collection,KA04AG7476,Thiruvananthapuram,,Mysore,DRS Agarwal,Household,,,16500,14500,14000,0,,2000,0,User said DRS paid 14500 advance. User paid driver 10000 advance and 4000 balance. Later user clarified DRS was charged 16500 and 2000 is still due.
2026-05-17-ka04ag7476-krs-partload,2026-05-17,handled directly by shipper,KA04AG7476,Kollam,,Bangalore,KRS,,MG car battery,,11000,5000,,,,6000,0,KRS handled payment directly. Driver received 5000 advance from KRS and 6000 on delivery. User said this part-load does not create pending for them.
2026-05-17-hr38ac0945-agarwal-packers-movers,2026-05-17,pending collection,HR38AC0945,Trivandrum,,Chennai,Agarwal Packers and Movers,,,,19500,15000,15000,,,4500,0,Manager Vikas paid driver 15000 as advance. Balance of 4500 was pending.
2026-05-15-tn25ca9552-century-polymers,2026-05-15,commission received,TN25CA9552,Kollam,,Chennai,Century Polymers,,,Ambattur | Madhavaram,18000,,,1000,,,,Payment managed by Century Polymers. User received 1000 cash commission from driver.
2026-05-15-tn41dc5854-chips,2026-05-15,commission due,TN41DC5854,Thiruvananthapuram,,Palakkad,Chips,,,,11000,,,600,,,,User said commission due is 600.
2026-05-14-kl07bp2609-sahara-packers,2026-05-14,settled,KL07BP2609,Adoor,,Cochin,Sahara Packers,,,,7000,7000,6500,500,,0,0,"User clarified Sahara paid 7000 total, user paid 5500 advance and 1000 balance to truck, leaving 500 profit."
2026-05-14-ka06ba2739-agarwal,2026-05-14,fully pending from shipper,KA06BA2739,Thiruvananthapuram,,Hyderabad,Agarwal,,,,38000,0,33500,,,38000,4500,User said they did not receive any payment from Agarwal for this load. User paid driver 30000 and 3500.
2026-05-15-tn37bs7431-ambika-packers,2026-05-15,partially pending,TN37BS7431,Thiruvananthapuram,,Thrissur,Ambika Packers,,,,5500,5000,5000,500,,500,500,User said 500 will be their commission. There is also 500 still due from the shipper based on the numbers given.
2026-05-13-tn48bd4858-agarwal-packers-movers,2026-05-13,settled,TN48BD4858,Thiruvananthapuram,,Thirupathy,Agarwal Packers and Movers,,,,23000,23000,21700,1300,,0,0,"User later confirmed the pending 2000 was also paid, so the load is settled."
2026-05-17-ka63a7003-indian-cbe-shipper,2026-05-17,partially pending,KA63A7003,Thiruvananthapuram,,Coimbatore,Indian CBE Shipper,,,,7000,6500,5000,500,6000,500,500,"User said they received 6500 advance, paid 5000, and will charge the driver another 500 as commission."
2026-05-12-mh48dc1206-agarwal-packers-movers,2026-05-12,reconciled,MH48DC1206,Trivandrum,,Mumbai,Agarwal Packers and Movers,,,,41000,38000,40000,2000,,3000,0,"User first shared total 41000, advance 38000, balance 3000. Later clarified they received 38000, paid 20000 + 15000, and the driver freight was 40000 with 2000 commission."
1 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
2 2026-05-17-jinu-coin-trivandrum-shabarimala-chennai 2026-05-17 partial Trivandrum Shabarimala Chennai Jinu Coin User first said shipper was Minutes Coin, then corrected to Jinu Coin. No amounts were provided.
3 2026-05-17-ka04ag7476-drs-agarwal 2026-05-17 pending collection KA04AG7476 Thiruvananthapuram Mysore DRS Agarwal Household 16500 14500 14000 0 2000 0 User said DRS paid 14500 advance. User paid driver 10000 advance and 4000 balance. Later user clarified DRS was charged 16500 and 2000 is still due.
4 2026-05-17-ka04ag7476-krs-partload 2026-05-17 handled directly by shipper KA04AG7476 Kollam Bangalore KRS MG car battery 11000 5000 6000 0 KRS handled payment directly. Driver received 5000 advance from KRS and 6000 on delivery. User said this part-load does not create pending for them.
5 2026-05-17-hr38ac0945-agarwal-packers-movers 2026-05-17 pending collection HR38AC0945 Trivandrum Chennai Agarwal Packers and Movers 19500 15000 15000 4500 0 Manager Vikas paid driver 15000 as advance. Balance of 4500 was pending.
6 2026-05-15-tn25ca9552-century-polymers 2026-05-15 commission received TN25CA9552 Kollam Chennai Century Polymers Ambattur | Madhavaram 18000 1000 Payment managed by Century Polymers. User received 1000 cash commission from driver.
7 2026-05-15-tn41dc5854-chips 2026-05-15 commission due TN41DC5854 Thiruvananthapuram Palakkad Chips 11000 600 User said commission due is 600.
8 2026-05-14-kl07bp2609-sahara-packers 2026-05-14 settled KL07BP2609 Adoor Cochin Sahara Packers 7000 7000 6500 500 0 0 User clarified Sahara paid 7000 total, user paid 5500 advance and 1000 balance to truck, leaving 500 profit.
9 2026-05-14-ka06ba2739-agarwal 2026-05-14 fully pending from shipper KA06BA2739 Thiruvananthapuram Hyderabad Agarwal 38000 0 33500 38000 4500 User said they did not receive any payment from Agarwal for this load. User paid driver 30000 and 3500.
10 2026-05-15-tn37bs7431-ambika-packers 2026-05-15 partially pending TN37BS7431 Thiruvananthapuram Thrissur Ambika Packers 5500 5000 5000 500 500 500 User said 500 will be their commission. There is also 500 still due from the shipper based on the numbers given.
11 2026-05-13-tn48bd4858-agarwal-packers-movers 2026-05-13 settled TN48BD4858 Thiruvananthapuram Thirupathy Agarwal Packers and Movers 23000 23000 21700 1300 0 0 User later confirmed the pending 2000 was also paid, so the load is settled.
12 2026-05-17-ka63a7003-indian-cbe-shipper 2026-05-17 partially pending KA63A7003 Thiruvananthapuram Coimbatore Indian CBE Shipper 7000 6500 5000 500 6000 500 500 User said they received 6500 advance, paid 5000, and will charge the driver another 500 as commission.
13 2026-05-12-mh48dc1206-agarwal-packers-movers 2026-05-12 reconciled MH48DC1206 Trivandrum Mumbai Agarwal Packers and Movers 41000 38000 40000 2000 3000 0 User first shared total 41000, advance 38000, balance 3000. Later clarified they received 38000, paid 20000 + 15000, and the driver freight was 40000 with 2000 commission.

30
truck_freight_summary.md Normal file
View file

@ -0,0 +1,30 @@
# Truck Freight Ledger Summary
Overview
- Records: 12
- Settled loads: 2
- Pending/partial loads: 10
Totals
- Freight charged: 197500
- Advance received: 114000
- Paid to driver: 140700
- Commission: 6400
- Pending from shipper: 54500
- Pending to driver: 5500
Record snapshot
| Date | Vehicle | Shipper | Route | Freight | Advance | Paid driver | Commission | Pending shipper | Status |
|---|---|---|---|---:|---:|---:|---:|---:|---|
| 2026-05-12 | MH48DC1206 | Agarwal Packers and Movers | Trivandrum → Mumbai | 41000 | 38000 | 40000 | 2000 | 3000 | reconciled |
| 2026-05-13 | TN48BD4858 | Agarwal Packers and Movers | Thiruvananthapuram → Thirupathy | 23000 | 23000 | 21700 | 1300 | 0 | settled |
| 2026-05-14 | KA06BA2739 | Agarwal | Thiruvananthapuram → Hyderabad | 38000 | 0 | 33500 | - | 38000 | fully pending from shipper |
| 2026-05-14 | KL07BP2609 | Sahara Packers | Adoor → Cochin | 7000 | 7000 | 6500 | 500 | 0 | settled |
| 2026-05-15 | TN25CA9552 | Century Polymers | Kollam → Chennai | 18000 | - | - | 1000 | - | commission received |
| 2026-05-15 | TN37BS7431 | Ambika Packers | Thiruvananthapuram → Thrissur | 5500 | 5000 | 5000 | 500 | 500 | partially pending |
| 2026-05-15 | TN41DC5854 | Chips | Thiruvananthapuram → Palakkad | 11000 | - | - | 600 | - | commission due |
| 2026-05-17 | - | Jinu Coin | Trivandrum via Shabarimala → Chennai | - | - | - | - | - | partial |
| 2026-05-17 | HR38AC0945 | Agarwal Packers and Movers | Trivandrum → Chennai | 19500 | 15000 | 15000 | - | 4500 | pending collection |
| 2026-05-17 | KA04AG7476 | DRS Agarwal | Thiruvananthapuram → Mysore | 16500 | 14500 | 14000 | 0 | 2000 | pending collection |
| 2026-05-17 | KA04AG7476 | KRS | Kollam → Bangalore | 11000 | 5000 | - | - | 6000 | handled directly by shipper |
| 2026-05-17 | KA63A7003 | Indian CBE Shipper | Thiruvananthapuram → Coimbatore | 7000 | 6500 | 5000 | 500 | 500 | partially pending |