ERP Order Verification API Reference
This document provides technical details for developers working with the ERP Order Verification system. It covers the API endpoints, Temporal workflows, data structures, and implementation patterns.
Core Verification Methods
Section titled “Core Verification Methods”1. fetchVerifiedOrderItems
Section titled “1. fetchVerifiedOrderItems”Located in apps/webapp/src/services/erp/implementations/prophet21-service.ts, this private method fetches the actual order items from the P21 Data Services API.
private async fetchVerifiedOrderItems( connection: ERPConnection, erpOrderId: string): Promise<Array<{ itemId: string; quantityOrdered: number; unitPrice: number; }> | null> { // ...implementation details...}Purpose: Makes a GET request to P21 Data Services API endpoint /data/erp/views/v1/p21_view_oe_line to retrieve the actual items in an order as recorded in the ERP system.
Parameters:
connection: ERPConnection object with authentication detailserpOrderId: The ERP order ID to verify
Returns: Array of verified items from the ERP or null if the request fails.
Error Handling: Returns null on API error and logs detailed error information.
2. executeOrderVerification
Section titled “2. executeOrderVerification”private async executeOrderVerification( connection: ERPConnection, erpOrderId: string, sentItems: Array<{ id: string; name: string; quantity: number; price: number; }>): Promise< | { status: 'verified'; erpOrderId: string; verifiedItems: Array<{ itemId: string; quantityOrdered: number; unitPrice: number; }>; } | { status: 'mismatch'; erpOrderId: string; missingOrMismatchedItems: ErpUnverifiedItemDetail[]; verifiedItems: Array<{ itemId: string; quantityOrdered: number; unitPrice: number; }>; } | { status: 'verification_failed'; erpOrderId: string; error: { message: string; details?: any }; }>Purpose: Compares the items sent to the ERP with what was actually stored in the ERP system.
Parameters:
connection: ERPConnection objecterpOrderId: The ERP order ID to verifysentItems: Array of items that were sent to the ERP
Returns: Verification result with appropriate status and details:
verified: All items matchmismatch: Some items missing or have quantity discrepanciesverification_failed: Error during verification process
API Endpoints
Section titled “API Endpoints”1. Generate Quote Endpoint
Section titled “1. Generate Quote Endpoint”Path: /api/erp/orders/generate-quote
Method: POST
File: apps/webapp/src/pages/api/erp/orders/generate-quote.ts
Pre-commits a QUOTE_PENDING row in the orders table and starts the asynchronous Temporal workflow ERPQuoteGenerationWorkflow (apps/ts-temporal-worker/src/workflows/erp-submission.ts).
Request Payload:
{ localOrderId: string; // ID of the extracted order erpCustomerId: string; customerName: string; erpCompanyId: string; erpShipToId: string; poNumber: string; items: Array<{ erpItemId: string; quantity: number; price: number; name: string; productId: string; unitOfMeasure?: string; isDeleted?: boolean; }>;}Response (202 Accepted — Workflow Started):
{ workflowId: string; orderId: string; status: 'QUOTE_PENDING'; message: string;}The client awaits workflow completion via SSE (/api/temporal/workflow/[workflowId]), which resolves with the ERP order/quote number and verification outcome (verificationStatus, verificationMessage, unverifiedItems).
Response (Error — 4xx / 409 Conflict):
{ error: string; code?: 'ALREADY_HAS_ERP_ORDER_NUMBER' | 'DUPLICATE_REQUEST_IN_PROGRESS'; erpMessage?: string;}2. Update Order / Quote Endpoint
Section titled “2. Update Order / Quote Endpoint”Path: /api/erp/orders/[id]
Method: PUT
File: apps/webapp/src/pages/api/erp/orders/[id].ts
Handles both quote updates and non-quote sales-order updates:
- Quote updates (
QUOTE_PENDING/QUOTE_GENERATED/QUOTE_FAILEDorisQuote: true): Starts the durable Temporal workflowERPOrderUpdateWorkflowand returns202 Acceptedwith{ workflowId, orderId }. - Non-quote sales-order updates: Calls the ERP connector synchronously and returns
200 OKwith the updated order and verification details.
Request Payload:
{ items: Array<{ erpItemId: string; quantity: number; price: number; name?: string; unitOfMeasure?: string; }>; erpCustomerId?: string; erpShipToId?: string; poNumber?: string; isQuote?: boolean;}Response (202 Accepted for Quotes / 200 OK for Sync Updates):
// 202 Accepted (Quote update via ERPOrderUpdateWorkflow):{ workflowId: string; orderId: string;}
// 200 OK (Synchronous update / resolved workflow result):{ erpOrderNumber: string; verificationStatus: 'verified' | 'mismatch' | 'verification_failed' | null; verificationMessage: string; unverifiedItems: ErpUnverifiedItemDetail[];}3. Direct Order Submit Endpoint
Section titled “3. Direct Order Submit Endpoint”Path: /api/erp/orders/[id]/submit
Method: POST
File: apps/webapp/src/pages/api/erp/orders/[id]/submit.ts
Used by the review-v2 workbench (ReviewSubmitFlow.tsx) and orderEditStore to submit an order directly to the ERP. Runs server-side validation gates (price review, serialization, discounts, address deliverability, revision conflicts, work-item ownership) and starts ERPOrderSubmissionWorkflow, returning HTTP 202 Accepted with { workflowId, orderId, erpOrderRef? }.
Data Types
Section titled “Data Types”1. ErpUnverifiedItemDetail
Section titled “1. ErpUnverifiedItemDetail”interface ErpUnverifiedItemDetail { id: string; // erpItemId name: string; // Item name sentQuantity: number; // Quantity that was sent to ERP erpQuantity?: number; // Quantity found in ERP (if item exists but with different quantity) reason: 'missing' | 'quantity_mismatch'; // Why the item failed verification}2. VerificationResult
Section titled “2. VerificationResult”type VerificationResult = | { status: 'verified'; erpOrderId: string; verifiedItems: P21VerifiedItem[] } | { status: 'mismatch'; erpOrderId: string; missingOrMismatchedItems: ErpUnverifiedItemDetail[]; verifiedItems: P21VerifiedItem[]; } | { status: 'verification_failed'; erpOrderId: string; error: { message: string; details?: any }; };3. P21VerifiedItem
Section titled “3. P21VerifiedItem”interface P21VerifiedItem { itemId: string; // from p21_view_oe_line.item_id quantityOrdered: number; // from p21_view_oe_line.qty_ordered unitPrice: number; // from p21_view_oe_line.unit_price}Database Schema
Section titled “Database Schema”The verification system uses these columns on the orders table (packages/db/src/schema/orders.ts):
erpVerificationStatus: text('erp_verification_status'),erpUnverifiedItemIds: jsonb('erp_unverified_item_ids').$type<ErpUnverifiedItemDetail[]>(),Frontend Integration
Section titled “Frontend Integration”1. Store Management
Section titled “1. Store Management”The verification data is managed in apps/webapp/src/stores/pdfOrder/order.ts (and actions in apps/webapp/src/stores/pdfOrder/actions.ts). Key properties:
// In ExtractedOrderData interfaceerpVerificationStatus?: 'verified' | 'mismatch' | 'verification_failed' | 'pending' | null;erpUnverifiedItemDetails?: ErpUnverifiedItemDetail[] | null;
// Store atom for displaying verification messagessubmissionMessage = atom<string | null>(null);2. API Calls
Section titled “2. API Calls”The store has two methods that interact with verification:
generateQuoteInERP- Creates a new quote and processes verification resultsupdateQuoteInERP- Updates an existing quote and processes verification results
Both methods handle the verification data in a similar way:
// Example from updateQuoteInERP (simplified)const updatedOrder = { ...orderToUpdate };if (data.verificationStatus) updatedOrder.erpVerificationStatus = data.verificationStatus;if (data.unverifiedItems) updatedOrder.erpUnverifiedItemDetails = data.unverifiedItems;editingOrder.set(updatedOrder);if (data.verificationMessage) submissionMessage.set(data.verificationMessage);Implementation Notes
Section titled “Implementation Notes”-
Data Services API vs Transaction API: The verification system uses the P21 Data Services API (
/data/erp/views/v1/p21_view_oe_line) because the transaction-based approach failed with 400 errors. -
Error Handling Strategy: The system logs details at various levels but keeps user-facing errors actionable and context-appropriate.
-
Verification Timing: Verification runs immediately after successful order creation or update. It’s a separate process from the order creation/update itself.
-
Persistence Strategy: Verification data is stored in the database to ensure it’s available after page refreshes or navigation.
-
Backward Compatibility: The verification functionality is designed as an enhancement, not a requirement. If verification fails, the order creation/update is still considered successful.
Debugging Tips
Section titled “Debugging Tips”- Look at the
erpVerificationStatusanderpUnverifiedItemIdsfields in the order record - Check the logs for calls to
fetchVerifiedOrderItemsandexecuteOrderVerification - Verify that the P21 Data Services API is accessible (may require different permissions than the transaction API)
- If verification is failing, check the error details in the logs
Known Limitations
Section titled “Known Limitations”- The verification depends on the P21 Data Services API, which may have different permissions or availability than the transaction API
- Verification is a point-in-time check and does not continuously monitor the order
- Some order modifications in the ERP might not be detected if they don’t affect item IDs or quantities