mirror of
http://forgejo-oa09toasww4dgii9cj3gpzda.187.127.164.61.sslip.io/iamcoolvivek007/data.git
synced 2026-06-11 00:06:51 +00:00
Add CSV export and summary files
This commit is contained in:
parent
1bcd969bdd
commit
ae37e3d550
4 changed files with 156 additions and 0 deletions
|
|
@ -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
108
append_load.py
Executable 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
13
truck_freight_ledger.csv
Normal 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."
|
||||||
|
30
truck_freight_summary.md
Normal file
30
truck_freight_summary.md
Normal 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 |
|
||||||
Loading…
Reference in a new issue