@things-factory/worksheet-base 4.1.38 → 4.2.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.
Files changed (83) hide show
  1. package/dist-server/controllers/inbound/unloading-worksheet-controller.js +2 -0
  2. package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/outbound/packing-worksheet-controller.js +166 -8
  4. package/dist-server/controllers/outbound/packing-worksheet-controller.js.map +1 -1
  5. package/dist-server/controllers/outbound/picking-worksheet-controller.js +22 -22
  6. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  7. package/dist-server/controllers/outbound/sorting-worksheet-controller.js +110 -3
  8. package/dist-server/controllers/outbound/sorting-worksheet-controller.js.map +1 -1
  9. package/dist-server/controllers/render-grn.js +27 -3
  10. package/dist-server/controllers/render-grn.js.map +1 -1
  11. package/dist-server/controllers/render-orientage-do.js.map +1 -1
  12. package/dist-server/controllers/render-orientage-grn.js.map +1 -1
  13. package/dist-server/controllers/render-ro-do.js +65 -1
  14. package/dist-server/controllers/render-ro-do.js.map +1 -1
  15. package/dist-server/controllers/worksheet-controller.js +2 -1
  16. package/dist-server/controllers/worksheet-controller.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +30 -1
  18. package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
  19. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js +3 -0
  20. package/dist-server/graphql/resolvers/worksheet/inventories-by-pallet.js.map +1 -1
  21. package/dist-server/graphql/resolvers/worksheet/packing/index.js +2 -1
  22. package/dist-server/graphql/resolvers/worksheet/packing/index.js.map +1 -1
  23. package/dist-server/graphql/resolvers/worksheet/packing/packing.js +4 -4
  24. package/dist-server/graphql/resolvers/worksheet/packing/packing.js.map +1 -1
  25. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js +4 -4
  26. package/dist-server/graphql/resolvers/worksheet/packing/scan-product-packing.js.map +1 -1
  27. package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js +15 -0
  28. package/dist-server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.js.map +1 -0
  29. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js +152 -133
  30. package/dist-server/graphql/resolvers/worksheet/packing-worksheet.js.map +1 -1
  31. package/dist-server/graphql/resolvers/worksheet/picking/assign-picking-worker.js +13 -10
  32. package/dist-server/graphql/resolvers/worksheet/picking/assign-picking-worker.js.map +1 -1
  33. package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js +4 -7
  34. package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js.map +1 -1
  35. package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js +4 -4
  36. package/dist-server/graphql/resolvers/worksheet/sorting/scan-product-sorting.js.map +1 -1
  37. package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js +4 -4
  38. package/dist-server/graphql/resolvers/worksheet/sorting/sorting-product.js.map +1 -1
  39. package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js +6 -0
  40. package/dist-server/graphql/resolvers/worksheet/sorting-worksheet.js.map +1 -1
  41. package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js +4 -5
  42. package/dist-server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.js.map +1 -1
  43. package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js +4 -2
  44. package/dist-server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.js.map +1 -1
  45. package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js +11 -0
  46. package/dist-server/graphql/types/worksheet/find-release-orders-by-task-no.js.map +1 -0
  47. package/dist-server/graphql/types/worksheet/index.js +14 -4
  48. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  49. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js +2 -0
  50. package/dist-server/graphql/types/worksheet/worksheet-detail-info.js.map +1 -1
  51. package/dist-server/graphql/types/worksheet-detail/index.js +0 -2
  52. package/dist-server/graphql/types/worksheet-detail/index.js.map +1 -1
  53. package/dist-server/utils/inventory-util.js +14 -25
  54. package/dist-server/utils/inventory-util.js.map +1 -1
  55. package/package.json +17 -17
  56. package/server/controllers/inbound/unloading-worksheet-controller.ts +2 -0
  57. package/server/controllers/outbound/packing-worksheet-controller.ts +217 -11
  58. package/server/controllers/outbound/picking-worksheet-controller.ts +23 -24
  59. package/server/controllers/outbound/sorting-worksheet-controller.ts +149 -4
  60. package/server/controllers/render-grn.ts +39 -5
  61. package/server/controllers/render-orientage-do.ts +11 -11
  62. package/server/controllers/render-orientage-grn.ts +11 -11
  63. package/server/controllers/render-ro-do.ts +93 -8
  64. package/server/controllers/worksheet-controller.ts +2 -1
  65. package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +35 -2
  66. package/server/graphql/resolvers/worksheet/inventories-by-pallet.ts +2 -0
  67. package/server/graphql/resolvers/worksheet/packing/index.ts +3 -1
  68. package/server/graphql/resolvers/worksheet/packing/packing.ts +5 -4
  69. package/server/graphql/resolvers/worksheet/packing/scan-product-packing.ts +9 -4
  70. package/server/graphql/resolvers/worksheet/packing/undo-serial-number-packing.ts +24 -0
  71. package/server/graphql/resolvers/worksheet/packing-worksheet.ts +166 -144
  72. package/server/graphql/resolvers/worksheet/picking/assign-picking-worker.ts +15 -11
  73. package/server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.ts +5 -7
  74. package/server/graphql/resolvers/worksheet/sorting/scan-product-sorting.ts +5 -4
  75. package/server/graphql/resolvers/worksheet/sorting/sorting-product.ts +5 -4
  76. package/server/graphql/resolvers/worksheet/sorting-worksheet.ts +6 -0
  77. package/server/graphql/resolvers/worksheet-detail/generate-batch-picking-worksheet-details-by-bulk.ts +10 -12
  78. package/server/graphql/resolvers/worksheet-detail/generate-picking-worksheet-details.ts +4 -2
  79. package/server/graphql/types/worksheet/find-release-orders-by-task-no.ts +8 -0
  80. package/server/graphql/types/worksheet/index.ts +14 -4
  81. package/server/graphql/types/worksheet/worksheet-detail-info.ts +2 -0
  82. package/server/graphql/types/worksheet-detail/index.ts +0 -2
  83. package/server/utils/inventory-util.ts +15 -23
