@things-factory/operato-hub 4.3.626 → 4.3.629

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.
Files changed (20) hide show
  1. package/dist-server/controllers/company-initializer/settings.js +2 -1
  2. package/dist-server/controllers/company-initializer/settings.js.map +1 -1
  3. package/dist-server/routers/api/restful-apis/v1/utils/params.js +35 -3
  4. package/dist-server/routers/api/restful-apis/v1/utils/params.js.map +1 -1
  5. package/dist-server/routers/api/restful-apis/v1/warehouse/add-return-order.js +325 -0
  6. package/dist-server/routers/api/restful-apis/v1/warehouse/add-return-order.js.map +1 -0
  7. package/dist-server/routers/api/restful-apis/v1/warehouse/get-return-order-details.js +94 -0
  8. package/dist-server/routers/api/restful-apis/v1/warehouse/get-return-order-details.js.map +1 -0
  9. package/dist-server/routers/api/restful-apis/v1/warehouse/get-return-order-list.js +63 -0
  10. package/dist-server/routers/api/restful-apis/v1/warehouse/get-return-order-list.js.map +1 -0
  11. package/dist-server/routers/api/restful-apis/v1/warehouse/index.js +13 -10
  12. package/dist-server/routers/api/restful-apis/v1/warehouse/index.js.map +1 -1
  13. package/openapi/v1/return-order.yaml +486 -0
  14. package/package.json +4 -4
  15. package/server/controllers/company-initializer/settings.ts +2 -1
  16. package/server/routers/api/restful-apis/v1/utils/params.ts +35 -3
  17. package/server/routers/api/restful-apis/v1/warehouse/add-return-order.ts +360 -0
  18. package/server/routers/api/restful-apis/v1/warehouse/get-return-order-details.ts +99 -0
  19. package/server/routers/api/restful-apis/v1/warehouse/get-return-order-list.ts +68 -0
  20. package/server/routers/api/restful-apis/v1/warehouse/index.ts +13 -10
@@ -633,6 +633,30 @@ export const params = {
633
633
  'sellerDiscount',
634
634
  'shippingFee',
635
635
  'actualShippingFee'
636
+ ],
637
+ 'add-return-order': [
638
+ 'bizplaceId',
639
+ 'releaseGoodName',
640
+ 'orderInventories',
641
+ 'orderInventories.productDetail',
642
+ 'orderInventories.productDetail.id',
643
+ 'orderInventories.returnQty',
644
+ 'orderInventories.batchId',
645
+ 'remark',
646
+ 'ownTransport',
647
+ 'warehouseTransport',
648
+ 'collectionOrderNo'
649
+ ],
650
+ 'get-return-order-list': [
651
+ 'bizplaceId',
652
+ 'name',
653
+ ...fromToDate,
654
+ ...limitOffset
655
+ ],
656
+ 'get-return-order-details': [
657
+ 'bizplaceId',
658
+ 'id',
659
+ 'returnOrderNo'
636
660
  ]
637
661
  }
638
662
 
@@ -1106,7 +1130,13 @@ export const reqParams = {
1106
1130
  { name: 'paidPrice', required: true, type: 'field' }
1107
1131
  ]
1108
1132
  }
1109
- ]
1133
+ ],
1134
+ 'add-return-order': [
1135
+ { name: 'bizplaceId', required: true, type: 'field' },
1136
+ { name: 'releaseGoodName', required: true, type: 'field' }
1137
+ ],
1138
+ 'get-return-order-list': ['bizplaceId'],
1139
+ 'get-return-order-details': []
1110
1140
  }
1111
1141
 
1112
1142
  // Require Offset
@@ -1124,7 +1154,8 @@ export const requireLimitOffsetValidation = [
1124
1154
  'get-contact-point-list',
1125
1155
  'get-bizplace-list',
1126
1156
  'get-draft-order-list',
1127
- 'get-inventory-adjustment-list'
1157
+ 'get-inventory-adjustment-list',
1158
+ 'get-return-order-list'
1128
1159
  ]
1129
1160
 
1130
1161
  // Require fromDate and toDate
@@ -1135,5 +1166,6 @@ export const requireFromToDateValidation = [
1135
1166
  'get-delivery-order-list',
1136
1167
  'get-marketplace-order-shipping-list',
1137
1168
  'get-draft-order-list',
1138
- 'get-inventory-adjustment-list'
1169
+ 'get-inventory-adjustment-list',
1170
+ 'get-return-order-list'
1139
1171
  ]
