+
+
+ Order #
+ PO #
+ Order Date
+ Need By
+ Customer Part
+ Vorteq Part
+ Qty
+ Shipped
+ Remaining
+ Status
+
+
+
+ {filteredData.length === 0 ? (
+
+
+ No orders found
+
+
+ ) : (
+ filteredData.map((row, i) => (
+
+
+
+ {row.order_num}
+
+
+ {row.po_num || '-'}
+
+ {row.order_date
+ ? new Date(row.order_date).toLocaleDateString()
+ : '-'}
+
+
+ {row.need_by_date
+ ? new Date(row.need_by_date).toLocaleDateString()
+ : '-'}
+
+ {row.customer_part || '-'}
+
+ {row.vorteq_part || '-'}
+
+
+ {row.order_qty?.toFixed(0) || '0'}
+
+
+ {row.shipped_qty?.toFixed(0) || '0'}
+
+
+ {row.remaining_qty?.toFixed(0) || '0'}
+
+
+
+ {row.status}
+
+
+
+ ))
+ )}
+
+
+
+
+
+ Showing {filteredData.length} of {data.length} orders
+
+
+
+ );
+}
diff --git a/src/services/orders.ts b/src/services/orders.ts
new file mode 100644
index 0000000..7d32878
--- /dev/null
+++ b/src/services/orders.ts
@@ -0,0 +1,152 @@
+/**
+ * Orders Service
+ * Handles order data retrieval from Epicor
+ */
+
+import { execQuery } from '@/lib/epicor';
+
+export type OrderRow = {
+ order_num: number;
+ po_num: string;
+ order_date: Date;
+ need_by_date: Date;
+ customer_part: string;
+ vorteq_part: string;
+ order_qty: number;
+ shipped_qty: number;
+ remaining_qty: number;
+ um: string;
+ open_order: boolean;
+ status: string;
+ ship_to_name?: string;
+ [key: string]: unknown;
+};
+
+/**
+ * Get top 100 orders for a customer
+ * Special handling for HDC customer
+ */
+export async function getTop100Orders(custId: string): Promise {
+ // HDC exception: use different customer ID for second parameter
+ const cust2 = custId === 'HDC' ? 'HDM' : custId;
+
+ // Query Epicor OrderHed and OrderDtl tables
+ // This is a simplified version - the actual portal_Orders.sql may have more complex logic
+ const sql = `
+ SELECT TOP 100
+ oh.OrderNum AS order_num,
+ oh.PONum AS po_num,
+ oh.OrderDate AS order_date,
+ oh.NeedByDate AS need_by_date,
+ od.XPartNum AS customer_part,
+ od.PartNum AS vorteq_part,
+ od.OrderQty AS order_qty,
+ od.ShippedQty AS shipped_qty,
+ (od.OrderQty - od.ShippedQty) AS remaining_qty,
+ od.IUM AS um,
+ oh.OpenOrder AS open_order,
+ CASE
+ WHEN oh.OpenOrder = 1 THEN 'Open'
+ ELSE 'Closed'
+ END AS status,
+ st.Name AS ship_to_name
+ FROM Erp.OrderHed oh
+ INNER JOIN Erp.OrderDtl od ON oh.Company = od.Company AND oh.OrderNum = od.OrderNum
+ INNER JOIN Erp.Customer c ON oh.Company = c.Company AND oh.CustNum = c.CustNum
+ LEFT JOIN Erp.ShipTo st ON oh.Company = st.Company AND oh.ShipToNum = st.ShipToNum
+ WHERE c.CustID = @Cust1
+ OR c.CustID = @Cust2
+ ORDER BY oh.OrderDate DESC, oh.OrderNum DESC
+ `;
+
+ const result = await execQuery(sql, {
+ Cust1: custId,
+ Cust2: cust2,
+ });
+
+ return result;
+}
+
+/**
+ * Get orders for a specific customer on or after a date
+ * Used for allocation requests
+ */
+export async function getOrdersForCustomerOnOrAfterDate(
+ custId: string,
+ date: string,
+ excludedOrderNumbers: number[] = []
+): Promise {
+ let sql = `
+ SELECT
+ oh.OrderNum AS order_num,
+ oh.PONum AS po_num,
+ oh.OrderDate AS order_date,
+ od.PartNum AS vorteq_part,
+ od.OrderQty AS order_qty,
+ od.ShippedQty AS shipped_qty,
+ (od.OrderQty - od.ShippedQty) AS remaining_qty
+ FROM Erp.OrderHed oh
+ INNER JOIN Erp.OrderDtl od ON oh.Company = od.Company AND oh.OrderNum = od.OrderNum
+ INNER JOIN Erp.Customer c ON oh.Company = c.Company AND oh.CustNum = c.CustNum
+ WHERE c.CustID = @CustomerID
+ AND oh.OrderDate >= @Date
+ AND oh.OpenOrder = 1
+ `;
+
+ if (excludedOrderNumbers.length > 0) {
+ const excludedList = excludedOrderNumbers.join(',');
+ sql += ` AND oh.OrderNum NOT IN (${excludedList})`;
+ }
+
+ sql += ' ORDER BY oh.OrderDate DESC';
+
+ const result = await execQuery(sql, {
+ CustomerID: custId,
+ Date: date,
+ });
+
+ return result;
+}
+
+/**
+ * Get order details for acknowledgement
+ */
+export async function getOrderDetails(orderNum: number): Promise {
+ const sql = `
+ SELECT
+ oh.OrderNum AS order_num,
+ oh.PONum AS po_num,
+ oh.OrderDate AS order_date,
+ oh.NeedByDate AS need_by_date,
+ od.OrderLine AS order_line,
+ od.XPartNum AS customer_part,
+ od.PartNum AS vorteq_part,
+ od.LineDesc AS line_desc,
+ od.OrderQty AS order_qty,
+ od.ShippedQty AS shipped_qty,
+ (od.OrderQty - od.ShippedQty) AS remaining_qty,
+ od.IUM AS um,
+ od.UnitPrice AS unit_price,
+ (od.OrderQty * od.UnitPrice) AS extended_price,
+ c.Name AS customer_name,
+ c.CustID AS cust_id,
+ st.Name AS ship_to_name,
+ st.Address1 AS ship_to_address1,
+ st.Address2 AS ship_to_address2,
+ st.City AS ship_to_city,
+ st.State AS ship_to_state,
+ st.ZIP AS ship_to_zip
+ FROM Erp.OrderHed oh
+ INNER JOIN Erp.OrderDtl od ON oh.Company = od.Company AND oh.OrderNum = od.OrderNum
+ INNER JOIN Erp.Customer c ON oh.Company = c.Company AND oh.CustNum = c.CustNum
+ LEFT JOIN Erp.ShipTo st ON oh.Company = st.Company AND oh.CustNum = st.CustNum AND oh.ShipToNum = st.ShipToNum
+ WHERE oh.OrderNum = @OrderNum
+ ORDER BY od.OrderLine
+ `;
+
+ const result = await execQuery(sql, {
+ OrderNum: orderNum,
+ });
+
+ return result;
+}