@@ -1,7 +1,8 @@
1
+ import _ from 'lodash'
1
2
  import FormData from 'form-data'
2
3
  import fetch from 'node-fetch'
3
4
  import { getRepository, IsNull, Not } from 'typeorm'
4
-
5
+ import { InventoryItem } from '@things-factory/warehouse-base'
5
6
  import { Attachment, STORAGE } from '@things-factory/attachment-base'
6
7
  import { Partner } from '@things-factory/auth-base'
7
8
  import { Bizplace, ContactPoint } from '@things-factory/biz-base'
@@ -32,6 +33,10 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
32
33
  const foundGAN: ArrivalNotice = foundGRN.arrivalNotice
33
34
  const ownRefNo = foundGAN.refNo
34
35
 
36
+ const foundInventoryItem: InventoryItem[] = await getRepository(InventoryItem).query(
37
+ `select row_number() over (partition by p.sku) as "seq",p.sku,p.brand_sku, ii.serial_number from inventory_items ii left join products p on ii.product_id = p.id where inbound_order_id = '${foundGAN.id}' group by p.sku,ii.serial_number,p.brand_sku`
38
+ )
39
+
35
40
  // 4. find customer bizplace
36
41
  const partnerBiz: Bizplace = foundGRN.bizplace
37
42
 
@@ -142,6 +147,32 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
142
147
  cop = 'data:' + foundSignature.mimetype + ';base64,' + (await STORAGE.readFile(foundCop.path, 'base64'))
143
148
  }
144
149
 