@@ -0,0 +1,360 @@
1
+ import { EntityManager, getConnection, In } from 'typeorm'
2
+
3
+ import { restfulApiRouter as router } from '@things-factory/api'
4
+ import { User } from '@things-factory/auth-base'
5
+ import { Bizplace } from '@things-factory/biz-base'
6
+ import { ORDER_STATUS, generateReturnOrder, ReleaseGood } from '@things-factory/sales-base'
7
+ import { Domain } from '@things-factory/shell'
8
+
9
+ import { businessMiddleware, loggingMiddleware, validationMiddleware } from '../middlewares'
10
+ import { ApiError, ApiErrorHandler, throwInternalServerError } from '../utils/error-util'
11
+
12
+ router.post(
13
+ '/v1/warehouse/add-return-order',
14
+ businessMiddleware,
15
+ validationMiddleware,
16
+ loggingMiddleware,
17
+ async (context, next) => {
18
+ try {
19
+ const { domain, user } = context.state
20
+ const bodyReq = context.request.body.data
21
+
22
+ // // Basic validations before
23
+ // Transport type validations
24
+ if (!bodyReq.ownTransport && !bodyReq.warehouseTransport) {
25
+ throw new ApiError('E01', 'Please select a transport type')
26
+ }
27
+
28
+ if (bodyReq.ownTransport && bodyReq.warehouseTransport) {
29
+ throw new ApiError('E01', 'You can only select one transport type')
30
+ }
31
+
32
+ // // Order inventories basic validations
33
+ if (!bodyReq.orderInventories || !Array.isArray(bodyReq.orderInventories) || bodyReq.orderInventories.length === 0) {
34
+ throw new ApiError('E01', 'orderInventories is required and must be a non-empty array')
35
+ }
36
+
37
+ // Validate each inventory item's required fields
38
+ for (const returnItem of bodyReq.orderInventories) {
39
+ if (!returnItem.productDetail || !returnItem.productDetail.id) {
40
+ throw new ApiError('E01', 'productDetail.id is required for each order inventory')
41
+ }
42
+
43
+ if (!returnItem.returnQty || returnItem.returnQty <= 0) {
44
+ throw new ApiError('E01', 'returnQty must be greater than 0 for each order inventory')
45
+ }
46
+
47
+ if (!returnItem.batchId) {
48
+ throw new ApiError('E01', 'batchId is required for each order inventory')
49
+ }
50
+ }
51
+
52
+ await getConnection().transaction(async (tx: EntityManager) => {
53
+ // 1. Get customer bizplace
54
+ const customerBizplace: Bizplace = await tx.getRepository(Bizplace).findOne({
55
+ where: { id: bodyReq.bizplaceId },
56
+ relations: ['domain']
57
+ })
58
+
59
+ if (!customerBizplace) {
60
+ throw new ApiError('E04', 'customer bizplace not found')
61
+ }
62
+
63
+ // 2. Get release good details and validate
64
+ const releaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
65
+ where: {
66
+ domain,
67
+ name: bodyReq.releaseGoodName,
68
+ bizplace: customerBizplace,
69
+ status: In([ORDER_STATUS.DONE])
70
+ },
71
+ relations: [
72
+ 'orderInventories',
73
+ 'orderInventories.product',
74
+ 'orderInventories.productDetail',
75
+ 'orderInventories.inventory',
76
+ 'orderInventories.inventory.product',
77
+ 'orderInventories.inventory.product.productDetails'
78
+ ]
79
+ })
80
+
81
+ if (!releaseGood) {
82
+ throw new ApiError('E04', `Release good ${bodyReq.releaseGoodName} not found`)
83
+ }
84
+
85
+ // 3. Validate each return item against original order (by productDetailId only)
86
+ for (const returnItem of bodyReq.orderInventories) {
87
+ const originalOrderInventory = releaseGood.orderInventories.find(oi =>
88
+ oi.productDetail && oi.productDetail.id === returnItem.productDetail.id && oi.inventory.batchId === returnItem.batchId
89
+ )
90
+
91
+ if (!originalOrderInventory) {
92
+ throw new ApiError('E01', `productDetail.id:${returnItem.productDetail.id} with batchId:${returnItem.batchId} was not found in the original order`)
93
+ }
94
+
95
+ if (returnItem.returnQty > originalOrderInventory.releaseQty) {
96
+ throw new ApiError('E01', `Return quantity ${returnItem.returnQty} exceeds original order quantity ${originalOrderInventory.releaseQty} for product detail ${returnItem.productDetail.id}`)
97
+ }
98
+
99
+ returnItem.product = originalOrderInventory.product
100
+ }
101
+
102
+ // 4. Prepare return order data
103
+ const returnOrder = {
104
+ customerBizplaceId: bodyReq.bizplaceId,
105
+ orderInventories: bodyReq.orderInventories,
106
+ remark: bodyReq.remark || null,
107
+ ownTransport: bodyReq.ownTransport || false,
108
+ collectionOrderNo: bodyReq.collectionOrderNo || null
109
+ }
110
+
111
+ // 5. Generate return order
112
+ const result = await generateReturnOrder(tx, domain, user, returnOrder, [], context)
113
+
114
+ // 6. Prepare response data
115
+ const data = {
116
+ id: result.id,
117
+ name: result.name,
118
+ status: result.status,
119
+ remark: result.remark,
120
+ ownTransport: result.ownTransport,
121
+ collectionOrderNo: result.collectionOrderNo,
122
+ bizplace: { name: result.bizplace.name },
123
+ domain: { name: result.domain.name }
124
+ }
125
+
126
+ context.body = {
127
+ responseCode: '200',
128
+ message: 'success',
129
+ data
130
+ }
131
+ })
132
+ } catch (e) {
133
+ if (e instanceof ApiError) {
134
+ ApiErrorHandler(context, e)
135
+ } else {
136
+ throwInternalServerError(context, e)
137
+ }
138
+ }
139
+ }
140
+ )
141
+
142
+ // Sample Request:
143
+ // POST /api/v1/warehouse/add-return-order
144
+ // Headers:
145
+ // Content-Type: application/json
146
+ // Authorization: Bearer <token>
147
+ // Body:
148
+ // {
149
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
150
+ // "releaseGoodName": "RG-2023001",
151
+ // "orderInventories": [
152
+ // {
153
+ // "productDetail": {
154
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
155
+ // },
156
+ // "returnQty": 10,
157
+ // "batchId": "batch-001"
158
+ // }
159
+ // ],
160
+ // "remark": "Customer returned items due to defect",
161
+ // "ownTransport": true,
162
+ // "collectionOrderNo": "COL-123456"
163
+ // }
164
+
165
+ // Sample Postman Test Cases:
166
+ // Test Case 1: Valid Return Order with Single Inventory
167
+ // Description: Test the creation of a return order with valid data and a single inventory item.
168
+ // Method: POST
169
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
170
+ // Headers:
171
+ // Content-Type: application/json
172
+ // Authorization: Bearer <token>
173
+ // Body:
174
+ // {
175
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
176
+ // "releaseGoodName": "RG-2023001",
177
+ // "orderInventories": [
178
+ // {
179
+ // "productDetail": {
180
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
181
+ // },
182
+ // "returnQty": 10,
183
+ // "batchId": "batch-001"
184
+ // }
185
+ // ],
186
+ // "remark": "Customer returned items due to defect",
187
+ // "ownTransport": true,
188
+ // "collectionOrderNo": "COL-123456"
189
+ // }
190
+
191
+ // Test Case 2: Valid Return Order with Multiple Inventories
192
+ // Description: Test the creation of a return order with valid data and multiple inventory items.
193
+ // Method: POST
194
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
195
+ // Headers:
196
+ // Content-Type: application/json
197
+ // Authorization: Bearer <token>
198
+ // Body:
199
+ // {
200
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
201
+ // "releaseGoodName": "RG-2023001",
202
+ // "orderInventories": [
203
+ // {
204
+ // "productDetail": {
205
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
206
+ // },
207
+ // "returnQty": 10,
208
+ // "batchId": "batch-001"
209
+ // },
210
+ // {
211
+ // "productDetail": {
212
+ // "id": "123e4567-e89b-12d3-a456-426614174998"
213
+ // },
214
+ // "returnQty": 5,
215
+ // "batchId": "batch-002"
216
+ // }
217
+ // ],
218
+ // "remark": "Customer returned items due to defect",
219
+ // "ownTransport": true,
220
+ // "collectionOrderNo": "COL-123456"
221
+ // }
222
+
223
+ // Test Case 3: Missing Bizplace ID
224
+ // Description: Test the creation of a return order without a bizplace ID.
225
+ // Method: POST
226
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
227
+ // Headers:
228
+ // Content-Type: application/json
229
+ // Authorization: Bearer <token>
230
+ // Body:
231
+ // {
232
+ // "releaseGoodName": "RG-2023001",
233
+ // "orderInventories": [
234
+ // {
235
+ // "productDetail": {
236
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
237
+ // },
238
+ // "returnQty": 10,
239
+ // "batchId": "batch-001"
240
+ // }
241
+ // ],
242
+ // "remark": "Customer returned items due to defect",
243
+ // "ownTransport": true,
244
+ // "collectionOrderNo": "COL-123456"
245
+ // }
246
+
247
+ // Test Case 4: Invalid Return Quantity
248
+ // Description: Test the creation of a return order with a negative return quantity.
249
+ // Method: POST
250
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
251
+ // Headers:
252
+ // Content-Type: application/json
253
+ // Authorization: Bearer <token>
254
+ // Body:
255
+ // {
256
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
257
+ // "releaseGoodName": "RG-2023001",
258
+ // "orderInventories": [
259
+ // {
260
+ // "productDetail": {
261
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
262
+ // },
263
+ // "returnQty": -5,
264
+ // "batchId": "batch-001"
265
+ // }
266
+ // ],
267
+ // "remark": "Customer returned items due to defect",
268
+ // "ownTransport": true,
269
+ // "collectionOrderNo": "COL-123456"
270
+ // }
271
+
272
+ // Test Case 5: Missing Order Inventories
273
+ // Description: Test the creation of a return order without order inventories.
274
+ // Method: POST
275
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
276
+ // Headers:
277
+ // Content-Type: application/json
278
+ // Authorization: Bearer <token>
279
+ // Body:
280
+ // {
281
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
282
+ // "releaseGoodName": "RG-2023001",
283
+ // "remark": "Customer returned items due to defect",
284
+ // "ownTransport": true,
285
+ // "collectionOrderNo": "COL-123456"
286
+ // }
287
+
288
+ // Test Case 6: Invalid Product Detail ID
289
+ // Description: Test the creation of a return order with an invalid productDetail.id.
290
+ // Method: POST
291
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
292
+ // Headers:
293
+ // Content-Type: application/json
294
+ // Authorization: Bearer <token>
295
+ // Body:
296
+ // {
297
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
298
+ // "releaseGoodName": "RG-2023001",
299
+ // "orderInventories": [
300
+ // {
301
+ // "productDetail": {
302
+ // "id": "invalid-product-detail-id"
303
+ // },
304
+ // "returnQty": 10,
305
+ // "batchId": "batch-001"
306
+ // }
307
+ // ],
308
+ // "remark": "Customer returned items due to defect",
309
+ // "ownTransport": true,
310
+ // "collectionOrderNo": "COL-123456"
311
+ // }
312
+
313
+ // Test Case 7: Missing Release Good Name
314
+ // Description: Test the creation of a return order without a release good name.
315
+ // Method: POST
316
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
317
+ // Headers:
318
+ // Content-Type: application/json
319
+ // Authorization: Bearer <token>
320
+ // Body:
321
+ // {
322
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
323
+ // "orderInventories": [
324
+ // {
325
+ // "productDetail": {
326
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
327
+ // },
328
+ // "returnQty": 10,
329
+ // "batchId": "batch-001"
330
+ // }
331
+ // ],
332
+ // "remark": "Customer returned items due to defect",
333
+ // "ownTransport": true,
334
+ // "collectionOrderNo": "COL-123456"
335
+ // }
336
+
337
+ // Test Case 8: Invalid Release Good Name
338
+ // Description: Test the creation of a return order with a non-existent release good name.
339
+ // Method: POST
340
+ // URL: http://<server-url>/api/v1/warehouse/add-return-order
341
+ // Headers:
342
+ // Content-Type: application/json
343
+ // Authorization: Bearer <token>
344
+ // Body:
345
+ // {
346
+ // "bizplaceId": "123e4567-e89b-12d3-a456-426614174000",
347
+ // "releaseGoodName": "INVALID-RG-2023001",
348
+ // "orderInventories": [
349
+ // {
350
+ // "productDetail": {
351
+ // "id": "987e6543-e21b-12d3-a456-426614174999"
352
+ // },
353
+ // "returnQty": 10,
354
+ // "batchId": "batch-001"
355
+ // }
356
+ // ],
357
+ // "remark": "Customer returned items due to defect",
358
+ // "ownTransport": true,
359
+ // "collectionOrderNo": "COL-123456"
360
+ // }
@@ -0,0 +1,99 @@
1
+ import _ from 'lodash'
2
+ import { getRepository } from 'typeorm'
3
+ import { ReturnOrder } from '@things-factory/sales-base'
4
+
5
+ import { restfulApiRouter as router } from '@things-factory/api'
6
+ import { businessMiddleware, loggingMiddleware, validationMiddleware } from '../middlewares'
7
+ import { ApiError, ApiErrorHandler, throwInternalServerError } from '../utils/error-util'
8
+
9
+ router.get(
10
+ '/v1/warehouse/get-return-order-details',
11
+ businessMiddleware,
12
+ validationMiddleware,
13
+ loggingMiddleware,
14
+ async (context, next) => {
15
+ try {
16
+ const { domain } = context.state
17
+ let filter = { ...context.query, domain: domain.id }
18
+ if (filter.bizplaceId) {
19
+ filter['bizplace'] = filter['bizplaceId']
20
+ delete filter['bizplaceId']
21
+ }
22
+ if (filter.id) {
23
+ filter['id'] = filter['id']
24
+ }
25
+
26
+ if (filter.returnOrderNo) {
27
+ filter['name'] = filter['returnOrderNo']
28
+ delete filter['returnOrderNo']
29
+ }
30
+
31
+ if (!filter.id && !filter.name) {
32
+ throw new ApiError('E01', 'return order number or id is required')
33
+ }
34
+
35
+ const returnOrder: ReturnOrder = await getRepository(ReturnOrder).findOne({
36
+ where: filter,
37
+ relations: [
38
+ 'bizplace',
39
+ 'orderInventories',
40
+ 'orderInventories.product',
41
+ 'orderInventories.productDetail',
42
+ 'creator',
43
+ 'updater',
44
+ 'acceptedBy'
45
+ ]
46
+ })
47
+ if (!returnOrder) {
48
+ throw new ApiError('E04', 'return order')
49
+ }
50
+ // Flatten inventoryInfos for frontend
51
+ const itemInfos = (returnOrder.orderInventories || []).map(orderInv => {
52
+ return {
53
+ batchId: orderInv.batchId,
54
+ product: {
55
+ id: orderInv.product.id,
56
+ sku: orderInv.product.sku,
57
+ brandSku: orderInv.product?.brandSku,
58
+ brand: orderInv.product?.brand,
59
+ subBrand: orderInv.product?.subBrand
60
+ },
61
+ productDetail: {
62
+ id: orderInv.productDetail.id,
63
+ refCode: orderInv.productDetail.refCode,
64
+ isDefault: orderInv.productDetail?.isDefault,
65
+ packingType: orderInv.productDetail.packingType,
66
+ packingSize: orderInv.productDetail.packingSize,
67
+ movement: orderInv.productDetail?.movement,
68
+ uom: orderInv.productDetail?.uom,
69
+ uomValue: orderInv.productDetail?.uomValue
70
+ },
71
+ returnQty: orderInv.returnQty,
72
+ remark: orderInv.remark,
73
+ status: orderInv.status
74
+ }
75
+ })
76
+ const data = {
77
+ id: returnOrder.id,
78
+ name: returnOrder.name,
79
+ status: returnOrder.status,
80
+ ownTransport: returnOrder.ownTransport,
81
+ eta: returnOrder.eta,
82
+ etaDate: returnOrder.etaDate,
83
+ remark: returnOrder.remark,
84
+ refNo: returnOrder.refNo,
85
+ bizplace: returnOrder.bizplace ? { id: returnOrder.bizplace.id, name: returnOrder.bizplace.name } : null,
86
+ creator: returnOrder.creator ? { id: returnOrder.creator.id, name: returnOrder.creator.name } : null,
87
+ updater: returnOrder.updater ? { id: returnOrder.updater.id, name: returnOrder.updater.name } : null,
88
+ acceptedBy: returnOrder.acceptedBy ? { id: returnOrder.acceptedBy.id, name: returnOrder.acceptedBy.name } : null,
89
+ createdAt: returnOrder.createdAt,
90
+ updatedAt: returnOrder.updatedAt,
91
+ itemInfos
92
+ }
93
+ context.body = { data }
94
+ } catch (e) {
95
+ if (e instanceof ApiError) ApiErrorHandler(context, e)
96
+ else throwInternalServerError(context, e)
97
+ }
98
+ }
99
+ )
@@ -0,0 +1,68 @@
1
+ import _ from 'lodash'
2
+ import { Between, getRepository } from 'typeorm'
3
+
4
+ import { restfulApiRouter as router } from '@things-factory/api'
5
+ import { ReturnOrder } from '@things-factory/sales-base'
6
+
7
+ import { businessMiddleware, loggingMiddleware, validationMiddleware } from '../middlewares'
8
+ import { ApiError, ApiErrorHandler, throwInternalServerError } from '../utils/error-util'
9
+
10
+ router.get(
11
+ '/v1/warehouse/get-return-order-list',
12
+ businessMiddleware,
13
+ validationMiddleware,
14
+ loggingMiddleware,
15
+ async (context, next) => {
16
+ try {
17
+ let filter = { ...context.query }
18
+ const { fromDate, toDate, offset, limit } = filter
19
+ if (filter.bizplaceId) {
20
+ filter['bizplace'] = filter['bizplaceId']
21
+ delete filter['bizplaceId']
22
+ }
23
+ if (filter.name) {
24
+ filter['name'] = filter['name']
25
+ }
26
+ if (fromDate && toDate) {
27
+ filter['createdAt'] = Between(fromDate, toDate)
28
+ }
29
+ delete filter['fromDate']
30
+ delete filter['toDate']
31
+ delete filter['limit']
32
+ delete filter['offset']
33
+
34
+ const [returnOrders, totalCount]: [ReturnOrder[], number] = await getRepository(ReturnOrder).findAndCount({
35
+ where: filter,
36
+ relations: ['bizplace', 'creator', 'updater', 'acceptedBy'],
37
+ skip: offset ? Number(offset) : 0,
38
+ take: limit ? Number(limit) : 100,
39
+ order: { createdAt: 'DESC' }
40
+ })
41
+ const data = returnOrders.map(ro => ({
42
+ id: ro.id,
43
+ name: ro.name,
44
+ status: ro.status,
45
+ ownTransport: ro.ownTransport,
46
+ eta: ro.eta,
47
+ etaDate: ro.etaDate,
48
+ remark: ro.remark,
49
+ refNo: ro.refNo,
50
+ bizplace: ro.bizplace ? { id: ro.bizplace.id, name: ro.bizplace.name } : null,
51
+ creator: ro.creator ? { id: ro.creator.id, name: ro.creator.name } : null,
52
+ updater: ro.updater ? { id: ro.updater.id, name: ro.updater.name } : null,
53
+ acceptedBy: ro.acceptedBy ? { id: ro.acceptedBy.id, name: ro.acceptedBy.name } : null,
54
+ createdAt: ro.createdAt,
55
+ updatedAt: ro.updatedAt
56
+ }))
57
+ context.body = {
58
+ data,
59
+ totalCount,
60
+ limit: limit ? Number(limit) : 100,
61
+ offset: offset ? Number(offset) : 0
62
+ }
63
+ } catch (e) {
64
+ if (e instanceof ApiError) ApiErrorHandler(context, e)
65
+ else throwInternalServerError(context, e)
66
+ }
67
+ }
68
+ )
@@ -1,26 +1,29 @@
1
1
  import './add-inbound-order'
