updateson the profitability page
This commit is contained in:
@@ -4327,7 +4327,7 @@ const Dispatch = ({
|
|||||||
<div className="rd-stat rd-stat-distance">
|
<div className="rd-stat rd-stat-distance">
|
||||||
<div className="rd-stat-icon"><MdStraighten /></div>
|
<div className="rd-stat-icon"><MdStraighten /></div>
|
||||||
<div className="rd-stat-value">{riderKm.toFixed(1)}<span className="rd-stat-unit">km</span></div>
|
<div className="rd-stat-value">{riderKm.toFixed(1)}<span className="rd-stat-unit">km</span></div>
|
||||||
<div className="rd-stat-label">Rider KMs</div>
|
<div className="rd-stat-label">Trip KMs</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ function getStatusConfig(raw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function orderRevenue(order) {
|
function orderRevenue(order) {
|
||||||
const km = parseFloat(order.kms || order.actualkms || 0);
|
const km = parseFloat(order.riderkms || 0);
|
||||||
return km <= BASE_KM_LIMIT ? BASE_REVENUE : BASE_REVENUE + (km - BASE_KM_LIMIT) * EXTRA_RATE_KM;
|
return km <= BASE_KM_LIMIT ? BASE_REVENUE : BASE_REVENUE + (km - BASE_KM_LIMIT) * EXTRA_RATE_KM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ function calcRiderMetrics(rider, selectedDate, batches) {
|
|||||||
|
|
||||||
for (const o of orders) {
|
for (const o of orders) {
|
||||||
revenue += orderRevenue(o);
|
revenue += orderRevenue(o);
|
||||||
kms += parseFloat(o.kms || o.actualkms || 0);
|
kms += parseFloat(o.riderkms || 0);
|
||||||
|
|
||||||
const slot = getRowBatch(o, batches);
|
const slot = getRowBatch(o, batches);
|
||||||
if (!slot) continue;
|
if (!slot) continue;
|
||||||
@@ -125,6 +125,15 @@ function calcRiderMetrics(rider, selectedDate, batches) {
|
|||||||
return { revenue, kms, varCost, fixedCost, totalCost, net, margin, orders };
|
return { revenue, kms, varCost, fixedCost, totalCost, net, margin, orders };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Format a km value, switching to metres below 1 km so short hops don't round to "0.0 km". */
|
||||||
|
function formatDistance(km) {
|
||||||
|
const value = Number.isFinite(km) ? km : 0;
|
||||||
|
if (value > 0 && value < 1) {
|
||||||
|
return { value: String(Math.round(value * 1000)), unit: 'm' };
|
||||||
|
}
|
||||||
|
return { value: value.toFixed(1), unit: 'km' };
|
||||||
|
}
|
||||||
|
|
||||||
function rupees(v, decimals = 0) {
|
function rupees(v, decimals = 0) {
|
||||||
if (v == null) return '—';
|
if (v == null) return '—';
|
||||||
return `₹${parseFloat(v).toFixed(decimals)}`;
|
return `₹${parseFloat(v).toFixed(decimals)}`;
|
||||||
@@ -202,7 +211,9 @@ function OrdersBreakdownTable({ orders, getRevenue }) {
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Customer</th>
|
<th scope="col">Customer</th>
|
||||||
<th scope="col">Status</th>
|
<th scope="col">Status</th>
|
||||||
<th scope="col">Distance</th>
|
<th scope="col">Planned KMs</th>
|
||||||
|
<th scope="col">Actual KMs</th>
|
||||||
|
<th scope="col">Trip KMs</th>
|
||||||
<th scope="col" style={{ textAlign: 'right' }}>
|
<th scope="col" style={{ textAlign: 'right' }}>
|
||||||
Revenue
|
Revenue
|
||||||
</th>
|
</th>
|
||||||
@@ -210,7 +221,10 @@ function OrdersBreakdownTable({ orders, getRevenue }) {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{orders.map((order, idx) => {
|
{orders.map((order, idx) => {
|
||||||
const km = parseFloat(order.kms ?? order.actualkms ?? 0);
|
const km = parseFloat(order.riderkms ?? 0);
|
||||||
|
const dist = formatDistance(km);
|
||||||
|
const plannedDist = formatDistance(parseFloat(order.kms ?? 0));
|
||||||
|
const actualDist = formatDistance(parseFloat(order.actualkms ?? 0));
|
||||||
const rev = getRevenue(order);
|
const rev = getRevenue(order);
|
||||||
return (
|
return (
|
||||||
<tr key={`${order.orderid ?? 'order'}-${idx}`}>
|
<tr key={`${order.orderid ?? 'order'}-${idx}`}>
|
||||||
@@ -221,8 +235,16 @@ function OrdersBreakdownTable({ orders, getRevenue }) {
|
|||||||
<OrderStatusPill status={order.orderstatus ?? order.status} />
|
<OrderStatusPill status={order.orderstatus ?? order.status} />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span className="distance-value">{km.toFixed(1)}</span>
|
<span className="distance-value">{plannedDist.value}</span>
|
||||||
<span className="distance-unit">km</span>
|
<span className="distance-unit">{plannedDist.unit}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span className="distance-value">{actualDist.value}</span>
|
||||||
|
<span className="distance-unit">{actualDist.unit}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span className="distance-value">{dist.value}</span>
|
||||||
|
<span className="distance-unit">{dist.unit}</span>
|
||||||
</td>
|
</td>
|
||||||
<td style={{ textAlign: 'right' }}>
|
<td style={{ textAlign: 'right' }}>
|
||||||
<span className="revenue-amount">{rupees(rev)}</span>
|
<span className="revenue-amount">{rupees(rev)}</span>
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ export default function ProfitabilityReport() {
|
|||||||
const slot = getRowBatch(o, customBatches);
|
const slot = getRowBatch(o, customBatches);
|
||||||
if (!slot) return;
|
if (!slot) return;
|
||||||
|
|
||||||
const oKms = parseFloat(o.kms || o.actualkms || 0);
|
const oKms = parseFloat(o.riderkms || 0);
|
||||||
rKms += oKms;
|
rKms += oKms;
|
||||||
rRevenue += oKms <= 8 ? 30 : 30 + (oKms - 8) * 6;
|
rRevenue += oKms <= 8 ? 30 : 30 + (oKms - 8) * 6;
|
||||||
|
|
||||||
@@ -611,7 +611,7 @@ export default function ProfitabilityReport() {
|
|||||||
>
|
>
|
||||||
<MobileFieldGrid columns={2}>
|
<MobileFieldGrid columns={2}>
|
||||||
<MobileField label="Orders" value={row.orders.length} />
|
<MobileField label="Orders" value={row.orders.length} />
|
||||||
<MobileField label="Distance" value={`${row.kms.toFixed(2)} km`} />
|
<MobileField label="Rider KMs" value={`${row.kms.toFixed(2)} 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)} />
|
||||||
@@ -658,7 +658,7 @@ export default function ProfitabilityReport() {
|
|||||||
<TableCell>#</TableCell>
|
<TableCell>#</TableCell>
|
||||||
<TableCell>Rider</TableCell>
|
<TableCell>Rider</TableCell>
|
||||||
<TableCell align="center">Orders</TableCell>
|
<TableCell align="center">Orders</TableCell>
|
||||||
<TableCell align="center">Distance</TableCell>
|
<TableCell align="center">Rider KMs</TableCell>
|
||||||
<TableCell align="center">Revenue</TableCell>
|
<TableCell align="center">Revenue</TableCell>
|
||||||
<TableCell align="center">Fixed Cost</TableCell>
|
<TableCell align="center">Fixed Cost</TableCell>
|
||||||
<TableCell align="center">Variable Cost</TableCell>
|
<TableCell align="center">Variable Cost</TableCell>
|
||||||
|
|||||||
Reference in New Issue
Block a user