@pelygo/janus 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +621 -166
- package/USAGE.md +393 -0
- package/dist/index.d.ts +77 -6
- package/dist/index.js +84 -60
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,263 +1,718 @@
|
|
|
1
1
|
# @pelygo/janus
|
|
2
2
|
|
|
3
|
-
TypeScript API client for JANUS (VCOMSUITE backend)
|
|
3
|
+
TypeScript API client for JANUS (VCOMSUITE warehouse management backend). Provides typed access to orders, returns, products, stock, invoices, ASNs, dispatches, and more.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install @pelygo/janus @pelygo/auth
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
`@pelygo/auth` is a required peer dependency. It handles token storage and refresh automatically.
|
|
14
|
+
|
|
15
|
+
### Configure
|
|
16
|
+
|
|
17
|
+
The JANUS API server and the auth server are **different hosts**. You must provide both URLs.
|
|
12
18
|
|
|
13
19
|
```typescript
|
|
14
20
|
import { createJanusApi } from '@pelygo/janus';
|
|
15
21
|
|
|
16
|
-
// Create API instance
|
|
17
22
|
const janus = createJanusApi({
|
|
18
|
-
baseUrl: 'https://api.janus.pelygo.com',
|
|
23
|
+
baseUrl: 'https://api.janus.pelygo.com', // JANUS API server
|
|
24
|
+
authUrl: 'https://auth.pelygo.com', // Auth server (different host)
|
|
19
25
|
onUnauthorized: () => {
|
|
20
|
-
//
|
|
26
|
+
// IMPORTANT: use setTimeout in Base44/iframe environments
|
|
27
|
+
setTimeout(() => window.location.href = '/login', 0);
|
|
21
28
|
},
|
|
22
29
|
});
|
|
23
|
-
|
|
24
|
-
// Authenticate
|
|
25
|
-
await janus.auth.login('username', 'password');
|
|
26
|
-
|
|
27
|
-
// Use typed resources
|
|
28
|
-
const clients = await janus.clients.getAll();
|
|
29
|
-
const returns = await janus.returns.query({ clientId: 5, pageSize: 50 });
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### Creating the Client
|
|
32
|
+
**Dev environment:**
|
|
35
33
|
|
|
36
34
|
```typescript
|
|
37
35
|
const janus = createJanusApi({
|
|
38
|
-
baseUrl:
|
|
39
|
-
|
|
36
|
+
baseUrl: 'https://api.janus.dev.pelygo.com',
|
|
37
|
+
authUrl: 'https://auth.dev.pelygo.com',
|
|
40
38
|
});
|
|
41
39
|
```
|
|
42
40
|
|
|
43
|
-
###
|
|
41
|
+
### Read-only mode (default)
|
|
44
42
|
|
|
45
|
-
|
|
43
|
+
By default the client is **read-only** — any attempt to create, update, or delete data will throw an error. This prevents accidental writes from AI-generated code or dashboard apps that should only display data.
|
|
46
44
|
|
|
47
45
|
```typescript
|
|
48
|
-
//
|
|
49
|
-
|
|
46
|
+
// Read-only (default) — getAll, query, getById work; create, update, delete throw
|
|
47
|
+
const janus = createJanusApi({ baseUrl: '...' });
|
|
50
48
|
|
|
51
|
-
//
|
|
52
|
-
const
|
|
49
|
+
// Full access — all operations allowed
|
|
50
|
+
const janus = createJanusApi({ baseUrl: '...', allowWrites: true });
|
|
51
|
+
```
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
Read-only mode allows:
|
|
54
|
+
- All `GET` requests (list, getById, stats, reports, filter options)
|
|
55
|
+
- Query-style `POST` requests (`returns.queryPost`, `legacy.queryProducts`)
|
|
56
|
+
- Authentication (`janus.auth.login`, `janus.auth.verify`)
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
Read-only mode blocks:
|
|
59
|
+
- `POST` create operations (e.g. `products.create`, `orders.create`)
|
|
60
|
+
- `PUT` / `PATCH` update operations (e.g. `clients.update`, `returns.update`)
|
|
61
|
+
- `DELETE` operations (e.g. `products.delete`, `users.delete`)
|
|
62
|
+
|
|
63
|
+
When a blocked operation is attempted, it throws:
|
|
64
|
+
```
|
|
65
|
+
@pelygo/janus: Write operation blocked (POST /products).
|
|
66
|
+
The client is in read-only mode. To enable writes, set allowWrites: true in createJanusApi options.
|
|
59
67
|
```
|
|
60
68
|
|
|
61
|
-
###
|
|
69
|
+
### Authenticate
|
|
62
70
|
|
|
63
71
|
```typescript
|
|
64
|
-
|
|
65
|
-
const
|
|
72
|
+
await janus.auth.login('username', 'password');
|
|
73
|
+
const user = await janus.auth.getUser();
|
|
74
|
+
const isLoggedIn = janus.auth.isAuthenticated();
|
|
75
|
+
await janus.auth.logout();
|
|
76
|
+
```
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## All Available Resources
|
|
81
|
+
|
|
82
|
+
| Resource | Accessor | Auth | Description |
|
|
83
|
+
|----------|----------|------|-------------|
|
|
84
|
+
| Clients | `janus.clients` | Yes | Client account CRUD, courier services per client |
|
|
85
|
+
| Returns | `janus.returns` | Yes | Full returns management: CRUD, items, comments, statuses, reasons, categories, sources |
|
|
86
|
+
| Orders | `janus.orders` | Yes | Query orders, stats, filter options, create/update |
|
|
87
|
+
| Products | `janus.products` | Yes | Product CRUD (preferred over `legacy.queryProducts`) |
|
|
88
|
+
| Product Categories | `janus.productCategories` | Yes | Product category CRUD |
|
|
89
|
+
| Stocks | `janus.stocks` | Yes | Stock record CRUD |
|
|
90
|
+
| Stock Transactions | `janus.stockTransactions` | Yes | Stock transaction history |
|
|
91
|
+
| Stock Allocations | `janus.stockAllocations` | Yes | Stock allocation records |
|
|
92
|
+
| Locations | `janus.locations` | Yes | Warehouse location CRUD |
|
|
93
|
+
| Dispatches | `janus.dispatches` | Yes | Dispatch CRUD |
|
|
94
|
+
| Consignments | `janus.consignments` | Yes | Consignment records |
|
|
95
|
+
| Invoices | `janus.invoices` | Yes | Invoice CRUD with line items |
|
|
96
|
+
| ASNs | `janus.asns` | Yes | Advance Shipping Notices with lines and receipts |
|
|
97
|
+
| Couriers | `janus.couriers` | Yes | Courier and service management |
|
|
98
|
+
| Reports | `janus.reports` | Yes | Returns summary, reasons, overview reports (JSON + CSV) |
|
|
99
|
+
| Integrations | `janus.integrations` | Yes | Integration management |
|
|
100
|
+
| Users | `janus.users` | Yes | User management |
|
|
101
|
+
| Logs | `janus.logs` | Yes | Activity and order issue logs |
|
|
102
|
+
| Tasks | `janus.tasks` | Yes | Task history |
|
|
103
|
+
| Audits | `janus.audits` | Yes | Audit trail (read-only) |
|
|
104
|
+
| Legacy | `janus.legacy` | Yes | Legacy couriers, post services, products |
|
|
105
|
+
| Helpers | `janus.helpers` | No | Public endpoints: return portal form submission, notification settings |
|
|
106
|
+
| Customer | `janus.customer` | No | Public customer tracking (order lookup) |
|
|
107
|
+
| Auth | `janus.auth` | -- | Underlying AuthApi instance for raw requests |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Entity Field Reference
|
|
112
|
+
|
|
113
|
+
### Return
|
|
114
|
+
|
|
115
|
+
| Field | Type | Description |
|
|
116
|
+
|-------|------|-------------|
|
|
117
|
+
| `id` | `number` | Unique ID |
|
|
118
|
+
| `return_reference` | `string?` | Human-readable return reference |
|
|
119
|
+
| `wms_order_ref` | `string?` | Original order reference |
|
|
120
|
+
| `client_id` | `number?` | Client ID |
|
|
121
|
+
| `status_id` | `number?` | Current status ID |
|
|
122
|
+
| `reason_id` | `number?` | Return reason ID |
|
|
123
|
+
| `customername` | `string?` | Full customer name |
|
|
124
|
+
| `forename` | `string?` | First name |
|
|
125
|
+
| `surname` | `string?` | Last name |
|
|
126
|
+
| `email` | `string?` | Customer email |
|
|
127
|
+
| `tracking_number` | `string?` | Courier tracking number |
|
|
128
|
+
| `tracking_url` | `string?` | Tracking page URL |
|
|
129
|
+
| `approval_status` | `'pending' \| 'approved' \| 'rejected'?` | Approval state |
|
|
130
|
+
| `approved` | `boolean?` | Whether approved |
|
|
131
|
+
| `approved_ts` | `string?` | Approval timestamp |
|
|
132
|
+
| `line_1` | `string?` | Address line 1 |
|
|
133
|
+
| `line_2` | `string?` | Address line 2 |
|
|
134
|
+
| `line_3` | `string?` | Address line 3 |
|
|
135
|
+
| `city` | `string?` | City |
|
|
136
|
+
| `county` | `string?` | County/state |
|
|
137
|
+
| `country` | `string?` | Country name |
|
|
138
|
+
| `country_code` | `string?` | ISO country code (e.g. `"GB"`) |
|
|
139
|
+
| `postcode` | `string?` | Postal code |
|
|
140
|
+
| `company` | `string?` | Company name |
|
|
141
|
+
| `wms_service_cost` | `number?` | WMS service cost |
|
|
142
|
+
| `courier_service_cost` | `number?` | Courier service cost |
|
|
143
|
+
| `courier_service_id` | `number?` | Assigned courier service ID |
|
|
144
|
+
| `items` | `ReturnItem[]?` | Line items (when included) |
|
|
145
|
+
| `statuses` | `ReturnStatusHistory[]?` | Status history (when included) |
|
|
146
|
+
| `comments` | `ReturnComment[]?` | Comments (when included) |
|
|
147
|
+
| `latestStatus` | `ReturnStatusHistory?` | Most recent status |
|
|
148
|
+
| `created_ts` | `string?` | ISO timestamp |
|
|
149
|
+
| `updated_ts` | `string?` | ISO timestamp |
|
|
150
|
+
|
|
151
|
+
### LegacyOrder
|
|
152
|
+
|
|
153
|
+
| Field | Type | Description |
|
|
154
|
+
|-------|------|-------------|
|
|
155
|
+
| `id` | `number` | Primary key |
|
|
156
|
+
| `customerId` | `number?` | FK to customer |
|
|
157
|
+
| `reference` | `string?` | Order reference string |
|
|
158
|
+
| `source` | `number?` | Source ID |
|
|
159
|
+
| `orderDate` | `string?` | ISO date the order was placed |
|
|
160
|
+
| `dispatchCompletedDate` | `string?` | ISO date all dispatches completed |
|
|
161
|
+
| `orderStatus` | `number?` | Numeric status code |
|
|
162
|
+
| `postServiceId` | `number?` | FK to shipping service |
|
|
163
|
+
| `courierId` | `number?` | FK to courier |
|
|
164
|
+
| `actualWeight` | `number?` | Measured weight |
|
|
165
|
+
| `notes` | `string?` | Internal notes |
|
|
166
|
+
| `hold` | `unknown?` | Whether order is on hold |
|
|
167
|
+
| `releaseDate` | `string?` | ISO date when hold was released |
|
|
168
|
+
| `draft` | `unknown?` | Whether order is a draft |
|
|
169
|
+
| `giftMessage` | `string?` | Gift message text |
|
|
170
|
+
| `deliveryInstructions` | `string?` | Delivery instructions |
|
|
171
|
+
| `orderIssue` | `number?` | Issue flag |
|
|
172
|
+
| `deliveryTerms` | `string?` | Incoterms code (e.g. `"DAP"`) |
|
|
173
|
+
| `transaction_type` | `'b2c' \| 'b2b' \| 'internal_transfer' \| 'damage' \| 'expiry'` | **Required.** Transaction classification |
|
|
174
|
+
| `external_order_id` | `string?` | External system order ID |
|
|
175
|
+
| `channel_order_id` | `string?` | Sales channel order ID |
|
|
176
|
+
| `channel` | `string?` | Sales channel name |
|
|
177
|
+
| `created` | `string?` | ISO created timestamp |
|
|
178
|
+
| `modified` | `string?` | ISO modified timestamp |
|
|
179
|
+
| `status` | `number?` | Record status (0 = inactive, 1 = active) |
|
|
180
|
+
| `orderItems` | `LegacyOrderItem[]` | Line items |
|
|
181
|
+
| `orderMeta` | `LegacyOrderMeta[]` | Metadata key-value pairs |
|
|
182
|
+
| `shopperDeliveryAddress` | `LegacyShopperAddress` | Delivery address |
|
|
183
|
+
| `shopperBillingAddress` | `LegacyShopperAddress` | Billing address |
|
|
184
|
+
| `dispatches` | `LegacyDispatch[]` | All dispatches for this order |
|
|
185
|
+
| `dispatch` | `LegacyDispatch` | Primary dispatch |
|
|
186
|
+
| `orderSource` | `Source` | Source reference data |
|
|
187
|
+
|
|
188
|
+
### LegacyDispatch
|
|
189
|
+
|
|
190
|
+
| Field | Type | Description |
|
|
191
|
+
|-------|------|-------------|
|
|
192
|
+
| `id` | `number` | Primary key |
|
|
193
|
+
| `orderId` | `number?` | FK to parent order |
|
|
194
|
+
| `reference` | `string?` | Client-facing reference code |
|
|
195
|
+
| `dispatchDate` | `string?` | ISO date shipped |
|
|
196
|
+
| `dispatchStatus` | `number?` | 0 = pending, 1 = dispatched, 2 = cancelled |
|
|
197
|
+
| `trackingNumber` | `string?` | Carrier tracking number |
|
|
198
|
+
| `actualWeight` | `number?` | Measured weight |
|
|
199
|
+
| `courierId` | `number?` | FK to courier |
|
|
200
|
+
| `postServiceId` | `number?` | FK to shipping service |
|
|
201
|
+
| `notes` | `string?` | Internal notes |
|
|
202
|
+
| `hold` | `unknown?` | 0 = not held, 1 = on hold |
|
|
203
|
+
| `draft` | `unknown?` | 0 = finalised, 1 = draft |
|
|
204
|
+
| `deliveryInstructions` | `string?` | Special delivery instructions |
|
|
205
|
+
| `dispatchActionId` | `number?` | Current action (pick, pack, ship) |
|
|
206
|
+
| `dispatchActionStatus` | `number?` | 0 = not started, 1 = in progress, 2 = completed |
|
|
207
|
+
| `stockStatus` | `number?` | 0 = unallocated, 1 = partial, 2 = fully allocated |
|
|
208
|
+
| `dispatchIssue` | `number?` | 0 = no issue, 1 = issue flagged |
|
|
209
|
+
| `priority` | `number?` | Higher = higher priority |
|
|
210
|
+
| `complete` | `number?` | 0 = incomplete, 1 = complete |
|
|
211
|
+
| `complete_date` | `string?` | ISO date marked complete |
|
|
212
|
+
| `deliveryTerms` | `string?` | Incoterms code |
|
|
213
|
+
| `created` | `string?` | ISO created timestamp |
|
|
214
|
+
| `modified` | `string?` | ISO modified timestamp |
|
|
215
|
+
| `status` | `number?` | 0 = inactive/deleted, 1 = active |
|
|
216
|
+
| `dispatchItems` | `LegacyDispatchItem[]` | Line items in this dispatch |
|
|
217
|
+
| `shopperDeliveryAddress` | `LegacyShopperAddress` | Delivery address |
|
|
218
|
+
| `consignment` | `Consignment` | Consignment record |
|
|
219
|
+
| `postService` | `LegacyPostService` | Shipping service details |
|
|
220
|
+
|
|
221
|
+
### FormattedProduct
|
|
222
|
+
|
|
223
|
+
Returned by `janus.products.getAll()`. Field names are snake_case (different from the raw `LegacyProduct` entity).
|
|
224
|
+
|
|
225
|
+
| Field | Type | Description |
|
|
226
|
+
|-------|------|-------------|
|
|
227
|
+
| `product_id` | `number` | Primary key |
|
|
228
|
+
| `client_id` | `number` | FK to owning client |
|
|
229
|
+
| `sku_code` | `string?` | SKU -- unique product identifier within the client |
|
|
230
|
+
| `product_name` | `string?` | Human-readable name |
|
|
231
|
+
| `description` | `string?` | Extended description |
|
|
232
|
+
| `additional_skus` | `string?` | Comma-separated alternative SKUs |
|
|
233
|
+
| `asins` | `string?` | Amazon Standard Identification Numbers |
|
|
234
|
+
| `custom_fields` | `Record<string, unknown>?` | Client-defined key-value pairs |
|
|
235
|
+
| `hs_code` | `string?` | Harmonized System code for customs |
|
|
236
|
+
| `unit_of_measure` | `string?` | e.g. `"each"`, `"kg"`, `"litre"` |
|
|
237
|
+
| `eaches_per_pack` | `number?` | Units per case pack |
|
|
238
|
+
| `case_pack_sku_code` | `string?` | SKU of the case pack |
|
|
239
|
+
| `weight_grams` | `number?` | Unit weight in grams |
|
|
240
|
+
| `barcode` | `string?` | Primary EAN/UPC barcode |
|
|
241
|
+
| `case_pack_barcode` | `string?` | Case pack barcode |
|
|
242
|
+
| `product_category_id` | `number?` | FK to product category |
|
|
243
|
+
| `product_type` | `string?` | e.g. `"physical"`, `"digital"`, `"service"` |
|
|
244
|
+
| `sellable_format` | `string?` | e.g. `"single"`, `"pack"`, `"case"` |
|
|
245
|
+
| `commodity_description` | `string?` | Customs commodity description |
|
|
246
|
+
| `price` | `number?` | Unit sale price |
|
|
247
|
+
| `currency` | `string?` | ISO 4217 code (e.g. `"GBP"`) |
|
|
248
|
+
| `country_of_origin` | `string?` | ISO 3166-1 alpha-2 (e.g. `"CN"`) |
|
|
249
|
+
| `primary_material` | `string?` | Primary material |
|
|
250
|
+
| `secondary_material` | `string?` | Secondary material |
|
|
251
|
+
| `dangerous_goods` | `string?` | DG classification / UN number |
|
|
252
|
+
| `image_url` | `string?` | Product image URL |
|
|
253
|
+
| `low_stock_threshold` | `number?` | Low-stock alert threshold |
|
|
254
|
+
| `requires_batch_tracking` | `number?` | 0 = no, 1 = yes |
|
|
255
|
+
| `requires_serial_tracking` | `number?` | 0 = no, 1 = yes |
|
|
256
|
+
| `requires_bbe_tracking` | `number?` | 0 = no, 1 = yes (best-before/expiry) |
|
|
257
|
+
| `is_bundle` | `number?` | 0 = standalone, 1 = bundle |
|
|
258
|
+
| `bundle_components` | `string?` | Component SKUs and quantities |
|
|
259
|
+
| `default_stock_status` | `string?` | Status assigned on receipt |
|
|
260
|
+
| `product_status` | `string?` | e.g. `"active"`, `"discontinued"` |
|
|
261
|
+
| `status` | `number?` | 0 = inactive/deleted, 1 = active |
|
|
262
|
+
| `created_date` | `string?` | ISO created timestamp |
|
|
263
|
+
| `updated_date` | `string?` | ISO updated timestamp |
|
|
264
|
+
|
|
265
|
+
### Stock
|
|
266
|
+
|
|
267
|
+
Extends `BaseEntity` (adds `id`, `created_by`, `updated_by`, `created_ts`, `updated_ts`, `partition_id`).
|
|
268
|
+
|
|
269
|
+
| Field | Type | Description |
|
|
270
|
+
|-------|------|-------------|
|
|
271
|
+
| `id` | `number` | Primary key (from BaseEntity) |
|
|
272
|
+
| `clientId` | `number?` | FK to owning client |
|
|
273
|
+
| `sku_code` | `string?` | SKU identifying the product |
|
|
274
|
+
| `location` | `string?` | Location code (e.g. `"A-01-03-B"`) |
|
|
275
|
+
| `quantity` | `number?` | Units at this location |
|
|
276
|
+
| `batch_number` | `string?` | Batch/lot number |
|
|
277
|
+
| `serial_number` | `string?` | Serial number |
|
|
278
|
+
| `best_before_date` | `string?` | ISO expiry date (FEFO rotation) |
|
|
279
|
+
| `received_date` | `string?` | ISO date received into warehouse |
|
|
280
|
+
| `stock_status` | `'available' \| 'quarantined' \| 'expired' \| 'damaged' \| 'reserved'` | **Required.** Current status |
|
|
281
|
+
| `fulfilment_location_id` | `number?` | FK to fulfilment centre |
|
|
282
|
+
| `fulfilment_location_name` | `string?` | Fulfilment centre name |
|
|
283
|
+
| `fulfilment_location_country` | `string?` | ISO country code |
|
|
284
|
+
| `notes` | `string?` | Free-text notes |
|
|
285
|
+
| `created_ts` | `string?` | ISO created timestamp (from BaseEntity) |
|
|
286
|
+
| `updated_ts` | `string?` | ISO updated timestamp (from BaseEntity) |
|
|
287
|
+
|
|
288
|
+
### Location
|
|
289
|
+
|
|
290
|
+
Extends `BaseEntity`.
|
|
291
|
+
|
|
292
|
+
| Field | Type | Description |
|
|
293
|
+
|-------|------|-------------|
|
|
294
|
+
| `id` | `number` | Primary key |
|
|
295
|
+
| `clientId` | `number?` | FK to owning client |
|
|
296
|
+
| `location_code` | `string?` | Unique code (e.g. `"A-01-03-B"`) |
|
|
297
|
+
| `location_type` | `'pick' \| 'bulk' \| 'staging' \| 'receiving' \| 'shipping' \| 'quarantine' \| 'returns'` | **Required.** Location role |
|
|
298
|
+
| `zone` | `string?` | Warehouse zone (e.g. `"A"`) |
|
|
299
|
+
| `aisle` | `string?` | Aisle identifier |
|
|
300
|
+
| `bay` | `string?` | Bay/rack identifier |
|
|
301
|
+
| `level` | `string?` | Vertical level/shelf |
|
|
302
|
+
| `position` | `string?` | Horizontal position |
|
|
303
|
+
| `fulfilment_location_id` | `number?` | FK to fulfilment centre |
|
|
304
|
+
| `fulfilment_location_name` | `string?` | Fulfilment centre name |
|
|
305
|
+
| `current_units` | `number?` | Stock units currently held |
|
|
306
|
+
| `max_capacity_units` | `number?` | Maximum unit capacity |
|
|
307
|
+
| `max_capacity_weight_kg` | `number?` | Maximum weight (kg) |
|
|
308
|
+
| `is_mixed_sku_allowed` | `number?` | 0 = single SKU only, 1 = mixed |
|
|
309
|
+
| `is_active` | `number?` | 0 = decommissioned, 1 = in use |
|
|
310
|
+
| `is_pickable` | `number?` | 0 = no, 1 = yes |
|
|
311
|
+
| `is_receivable` | `number?` | 0 = no, 1 = yes |
|
|
312
|
+
| `temperature_zone` | `'ambient' \| 'chilled' \| 'frozen'` | **Required.** Temperature classification |
|
|
313
|
+
| `notes` | `string?` | Free-text notes |
|
|
314
|
+
|
|
315
|
+
### Invoice
|
|
316
|
+
|
|
317
|
+
Extends `BaseEntity`.
|
|
318
|
+
|
|
319
|
+
| Field | Type | Description |
|
|
320
|
+
|-------|------|-------------|
|
|
321
|
+
| `id` | `number` | Primary key |
|
|
322
|
+
| `clientId` | `number?` | FK to client |
|
|
323
|
+
| `invoice_date` | `string` | **Required.** ISO invoice date |
|
|
324
|
+
| `xero_reference` | `string?` | Xero accounting reference |
|
|
325
|
+
| `total` | `number?` | Total invoice amount |
|
|
326
|
+
| `emailed` | `number?` | 0 = not emailed, 1 = emailed |
|
|
327
|
+
| `paid` | `number?` | 0 = unpaid, 1 = paid |
|
|
328
|
+
| `fuel_mode` | `number?` | 0 = flat rate, 1 = percentage |
|
|
329
|
+
| `status` | `number?` | 0 = inactive/deleted, 1 = active |
|
|
330
|
+
| `invoiceLines` | `InvoiceLine[]?` | Line items |
|
|
331
|
+
|
|
332
|
+
### InvoiceLine
|
|
333
|
+
|
|
334
|
+
Extends `BaseEntity`.
|
|
335
|
+
|
|
336
|
+
| Field | Type | Description |
|
|
337
|
+
|-------|------|-------------|
|
|
338
|
+
| `id` | `number` | Primary key |
|
|
339
|
+
| `invoice_id` | `number?` | FK to parent invoice |
|
|
340
|
+
| `class_id` | `number?` | Charge classification (storage, fulfilment, shipping) |
|
|
341
|
+
| `object_id` | `number?` | FK to billable object (dispatch ID, etc.) |
|
|
342
|
+
| `reference` | `string` | **Required.** Client-facing reference |
|
|
343
|
+
| `description` | `string?` | Charge description |
|
|
344
|
+
| `dispatch_date` | `string?` | ISO dispatch date |
|
|
345
|
+
| `service_name` | `string?` | Shipping service name |
|
|
346
|
+
| `price` | `number?` | Unit price |
|
|
347
|
+
| `discount_rate` | `number?` | Discount percentage |
|
|
348
|
+
| `postcode` | `string?` | Destination postcode |
|
|
349
|
+
| `country_code` | `string?` | ISO destination country |
|
|
350
|
+
| `tax_class` | `number?` | 0 = zero-rated, 1 = standard, 2 = exempt |
|
|
351
|
+
| `consignment_price` | `number?` | Carrier cost before margin |
|
|
352
|
+
| `fuel` | `number?` | Fuel surcharge |
|
|
353
|
+
| `packaging_price` | `number?` | Packaging material cost |
|
|
354
|
+
| `discount` | `number?` | Calculated discount amount |
|
|
355
|
+
| `lines` | `number?` | Number of order lines |
|
|
356
|
+
| `picks` | `number?` | Number of picks |
|
|
357
|
+
| `weight` | `number?` | Total weight (kg) |
|
|
358
|
+
| `margin_charged` | `number?` | Margin on carrier cost |
|
|
359
|
+
| `total_override` | `number?` | Manual total override |
|
|
360
|
+
| `status` | `number?` | 0 = inactive/deleted, 1 = active |
|
|
361
|
+
|
|
362
|
+
### ASN (Advance Shipping Notice)
|
|
363
|
+
|
|
364
|
+
Extends `BaseEntity`.
|
|
365
|
+
|
|
366
|
+
| Field | Type | Description |
|
|
367
|
+
|-------|------|-------------|
|
|
368
|
+
| `id` | `number` | Primary key |
|
|
369
|
+
| `clientId` | `number` | **Required.** FK to client |
|
|
370
|
+
| `asn_status` | `string` | **Required.** One of: `draft`, `awaiting_arrival`, `arrived`, `processing`, `receipted`, `receipted_with_discrepancies`, `temporarily_receipted`, `quarantined`, `cancelled` |
|
|
371
|
+
| `expected_arrival_date` | `string?` | ISO expected arrival date |
|
|
372
|
+
| `total_expected_units` | `number?` | Total expected units |
|
|
373
|
+
| `asnLines` | `AsnLine[]` | Line items |
|
|
374
|
+
|
|
375
|
+
### AsnLine
|
|
376
|
+
|
|
377
|
+
Extends `BaseEntity`.
|
|
378
|
+
|
|
379
|
+
| Field | Type | Description |
|
|
380
|
+
|-------|------|-------------|
|
|
381
|
+
| `id` | `number` | Primary key |
|
|
382
|
+
| `asn_id` | `number` | **Required.** FK to parent ASN |
|
|
383
|
+
| `product_id` | `number?` | FK to product |
|
|
384
|
+
| `sku_code` | `string` | **Required.** SKU code |
|
|
385
|
+
| `expected_quantity` | `number` | **Required.** Expected unit count |
|
|
386
|
+
| `received_quantity` | `number?` | Actual received count |
|
|
387
|
+
| `asnReceipts` | `AsnReceipt[]` | Receipt records |
|
|
388
|
+
|
|
389
|
+
### AsnReceipt
|
|
390
|
+
|
|
391
|
+
Extends `BaseEntity`.
|
|
392
|
+
|
|
393
|
+
| Field | Type | Description |
|
|
394
|
+
|-------|------|-------------|
|
|
395
|
+
| `id` | `number` | Primary key |
|
|
396
|
+
| `asn_id` | `number` | **Required.** FK to ASN |
|
|
397
|
+
| `asn_line_id` | `number` | **Required.** FK to ASN line |
|
|
398
|
+
| `received_quantity` | `number` | **Required.** Quantity received |
|
|
399
|
+
| `stock_status` | `'available' \| 'quarantined' \| 'expired' \| 'damaged' \| 'reserved'` | **Required.** Status of received stock |
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Query Filter Reference
|
|
404
|
+
|
|
405
|
+
### PaginatedQueryFilters (v2 endpoints: products, stocks, locations, invoices, ASNs, dispatches)
|
|
406
|
+
|
|
407
|
+
| Param | Type | Required | Description |
|
|
408
|
+
|-------|------|----------|-------------|
|
|
409
|
+
| `clientId` | `number` | **Yes** | Client ID from `useClient()` |
|
|
410
|
+
| `pageSize` | `number` | No | Results per page (default: 25) |
|
|
411
|
+
| `pageNumber` | `number` | No | Page number, 1-based (default: 1) |
|
|
412
|
+
| `orderColumn` | `string` | No | Column to sort by (e.g. `'id'`, `'created'`) |
|
|
413
|
+
| `orderDirection` | `'ASC' \| 'DESC'` | No | Sort direction (default: DESC) |
|
|
414
|
+
| `query` | `string` | No | Free-text search across key fields |
|
|
415
|
+
|
|
416
|
+
### ReturnsQueryFilters (janus.returns.query)
|
|
417
|
+
|
|
418
|
+
| Param | Type | Required | Description |
|
|
419
|
+
|-------|------|----------|-------------|
|
|
420
|
+
| `clientId` | `number` | **Yes** | Client ID |
|
|
421
|
+
| `page` | `number` | No | Page number |
|
|
422
|
+
| `pageSize` | `number` | No | Results per page |
|
|
423
|
+
| `created_at` | `string` | No | Start date (ISO, e.g. `'2025-01-01'`) |
|
|
424
|
+
| `created_to` | `string` | No | End date (ISO) |
|
|
425
|
+
| `last_status_ids` | `string` | No | Comma-separated status IDs to match current status |
|
|
426
|
+
| `include_status_ids` | `string` | No | Include returns with any of these status IDs |
|
|
427
|
+
| `exclude_status_ids` | `string` | No | Exclude returns with these status IDs |
|
|
428
|
+
| `processed_at` | `string` | No | Processed start date (ISO) |
|
|
429
|
+
| `processed_to` | `string` | No | Processed end date (ISO) |
|
|
430
|
+
| `include_associations` | `string` | No | Nested data: `'return_items'`, `'return_comments'`, or comma-separated |
|
|
431
|
+
| `csv` | `boolean` | No | Export as CSV instead of JSON |
|
|
432
|
+
| `group_by` | `string` | No | Group results by field |
|
|
433
|
+
|
|
434
|
+
### OrdersQueryFilters (janus.orders.getAll)
|
|
435
|
+
|
|
436
|
+
| Param | Type | Required | Description |
|
|
437
|
+
|-------|------|----------|-------------|
|
|
438
|
+
| `clientId` | `number` | **Yes** | Client ID |
|
|
439
|
+
| `page` | `number` | No | Page number |
|
|
440
|
+
| `pageSize` | `number` | No | Results per page |
|
|
441
|
+
| `order_column` | `string` | No | Sort column |
|
|
442
|
+
| `order_direction` | `'ASC' \| 'DESC'` | No | Sort direction |
|
|
443
|
+
| `created_at` | `string` | No | Start date (ISO) |
|
|
444
|
+
| `created_to` | `string` | No | End date (ISO) |
|
|
445
|
+
| `channel` | `string` | No | Filter by sales channel |
|
|
446
|
+
| `destination` | `string` | No | Filter by destination |
|
|
447
|
+
| `courier` | `string` | No | Filter by courier name |
|
|
448
|
+
| `service` | `string` | No | Filter by courier service |
|
|
449
|
+
| `status` | `string` | No | Filter by order status |
|
|
450
|
+
| `query` | `string` | No | Free-text search |
|
|
451
|
+
| `include_all_stages` | `boolean` | No | Include all order stages |
|
|
452
|
+
|
|
453
|
+
### ReturnsSummaryFilters (janus.reports.returnsSummary / returnsSummaryCsv)
|
|
454
|
+
|
|
455
|
+
| Param | Type | Required | Description |
|
|
456
|
+
|-------|------|----------|-------------|
|
|
457
|
+
| `clientId` | `number` | **Yes** | Client ID |
|
|
458
|
+
| `createdFrom` | `string` | No | Start date (ISO) |
|
|
459
|
+
| `createdTo` | `string` | No | End date (ISO) |
|
|
460
|
+
| `approvedFrom` | `string` | No | Approval start date |
|
|
461
|
+
| `approvedTo` | `string` | No | Approval end date |
|
|
462
|
+
| `courierServiceId` | `number` | No | Filter by courier service |
|
|
463
|
+
| `approved` | `boolean` | No | Only approved returns |
|
|
464
|
+
| `isClientsReport` | `boolean` | No | Format as client-level report |
|
|
465
|
+
| `page` | `number` | No | Page number |
|
|
466
|
+
| `pageSize` | `number` | No | Results per page |
|
|
467
|
+
|
|
468
|
+
### ReturnsReasonsFilters (janus.reports.returnsReasons / returnsReasonsCsv)
|
|
469
|
+
|
|
470
|
+
| Param | Type | Required | Description |
|
|
471
|
+
|-------|------|----------|-------------|
|
|
472
|
+
| `clientId` | `number` | **Yes** | Client ID |
|
|
473
|
+
| `createdFrom` | `string` | No | Start date (ISO) |
|
|
474
|
+
| `createdTo` | `string` | No | End date (ISO) |
|
|
475
|
+
|
|
476
|
+
### OrdersStatsFilters (janus.orders.getStats)
|
|
477
|
+
|
|
478
|
+
| Param | Type | Required | Description |
|
|
479
|
+
|-------|------|----------|-------------|
|
|
480
|
+
| `clientId` | `number` | **Yes** | Client ID |
|
|
481
|
+
| `created_at` | `string` | No | Start date (ISO) |
|
|
482
|
+
| `created_to` | `string` | No | End date (ISO) |
|
|
483
|
+
| `dashboard` | `boolean` | No | Return dashboard-formatted stats (recommended: `true`) |
|
|
484
|
+
|
|
485
|
+
### Resource-specific extra filters
|
|
486
|
+
|
|
487
|
+
| Resource method | Extra param | Type | Description |
|
|
488
|
+
|----------------|-----------|------|-------------|
|
|
489
|
+
| `janus.stockTransactions.getAll` | `stockId` | `number` | Filter by stock record |
|
|
490
|
+
| `janus.stockAllocations.getAll` | `orderId` | `number` | Filter by order |
|
|
491
|
+
| `janus.dispatches.getAll` | `orderId` | `number` | Filter by order |
|
|
492
|
+
| `janus.audits.getAll` | `filter` | `string` | Additional filter |
|
|
493
|
+
| `janus.users.getAll` | `filterRole` | `string` | Filter by user role |
|
|
494
|
+
| `janus.users.getAll` | `filterType` | `string` | Filter by user type |
|
|
495
|
+
| `janus.users.getAll` | `filterClientId` | `number` | Filter by assigned client |
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Common Patterns
|
|
500
|
+
|
|
501
|
+
### Querying with Filters and Pagination
|
|
502
|
+
|
|
503
|
+
**v2 endpoints** (products, stocks, locations, invoices, ASNs, dispatches) use `ClientScopedPaginatedQueryFilters`:
|
|
69
504
|
|
|
70
|
-
|
|
71
|
-
const
|
|
505
|
+
```typescript
|
|
506
|
+
const { data, meta } = await janus.products.getAll({
|
|
507
|
+
clientId: 5, // REQUIRED
|
|
508
|
+
pageSize: 50,
|
|
509
|
+
pageNumber: 1,
|
|
510
|
+
orderColumn: 'sku_code',
|
|
511
|
+
orderDirection: 'ASC',
|
|
512
|
+
query: 'widget', // free-text search
|
|
513
|
+
});
|
|
72
514
|
|
|
73
|
-
//
|
|
74
|
-
const services = await janus.clients.getCourierServices(5);
|
|
75
|
-
const service = await janus.clients.getCourierServiceById(5, serviceId);
|
|
76
|
-
await janus.clients.updateCourierService(5, serviceId, { active: true });
|
|
515
|
+
// meta = { total_items, total_pages, current_page, page_size }
|
|
77
516
|
```
|
|
78
517
|
|
|
79
|
-
|
|
518
|
+
**Legacy endpoints** (orders, returns) use their own filter shapes:
|
|
80
519
|
|
|
81
520
|
```typescript
|
|
82
|
-
// Query returns with filters
|
|
83
521
|
const returns = await janus.returns.query({
|
|
84
522
|
clientId: 5,
|
|
85
523
|
last_status_ids: '1,2,3',
|
|
86
524
|
created_at: '2024-01-01',
|
|
87
525
|
created_to: '2024-12-31',
|
|
88
526
|
pageSize: 100,
|
|
527
|
+
csv: false,
|
|
89
528
|
});
|
|
90
529
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// ...
|
|
530
|
+
const orders = await janus.orders.getAll({
|
|
531
|
+
clientId: 5,
|
|
532
|
+
created_at: '2024-01-01',
|
|
533
|
+
created_to: '2024-12-31',
|
|
534
|
+
status: 'dispatched',
|
|
535
|
+
order_column: 'created',
|
|
536
|
+
order_direction: 'DESC',
|
|
99
537
|
});
|
|
538
|
+
```
|
|
100
539
|
|
|
101
|
-
|
|
102
|
-
await janus.returns.update(123, { customer_name: 'Jane Doe' });
|
|
103
|
-
|
|
104
|
-
// Delete a return
|
|
105
|
-
await janus.returns.delete(123);
|
|
106
|
-
|
|
107
|
-
// Manage statuses
|
|
108
|
-
await janus.returns.addStatus(123, statusId);
|
|
109
|
-
await janus.returns.removeStatus(123, statusId);
|
|
110
|
-
const statuses = await janus.returns.getStatuses(123);
|
|
111
|
-
|
|
112
|
-
// Manage comments
|
|
113
|
-
await janus.returns.addComment(123, 'Comment text');
|
|
114
|
-
await janus.returns.removeComment(123, commentId);
|
|
115
|
-
const comments = await janus.returns.getComments(123);
|
|
116
|
-
|
|
117
|
-
// Manage items
|
|
118
|
-
const items = await janus.returns.getItems(123);
|
|
119
|
-
await janus.returns.addItem(123, { wms_product_sku: 'SKU123', qty: 2 });
|
|
120
|
-
await janus.returns.updateItem(123, itemId, { qty: 3 });
|
|
540
|
+
### CSV Export
|
|
121
541
|
|
|
122
|
-
|
|
123
|
-
await janus.returns.setApproval(123, true); // Approve
|
|
124
|
-
await janus.returns.setApproval(123, false); // Reject
|
|
542
|
+
Reports have dedicated CSV methods:
|
|
125
543
|
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
const
|
|
544
|
+
```typescript
|
|
545
|
+
const csvString = await janus.reports.returnsSummaryCsv({ clientId: 5 });
|
|
546
|
+
const reasonsCsv = await janus.reports.returnsReasonsCsv({ clientId: 5 });
|
|
547
|
+
const overviewCsv = await janus.reports.returnsOverviewCsv({ clientId: 5 });
|
|
130
548
|
```
|
|
131
549
|
|
|
132
|
-
|
|
550
|
+
Returns can also export as CSV via the query filter:
|
|
133
551
|
|
|
134
552
|
```typescript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
clientId: 5,
|
|
138
|
-
created_at: '2024-01-01',
|
|
139
|
-
created_to: '2024-12-31',
|
|
140
|
-
groupBy: 'month',
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// CSV export
|
|
144
|
-
const csvData = await janus.reports.returnsSummaryCsv({ clientId: 5 });
|
|
553
|
+
const csv = await janus.returns.query({ clientId: 5, csv: true });
|
|
554
|
+
```
|
|
145
555
|
|
|
146
|
-
|
|
147
|
-
const reasonReport = await janus.reports.returnsReasons({ clientId: 5 });
|
|
148
|
-
const reasonCsv = await janus.reports.returnsReasonsCsv({ clientId: 5 });
|
|
556
|
+
### CRUD on Sub-Resources
|
|
149
557
|
|
|
150
|
-
|
|
151
|
-
const overview = await janus.reports.returnsOverview({ clientId: 5 });
|
|
152
|
-
const overviewCsv = await janus.reports.returnsOverviewCsv({ clientId: 5 });
|
|
558
|
+
Invoices, ASNs, and returns have nested sub-resources:
|
|
153
559
|
|
|
154
|
-
|
|
155
|
-
|
|
560
|
+
```typescript
|
|
561
|
+
// Invoice lines
|
|
562
|
+
const { data: lines } = await janus.invoices.getLines(invoiceId, { clientId: 5 });
|
|
563
|
+
await janus.invoices.createLine(invoiceId, lineData);
|
|
564
|
+
await janus.invoices.updateLine(invoiceId, lineId, updatedData);
|
|
565
|
+
|
|
566
|
+
// ASN lines and receipts
|
|
567
|
+
const { data: asnLines } = await janus.asns.getLines(asnId, { clientId: 5 });
|
|
568
|
+
await janus.asns.createReceipt(asnId, lineId, receiptData);
|
|
569
|
+
|
|
570
|
+
// Return items, comments, statuses
|
|
571
|
+
const items = await janus.returns.getItems(returnId);
|
|
572
|
+
await janus.returns.addComment(returnId, 'Inspected, item damaged');
|
|
573
|
+
await janus.returns.addStatus(returnId, statusId);
|
|
156
574
|
```
|
|
157
575
|
|
|
158
|
-
###
|
|
576
|
+
### Paginated Response Shape
|
|
159
577
|
|
|
160
|
-
|
|
161
|
-
// Submit return portal form (no auth required)
|
|
162
|
-
const result = await janus.helpers.submitReturnPortalForm(formData);
|
|
578
|
+
v2 endpoints return:
|
|
163
579
|
|
|
164
|
-
|
|
165
|
-
|
|
580
|
+
```typescript
|
|
581
|
+
{
|
|
582
|
+
data: T[],
|
|
583
|
+
meta: {
|
|
584
|
+
total_items: number,
|
|
585
|
+
total_pages: number,
|
|
586
|
+
current_page: number,
|
|
587
|
+
page_size: number,
|
|
588
|
+
}
|
|
589
|
+
}
|
|
166
590
|
```
|
|
167
591
|
|
|
168
|
-
|
|
592
|
+
### Raw API Access
|
|
169
593
|
|
|
170
|
-
|
|
594
|
+
For endpoints not yet wrapped:
|
|
171
595
|
|
|
172
596
|
```typescript
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
Return,
|
|
176
|
-
ReturnItem,
|
|
177
|
-
ReturnStatus,
|
|
178
|
-
ReturnReason,
|
|
179
|
-
User,
|
|
180
|
-
// ... more types
|
|
181
|
-
} from '@pelygo/janus';
|
|
597
|
+
const result = await janus.auth.get('/some/endpoint?clientId=5');
|
|
598
|
+
const result = await janus.auth.post('/some/endpoint', { body: 'data' });
|
|
182
599
|
```
|
|
183
600
|
|
|
184
|
-
|
|
601
|
+
---
|
|
185
602
|
|
|
186
|
-
|
|
187
|
-
import type { ReturnsQueryParams, ReportFilters } from '@pelygo/janus';
|
|
603
|
+
## Important Rules
|
|
188
604
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
};
|
|
194
|
-
```
|
|
605
|
+
1. **Always pass `clientId`.**
|
|
606
|
+
Get it from `useClient()` or equivalent. Never omit it.
|
|
607
|
+
- New v2 endpoints (`products`, `stocks`, `locations`, `invoices`, `asns`, `dispatches`) **reject with 400** if `clientId` is missing.
|
|
608
|
+
- Older endpoints (`orders`, `returns`) silently return **all clients' data** if omitted -- this is a data leak, not a feature.
|
|
195
609
|
|
|
196
|
-
|
|
610
|
+
2. **Use the exact field names from this README.**
|
|
611
|
+
Field names differ between entities (e.g. `sku_code` not `sku`, `product_name` not `name`, `price` not `value`). Do not guess -- refer to the tables above.
|
|
197
612
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
613
|
+
3. **Navigation in Base44/iframe environments must use `setTimeout`.**
|
|
614
|
+
Direct `window.location` or router calls inside callbacks (like `onUnauthorized`) will fail silently in iframed environments:
|
|
615
|
+
```typescript
|
|
616
|
+
onUnauthorized: () => {
|
|
617
|
+
setTimeout(() => window.location.href = '/login', 0);
|
|
618
|
+
},
|
|
619
|
+
```
|
|
201
620
|
|
|
202
|
-
|
|
203
|
-
|
|
621
|
+
4. **`baseUrl` and `authUrl` are different servers.**
|
|
622
|
+
Do not pass the same URL for both. The JANUS API server handles data; the auth server handles tokens.
|
|
204
623
|
|
|
205
|
-
|
|
206
|
-
|
|
624
|
+
5. **Use `janus.products` instead of `janus.legacy.queryProducts`.**
|
|
625
|
+
The `products` resource uses the newer v2 endpoint with proper pagination and typed responses.
|
|
207
626
|
|
|
208
|
-
|
|
209
|
-
npm run typecheck
|
|
627
|
+
---
|
|
210
628
|
|
|
211
|
-
|
|
212
|
-
npm run build
|
|
629
|
+
## API Behaviour Notes
|
|
213
630
|
|
|
214
|
-
|
|
215
|
-
|
|
631
|
+
### Error responses
|
|
632
|
+
```json
|
|
633
|
+
{ "statusCode": 400, "message": "Error description" }
|
|
216
634
|
```
|
|
635
|
+
Common codes: 400 (bad request/validation), 401 (unauthorized), 404 (not found).
|
|
217
636
|
|
|
218
|
-
###
|
|
637
|
+
### Date formats
|
|
638
|
+
- **Query params:** ISO 8601 format (`'2025-01-01'` or `'2025-01-01 12:00:00'`)
|
|
639
|
+
- **Response fields:** ISO 8601 timestamps (e.g. `created_ts`, `orderDate`, `created`)
|
|
640
|
+
- **CSV exports:** formatted as `DD-MM-YYYY HH:mm`
|
|
219
641
|
|
|
220
|
-
|
|
642
|
+
### Pagination defaults
|
|
643
|
+
- Default `pageSize`: 50 (v2 endpoints)
|
|
644
|
+
- Default `pageNumber`: 1 (1-based indexing)
|
|
645
|
+
- Default sort: DESC (newest first)
|
|
646
|
+
- Max sensible page size: 1,000
|
|
221
647
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
648
|
+
### Search behaviour (`query` param)
|
|
649
|
+
Free-text search is case-insensitive LIKE matching across key text columns:
|
|
650
|
+
- **Products:** `sku`, `name`, `description`
|
|
651
|
+
- **Returns:** order references, tracking numbers
|
|
652
|
+
- **Clients:** client names
|
|
653
|
+
- **Orders:** order references, channel IDs
|
|
227
654
|
|
|
228
|
-
|
|
229
|
-
|
|
655
|
+
### Returns-specific behaviour
|
|
656
|
+
- **Archived returns** (status ID 10) are excluded by default — pass `include_archived: true` to include
|
|
657
|
+
- **Return types:** `0` = regular return, `1` = exchange — filter with `return_types: '0'` or `'1'`
|
|
658
|
+
- **Associations:** `include_associations: 'return_items'` loads line items; `'return_items,return_comments'` loads both
|
|
659
|
+
- **Approval statuses:** `'pending'`, `'approved'`, `'rejected'`
|
|
230
660
|
|
|
231
|
-
|
|
661
|
+
### Stats responses
|
|
662
|
+
`getStats()` endpoints return flat objects with numeric values. **Keys vary by client data.** Always use `Object.entries(stats)` to iterate — never hardcode expected keys.
|
|
232
663
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## Type Imports
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
import type {
|
|
670
|
+
// Entities
|
|
671
|
+
Return, ReturnItem, ReturnStatus, ReturnReason, ReturnComment,
|
|
672
|
+
LegacyOrder, LegacyDispatch, LegacyOrderItem, LegacyDispatchItem,
|
|
673
|
+
LegacyShopperAddress,
|
|
674
|
+
FormattedProduct,
|
|
675
|
+
Stock,
|
|
676
|
+
Location,
|
|
677
|
+
Invoice, InvoiceLine,
|
|
678
|
+
Asn, AsnLine, AsnReceipt,
|
|
679
|
+
Client,
|
|
680
|
+
|
|
681
|
+
// Filters
|
|
682
|
+
ReturnsQueryFilters,
|
|
683
|
+
OrdersQueryFilters,
|
|
684
|
+
ClientScopedPaginatedQueryFilters,
|
|
685
|
+
PaginatedQueryFilters,
|
|
686
|
+
ReturnsSummaryFilters,
|
|
687
|
+
|
|
688
|
+
// Responses
|
|
689
|
+
PaginatedListResponse,
|
|
690
|
+
PaginatedResponse,
|
|
691
|
+
PaginationMeta,
|
|
692
|
+
ReturnsStatsResponse,
|
|
693
|
+
FilterOptionsResponse,
|
|
694
|
+
|
|
695
|
+
// API types
|
|
696
|
+
JanusApi,
|
|
697
|
+
JanusApiOptions,
|
|
698
|
+
} from '@pelygo/janus';
|
|
248
699
|
```
|
|
249
700
|
|
|
250
|
-
|
|
701
|
+
---
|
|
251
702
|
|
|
252
|
-
|
|
703
|
+
## Development
|
|
253
704
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
705
|
+
```bash
|
|
706
|
+
npm run build # Build with Vite
|
|
707
|
+
npm run typecheck # TypeScript check
|
|
708
|
+
npm run test # Run tests with Vitest
|
|
709
|
+
npm run test:run # Run tests once
|
|
710
|
+
npm run generate-types # Generate entity types from v2 TypeORM entities
|
|
711
|
+
```
|
|
257
712
|
|
|
258
713
|
## Related Packages
|
|
259
714
|
|
|
260
|
-
- [@pelygo/auth](https://www.npmjs.com/package/@pelygo/auth)
|
|
715
|
+
- [@pelygo/auth](https://www.npmjs.com/package/@pelygo/auth) -- Authentication client (peer dependency)
|
|
261
716
|
|
|
262
717
|
## License
|
|
263
718
|
|