2
2
  import './add-release-order'
3
+ import './add-return-order'
4
+ import './add-sales-invoice'
3
5
  import './cancel-inbound-order'
4
6
  import './cancel-release-order'
7
+ import './complete-delivery-order'
8
+ import './dispatch-delivery-order'
5
9
  import './get-delivery-order-list'
10
+ import './get-do-document'
11
+ import './get-draft-order-details'
6
12
  import './get-draft-order-list'
7
13
  import './get-goods-received-note-list'
14
+ import './get-grn-document'
8
15
  import './get-inbound-order-details'
9
16
  import './get-inbound-order-list'
17
+ import './get-inventory-adjustment-details'
18
+ import './get-inventory-adjustment-list'
10
19
  import './get-inventory-product-group-list'
20
+ import './get-manifest-details'
11
21
  import './get-onhand-inventory-list'
12
- import './get-draft-order-details'
13
22
  import './get-release-order-details'
14
23
  import './get-release-order-list'
24
+ import './get-return-order-details'
25
+ import './get-return-order-list'
15
26
  import './get-warehouse-bizplace-onhand-inventories'
16
- import './update-release-order-details'
17
- import './get-grn-document'
18
- import './get-do-document'
19
- import './dispatch-delivery-order'
20
27
  import './update-gan-to-arrived'
21
- import './complete-delivery-order'
22
- import './get-inventory-adjustment-list'
23
- import './get-inventory-adjustment-details'
24
- import './get-manifest-details'
25
28
  import './update-order-package-details'
26
- import './add-sales-invoice'
29
+ import './update-release-order-details'