Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion app/(logged-in)/org/[slug]/orders/components/orders-columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';

import { statusColors } from '../utils';
import { deliveryWindow, statusColors } from '../utils';

// Infer OrderWithDetails from tRPC router output
type RouterOutput = inferRouterOutputs<AppRouter>;
Expand Down Expand Up @@ -139,6 +139,15 @@ export function getOrderColumns(
),
cell: ({ row }) => formatDate(row.original.orderDate),
},
{
id: 'delivery',
header: () => <DataTableColumnHeader title="Delivery" />,
cell: ({ row }) => {
const window = deliveryWindow(row.original.status, row.original.orderDate);
if (!window) return <span className="text-muted-foreground">—</span>;
return `${formatDate(window[0])} – ${formatDate(window[1])}`;
},
},
{
id: 'actions',
enableHiding: false,
Expand Down
30 changes: 30 additions & 0 deletions app/(logged-in)/org/[slug]/orders/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,33 @@ export const statusColors: Record<OrderStatus, string> = {
};

export const MAX_AMOUNT = 10000;

/** Working days a parcel spends with the carrier once it has shipped. */
const TRANSIT_DAYS = 3;

/** Working days an order still needs to leave the warehouse, by status. */
const LEAD_DAYS: Partial<Record<OrderStatus, number>> = {
pending: 2,
processing: 1,
shipped: 0,
};

/**
* The window an order should arrive in, or null once it is delivered or
* cancelled. Orders that have not shipped add the days they still need to
* leave the warehouse.
*/
export function deliveryWindow(status: OrderStatus, orderDate: Date): [Date, Date] | null {
if (status === 'delivered' || status === 'cancelled') return null;
const from = addWorkingDays(orderDate, (LEAD_DAYS[status] ?? 0) + TRANSIT_DAYS);
return [from, addWorkingDays(from, 2)];
}

function addWorkingDays(date: Date, days: number): Date {
const out = new Date(date);
for (let left = days; left > 0; ) {
out.setDate(out.getDate() + 1);
if (out.getDay() !== 0 && out.getDay() !== 6) left -= 1;
}
return out;
}
Loading