Compare commits
2 Commits
4ed734e5c0
...
fix-number
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cb41a7e4c | |||
| d05d27494d |
@@ -46,8 +46,10 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
const startTime = Date.now();
|
||||
let poRecordsAdded = 0;
|
||||
let poRecordsUpdated = 0;
|
||||
let poRecordsDeleted = 0;
|
||||
let receivingRecordsAdded = 0;
|
||||
let receivingRecordsUpdated = 0;
|
||||
let receivingRecordsDeleted = 0;
|
||||
let totalProcessed = 0;
|
||||
|
||||
// Batch size constants
|
||||
@@ -257,6 +259,10 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
const totalPOs = poCount[0].total;
|
||||
console.log(`Found ${totalPOs} relevant purchase orders`);
|
||||
|
||||
// Skip processing if no POs to process
|
||||
if (totalPOs === 0) {
|
||||
console.log('No purchase orders to process, skipping PO import step');
|
||||
} else {
|
||||
// Fetch and process POs in batches
|
||||
let offset = 0;
|
||||
let allPOsProcessed = false;
|
||||
@@ -401,6 +407,7 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
allPOsProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Next, fetch all relevant receivings
|
||||
outputProgress({
|
||||
@@ -424,6 +431,10 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
const totalReceivings = receivingCount[0].total;
|
||||
console.log(`Found ${totalReceivings} relevant receivings`);
|
||||
|
||||
// Skip processing if no receivings to process
|
||||
if (totalReceivings === 0) {
|
||||
console.log('No receivings to process, skipping receivings import step');
|
||||
} else {
|
||||
// Fetch and process receivings in batches
|
||||
offset = 0; // Reset offset for receivings
|
||||
let allReceivingsProcessed = false;
|
||||
@@ -603,6 +614,7 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
allReceivingsProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add this section to filter out invalid PIDs before final import
|
||||
outputProgress({
|
||||
@@ -655,6 +667,31 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
message: "Inserting final purchase order records"
|
||||
});
|
||||
|
||||
// Create a temp table to track PO IDs being processed
|
||||
await localConnection.query(`
|
||||
DROP TABLE IF EXISTS processed_po_ids;
|
||||
CREATE TEMP TABLE processed_po_ids AS (
|
||||
SELECT DISTINCT po_id FROM temp_purchase_orders
|
||||
);
|
||||
`);
|
||||
|
||||
// Delete products that were removed from POs and count them
|
||||
const [poDeletedResult] = await localConnection.query(`
|
||||
WITH deleted AS (
|
||||
DELETE FROM purchase_orders
|
||||
WHERE po_id IN (SELECT po_id FROM processed_po_ids)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM temp_purchase_orders tp
|
||||
WHERE purchase_orders.po_id = tp.po_id AND purchase_orders.pid = tp.pid
|
||||
)
|
||||
RETURNING po_id, pid
|
||||
)
|
||||
SELECT COUNT(*) as count FROM deleted
|
||||
`);
|
||||
|
||||
poRecordsDeleted = poDeletedResult.rows[0]?.count || 0;
|
||||
console.log(`Deleted ${poRecordsDeleted} products that were removed from purchase orders`);
|
||||
|
||||
const [poResult] = await localConnection.query(`
|
||||
INSERT INTO purchase_orders (
|
||||
po_id, vendor, date, expected_date, pid, sku, name,
|
||||
@@ -706,6 +743,31 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
message: "Inserting final receiving records"
|
||||
});
|
||||
|
||||
// Create a temp table to track receiving IDs being processed
|
||||
await localConnection.query(`
|
||||
DROP TABLE IF EXISTS processed_receiving_ids;
|
||||
CREATE TEMP TABLE processed_receiving_ids AS (
|
||||
SELECT DISTINCT receiving_id FROM temp_receivings
|
||||
);
|
||||
`);
|
||||
|
||||
// Delete products that were removed from receivings and count them
|
||||
const [receivingDeletedResult] = await localConnection.query(`
|
||||
WITH deleted AS (
|
||||
DELETE FROM receivings
|
||||
WHERE receiving_id IN (SELECT receiving_id FROM processed_receiving_ids)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM temp_receivings tr
|
||||
WHERE receivings.receiving_id = tr.receiving_id AND receivings.pid = tr.pid
|
||||
)
|
||||
RETURNING receiving_id, pid
|
||||
)
|
||||
SELECT COUNT(*) as count FROM deleted
|
||||
`);
|
||||
|
||||
receivingRecordsDeleted = receivingDeletedResult.rows[0]?.count || 0;
|
||||
console.log(`Deleted ${receivingRecordsDeleted} products that were removed from receivings`);
|
||||
|
||||
const [receivingsResult] = await localConnection.query(`
|
||||
INSERT INTO receivings (
|
||||
receiving_id, pid, sku, name, vendor, qty_each, qty_each_orig,
|
||||
@@ -765,6 +827,8 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
DROP TABLE IF EXISTS employee_names;
|
||||
DROP TABLE IF EXISTS temp_supplier_names;
|
||||
DROP TABLE IF EXISTS temp_invalid_pids;
|
||||
DROP TABLE IF EXISTS processed_po_ids;
|
||||
DROP TABLE IF EXISTS processed_receiving_ids;
|
||||
`);
|
||||
|
||||
// Commit transaction
|
||||
@@ -774,10 +838,13 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
status: "complete",
|
||||
recordsAdded: poRecordsAdded + receivingRecordsAdded,
|
||||
recordsUpdated: poRecordsUpdated + receivingRecordsUpdated,
|
||||
recordsDeleted: poRecordsDeleted + receivingRecordsDeleted,
|
||||
poRecordsAdded,
|
||||
poRecordsUpdated,
|
||||
poRecordsDeleted,
|
||||
receivingRecordsAdded,
|
||||
receivingRecordsUpdated,
|
||||
receivingRecordsDeleted,
|
||||
totalRecords: totalProcessed
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -795,6 +862,7 @@ async function importPurchaseOrders(prodConnection, localConnection, incremental
|
||||
error: error.message,
|
||||
recordsAdded: 0,
|
||||
recordsUpdated: 0,
|
||||
recordsDeleted: 0,
|
||||
totalRecords: 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,13 +115,13 @@ export default function PurchaseOrderAccordion({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-h-[350px] overflow-y-auto bg-gray-50 rounded-md p-2">
|
||||
<div className="max-h-[600px] overflow-y-auto bg-gray-50 rounded-md p-2">
|
||||
<Table className="w-full">
|
||||
<TableHeader className="bg-white sticky top-0 z-10">
|
||||
<TableRow>
|
||||
<TableHead className="w-[100px]">SKU</TableHead>
|
||||
<TableHead className="w-[100px]">Item Number</TableHead>
|
||||
<TableHead className="w-auto">Product</TableHead>
|
||||
<TableHead className="w-[100px] text-right">UPC</TableHead>
|
||||
<TableHead className="w-[100px]">UPC</TableHead>
|
||||
<TableHead className="w-[80px] text-right">Ordered</TableHead>
|
||||
<TableHead className="w-[80px] text-right">Received</TableHead>
|
||||
<TableHead className="w-[100px] text-right">Unit Cost</TableHead>
|
||||
@@ -151,9 +151,39 @@ export default function PurchaseOrderAccordion({
|
||||
) : (
|
||||
items.map((item) => (
|
||||
<TableRow key={item.id} className="hover:bg-gray-100">
|
||||
<TableCell className="font-mono text-xs">{item.sku}</TableCell>
|
||||
<TableCell className="font-medium">{item.product_name}</TableCell>
|
||||
<TableCell className="text-right font-mono text-xs">{item.upc}</TableCell>
|
||||
<TableCell className="">
|
||||
<a
|
||||
href={`https://backend.acherryontop.com/product/${item.pid}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:underline"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{item.sku}
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
<a
|
||||
href={`https://backend.acherryontop.com/product/${item.pid}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:underline"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{item.product_name}
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell className="">
|
||||
<a
|
||||
href={`https://backend.acherryontop.com/product/${item.pid}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:underline"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{item.upc}
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{item.ordered}
|
||||
</TableCell>
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function PurchaseOrdersTable({
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center justify-center border-green-500 text-green-700 bg-green-50 px-0 tracking-tight w-[85px]"
|
||||
className="flex items-center justify-center border-green-500 text-green-700 bg-green-50 px-0 text-xs w-[85px]"
|
||||
>
|
||||
Received PO
|
||||
</Badge>
|
||||
@@ -78,7 +78,7 @@ export default function PurchaseOrdersTable({
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center justify-center border-blue-500 text-blue-700 bg-blue-50 px-0 tracking-tight w-[85px]"
|
||||
className="flex items-center justify-center border-blue-500 text-blue-700 bg-blue-50 px-0 text-xs w-[85px]"
|
||||
>
|
||||
PO
|
||||
</Badge>
|
||||
@@ -87,7 +87,7 @@ export default function PurchaseOrdersTable({
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center justify-center border-amber-500 text-amber-700 bg-amber-50 px-0 tracking-tight w-[85px]"
|
||||
className="flex items-center justify-center border-amber-500 text-amber-700 bg-amber-50 px-0 text-xs w-[85px]"
|
||||
>
|
||||
Receiving
|
||||
</Badge>
|
||||
@@ -96,7 +96,7 @@ export default function PurchaseOrdersTable({
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center justify-center border-gray-500 text-gray-700 bg-gray-50 px-0 tracking-tight w-[85px]"
|
||||
className="flex items-center justify-center border-gray-500 text-gray-700 bg-gray-50 px-0 text-xs w-[85px]"
|
||||
>
|
||||
{recordType || "Unknown"}
|
||||
</Badge>
|
||||
@@ -108,7 +108,7 @@ export default function PurchaseOrdersTable({
|
||||
if (recordType === "receiving_only") {
|
||||
return (
|
||||
<Badge
|
||||
className="w-[100px] flex items-center justify-center px-0 tracking-tight"
|
||||
className="w-[115px] flex items-center text-xs justify-center px-1"
|
||||
variant={getReceivingStatusVariant(status)}
|
||||
>
|
||||
{getReceivingStatusLabel(status)}
|
||||
@@ -118,7 +118,7 @@ export default function PurchaseOrdersTable({
|
||||
|
||||
return (
|
||||
<Badge
|
||||
className="w-[100px] flex items-center justify-center px-0 tracking-tight"
|
||||
className="w-[115px] flex items-center text-xs justify-center px-1"
|
||||
variant={getPurchaseOrderStatusVariant(status)}
|
||||
>
|
||||
{getPurchaseOrderStatusLabel(status)}
|
||||
@@ -342,7 +342,18 @@ export default function PurchaseOrdersTable({
|
||||
<TableCell className="text-center">
|
||||
{getRecordTypeIndicator(po.record_type)}
|
||||
</TableCell>
|
||||
<TableCell className="font-semibold text-center">{po.id}</TableCell>
|
||||
<TableCell className="font-semibold text-center">
|
||||
<a
|
||||
href={po.record_type === "po_only"
|
||||
? `https://backend.acherryontop.com/po/edit/${po.id}`
|
||||
: `https://backend.acherryontop.com/receiving/edit/${po.id}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:underline"
|
||||
>
|
||||
{po.id}
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell>{po.vendor_name}</TableCell>
|
||||
<TableCell>
|
||||
{getStatusBadge(po.status, po.record_type)}
|
||||
@@ -378,7 +389,7 @@ export default function PurchaseOrdersTable({
|
||||
year: "numeric",
|
||||
}
|
||||
)
|
||||
: ""}
|
||||
: "-"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{po.receiving_date
|
||||
@@ -390,18 +401,18 @@ export default function PurchaseOrdersTable({
|
||||
year: "numeric",
|
||||
}
|
||||
)
|
||||
: ""}
|
||||
: "-"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{po.total_quantity.toLocaleString()}
|
||||
{po.record_type === "receiving_only" ? "-" : po.total_quantity.toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{po.total_received.toLocaleString()}
|
||||
{po.record_type === "po_only" ? "-" : po.total_received.toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell className="text-right" >
|
||||
{po.fulfillment_rate === null
|
||||
? "N/A"
|
||||
: formatPercent(po.fulfillment_rate)}
|
||||
<TableCell className="text-center" >
|
||||
{po.record_type === "po_with_receiving"
|
||||
? (po.fulfillment_rate === null ? "N/A" : formatPercent(po.fulfillment_rate))
|
||||
: "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</PurchaseOrderAccordion>
|
||||
|
||||
Reference in New Issue
Block a user