150
+ const filterInventoryItem = _.groupBy(foundInventoryItem, i => i.sku)
151
+
152
+ const tempIndexArr = []
153
+
154
+ const tempTotalQuantity = []
155
+
156
+ Object.keys(filterInventoryItem).forEach(k => {
157
+ const tempIndex = foundInventoryItem.findIndex(i => {
158
+ return i.sku == k
159
+ })
160
+
161
+ tempIndexArr.push(tempIndex)
162
+ })
163
+
164
+ Object.values(filterInventoryItem).forEach(k => {
165
+ const tempQuantity = k.length
166
+
167
+ tempTotalQuantity.push(tempQuantity)
168
+ })
169
+
170
+ tempIndexArr.forEach((t, index) => {
171
+ if (t >= 0)
172
+ foundInventoryItem[t].totalQuantity = tempTotalQuantity[index]
173
+ })
174
+
175
+
145
176
  const data = {
146
177
  logo_url: logo,
147
178
  sign_url: signature,
@@ -166,6 +197,7 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
166
197
  gan_accepted_at: foundGAN.acceptedAt ? DateTimeConverter.datetime(foundGAN.acceptedAt, timezoneOffSet) : '',
167
198
  unload_date: DateTimeConverter.date(foundWS.endedAt),
168
199
  ref_no: ownRefNo ? `${foundGAN.name} / ${foundGAN.refNo}` : `${foundGAN.name}`,
200
+ ref_no_only: ownRefNo ? ` ${foundGAN.refNo}` : '',
169
201
  ref_no1: foundGAN.refNo2 ? `${foundGAN.refNo2}` : '',
170
202
  ref_no2: foundGAN.refNo3 ? `${foundGAN.refNo3}` : '',
171
203
  received_date: DateTimeConverter.date(foundWS.endedAt),
@@ -188,6 +220,7 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
188
220
  return {
189
221
  list_no: idx + 1,
190
222
  product_sku: `${item.product.sku}`,
223
+ product_brand_sku: `${item.product.brandSku}`,
191
224
  product_name: `${item.product.name}(${item.product.description})`,
192
225
  product_desc: item.product.description,
193
226
  product_nameOnly: item.product.name,
@@ -198,17 +231,18 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
198
231
  pallet_qty: item.actualPalletQty,
199
232
  product_qty: unloadInvHistory.qty || item.actualPackQty,
200
233
  product_unit_uom_value: `${Math.round(item.uomValue * 100) / 100}`,
201
- product_total_uom_value: `${
202
- Math.round((unloadInvHistory.uomValue || item.uomValue * item.actualPackQty) * 100) / 100
203
- }`,
234
+ product_total_uom_value: `${Math.round((unloadInvHistory.uomValue || item.uomValue * item.actualPackQty) * 100) / 100
235
+ }`,
204
236
  product_uom: `${unloadInvHistory.uom || item.uom}`,
205
237
  product_gross_weight: item.product.grossWeight || null,
206
238
  unit_price: item.unitPrice || null,
207
239
  expiry_date: unloadInvHistory.expiryDate || '',
240
+ manufacture_date: item.manufactureDate,
208
241
  reusable_pallet_id: unloadInvHistory.reusablePalletId || '',
209
242
  remark: (item.remark ? item.remark : '') + (item.issue ? ' [Issue]: ' + item.issue : '')
210
243
  }
211
- })
244
+ }),
245
+ serialNumber: foundInventoryItem
212
246
  }
213
247
 
214
248
  const formData = new FormData()
