Workflow
Supplier Procurement
Detect low stock, automatically generate purchase orders, receive goods with batch tracking, and update inventory. Connects reorder rules, suppliers, batches, and stock.
1
Low Stock Alert2
Select Supplier3
Create PO4
Submit & Confirm PO5
Receive Goods6
Register Batches7
Register Serials8
Update Inventory9
Audit & ReportComplete Procurement Workflow
Step 1: Detect low stock via reorder alerts
import { createServices } from "commercio";
const services = createServices();
// Check all active reorder rules against current stock
const alerts = await services.reorderService.checkReorderAlerts();
console.log(`Found ${alerts.length} products below reorder point:\n`);
for (const alert of alerts) {
console.log(` Product: ${alert.rule.productId}`);
console.log(` Warehouse: ${alert.rule.warehouseId}`);
console.log(` Current stock: ${alert.currentStock}`);
console.log(` Reorder point: ${alert.rule.reorderPoint}`);
console.log(` Suggested order qty: ${alert.suggestedQuantity}`);
console.log(` Preferred supplier: ${alert.rule.preferredSupplierId ?? "none"}\n`);
}Step 2: Create and submit a purchase order
// Get or create a supplier
const supplier = await services.supplierService.createSupplier("Lenovo Direct", {
contactName: "Sales Team",
email: "b2b@lenovo.com",
phone: "+49 711 123 4567",
street: "Lenovo Allee 1",
city: "Stuttgart",
postalCode: "70173",
country: "Germany",
});
// Create purchase order based on alerts
const poItems = alerts.map(alert => ({
productId: alert.rule.productId,
quantity: alert.suggestedQuantity,
unitCost: 85000, // 850.00 EUR wholesale cost
}));
const purchaseOrder = await services.supplierService.createPurchaseOrder(
supplier.id, poItems,
{
expectedDelivery: new Date("2026-05-01"),
notes: "Auto-generated from reorder alerts",
}
);
console.log(`PO ${purchaseOrder.id} created (status: ${purchaseOrder.status})`); // DRAFT
// Submit the PO to the supplier
const submitted = await services.supplierService.submitPurchaseOrder(purchaseOrder.id);
console.log(`PO submitted (status: ${submitted.status})`); // SUBMITTED
// Supplier confirms
const confirmed = await services.supplierService.confirmPurchaseOrder(purchaseOrder.id);
console.log(`PO confirmed (status: ${confirmed.status})`); // CONFIRMED
// Audit the PO creation
await services.auditLogService.log("PurchaseOrder", purchaseOrder.id, "CREATE", {
actor: "procurement-bot",
newValues: {
supplierId: supplier.id,
itemCount: poItems.length,
totalCost: poItems.reduce((s, i) => s + i.quantity * i.unitCost, 0),
},
});Step 3: Receive goods, register batches & serial numbers
// Supplier ships the PO
await services.supplierService.shipPurchaseOrder(purchaseOrder.id);
// ── Goods arrive at warehouse ──────────────────────────
// Mark PO as received
const received = await services.supplierService.receivePurchaseOrder(purchaseOrder.id);
console.log(`PO received (status: ${received.status})`); // RECEIVED
// Register incoming batch
const batch = await services.batchTrackingService.createBatch(
alerts[0].rule.productId,
`BATCH-LENOVO-${Date.now()}`,
alerts[0].rule.warehouseId,
alerts[0].suggestedQuantity,
{
manufacturingDate: new Date("2026-03-15"),
expiryDate: new Date("2031-03-15"), // 5 year warranty
supplierId: supplier.id,
}
);
console.log(`Batch ${batch.batchNumber} registered (${batch.quantity} units)`);
// Register individual serial numbers
const serialNumbers = Array.from(
{ length: alerts[0].suggestedQuantity },
(_, i) => `SN-X1C-${batch.batchNumber}-${String(i + 1).padStart(4, "0")}`
);
const serials = await services.batchTrackingService.registerSerialNumbers(
alerts[0].rule.productId,
serialNumbers,
alerts[0].rule.warehouseId,
{ batchId: batch.id }
);
console.log(`${serials.length} serial numbers registered`);Step 4: Update inventory & verify
// Record the receipt as an inventory transaction
for (const alert of alerts) {
await services.inventoryTransactionService.createTransaction(
alert.rule.productId,
alert.rule.warehouseId,
alert.suggestedQuantity,
"RECEIPT",
purchaseOrder.id
);
}
// Verify stock levels are restored
for (const alert of alerts) {
const stock = await services.stockService.getStock(
alert.rule.productId, alert.rule.warehouseId
);
console.log(`Product ${alert.rule.productId}: ${stock?.quantity} units in stock`);
}
// Verify reorder alerts are cleared
const remainingAlerts = await services.reorderService.checkReorderAlerts();
console.log(`Remaining alerts: ${remainingAlerts.length}`); // 0
// ── Reporting ──────────────────────────────────────────
const inventory = await services.reportingService.getInventoryReport();
inventory.forEach(item => {
console.log(`${item.productName}: ${item.totalStock} total`);
item.warehouseBreakdown.forEach(w => {
console.log(` Warehouse ${w.warehouseId}: ${w.quantity}`);
});
});
// Check near-expiry batches
const expiringSoon = await services.batchTrackingService.getNearExpiryBatches(365);
console.log(`\n${expiringSoon.length} batches expiring within 1 year`);Services Used
ReorderService, SupplierService, BatchTrackingService, StockService, InventoryTransactionService, AuditLogService, ReportingService