Supplier Ordering
Procurement workflow, vendor management, and supplier order diagrams
Supplier Ordering
This page covers the procurement process including supplier order creation, automated ordering, and vendor management.
Supplier Order State Machine
stateDiagram-v2
[*] --> DRAFT: Create Order
DRAFT --> SENT: Send to Vendor
DRAFT --> CANCELLED: Cancel
SENT --> CONFIRMED: Vendor Confirms
SENT --> DRAFT: Vendor Requests Changes
SENT --> CANCELLED: Vendor Rejects
CONFIRMED --> PARTIAL_RECEIVED: Partial Delivery
CONFIRMED --> RECEIVED: Full Delivery
CONFIRMED --> CANCELLED: Cancel Before Delivery
PARTIAL_RECEIVED --> RECEIVED: Remaining Delivered
PARTIAL_RECEIVED --> CLOSED_PARTIAL: Close with Partial
RECEIVED --> CLOSED: Close Order
CLOSED_PARTIAL --> CLOSED: Reconcile
CLOSED --> [*]
CANCELLED --> [*]
note right of SENT
Email sent to vendor
with order details
end note
note right of PARTIAL_RECEIVED
Track partial deliveries
and discrepancies
end noteSupplier Order Workflow
flowchart TD
subgraph "Order Calculation"
TRIGGER[Trigger: Low Stock / Schedule] --> ANALYZE[Analyze Requirements]
ANALYZE --> FORECAST[Calculate Forecast]
FORECAST --> CURRENT[Check Current Stock]
CURRENT --> ORDERS[Check Pending Orders]
ORDERS --> CALCULATE[Calculate Order Quantity]
end
subgraph "Order Creation"
CALCULATE --> GROUP{Group by Vendor?}
GROUP -->|Yes| COMBINE[Combine Items per Vendor]
GROUP -->|No| SINGLE[Single Item Order]
COMBINE --> CREATE[Create Supplier Order]
SINGLE --> CREATE
CREATE --> ITEMS[Create Order Items]
end
subgraph "Approval & Sending"
ITEMS --> REVIEW{Auto-Send?}
REVIEW -->|Yes| SCHEDULE[Schedule Send]
REVIEW -->|No| MANUAL[Manual Review]
MANUAL --> APPROVE{Approved?}
APPROVE -->|Yes| SCHEDULE
APPROVE -->|No| EDIT[Edit Order]
EDIT --> MANUAL
SCHEDULE --> SEND[Send to Vendor]
end
SEND --> AWAIT[Await Confirmation]
style SEND fill:#e8f5e9Quantity Calculation Logic
flowchart TD
START[Calculate Order Quantity] --> GET_ORDERS[Get Orders in Period]
GET_ORDERS --> SUM[Sum Required Quantities]
SUM --> MARGIN[Add Safety Margin %]
MARGIN --> SUGGESTED[Suggested Quantity]
SUGGESTED --> STOCK[Subtract Current Stock]
STOCK --> PENDING[Subtract Pending Deliveries]
PENDING --> NEEDED{Quantity Needed?}
NEEDED -->|> 0| PACKAGE[Round to Package Size]
NEEDED -->|<= 0| SKIP[Skip - Sufficient Stock]
PACKAGE --> FINAL[Final Order Quantity]
subgraph "Example"
EX_ORD[Orders: 100 units]
EX_MARGIN[+ 10% margin = 110]
EX_STOCK[- Current: 30 = 80]
EX_PEND[- Pending: 20 = 60]
EX_PKG[Package size: 24]
EX_FINAL[Order: 3 packages = 72 units]
end
style FINAL fill:#e8f5e9
style SKIP fill:#fff3e0Automated Ordering Sequence
sequenceDiagram
participant Cron as Scheduler
participant Service as Supplier Order Service
participant DB as Database
participant Calc as Calculation Engine
participant Email as Email Service
participant Vendor
Cron->>Service: triggerAutoOrders()
Service->>DB: Get vendors with autoSend=true
DB-->>Service: Vendors list
loop For each vendor
Service->>DB: Get vendor schedule
DB-->>Service: Schedule config
Service->>Service: Check if today is order day
alt Is Order Day
Service->>DB: Get products for vendor
DB-->>Service: Products list
Service->>Calc: calculateOrderQuantities(products)
Calc->>DB: Get order forecasts
Calc->>DB: Get current stock
Calc->>DB: Get pending orders
Calc-->>Service: Calculated quantities
Service->>Service: Filter items needing order
alt Has Items to Order
Service->>DB: Create SupplierOrder
Service->>DB: Create SupplierOrderItems
DB-->>Service: Order created
Service->>Email: sendOrderEmail(order, vendor)
Email->>Vendor: Order email with PDF
Vendor-->>Email: Received
Service->>DB: Update emailSentAt
end
end
end
Service-->>Cron: Auto-orders completeVendor Configuration
erDiagram
VENDOR ||--o{ SUPPLIER_ORDER : receives
VENDOR ||--o{ PRODUCT : supplies
VENDOR }o--|| EMAIL_TEMPLATE : uses
VENDOR {
string id PK
string tenantId FK
string name
string email
string[] sendEmail
json sendSchedules
boolean autoSend
boolean groupedOrder
float defaultOveragePercent
json specificOveragePercent
int deliveryDays
string defaultPackagingType
json vendorLinks
}
SUPPLIER_ORDER {
string id PK
string vendorId FK
string tenantId FK
enum status
timestamp scheduledSendDate
timestamp emailSentAt
string emailSentBy
timestamp expectedDeliveryDate
timestamp actualDeliveryDate
enum supplierDeliveryStatus
json deliveryDiscrepancies
}
SUPPLIER_ORDER_ITEM {
string id PK
string orderId FK
string productId FK
int quantity
int currentStock
int quantityInOrders
int quantityAdded
int packageSize
float marginPercent
}Vendor Schedule Configuration
flowchart TD
subgraph "Schedule Types"
DAILY[Daily Orders]
WEEKLY[Weekly Orders]
BIWEEKLY[Bi-Weekly Orders]
MONTHLY[Monthly Orders]
end
subgraph "Weekly Example"
CONFIG[sendSchedules: [{day: 1, time: '08:00'}, {day: 4, time: '08:00'}]]
CONFIG --> MON[Monday 8:00 AM]
CONFIG --> THU[Thursday 8:00 AM]
end
subgraph "Lead Time"
SEND[Order Sent] --> LEAD[+ deliveryDays]
LEAD --> EXPECTED[Expected Delivery]
endReceiving Delivery Flow
flowchart TD
ARRIVE[Delivery Arrives] --> FIND[Find Supplier Order]
FIND --> VERIFY[Verify Items]
VERIFY --> MATCH{Quantities Match?}
MATCH -->|Yes| FULL[Mark Full Delivery]
MATCH -->|No| DISCREPANCY[Record Discrepancy]
DISCREPANCY --> TYPE{Discrepancy Type}
TYPE -->|Short| SHORT[Mark as Short]
TYPE -->|Over| OVER[Mark as Over]
TYPE -->|Damaged| DAMAGED[Mark as Damaged]
TYPE -->|Wrong Item| WRONG[Mark as Wrong Item]
SHORT --> PARTIAL[Mark Partial Received]
OVER --> FULL
DAMAGED --> PARTIAL
WRONG --> PARTIAL
FULL --> STOCK[Update Stock Levels]
PARTIAL --> STOCK
STOCK --> QC{Quality Check?}
QC -->|Pass| APPROVE[Approve for Sale]
QC -->|Fail| QUARANTINE[Quarantine Items]
APPROVE --> COMPLETE[Complete Receiving]
QUARANTINE --> CONTACT[Contact Vendor]
style COMPLETE fill:#e8f5e9Receiving Sequence
sequenceDiagram
participant Staff
participant UI as Receiving UI
participant API as TRPC Router
participant Service as Supplier Order Service
participant Inv as Inventory Service
participant DB as Database
Staff->>UI: Start receiving
UI->>API: startReceiving(orderId)
API->>Service: beginReceiving(orderId)
Service->>DB: Update status (RECEIVING)
loop For each item
Staff->>UI: Enter received quantity
UI->>API: recordItemReceived(itemId, qty, notes)
API->>Service: recordReceived(itemId, qty, notes)
Service->>Service: Compare to ordered qty
alt Quantity matches
Service->>DB: Update item (received)
else Discrepancy
Service->>DB: Log discrepancy
Service->>DB: Update item (partial/discrepancy)
end
Service->>Inv: incrementStock(productId, qty)
Inv->>DB: Create StockAction (INCREMENT)
Inv->>DB: Update stock levels
end
Staff->>UI: Complete receiving
UI->>API: completeReceiving(orderId)
API->>Service: finalizeReceiving(orderId)
Service->>Service: Check all items received
alt All received
Service->>DB: Update order (RECEIVED)
else Partial
Service->>DB: Update order (PARTIAL_RECEIVED)
end
Service-->>API: Receiving complete
API-->>UI: Show summaryVendor Performance Tracking
flowchart LR
subgraph "Metrics Collection"
ORDERS[Orders Placed]
DELIVERIES[Deliveries Received]
TIMES[Delivery Times]
QUALITY[Quality Issues]
end
subgraph "KPIs"
OTD[On-Time Delivery %]
FILL[Fill Rate %]
DEFECT[Defect Rate %]
LEAD[Avg Lead Time]
end
subgraph "Scoring"
SCORE[Vendor Score]
TIER[Performance Tier]
end
ORDERS --> OTD
DELIVERIES --> OTD
DELIVERIES --> FILL
TIMES --> LEAD
QUALITY --> DEFECT
OTD --> SCORE
FILL --> SCORE
DEFECT --> SCORE
LEAD --> SCORE
SCORE --> TIERPerformance Score Calculation
flowchart TD
START[Calculate Vendor Score] --> OTD[On-Time Delivery Score]
START --> FILL[Fill Rate Score]
START --> QUALITY[Quality Score]
START --> RESPONSE[Response Time Score]
OTD --> WEIGHT1[Weight: 30%]
FILL --> WEIGHT2[Weight: 25%]
QUALITY --> WEIGHT3[Weight: 25%]
RESPONSE --> WEIGHT4[Weight: 20%]
WEIGHT1 --> TOTAL[Total Score]
WEIGHT2 --> TOTAL
WEIGHT3 --> TOTAL
WEIGHT4 --> TOTAL
TOTAL --> TIER{Score Range}
TIER -->|90-100| GOLD[Gold Tier]
TIER -->|75-89| SILVER[Silver Tier]
TIER -->|60-74| BRONZE[Bronze Tier]
TIER -->|< 60| REVIEW[Under Review]
style GOLD fill:#ffd700
style SILVER fill:#c0c0c0
style BRONZE fill:#cd7f32
style REVIEW fill:#ffebeePurchase Order PDF Generation
sequenceDiagram
participant Service as Order Service
participant Template as Template Engine
participant PDF as PDF Generator
participant Storage as File Storage
participant Email as Email Service
Service->>Service: Prepare order data
Service->>Template: Render order template
Note over Template: Includes: vendor info, items,<br/>quantities, prices, terms
Template-->>Service: HTML content
Service->>PDF: generatePDF(html)
PDF-->>Service: PDF buffer
Service->>Storage: uploadFile(pdf, path)
Storage-->>Service: File URL
Service->>Email: sendEmail(vendor, attachment)
Email-->>Service: Sent
Service->>Service: Update order with PDF URLSupplier Order Analytics
erDiagram
SUPPLIER_ORDER_ANALYTICS ||--|| VENDOR : tracks
SUPPLIER_ORDER_ANALYTICS {
string id PK
string vendorId FK
date periodStart
date periodEnd
int totalOrders
decimal totalValue
int onTimeDeliveries
int lateDeliveries
decimal avgLeadTime
decimal fillRate
decimal defectRate
decimal score
}Multi-Vendor Order Optimization
flowchart TD
PRODUCTS[Products Needing Order] --> ANALYZE[Analyze Vendor Options]
ANALYZE --> FACTORS{Consider Factors}
FACTORS --> PRICE[Price]
FACTORS --> LEAD[Lead Time]
FACTORS --> MOQ[Minimum Order Qty]
FACTORS --> SCORE[Vendor Score]
FACTORS --> STOCK[Vendor Stock]
PRICE --> OPTIMIZE[Optimization Algorithm]
LEAD --> OPTIMIZE
MOQ --> OPTIMIZE
SCORE --> OPTIMIZE
STOCK --> OPTIMIZE
OPTIMIZE --> SPLIT{Split Order?}
SPLIT -->|Yes| MULTIPLE[Multiple Vendor Orders]
SPLIT -->|No| SINGLE[Single Vendor Order]
MULTIPLE --> CREATE[Create Orders]
SINGLE --> CREATE