-
- setFilters(prev => ({ ...prev, search: e.target.value }))}
- className="h-8 w-[300px]"
- />
-
-
-
-
-
+
+ setFilters(prev => ({ ...prev, search: e.target.value }))}
+ className="max-w-xs"
+ />
+
+
{/* Purchase Orders Table */}
@@ -343,7 +370,7 @@ export default function PurchaseOrders() {
{po.id}
{po.vendor_name}
{new Date(po.order_date).toLocaleDateString()}
-
{getStatusBadge(po.status)}
+
{getStatusBadge(po.status, po.receiving_status)}
{po.total_items.toLocaleString()}
{po.total_quantity.toLocaleString()}
${formatNumber(po.total_cost)}
diff --git a/inventory/src/types/products.ts b/inventory/src/types/products.ts
index 697d48e..bdeba2c 100644
--- a/inventory/src/types/products.ts
+++ b/inventory/src/types/products.ts
@@ -3,10 +3,10 @@ export interface Product {
title: string;
SKU: string;
stock_quantity: number;
- price: number;
- regular_price: number;
- cost_price: number;
- landing_cost_price: number | null;
+ price: string; // DECIMAL(15,3)
+ regular_price: string; // DECIMAL(15,3)
+ cost_price: string; // DECIMAL(15,3)
+ landing_cost_price: string | null; // DECIMAL(15,3)
barcode: string;
vendor: string;
vendor_reference: string;
@@ -24,32 +24,32 @@ export interface Product {
updated_at: string;
// Metrics
- daily_sales_avg?: number;
- weekly_sales_avg?: number;
- monthly_sales_avg?: number;
- avg_quantity_per_order?: number;
+ daily_sales_avg?: string; // DECIMAL(15,3)
+ weekly_sales_avg?: string; // DECIMAL(15,3)
+ monthly_sales_avg?: string; // DECIMAL(15,3)
+ avg_quantity_per_order?: string; // DECIMAL(15,3)
number_of_orders?: number;
first_sale_date?: string;
last_sale_date?: string;
last_purchase_date?: string;
- days_of_inventory?: number;
- weeks_of_inventory?: number;
- reorder_point?: number;
- safety_stock?: number;
- avg_margin_percent?: number;
- total_revenue?: number;
- inventory_value?: number;
- cost_of_goods_sold?: number;
- gross_profit?: number;
- gmroi?: number;
- avg_lead_time_days?: number;
+ days_of_inventory?: string; // DECIMAL(15,3)
+ weeks_of_inventory?: string; // DECIMAL(15,3)
+ reorder_point?: string; // DECIMAL(15,3)
+ safety_stock?: string; // DECIMAL(15,3)
+ avg_margin_percent?: string; // DECIMAL(15,3)
+ total_revenue?: string; // DECIMAL(15,3)
+ inventory_value?: string; // DECIMAL(15,3)
+ cost_of_goods_sold?: string; // DECIMAL(15,3)
+ gross_profit?: string; // DECIMAL(15,3)
+ gmroi?: string; // DECIMAL(15,3)
+ avg_lead_time_days?: string; // DECIMAL(15,3)
last_received_date?: string;
abc_class?: string;
stock_status?: string;
- turnover_rate?: number;
- current_lead_time?: number;
- target_lead_time?: number;
+ turnover_rate?: string; // DECIMAL(15,3)
+ current_lead_time?: string; // DECIMAL(15,3)
+ target_lead_time?: string; // DECIMAL(15,3)
lead_time_status?: string;
reorder_qty?: number;
- overstocked_amt?: number;
+ overstocked_amt?: string; // DECIMAL(15,3)
}
diff --git a/inventory/src/types/status-codes.ts b/inventory/src/types/status-codes.ts
new file mode 100644
index 0000000..1adfe06
--- /dev/null
+++ b/inventory/src/types/status-codes.ts
@@ -0,0 +1,81 @@
+// Purchase Order Status Codes
+export enum PurchaseOrderStatus {
+ Canceled = 0,
+ Created = 1,
+ ElectronicallyReadySend = 10,
+ Ordered = 11,
+ Preordered = 12,
+ ElectronicallySent = 13,
+ ReceivingStarted = 15,
+ Done = 50
+}
+
+// Receiving Status Codes
+export enum ReceivingStatus {
+ Canceled = 0,
+ Created = 1,
+ PartialReceived = 30,
+ FullReceived = 40,
+ Paid = 50
+}
+
+// Status Code Display Names
+export const PurchaseOrderStatusLabels: Record
= {
+ [PurchaseOrderStatus.Canceled]: 'Canceled',
+ [PurchaseOrderStatus.Created]: 'Created',
+ [PurchaseOrderStatus.ElectronicallyReadySend]: 'Ready to Send',
+ [PurchaseOrderStatus.Ordered]: 'Ordered',
+ [PurchaseOrderStatus.Preordered]: 'Preordered',
+ [PurchaseOrderStatus.ElectronicallySent]: 'Sent',
+ [PurchaseOrderStatus.ReceivingStarted]: 'Receiving Started',
+ [PurchaseOrderStatus.Done]: 'Done'
+};
+
+export const ReceivingStatusLabels: Record = {
+ [ReceivingStatus.Canceled]: 'Canceled',
+ [ReceivingStatus.Created]: 'Created',
+ [ReceivingStatus.PartialReceived]: 'Partially Received',
+ [ReceivingStatus.FullReceived]: 'Fully Received',
+ [ReceivingStatus.Paid]: 'Paid'
+};
+
+// Helper functions
+export function getPurchaseOrderStatusLabel(status: number): string {
+ return PurchaseOrderStatusLabels[status as PurchaseOrderStatus] || 'Unknown';
+}
+
+export function getReceivingStatusLabel(status: number): string {
+ return ReceivingStatusLabels[status as ReceivingStatus] || 'Unknown';
+}
+
+// Status checks
+export function isReceivingComplete(status: number): boolean {
+ return status >= ReceivingStatus.PartialReceived;
+}
+
+export function isPurchaseOrderComplete(status: number): boolean {
+ return status === PurchaseOrderStatus.Done;
+}
+
+export function isPurchaseOrderCanceled(status: number): boolean {
+ return status === PurchaseOrderStatus.Canceled;
+}
+
+export function isReceivingCanceled(status: number): boolean {
+ return status === ReceivingStatus.Canceled;
+}
+
+// Badge variants for different statuses
+export function getPurchaseOrderStatusVariant(status: number): 'default' | 'secondary' | 'destructive' | 'outline' {
+ if (isPurchaseOrderCanceled(status)) return 'destructive';
+ if (isPurchaseOrderComplete(status)) return 'default';
+ if (status >= PurchaseOrderStatus.ElectronicallyReadySend) return 'secondary';
+ return 'outline';
+}
+
+export function getReceivingStatusVariant(status: number): 'default' | 'secondary' | 'destructive' | 'outline' {
+ if (isReceivingCanceled(status)) return 'destructive';
+ if (status === ReceivingStatus.Paid) return 'default';
+ if (status >= ReceivingStatus.PartialReceived) return 'secondary';
+ return 'outline';
+}
\ No newline at end of file