freightdesk/webapp/src/lib/india.js
FreightDesk 1a4eaaa040 Initial commit: FreightDesk v1.0
- Express + EJS server-rendered app
- Supabase PostgreSQL database
- Auth: username/password with bcrypt
- Dashboard with business stats
- Load CRUD with filters
- WhatsApp message parser
- Payment tracking
- Shipper & vehicle management
- Reports (monthly, top shippers, routes)
- Government-app aesthetic (tricolor theme)
- Dark mode support
- Docker + Coolify deployment ready
- Seed data from existing business ledger (88 loads, 41 shippers, 70 vehicles)
2026-06-07 18:57:24 +00:00

92 lines
2.9 KiB
JavaScript

// India-specific utilities for FreightDesk
const STATES = {
KL:'Kerala',TN:'Tamil Nadu',KA:'Karnataka',AP:'Andhra Pradesh',TS:'Telangana',
MH:'Maharashtra',GJ:'Gujarat',RJ:'Rajasthan',UP:'Uttar Pradesh',DL:'Delhi',
HR:'Haryana',PB:'Punjab',WB:'West Bengal',MP:'Madhya Pradesh',GA:'Goa',
};
function formatINR(n) {
if (n === null || n === undefined || isNaN(n)) return '—';
return '₹' + parseFloat(n).toLocaleString('en-IN');
}
function formatINRShort(n) {
if (n === null || n === undefined || isNaN(n)) return '—';
const num = parseFloat(n);
if (num >= 100000) return '₹' + (num / 100000).toFixed(1) + 'L';
if (num >= 1000) return '₹' + (num / 1000).toFixed(1) + 'K';
return '₹' + num.toLocaleString('en-IN');
}
function formatDate(dateStr) {
if (!dateStr) return '—';
const d = new Date(dateStr);
if (isNaN(d.getTime())) return dateStr;
return d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' });
}
function formatDateShort(dateStr) {
if (!dateStr) return '—';
const d = new Date(dateStr);
if (isNaN(d.getTime())) return dateStr;
return d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short' });
}
function validateVehicleNumber(number) {
if (!number) return { valid: false };
const cleaned = number.replace(/[\s\-\.]/g, '').toUpperCase();
if (!/^[A-Z]{2}\d{1,2}[A-Z]{1,3}\d{4}$/.test(cleaned)) return { valid: false };
const sc = cleaned.substring(0, 2);
return {
valid: true,
state_code: sc,
state_name: STATES[sc] || 'Unknown',
formatted: `${cleaned.substring(0,2)} ${cleaned.substring(2,4)} ${cleaned.substring(4,cleaned.length-4)} ${cleaned.slice(-4)}`,
};
}
function getStatusColor(status) {
const colors = {
'settled': 'green',
'completed': 'green',
'commission received': 'green',
'reconciled': 'green',
'handled directly by shipper': 'green',
'loaded / in transit': 'blue',
'assigned': 'blue',
'assigned vehicle': 'blue',
'pending collection': 'orange',
'partially pending': 'orange',
'fully pending from shipper': 'orange',
'delivered / pending collection': 'orange',
'commission due': 'orange',
'pending lead': 'gray',
'partial': 'gray',
'available vehicle': 'gray',
'commission adjusted': 'purple',
'cancelled': 'red',
};
return colors[status] || 'gray';
}
function calcCommission(freight, paidToDriver) {
if (!freight || !paidToDriver) return null;
return freight - paidToDriver;
}
function calcPendingFromShipper(freight, advance) {
if (!freight) return null;
return freight - (advance || 0);
}
function calcPendingToDriver(driverFreight, paid) {
if (!driverFreight) return null;
return driverFreight - (paid || 0);
}
module.exports = {
STATES, formatINR, formatINRShort, formatDate, formatDateShort,
validateVehicleNumber, getStatusColor,
calcCommission, calcPendingFromShipper, calcPendingToDriver,
};