@@ -150,20 +150,20 @@ export async function renderOrientageDO({ doNo }, context: any) {
150
150
  pack_size: matchedProductDetail
151
151
  ? matchedProductDetail.uomValue
152
152
  ? matchedProductDetail.uomValue +
153
- ' ' +
154
- matchedProductDetail.uom +
155
- (inventory.product.volumeSize
156
- ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
157
- : '')
153
+ ' ' +
154
+ matchedProductDetail.uom +
155
+ (inventory.product.volumeSize
156
+ ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
157
+ : '')
158
158
  : null
159
159
  : inventory.product.primaryValue
160
- ? inventory.product.primaryValue +
160
+ ? inventory.product.primaryValue +
161
161
  ' ' +
162
162
  inventory.product.primaryUnit +
163
163
  (inventory.product.volumeSize
164
164
  ? ' x ' + (parseFloat(inventory.product.volumeSize) / 100).toFixed(2) + ' L'
165
165
  : '')
166
- : null,
166
+ : null,
167
167
  aux_value_3: matchedProductDetail ? matchedProductDetail.auxValue3 : inventory.product.auxValue3,
168
168
  product_qty: targetInventory.inventory.warehouse !== 'DAMAGE ZONE' ? targetInventory.releaseQty : 0,
169
169
  product_qty_damage: targetInventory.inventory.warehouse === 'DAMAGE ZONE' ? targetInventory.releaseQty : 0,
@@ -176,15 +176,15 @@ export async function renderOrientageDO({ doNo }, context: any) {
176
176
  ? matchedProductDetail.volume
177
177
  : 0
178
178
  : inventory?.product?.volume
179
- ? inventory.product.volume
180
- : 0,
179
+ ? inventory.product.volume
180
+ : 0,
181
181
  total_volume: matchedProductDetail
182
182
  ? matchedProductDetail.volume
183
183
  ? Number((matchedProductDetail.volume * targetInventory.releaseQty).toFixed(4))
184
184
  : 0
185
185
  : inventory?.product?.volume
186
- ? Number((inventory.product.volume * targetInventory.releaseQty).toFixed(4))
187
- : 0,
186
+ ? Number((inventory.product.volume * targetInventory.releaseQty).toFixed(4))
187
+ : 0,
188
188
  remark: targetInventory.remark,
189
189
  inventory_remark: inventory.remark,
190
190
  cross_docking: targetInventory.crossDocking,
@@ -123,16 +123,16 @@ export async function renderOrientageGRN({ grnNo }, context: any) {
123
123
  pack_size: matchedProductDetail
124
124
  ? matchedProductDetail.uomValue
125
125
  ? matchedProductDetail.uomValue +
126
- ' ' +
127
- matchedProductDetail.uom +
128
- (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
126
+ ' ' +
127
+ matchedProductDetail.uom +
128
+ (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
129
129
  : null
130
130
  : item.product.primaryValue
131
- ? item.product.primaryValue +
131
+ ? item.product.primaryValue +
132
132
  ' ' +
133
133
  item.product.primaryUnit +
134
134
  (item.product.volumeSize ? ' x ' + (parseFloat(item.product.volumeSize) / 100).toFixed(2) + ' L' : '')
135
- : null,
135
+ : null,
136
136
  pack_qty: item.packQty ? item.packQty : 0,
137
137
  actual_pack_qty: item.actualPackQty ? item.actualPackQty : 0,
138
138
  container_no: foundGAN.containerNo ? foundGAN.containerNo : '',
@@ -142,15 +142,15 @@ export async function renderOrientageGRN({ grnNo }, context: any) {
142
142
  ? matchedProductDetail.volume
143
143
  : 0
144
144
  : item?.product?.volume
145
- ? item.product.volume
146
- : 0,
145
+ ? item.product.volume
146
+ : 0,
147
147
  total_volume: matchedProductDetail
148
148
  ? matchedProductDetail.volume
149
149
  ? Number((matchedProductDetail.volume * item.actualPackQty).toFixed(4))
150
150
  : 0
151
151
  : item?.product?.volume
152
- ? Number((item.product.volume * item.actualPackQty).toFixed(4))
153
- : 0,
152
+ ? Number((item.product.volume * item.actualPackQty).toFixed(4))
153
+ : 0,
154
154
  manufacture_year: item.manufactureDate ? new Date(item.manufactureDate).getFullYear() : null,
155
155
  manufacture_date: item.manufactureDate ? item.manufactureDate : null,
156
156
  literage: matchedProductDetail
@@ -158,8 +158,8 @@ export async function renderOrientageGRN({ grnNo }, context: any) {
158
158
  ? parseFloat(matchedProductDetail.packingSize) * parseFloat(item.product.volumeSize)
159
159
  : 0
160
160
  : item.packingSize
161
- ? parseFloat(item.packingSize) * parseFloat(item.product.volumeSize)
162
- : 0,
161
+ ? parseFloat(item.packingSize) * parseFloat(item.product.volumeSize)
162
+ : 0,
163
163
  remark: item.remark || ''
164
164
  }
165
165
  })
@@ -1,3 +1,4 @@
1
+ import _ from 'lodash'
1
2
  import FormData from 'form-data'
2
3
  import fetch from 'node-fetch'
3
4
  import { Equal, getRepository, In } from 'typeorm'
@@ -10,9 +11,10 @@ import { ProductDetail } from '@things-factory/product-base'
10
11
  import { DeliveryOrder, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
11
12
  import { Domain } from '@things-factory/shell'
12
13
  import { Inventory, Pallet } from '@things-factory/warehouse-base'
13
-
14
+ import { InventoryItem } from '@things-factory/warehouse-base'
14
15
  import { TEMPLATE_TYPE, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../constants'
15
16
  import { Worksheet, WorksheetDetail } from '../entities'
17
+ import { DateTimeConverter } from '../utils/datetime-util'
16
18
 
17
19
  const REPORT_API_URL = config.get('reportApiUrl', 'http://localhost:8888/rest/report/show_html')
18
20
 
@@ -48,6 +50,10 @@ export async function renderRODO({ doNo }, context: any) {
48
50
  const partnerBiz: Bizplace = foundDO.bizplace //customer bizplace
49
51
  const ownRefNo = foundRO.refNo
50
52
 
53
+ let foundInventoryItem: InventoryItem[] = await getRepository(InventoryItem).query(
54
+ `select row_number() over (partition by p.sku) as "seq",p.sku,p.brand_sku, ii.serial_number from inventory_items ii left join products p on ii.product_id = p.id where outbound_order_id = '${foundDO.releaseGood.id}' group by p.sku,ii.serial_number,p.brand_sku`
55
+ )
56
+
51
57
  const partnerDomain: Partner = await getRepository(Partner).findOne({
52
58
  where: { partnerDomain: partnerBiz.domain, domain },
53
59
  relations: ['domain']
@@ -70,6 +76,11 @@ export async function renderRODO({ doNo }, context: any) {
70
76
  relations: ['updater']
71
77
  })
72
78
 
79
+ const foundLoadingWS: Worksheet = await getRepository(Worksheet).findOne({
80
+ where: { domain, releaseGood: foundRO, type: WORKSHEET_TYPE.LOADING },
81
+ relations: ['updater']
82
+ })
83
+
73
84
  //find reusable pallet
74
85
  const foundRP: Pallet[] = await getRepository(Pallet).find({
75
86
  where: { domain, refOrderNo: foundRO.name }
@@ -211,6 +222,68 @@ export async function renderRODO({ doNo }, context: any) {
211
222
  }
212
223
  }, [])
213
224
 
225
+
226
+
227
+ let tempFoundInventoryItem: any = []
228
+
229
+ const sepProductList = productList.flatMap(p => Array.from({ length: p.product_qty }, () => ({ ...p })))
230
+
231
+ sepProductList.forEach((product) => {
232
+
233
+ let temp = foundInventoryItem.filter((item) => {
234
+ return item.sku == product.product_sku
235
+ })
236
+
237
+ if (temp.length > 1) {
238
+ temp.forEach(res => {
239
+ console.log(res)
240
+
241
+ if (tempFoundInventoryItem.length == 0) {
242
+ tempFoundInventoryItem.push(res)
243
+ } else {
244
+ const index = tempFoundInventoryItem.findIndex(res => res.serial_number == res.serial_number)
245
+
246
+ if (!index) {
247
+ tempFoundInventoryItem.push(res)
248
+ }
249
+ }
250
+
251
+ tempFoundInventoryItem = _.uniqWith(tempFoundInventoryItem, _.isEqual)
252
+ })
253
+ } else {
254
+ tempFoundInventoryItem.push(Object.assign({}, ...temp))
255
+ }
256
+ })
257
+
258
+ foundInventoryItem = tempFoundInventoryItem;
259
+
260
+ const filterInventoryItem = _.groupBy(foundInventoryItem, i => i.sku)
261
+
262
+ const tempIndexArr = []
263
+
264
+ const tempTotalQuantity = []
265
+
266
+ Object.keys(filterInventoryItem).forEach(k => {
267
+ const tempIndex = foundInventoryItem.findIndex(i => {
268
+ return i.sku == k
269
+ })
270
+
271
+ tempIndexArr.push(tempIndex)
272
+ })
273
+
274
+ Object.values(filterInventoryItem).forEach(k => {
275
+ const tempQuantity = k.length
276
+
277
+ tempTotalQuantity.push(tempQuantity)
278
+ })
279
+
280
+ tempIndexArr.forEach((t, index) => {
281
+ if (t >= 0)
282
+ foundInventoryItem[t].totalQuantity = tempTotalQuantity[index]
283
+ })
284
+
285
+ foundInventoryItem[0].ref_no = ownRefNo || ""
286
+
214
287
  const data = {
215
288
  logo_url: logo,
216
289
  customer_biz: partnerBiz.name,
@@ -231,9 +304,16 @@ export async function renderRODO({ doNo }, context: any) {
231
304
  customer_name: foundCP ? foundCP.name : null,
232
305
  customer_delivery_address: foundCP ? foundCP.address : null,
233
306
  customer_billing_address: foundCP ? foundCP.billingAddress : null,
307
+ new_billing_address: foundRO?.billingAddress || null,
234
308
  new_delivery_address: foundRO?.deliveryAddress1 || null,
235
309
  new_delivery_address2: foundRO?.deliveryAddress2 || null,
236
- new_billing_address: foundRO?.billingAddress || null,
310
+ new_delivery_address3: foundRO?.deliveryAddress3 || null,
311
+ new_delivery_address4: foundRO?.deliveryAddress4 || null,
312
+ new_delivery_address5: foundRO?.deliveryAddress5 || null,
313
+ new_delivery_city: foundRO?.city || null,
314
+ new_delivery_state: foundRO?.state || null,
315
+ new_delivery_postal_code: foundRO?.postalCode || null,
316
+ new_delivery_country: foundRO?.country || null,
237
317
  new_attention_to: foundRO?.attentionTo || null,
238
318
  new_attention_company: foundRO?.attentionCompany || null,
239
319
  new_phone_no: foundRO?.phone1 || null,
@@ -251,6 +331,8 @@ export async function renderRODO({ doNo }, context: any) {
251
331
  ref_no3: foundRO.refNo3 ? `${foundRO.refNo3}` : '',
252
332
  order_no: foundDO.name,
253
333
  delivery_date: foundDO.deliveryDate || '',
334
+ complete_loading_date: DateTimeConverter.date(foundLoadingWS.endedAt),
335
+ ro_created_date: DateTimeConverter.date(foundRO.createdAt),
254
336
  truck_no: foundDO.truckNo,
255
337
  driver_name: foundDriver || '',
256
338
  pallet_qty: foundDO.palletQty,
@@ -266,15 +348,18 @@ export async function renderRODO({ doNo }, context: any) {
266
348
  remark: prod?.remark
267
349
  ? prod.remark
268
350
  : prod.cross_docking
269
- ? prod.pallet === ''
270
- ? `${prod.palletQty} PALLET(S) [C/D]`
271
- : `${prod.palletQty} PALLET(S) (${prod.pallet}) [C/D]`
272
- : prod.pallet === ''
273
- ? `${prod.palletQty} PALLET(S)`
274
- : `${prod.palletQty} PALLET(S) (${prod.pallet})`,
351
+ ? prod.pallet === ''
352
+ ? `${prod.palletQty} PALLET(S) [C/D]`
353
+ : `${prod.palletQty} PALLET(S) (${prod.pallet}) [C/D]`
354
+ : prod.pallet === ''
355
+ ? `${prod.palletQty} PALLET(S)`
356
+ : `${prod.palletQty} PALLET(S) (${prod.pallet})`,
275
357
  inventory_remark: prod?.inventory_remark ? prod.inventory_remark : '',
276
358
  batch_id_ref: prod.product_batch_ref
277
359
  }
360
+ }),
361
+ serialNumber: foundInventoryItem.map((item: any, idx) => {
362
+ return { ...item, delivery_to: foundDO.to }
278
363
  })
279
364
  } //.. make data from do
280
365
  const formData = new FormData()
@@ -950,7 +950,8 @@ export class WorksheetController {
950
950
  const duplicatedSerialNumberCnt: number = await this.trxMgr.getRepository(InventoryItem).count({
951
951
  domain: this.domain,
952
952
  product,
953
- serialNumber
953
+ serialNumber,
954
+ status: Not(Equal(INVENTORY_STATUS.DELETED))
954
955
  })
955
956
 
956
957
  if (duplicatedSerialNumberCnt) throw new Error(this.ERROR_MSG.VALIDITY.DUPLICATED('Serial Number', serialNumber))
@@ -1,11 +1,12 @@
1
1
  import { EntityManager, SelectQueryBuilder } from 'typeorm'
2
2
 
3
3
  import {
4
- ORDER_STATUS,
4
+ ORDER_STATUS, ORDER_INVENTORY_STATUS,
5
5
  OrderInventory as OrderInventoryEntity,
6
6
  ReleaseGood as ReleaseGoodEntity
7
7
  } from '@things-factory/sales-base'
8
8
  import { Domain } from '@things-factory/shell'
9
+ import { Location } from '@things-factory/warehouse-base'
9
10
 
10
11
  import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
11
12
  import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
@@ -16,6 +17,38 @@ export const findReleaseOrdersByTaskNoResolver = {
16
17
  let task = await tx.getRepository(WorksheetEntity).findOne({
17
18
  where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
18
19
  })
20
+
21
+ // Find Task based on Bin
22
+ if (!task) {
23
+ const binLocation: Location = await tx.getRepository(Location).findOne({
24
+ where: { domain, name: taskNo }
25
+ })
26
+
27
+ const qb: SelectQueryBuilder<OrderInventoryEntity> = tx.getRepository(OrderInventoryEntity).createQueryBuilder('orderInventory')
28
+
29
+ qb.innerJoinAndSelect('orderInventory.releaseGood', 'releaseGood')
30
+ .innerJoinAndSelect('worksheets', 'ws', `orderInventory.ref_worksheet_id = ws.id AND ws.type = 'BATCH_PICKING'`)
31
+ .innerJoinAndSelect('worksheets', 'ws2', `ws2.task_no = ws.task_no AND ws2.type = 'SORTING'`)
32
+ .innerJoinAndSelect('releaseGood.bizplace', 'bizplace')
33
+ .innerJoinAndSelect('bizplace.domain', 'domain')
34
+ .where('orderInventory.domain_id = :domainId', { domainId: domain.id })
35
+ .andWhere('orderInventory.status IN (:...orderInventoryStatus)', {
36
+ orderInventoryStatus: [ORDER_INVENTORY_STATUS.SORTING]
37
+ })
38
+ .andWhere('orderInventory.bin_location_id = :locationId', { locationId: binLocation.id })
39
+ .andWhere('releaseGood.status = :status', { status: ORDER_STATUS.SORTING })
40
+
41
+ const orderInventoryByBin = await qb.getRawOne()
42
+ if (orderInventoryByBin?.releaseGood_id) {
43
+ taskNo = orderInventoryByBin.ws_task_no
44
+ task = await tx.getRepository(WorksheetEntity).findOne({
45
+ where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
46
+ })
47
+ } else {
48
+ throw new Error(`Bin do not have any batch picking order.`)
49
+ }
50
+ }
51
+
19
52
  if (!task) throw new Error('Unable to find task no.')
20
53
 
21
54
  const qb: SelectQueryBuilder<WorksheetEntity> = tx
@@ -38,6 +71,6 @@ export const findReleaseOrdersByTaskNoResolver = {
38
71
  .addGroupBy('rg.status')
39
72
 
40
73
  const releaseGoods: ReleaseGoodEntity[] = await qb.getRawMany()
41
- return releaseGoods
74
+ return { releaseGoods, taskNo }
42
75
  }
43
76
  }
@@ -78,6 +78,8 @@ export const inventoriesByPalletResolver = {
78
78
  locationSortingRules.forEach((rule: { name: string; desc: boolean }) => {
79
79
  qb.addOrderBy(`location.${rule.name}`, rule.desc ? 'DESC' : 'ASC')
80
80
  })
81
+ } else {
82
+ qb.addOrderBy('location.name', 'DESC')
81
83
  }
82
84
 
83
85
  if (productFilters && productFilters.length > 0) {
@@ -2,10 +2,12 @@ import { activatePackingResolver } from './activate-packing'
2
2
  import { completePackingResolver } from './complete-packing'
3
3
  import { packingResolver } from './packing'
4
4
  import { scanProductPackingResolver } from './scan-product-packing'
5
+ import { undoSerialNumberPackingResolver } from './undo-serial-number-packing'
5
6
 
6
7
  export const Mutations = {
7
8
  ...activatePackingResolver,
8
9
  ...completePackingResolver,
9
10
  ...packingResolver,
10
- ...scanProductPackingResolver
11
+ ...scanProductPackingResolver,
12
+ ...undoSerialNumberPackingResolver
11
13
  }
@@ -9,9 +9,9 @@ import { PackingWorksheetController, SellercraftController } from '../../../../c
9
9
  import { Worksheet } from '../../../../entities'
10
10
 
11
11
  export const packingResolver = {
12
- async packing(_: any, { worksheetDetailName, releaseQty }, context: any) {
12
+ async packing(_: any, { worksheetDetailName, releaseQty, serialNumber }, context: any) {
13
13
  const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
14
- await packing(tx, domain, user, worksheetDetailName, releaseQty)
14
+ await packing(tx, domain, user, worksheetDetailName, releaseQty, serialNumber)
15
15
  }
16
16
  }
17
17
 
@@ -20,10 +20,11 @@ export async function packing(
20
20
  domain: Domain,
21
21
  user: User,
22
22
  worksheetDetailName: string,
23
- releaseQty: number
23
+ releaseQty: number,
24
+ serialNumber: string
24
25
  ) {
25
26
  const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
26
- const worksheetDetail = await worksheetController.packing(worksheetDetailName, releaseQty)
27
+ const worksheetDetail = await worksheetController.packing(worksheetDetailName, releaseQty, serialNumber)
27
28
 
28
29
  let releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
29
30
  const worksheet: Worksheet = worksheetDetail.worksheet
@@ -9,9 +9,9 @@ import { PackingWorksheetController, SellercraftController } from '../../../../c
9
9
  import { Worksheet } from '../../../../entities'
10
10
 
11
11
  export const scanProductPackingResolver = {
12
- async scanProductPacking(_: any, { worksheetDetailName, productBarcode }, context: any) {
12
+ async scanProductPacking(_: any, { worksheetDetailName, productBarcode, serialNumber }, context: any) {
13
13
  const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
14
- await scanProductPacking(tx, domain, user, worksheetDetailName, productBarcode)
14
+ await scanProductPacking(tx, domain, user, worksheetDetailName, productBarcode, serialNumber)
15
15
  }
16
16
  }
17
17
 
@@ -20,10 +20,15 @@ export async function scanProductPacking(
20
20
  domain: Domain,
21
21
  user: User,
22
22
  worksheetDetailName: string,
23
- productBarcode: string
23
+ productBarcode: string,
24
+ serialNumber?: string
24
25
  ) {
25
26
  const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
26
- const worksheetDetail = await worksheetController.scanProductPacking(worksheetDetailName, productBarcode)
27
+ const worksheetDetail = await worksheetController.scanProductPacking(
28
+ worksheetDetailName,
29
+ productBarcode,
30
+ serialNumber
31
+ )
27
32
 
28
33
  let releaseGood: ReleaseGood = worksheetDetail.targetInventory.releaseGood
29
34
  const worksheet: Worksheet = worksheetDetail.worksheet
@@ -0,0 +1,24 @@
1
+ import { EntityManager } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Domain } from '@things-factory/shell'
5
+
6
+ import { PackingWorksheetController } from '../../../../controllers'
7
+
8
+ export const undoSerialNumberPackingResolver = {
9
+ async undoSerialNumberPacking(_: any, { worksheetDetailName, inventoryItemId }, context: any) {
10
+ const { tx, domain, user }: { tx: EntityManager; domain: Domain; user: User } = context.state
11
+ await undoSerialNumberPacking(tx, domain, user, worksheetDetailName, inventoryItemId)
12
+ }
13
+ }
14
+
15
+ async function undoSerialNumberPacking(
16
+ tx: EntityManager,
17
+ domain: Domain,
18
+ user: User,
19
+ worksheetDetailName: string,
20
+ inventoryItemId: string
21
+ ): Promise<void> {
22
+ const worksheetController: PackingWorksheetController = new PackingWorksheetController(tx, domain, user)
23
+ await worksheetController.undoSerialNumberPacking(worksheetDetailName, inventoryItemId)
24
+ }