AutoCount x QianYi WMS Integration Plugin | Quotation PQ-260203 | RM 13,900 | Prepared 2026-04-03
The big picture: how all systems and actors relate.
graph TB
subgraph MELODIES["Melodies Distributors (Ulu Tiram)"]
direction LR
OFFICE["Office Staff
(AutoCount Desktop)"]
WH["Warehouse Staff
(QianYi WMS + Scanners)"]
end
subgraph PLUGIN["Prisma Integration Plugin"]
direction TB
PL["Plugin .dll
(C# .NET)"]
HTTP["Embedded HTTP Server"]
QUEUE["Retry Queue"]
end
NGROK["ngrok Tunnel
(Fixed Domain)"]
QIANYI["QianYi WMS Server
(China, 59.60.9.28)"]
RICKY["Ricky
(AutoCount Vendor)"]
SUPPLIER["Suppliers
(FMCG Goods)"]
RETAIL["Retail Customers"]
OFFICE -->|"Creates Picking List
Creates PO"| PL
PL -->|"Push jobs / Sync items"| HTTP
HTTP -->|"TLS tunnel"| NGROK
NGROK -->|"HTTPS"| QIANYI
QIANYI -->|"Callback status"| NGROK
NGROK --> HTTP
HTTP --> PL
PL -->|"Creates GRN
Updates status"| OFFICE
QIANYI -->|"Picking tasks"| WH
WH -->|"Scan & confirm"| QIANYI
SUPPLIER -->|"Deliver goods"| WH
OFFICE -->|"Ship orders"| RETAIL
RICKY -.->|"SDK & API support"| PL
style MELODIES fill:#e8f4f8,stroke:#0f3460,stroke-width:2px
style PLUGIN fill:#fff3cd,stroke:#ffc107,stroke-width:2px
style QIANYI fill:#f8d7da,stroke:#dc3545,stroke-width:2px
style NGROK fill:#d4edda,stroke:#28a745,stroke-width:2px
When the office creates a Picking List, the plugin pushes it to QianYi WMS. Warehouse staff picks items, and status flows back to AutoCount in real time.
sequenceDiagram
actor Office as Office Staff
participant AC as AutoCount
participant Plugin as Prisma Plugin
participant ngrok as ngrok Tunnel
participant WMS as QianYi WMS
actor Warehouse as Warehouse Worker
Office->>AC: Create Picking List (PL-001)
AC->>Plugin: Event: PL Created
Plugin->>Plugin: Map PL to WMS format
Plugin->>ngrok: POST /api/picking/create
ngrok->>WMS: Forward request
WMS->>Warehouse: New picking task appears
Warehouse->>WMS: Scan items, confirm picked
WMS->>ngrok: POST /callback/picking/status
ngrok->>Plugin: Forward callback
Plugin->>AC: Update PL-001 status = "Picked"
AC->>Office: PL-001 shows "Picked" ✅
Note over Office, Warehouse: Cancellation Flow
Office->>AC: Cancel Picking List (PL-001)
AC->>Plugin: Event: PL Cancelled
Plugin->>ngrok: DELETE /api/picking/PL-001
ngrok->>WMS: Forward cancellation
WMS->>Warehouse: Task cancelled ❌
When QianYi WMS confirms goods received against a Purchase Order, the plugin auto-creates a GRN in AutoCount.
sequenceDiagram
actor Supplier as Supplier Truck
actor Warehouse as Warehouse Worker
participant WMS as QianYi WMS
participant ngrok as ngrok Tunnel
participant Plugin as Prisma Plugin
participant AC as AutoCount
Supplier->>Warehouse: Deliver goods
Warehouse->>WMS: Scan items, confirm receipt
WMS->>WMS: Match to PO reference
WMS->>ngrok: POST /callback/grn/create
Note right of WMS: Payload: PO ref, items received, qty
ngrok->>Plugin: Forward GRN request
Plugin->>Plugin: Validate against AC Purchase Order
Plugin->>AC: Create GRN (Goods Received Note)
AC->>AC: GRN auto-links to PO
Plugin->>Plugin: Log to Integration Result List
Plugin->>ngrok: 200 OK + GRN DocNo
ngrok->>WMS: Forward response
WMS->>WMS: Mark receipt as synced ✅
sequenceDiagram
actor Staff as Office Staff
participant AC as AutoCount
participant Plugin as Prisma Plugin
participant ngrok as ngrok Tunnel
participant WMS as QianYi WMS
Staff->>AC: Create/Edit Item Code
AC->>Plugin: Event: Item Changed
Plugin->>Plugin: Map to WMS format
alt Normal sync
Plugin->>ngrok: POST /api/item/sync
ngrok->>WMS: Forward item data
WMS->>WMS: Create/Update SKU master
WMS-->>ngrok: 200 OK
ngrok-->>Plugin: Success
Plugin->>Plugin: Log: ✅ Synced
else Network error
Plugin->>ngrok: POST /api/item/sync
ngrok-->>Plugin: Timeout / Error
Plugin->>Plugin: Add to retry queue
Plugin->>Plugin: Log: 🔄 Queued for retry
loop Exponential backoff
Plugin->>ngrok: Retry POST
ngrok->>WMS: Forward
WMS-->>ngrok: 200 OK
ngrok-->>Plugin: Success
end
Plugin->>Plugin: Log: ✅ Synced (after retry)
end
graph TB
subgraph LOCAL["Melodies Office (On-Premises)"]
AC["AutoCount Accounting
(.NET Desktop App)"]
PLUGIN["PrismaWMS.dll
(Plugin in AC Plugins folder)"]
HTTPSVR["Embedded HTTP Server
(localhost:5080)"]
NGROK_AGENT["ngrok Agent
(Windows Service)"]
QUEUE_DB["SQLite Queue
(retry_queue.db)"]
LOG["Integration Log
(integration_results.json)"]
SQLSERVER["SQL Server / LocalDB
(AutoCount Database)"]
AC --- PLUGIN
PLUGIN --- HTTPSVR
PLUGIN --- QUEUE_DB
PLUGIN --- LOG
AC --- SQLSERVER
HTTPSVR --- NGROK_AGENT
end
subgraph CLOUD["Internet"]
NGROK_EDGE["ngrok Edge
(melody.ngrok-free.app)"]
end
subgraph CHINA["China Data Center"]
WMS_SERVER["QianYi WMS
(59.60.9.28:8077)"]
WMS_DB["WMS Database"]
WMS_SERVER --- WMS_DB
end
NGROK_AGENT ==>|"TLS Tunnel"| NGROK_EDGE
NGROK_EDGE ==>|"HTTPS"| WMS_SERVER
WMS_SERVER ==>|"HTTPS Callback"| NGROK_EDGE
NGROK_EDGE ==>|"Relay"| NGROK_AGENT
style LOCAL fill:#e8f4f8,stroke:#0f3460,stroke-width:2px
style CLOUD fill:#d4edda,stroke:#28a745,stroke-width:2px
style CHINA fill:#f8d7da,stroke:#dc3545,stroke-width:2px
flowchart TD
START["Operation Triggered
(Pick/GRN/Sync)"] --> SEND["Send to QianYi WMS"]
SEND --> CHECK{"Response?"}
CHECK -->|"200 OK"| SUCCESS["✅ Log Success"]
CHECK -->|"4xx Error"| PARSE["Parse Error Message"]
CHECK -->|"5xx / Timeout"| RETRY_Q["Add to Retry Queue"]
CHECK -->|"Network Down"| RETRY_Q
PARSE --> FIXABLE{"Fixable?"}
FIXABLE -->|"Yes (e.g. bad data)"| ALERT_USER["⚠️ Alert User
Show in Result List"]
FIXABLE -->|"No (e.g. 403)"| ALERT_ADMIN["🚨 Alert Admin
Config issue"]
RETRY_Q --> WAIT["Wait (exponential backoff)
5s → 30s → 2m → 10m → 1h"]
WAIT --> RETRY["Retry Send"]
RETRY --> CHECK2{"Response?"}
CHECK2 -->|"200 OK"| SUCCESS
CHECK2 -->|"Still failing"| COUNT{"Attempts < 5?"}
COUNT -->|"Yes"| WAIT
COUNT -->|"No (5 fails)"| DEAD["💀 Dead Letter
Manual intervention needed"]
DEAD --> ALERT_USER
style SUCCESS fill:#d4edda,stroke:#28a745
style ALERT_USER fill:#fff3cd,stroke:#ffc107
style ALERT_ADMIN fill:#f8d7da,stroke:#dc3545
style DEAD fill:#f8d7da,stroke:#dc3545
| AutoCount Field | Direction | QianYi WMS Field | Notes |
|---|---|---|---|
| ItemCode | → | SkuCode | Primary key, must be unique |
| Description | → | SkuName | Product name |
| UOM | → | BaseUOM | Unit of measure (PCS, CTN, etc.) |
| Barcode | → | Barcode | For scanner matching |
| ItemGroup | → | Category | Product category |
| IsActive | → | Status | Active/Inactive flag |
| AutoCount Field | Direction | QianYi WMS Field | Notes |
|---|---|---|---|
| DocNo | → | OrderNo / ExternalRef | Unique picking reference |
| DocDate | → | OrderDate | |
| DebtorCode | → | CustomerRef | Retail customer code |
| ItemCode (line) | → | SkuCode (line) | |
| Qty (line) | → | OrderQty (line) | |
| — | ← | PickedQty | Actual quantity picked |
| Status | ← | TaskStatus | Pending/Picking/Picked/Cancelled |
| QianYi WMS Field | Direction | AutoCount Field | Notes |
|---|---|---|---|
| AsnNo / InboundRef | → | GRN DocNo (auto) | Auto-generated by AC |
| PO Reference | → | PurchaseOrderNo | Links GRN to PO |
| SupplierRef | → | CreditorCode | |
| SkuCode (line) | → | ItemCode (line) | |
| ReceivedQty (line) | → | Qty (line) | |
| ReceiveDate | → | DocDate |
| # | Risk | Probability | Impact | Mitigation |
|---|---|---|---|---|
| 1 | QianYi WMS has no documented API | HIGH | CRITICAL | Contact vendor NOW. If no API → project redesign |
| 2 | ngrok tunnel drops during business hours | MEDIUM | HIGH | Paid plan + daemon + retry queue + monitoring |
| 3 | AC Picking List has no event hooks | MEDIUM | HIGH | Fallback: DB trigger or polling every N seconds |
| 4 | China firewall blocks ngrok | LOW | CRITICAL | Test early. Alt: Cloudflare Tunnel, VPN |
| 5 | Bulk SKU sync overloads WMS API | MEDIUM | MEDIUM | Batch sync with rate limiting |
| 6 | AutoCount version mismatch | LOW | HIGH | Confirm version before dev starts |
| 7 | GRN creation conflicts with manual process | MEDIUM | MEDIUM | UAT with real users; auto/manual toggle |
| 8 | Scope creep at UAT | HIGH | MEDIUM | Clear scope doc; Phase 2 pricing ready |