updates on the profitability page updates on the rider kms and actual kms
This commit is contained in:
@@ -23,7 +23,6 @@ import {
|
|||||||
MdMyLocation,
|
MdMyLocation,
|
||||||
MdCalendarMonth,
|
MdCalendarMonth,
|
||||||
MdPerson,
|
MdPerson,
|
||||||
MdOutlineLocalShipping,
|
|
||||||
MdOutlineCurrencyRupee,
|
MdOutlineCurrencyRupee,
|
||||||
MdStraighten,
|
MdStraighten,
|
||||||
MdPayments,
|
MdPayments,
|
||||||
@@ -281,26 +280,32 @@ export default function ProfitabilityReport() {
|
|||||||
// Calculate profitability metrics for all riders
|
// Calculate profitability metrics for all riders
|
||||||
const stats = useMemo(() => {
|
const stats = useMemo(() => {
|
||||||
let activeRiders = 0;
|
let activeRiders = 0;
|
||||||
let totalOrders = 0;
|
|
||||||
let totalRevenue = 0;
|
|
||||||
let totalCost = 0;
|
|
||||||
let profitableRiders = 0;
|
let profitableRiders = 0;
|
||||||
let lossRiders = 0;
|
let lossRiders = 0;
|
||||||
let totalKms = 0;
|
let totalKms = 0;
|
||||||
|
let totalPlannedKms = 0;
|
||||||
|
let totalActualKms = 0;
|
||||||
|
|
||||||
const list = ridersList
|
const list = ridersList
|
||||||
.map((r) => {
|
.map((r) => {
|
||||||
let rRevenue = 0;
|
let rRevenue = 0;
|
||||||
let rKms = 0;
|
let rKms = 0;
|
||||||
|
let rPlannedKms = 0;
|
||||||
|
let rActualKms = 0;
|
||||||
const slotsByDate = {};
|
const slotsByDate = {};
|
||||||
let ordersInSlots = 0;
|
let ordersInSlots = 0;
|
||||||
|
|
||||||
r.orders.forEach((o) => {
|
r.orders.forEach((o) => {
|
||||||
|
const status = String(o.orderstatus || '').toLowerCase();
|
||||||
|
if (status === 'cancelled' || status === 'skipped') return;
|
||||||
|
|
||||||
const slot = getRowBatch(o, customBatches);
|
const slot = getRowBatch(o, customBatches);
|
||||||
if (!slot) return;
|
if (!slot) return;
|
||||||
|
|
||||||
const oKms = parseFloat(o.riderkms || 0);
|
const oKms = parseFloat(o.riderkms || 0);
|
||||||
rKms += oKms;
|
rKms += oKms;
|
||||||
|
rPlannedKms += parseFloat(o.kms || 0);
|
||||||
|
rActualKms += parseFloat(o.actualkms || 0);
|
||||||
rRevenue += oKms <= 8 ? 30 : 30 + (oKms - 8) * 6;
|
rRevenue += oKms <= 8 ? 30 : 30 + (oKms - 8) * 6;
|
||||||
|
|
||||||
const dateStr = o.assigntime
|
const dateStr = o.assigntime
|
||||||
@@ -339,15 +344,17 @@ export default function ProfitabilityReport() {
|
|||||||
lossRiders++;
|
lossRiders++;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalOrders += ordersInSlots;
|
|
||||||
totalRevenue += rRevenue;
|
|
||||||
totalCost += rTotalCost;
|
|
||||||
totalKms += rKms;
|
totalKms += rKms;
|
||||||
|
totalPlannedKms += rPlannedKms;
|
||||||
|
totalActualKms += rActualKms;
|
||||||
activeRiders++;
|
activeRiders++;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...r,
|
...r,
|
||||||
|
orderCount: ordersInSlots,
|
||||||
kms: rKms,
|
kms: rKms,
|
||||||
|
plannedKms: rPlannedKms,
|
||||||
|
actualKms: rActualKms,
|
||||||
revenue: rRevenue,
|
revenue: rRevenue,
|
||||||
varCost: rVarCost,
|
varCost: rVarCost,
|
||||||
fixedCost: rFixedCost,
|
fixedCost: rFixedCost,
|
||||||
@@ -358,19 +365,13 @@ export default function ProfitabilityReport() {
|
|||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
const totalNet = totalRevenue - totalCost;
|
|
||||||
const totalMargin = totalRevenue > 0 ? (totalNet / totalRevenue) * 100 : 0;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeRiders,
|
activeRiders,
|
||||||
totalOrders,
|
|
||||||
totalRevenue,
|
|
||||||
totalCost,
|
|
||||||
totalNet,
|
|
||||||
totalMargin,
|
|
||||||
profitableRiders,
|
profitableRiders,
|
||||||
lossRiders,
|
lossRiders,
|
||||||
totalKms,
|
totalKms,
|
||||||
|
totalPlannedKms,
|
||||||
|
totalActualKms,
|
||||||
enrichedRiders: list
|
enrichedRiders: list
|
||||||
};
|
};
|
||||||
}, [ridersList, customBatches]);
|
}, [ridersList, customBatches]);
|
||||||
@@ -396,38 +397,36 @@ export default function ProfitabilityReport() {
|
|||||||
detail: `${stats?.profitableRiders ?? 0} in profit · ${stats?.lossRiders ?? 0} at loss`
|
detail: `${stats?.profitableRiders ?? 0} in profit · ${stats?.lossRiders ?? 0} at loss`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'kms',
|
key: 'planned-kms',
|
||||||
|
label: 'Planned KMs',
|
||||||
|
color: '#0ea5e9',
|
||||||
|
icon: MdRoute,
|
||||||
|
value: `${(stats?.totalPlannedKms ?? 0).toFixed(1)} km`,
|
||||||
|
detail: 'Solver-planned distance'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'rider-kms',
|
||||||
|
label: 'Rider KMs',
|
||||||
|
color: BRAND,
|
||||||
|
icon: MdStraighten,
|
||||||
|
value: `${(stats?.totalKms ?? 0).toFixed(1)} km`,
|
||||||
|
detail: 'Billed to riders'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'actual-kms',
|
||||||
|
label: 'Actual KMs',
|
||||||
|
color: '#f59e0b',
|
||||||
|
icon: MdMyLocation,
|
||||||
|
value: `${(stats?.totalActualKms ?? 0).toFixed(1)} km`,
|
||||||
|
detail: 'GPS-tracked distance'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'total-distance',
|
||||||
label: 'Total Distance',
|
label: 'Total Distance',
|
||||||
color: '#10b981',
|
color: '#10b981',
|
||||||
icon: MdStraighten,
|
icon: MdStraighten,
|
||||||
value: `${(stats?.totalKms ?? 0).toFixed(1)} km`,
|
value: `${(stats?.totalKms ?? 0).toFixed(1)} km`,
|
||||||
detail: 'Cumulative travel distance'
|
detail: 'Cumulative travel distance'
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'revenue',
|
|
||||||
label: 'Slot Revenue',
|
|
||||||
color: '#0ea5e9',
|
|
||||||
icon: MdOutlineLocalShipping,
|
|
||||||
value: formatNumberToRupees(stats?.totalRevenue ?? 0),
|
|
||||||
detail: `From ${stats?.totalOrders ?? 0} orders`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'cost',
|
|
||||||
label: 'Slot Cost',
|
|
||||||
color: '#f59e0b',
|
|
||||||
icon: MdPayments,
|
|
||||||
value: formatNumberToRupees(stats?.totalCost ?? 0),
|
|
||||||
detail: 'Fixed + variable'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'net',
|
|
||||||
label: 'Slot Net',
|
|
||||||
color: (stats?.totalNet ?? 0) >= 0 ? '#10b981' : '#ef4444',
|
|
||||||
icon: (stats?.totalNet ?? 0) >= 0 ? MdTrendingUp : MdTrendingDown,
|
|
||||||
value: `${(stats?.totalNet ?? 0) >= 0 ? '+' : ''}${formatNumberToRupees(stats?.totalNet ?? 0)}`,
|
|
||||||
detail: `${(stats?.totalRevenue ?? 0) > 0 ? ((stats?.totalNet ?? 0) / (stats?.totalRevenue ?? 1) >= 0 ? '+' : '') : ''}${(
|
|
||||||
stats?.totalMargin ?? 0
|
|
||||||
).toFixed(0)}% margin`
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -610,8 +609,8 @@ export default function ProfitabilityReport() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<MobileFieldGrid columns={2}>
|
<MobileFieldGrid columns={2}>
|
||||||
<MobileField label="Orders" value={row.orders.length} />
|
<MobileField label="Orders" value={row.orderCount} />
|
||||||
<MobileField label="Rider KMs" value={`${row.kms.toFixed(2)} km`} />
|
<MobileField label="Rider KMs" value={`${Math.round(row.kms)} km`} />
|
||||||
<MobileField label="Revenue" value={formatNumberToRupees(row.revenue)} />
|
<MobileField label="Revenue" value={formatNumberToRupees(row.revenue)} />
|
||||||
<MobileField label="Fixed Cost" value={formatNumberToRupees(row.fixedCost)} />
|
<MobileField label="Fixed Cost" value={formatNumberToRupees(row.fixedCost)} />
|
||||||
<MobileField label="Variable Cost" value={formatNumberToRupees(row.varCost)} />
|
<MobileField label="Variable Cost" value={formatNumberToRupees(row.varCost)} />
|
||||||
@@ -720,11 +719,11 @@ export default function ProfitabilityReport() {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<Typography variant="body2" sx={{ fontWeight: 700, color: DT.textPrimary }}>
|
<Typography variant="body2" sx={{ fontWeight: 700, color: DT.textPrimary }}>
|
||||||
{row.orders.length}
|
{row.orderCount}
|
||||||
</Typography>
|
</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<MetricPill color="#10b981" icon={<MdStraighten size={11} />} label={`${row.kms.toFixed(2)} km`} tooltip="KMS" />
|
<MetricPill color="#10b981" icon={<MdStraighten size={11} />} label={`${Math.round(row.kms)} km`} tooltip="KMS" />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<MetricPill
|
<MetricPill
|
||||||
|
|||||||
Reference in New Issue
Block a user