@things-factory/worksheet-base 4.3.37 → 4.3.40

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 (37) hide show
  1. package/dist-server/controllers/outbound/picking-worksheet-controller.js +6 -17
  2. package/dist-server/controllers/outbound/picking-worksheet-controller.js.map +1 -1
  3. package/dist-server/controllers/render-po.js +18 -9
  4. package/dist-server/controllers/render-po.js.map +1 -1
  5. package/dist-server/controllers/render-ro-do.js +1 -1
  6. package/dist-server/controllers/render-ro-do.js.map +1 -1
  7. package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js +64 -76
  8. package/dist-server/graphql/resolvers/worksheet/confirm-cancellation-release-order.js.map +1 -1
  9. package/dist-server/graphql/resolvers/worksheet/fetch-delivery-order-ro.js +169 -0
  10. package/dist-server/graphql/resolvers/worksheet/fetch-delivery-order-ro.js.map +1 -0
  11. package/dist-server/graphql/resolvers/worksheet/index.js +2 -1
  12. package/dist-server/graphql/resolvers/worksheet/index.js.map +1 -1
  13. package/dist-server/graphql/resolvers/worksheet/pending-cancellation-release-order.js +2 -1
  14. package/dist-server/graphql/resolvers/worksheet/pending-cancellation-release-order.js.map +1 -1
  15. package/dist-server/graphql/resolvers/worksheet/reject-cancellation-release-order.js +1 -0
  16. package/dist-server/graphql/resolvers/worksheet/reject-cancellation-release-order.js.map +1 -1
  17. package/dist-server/graphql/resolvers/worksheet-detail/generate-pallet-id.js +2 -2
  18. package/dist-server/graphql/resolvers/worksheet-detail/generate-pallet-id.js.map +1 -1
  19. package/dist-server/graphql/types/worksheet/delivery-order-ro.js +18 -0
  20. package/dist-server/graphql/types/worksheet/delivery-order-ro.js.map +1 -0
  21. package/dist-server/graphql/types/worksheet/index.js +7 -1
  22. package/dist-server/graphql/types/worksheet/index.js.map +1 -1
  23. package/dist-server/graphql/types/worksheet-detail/inventory-detail.js +1 -0
  24. package/dist-server/graphql/types/worksheet-detail/inventory-detail.js.map +1 -1
  25. package/package.json +15 -15
  26. package/server/controllers/outbound/picking-worksheet-controller.ts +7 -17
  27. package/server/controllers/render-po.ts +30 -13
  28. package/server/controllers/render-ro-do.ts +1 -1
  29. package/server/graphql/resolvers/worksheet/confirm-cancellation-release-order.ts +92 -131
  30. package/server/graphql/resolvers/worksheet/fetch-delivery-order-ro.ts +193 -0
  31. package/server/graphql/resolvers/worksheet/index.ts +3 -1
  32. package/server/graphql/resolvers/worksheet/pending-cancellation-release-order.ts +1 -0
  33. package/server/graphql/resolvers/worksheet/reject-cancellation-release-order.ts +16 -15
  34. package/server/graphql/resolvers/worksheet-detail/generate-pallet-id.ts +2 -1
  35. package/server/graphql/types/worksheet/delivery-order-ro.ts +15 -0
  36. package/server/graphql/types/worksheet/index.ts +9 -2
  37. package/server/graphql/types/worksheet-detail/inventory-detail.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/worksheet/index.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AACzC,yEAAmE;AACnE,6DAAuD;AACvD,mEAA6D;AAC7D,mDAA8C;AAC9C,+DAAyD;AACzD,6DAAwD;AACxD,+DAA0D;AAC1D,qFAA4E;AAC5E,+DAAyD;AACzD,2EAAqE;AACrE,uEAAiE;AACjE,iFAA0E;AAC1E,mDAA8C;AAC9C,2EAAqE;AACrE,yDAAoD;AACpD,qEAA+D;AAC/D,qEAA+D;AAC/D,+DAAyD;AACzD,2CAAuC;AACvC,mEAA6D;AAC7D,qDAAgD;AAChD,qDAAgD;AAChD,uDAAkD;AAClD,2EAAqE;AAExD,QAAA,QAAQ,GAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6hBrC,CAAA;AAEY,QAAA,KAAK,GAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0IlC,CAAA;AAEY,QAAA,KAAK,GAAiB;IACjC,qBAAS;IACT,uBAAU;IACV,4BAAY;IACZ,gCAAc;IACd,8BAAa;IACb,iDAAsB;IACtB,6CAAoB;IACpB,2CAAmB;IACnB,6CAAoB;IACpB,mDAAuB;IACvB,uCAAiB;IACjB,uCAAiB;IACjB,qCAAgB;IAChB,uCAAiB;IACjB,8BAAa;IACb,4BAAY;IACZ,sCAAiB;IACjB,2CAAmB;IACnB,wCAAkB;IAClB,+CAAqB;IACrB,kCAAe;IACf,mDAAuB;IACvB,mDAAuB;IACvB,wDAAyB;IACzB,0DAAyB;CAC1B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../server/graphql/types/worksheet/index.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AACzC,yEAAmE;AACnE,6DAAuD;AACvD,mEAA6D;AAC7D,mDAA8C;AAC9C,+DAAyD;AACzD,6DAAwD;AACxD,+DAA0D;AAC1D,qFAA4E;AAC5E,+DAAyD;AACzD,2EAAqE;AACrE,uEAAiE;AACjE,iFAA0E;AAC1E,mDAA8C;AAC9C,2EAAqE;AACrE,yDAAoD;AACpD,qEAA+D;AAC/D,qEAA+D;AAC/D,+DAAyD;AACzD,2CAAuC;AACvC,mEAA6D;AAC7D,qDAAgD;AAChD,qDAAgD;AAChD,uDAAkD;AAClD,2EAAqE;AACrE,2DAAqD;AAGxC,QAAA,QAAQ,GAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6hBrC,CAAA;AAEY,QAAA,KAAK,GAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8IlC,CAAA;AAEY,QAAA,KAAK,GAAgB;IAChC,qBAAS;IACT,uBAAU;IACV,4BAAY;IACZ,gCAAc;IACd,8BAAa;IACb,iDAAsB;IACtB,6CAAoB;IACpB,2CAAmB;IACnB,6CAAoB;IACpB,mDAAuB;IACvB,uCAAiB;IACjB,uCAAiB;IACjB,qCAAgB;IAChB,uCAAiB;IACjB,8BAAa;IACb,4BAAY;IACZ,sCAAiB;IACjB,2CAAmB;IACnB,wCAAkB;IAClB,+CAAqB;IACrB,kCAAe;IACf,mDAAuB;IACvB,mDAAuB;IACvB,wDAAyB;IACzB,0DAAyB;IACzB,mCAAe;CAChB,CAAA"}
@@ -39,6 +39,7 @@ exports.InventoryDetail = (0, graphql_tag_1.default) `
39
39
  orderProductRemark: String
40
40
  purchaseOrderNo: String
41
41
  arrivalNoticeRefNo: String
42
+ arrivalNoticeNo: String
42
43
  }
43
44
  `;
44
45
  //# sourceMappingURL=inventory-detail.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inventory-detail.js","sourceRoot":"","sources":["../../../../server/graphql/types/worksheet-detail/inventory-detail.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,eAAe,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCjC,CAAA"}
1
+ {"version":3,"file":"inventory-detail.js","sourceRoot":"","sources":["../../../../server/graphql/types/worksheet-detail/inventory-detail.ts"],"names":[],"mappings":";;;;;;AAAA,8DAA6B;AAEhB,QAAA,eAAe,GAAG,IAAA,qBAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCjC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/worksheet-base",
3
- "version": "4.3.37",
3
+ "version": "4.3.40",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,21 +24,21 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
25
25
  },
26
26
  "dependencies": {
27
- "@things-factory/auth-base": "^4.3.35",
28
- "@things-factory/biz-base": "^4.3.35",
27
+ "@things-factory/auth-base": "^4.3.40",
28
+ "@things-factory/biz-base": "^4.3.40",
29
29
  "@things-factory/document-template-base": "^4.3.35",
30
- "@things-factory/id-rule-base": "^4.3.35",
31
- "@things-factory/integration-lmd": "^4.3.35",
32
- "@things-factory/integration-marketplace": "^4.3.37",
33
- "@things-factory/integration-sellercraft": "^4.3.37",
34
- "@things-factory/integration-sftp": "^4.3.37",
35
- "@things-factory/marketplace-base": "^4.3.37",
36
- "@things-factory/notification": "^4.3.35",
37
- "@things-factory/sales-base": "^4.3.37",
38
- "@things-factory/setting-base": "^4.3.35",
30
+ "@things-factory/id-rule-base": "^4.3.40",
31
+ "@things-factory/integration-lmd": "^4.3.40",
32
+ "@things-factory/integration-marketplace": "^4.3.40",
33
+ "@things-factory/integration-sellercraft": "^4.3.40",
34
+ "@things-factory/integration-sftp": "^4.3.40",
35
+ "@things-factory/marketplace-base": "^4.3.40",
36
+ "@things-factory/notification": "^4.3.40",
37
+ "@things-factory/sales-base": "^4.3.40",
38
+ "@things-factory/setting-base": "^4.3.40",
39
39
  "@things-factory/shell": "^4.3.35",
40
- "@things-factory/transport-base": "^4.3.35",
41
- "@things-factory/warehouse-base": "^4.3.37"
40
+ "@things-factory/transport-base": "^4.3.40",
41
+ "@things-factory/warehouse-base": "^4.3.40"
42
42
  },
43
- "gitHead": "63cc1d86f82b002d7bd96a72347e8d333c1b696a"
43
+ "gitHead": "5ae9cd8d8abe747c4e8ac9e243468c1f6662481b"
44
44
  }
@@ -1152,25 +1152,15 @@ export class PickingWorksheetController extends VasWorksheetController {
1152
1152
 
1153
1153
  private async checkAndSetBinPicking(orderInventory, binLocation) {
1154
1154
  // bin picking validation
1155
- const binPickingSetting: Setting = await this.trxMgr.getRepository(Setting).findOne({
1156
- where: {
1157
- domain: this.domain,
1158
- name: 'enable-bin-picking'
1159
- }
1160
- })
1161
- if (binPickingSetting != undefined && binPickingSetting.value.toLowerCase() == 'true') {
1162
- if (binLocation) {
1163
- const foundBinLocation: Location = await this.trxMgr.getRepository(Location).findOne({
1164
- where: { domain: this.domain, name: binLocation, type: LOCATION_TYPE.BIN }
1165
- })
1166
-
1167
- if (!foundBinLocation)
1168
- throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
1155
+ if (binLocation) {
1156
+ const foundBinLocation: Location = await this.trxMgr.getRepository(Location).findOne({
1157
+ where: { domain: this.domain, name: binLocation, type: LOCATION_TYPE.BIN }
1158
+ })
1169
1159
 
1170
- orderInventory.binLocation = foundBinLocation
1171
- } else {
1160
+ if (!foundBinLocation)
1172
1161
  throw new Error(this.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`))
1173
- }
1162
+
1163
+ orderInventory.binLocation = foundBinLocation
1174
1164
  }
1175
1165
 
1176
1166
  return orderInventory
@@ -5,7 +5,13 @@ import { getRepository, SelectQueryBuilder } from 'typeorm'
5
5
  import { Attachment, STORAGE } from '@things-factory/attachment-base'
6
6
  import { Bizplace } from '@things-factory/biz-base'
7
7
  import { config } from '@things-factory/env'
8
- import { InvoiceProduct, ReleaseGood, PurchaseOrder, PurchaseOrderOtherCharge, OrderProduct } from '@things-factory/sales-base'
8
+ import {
9
+ InvoiceProduct,
10
+ ReleaseGood,
11
+ PurchaseOrder,
12
+ PurchaseOrderOtherCharge,
13
+ OrderProduct
14
+ } from '@things-factory/sales-base'
9
15
 
10
16
  import { Domain } from '@things-factory/shell'
11
17
 
@@ -31,6 +37,7 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
31
37
  .innerJoinAndSelect('bizplace.company', 'company')
32
38
  .innerJoinAndSelect('company.domain', 'company_domain')
33
39
  .leftJoinAndSelect('contact_points', 'cp', 'po.supplier_id = cp.id')
40
+ .leftJoinAndSelect('arrival_notices', 'an', 'an.purchase_order_id = po.id')
34
41
  .where('po.id = :poId')
35
42
  .andWhere('po.domain = :domainId')
36
43
  .setParameters({ poId, domainId: domain.id })
@@ -71,7 +78,6 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
71
78
 
72
79
  let poOtherCharges: any[] = await poocQb.getRawMany()
73
80
 
74
-
75
81
  const qb: SelectQueryBuilder<OrderProduct> = await getRepository(OrderProduct)
76
82
  .createQueryBuilder('op')
77
83
  .innerJoin('domains', 'd', 'op.domain_id = d.id')
@@ -89,17 +95,21 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
89
95
  product_sku: item.p_sku,
90
96
  product_name: item.p_name,
91
97
  product_desc: item.p_description,
98
+ product_remark: item.op_remark,
92
99
  product_qty: item.op_pack_qty,
93
100
  product_uom: item.op_uom,
94
101
  product_other_charges: item.ip_other_charges,
95
- product_unit_price: (item.op_unit_price).toFixed(2),
96
- product_total_price: ((((item.op_unit_price || 0) * item.op_pack_qty) - (item.op_discount_amt || 0)) * (1 + (item.op_tax_rate / 100))).toFixed(2),
102
+ product_unit_price: item.op_unit_price.toFixed(2),
103
+ product_total_price: (
104
+ ((item.op_unit_price || 0) * item.op_pack_qty - (item.op_discount_amt || 0)) *
105
+ (1 + item.op_tax_rate / 100)
106
+ ).toFixed(2),
97
107
  product_tax_rate: item.op_tax_rate,
98
- product_disc_amt: item.op_discount_amt
108
+ product_disc_amt: item.op_discount_amt,
109
+ ref_no: record.po_ref_no
99
110
  }
100
111
  })
101
112
 
102
-
103
113
  let date = DateTimeConverter.date(new Date(record.po_created_at - timezoneOffSet))
104
114
  let eta = DateTimeConverter.date(new Date(record.po_eta_date))
105
115
 
@@ -114,6 +124,7 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
114
124
  company_name: record.company_description,
115
125
  company_address: record.company_address,
116
126
  company_postal_code: record.company_postal_code,
127
+ an_name: record.an_name,
117
128
  po_number: record.po_name,
118
129
  po_order_date: date,
119
130
  po_delivery_date: eta,
@@ -126,14 +137,20 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
126
137
  product_list,
127
138
  charges_list: [
128
139
  {
129
- field: 'SUBTOTAL', value: subtotal.toFixed(2)
140
+ field: 'SUBTOTAL',
141
+ value: subtotal.toFixed(2)
130
142
  },
131
- ...poOtherCharges.map(itm => { return { field: itm.pooc_name.toUpperCase(), value: itm.pooc_total_amt.toFixed(2) } }),
143
+ ...poOtherCharges.map(itm => {
144
+ return { field: itm.pooc_name.toUpperCase(), value: itm.pooc_total_amt.toFixed(2) }
145
+ }),
132
146
  {
133
- field: 'TOTAL', value: (poOtherCharges.reduce((init, item) => {
134
- return init += (item.pooc_total_amt)
135
- }, subtotal) || 0).toFixed(2),
136
- },
147
+ field: 'TOTAL',
148
+ value: (
149
+ poOtherCharges.reduce((init, item) => {
150
+ return (init += item.pooc_total_amt)
151
+ }, subtotal) || 0
152
+ ).toFixed(2)
153
+ }
137
154
  ]
138
155
  }
139
156
 
@@ -141,7 +158,7 @@ export async function renderPO({ req, timezoneOffSet }, context: any) {
141
158
  formData.append('template', template)
142
159
  formData.append('jsonString', JSON.stringify(data))
143
160
 
144
- const response = await fetch(REPORT_API_URL, {
161
+ const response = await fetch(REPORT_API_URL, {
145
162
  method: 'POST',
146
163
  body: formData
147
164
  })
@@ -360,7 +360,7 @@ export async function renderRODO({ doNo }, context: any) {
360
360
  }),
361
361
  serialNumber: foundInventoryItem.map((item: any, idx) => {
362
362
  return { ...item, delivery_to: foundDO.to }
363
- })
363
+ }) || ''
364
364
  } //.. make data from do
365
365
  const formData = new FormData()
366
366
 
@@ -1,24 +1,20 @@
1
- import {
2
- Inventory,
3
- Location,
4
- LOCATION_STATUS,
5
- INVENTORY_STATUS,
6
- INVENTORY_TRANSACTION_TYPE
7
- } from '@things-factory/warehouse-base'
8
- import { User } from '@things-factory/auth-base'
9
- import { Domain } from '@things-factory/shell'
10
1
  import { EntityManager, In } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
11
4
  import {
5
+ DeliveryOrder,
12
6
  ORDER_INVENTORY_STATUS,
13
7
  ORDER_STATUS,
14
8
  ORDER_VAS_STATUS,
15
9
  OrderInventory,
16
- DeliveryOrder,
17
10
  OrderVas,
18
11
  ReleaseGood
19
12
  } from '@things-factory/sales-base'
20
- import { generateInventoryHistory } from '../../../utils'
13
+ import { Domain } from '@things-factory/shell'
14
+ import { Inventory, INVENTORY_STATUS, INVENTORY_TRANSACTION_TYPE, Location } from '@things-factory/warehouse-base'
15
+
21
16
  import { Worksheet, WorksheetDetail } from '../../../entities'
17
+ import { generateInventoryHistory } from '../../../utils'
22
18
 
23
19
  export const confirmCancellationReleaseOrder = {
24
20
  async confirmCancellationReleaseOrder(_: any, { name }, context: any) {
@@ -39,132 +35,82 @@ export const confirmCancellationReleaseOrder = {
39
35
  let foundOVs: OrderVas[] = releaseGood.orderVass
40
36
 
41
37
  // 1. Check Order Inventory status
42
- // 1a. separate into two groups, group 1: pending cancel, group 2: picked
43
- let cancelOI: OrderInventory[] = targetOIs.filter(
44
- (oi: OrderInventory) => oi.status === ORDER_INVENTORY_STATUS.PENDING_CANCEL
45
- ).reduce((acc, oi) => {
46
- let existingRecordIdx = acc.findIndex(i => i.inventory.id == oi.inventory.id)
47
- if (existingRecordIdx >= 0) {
48
- acc[existingRecordIdx].releaseQty += oi.releaseQty
49
- acc[existingRecordIdx].releaseUomValue += oi.releaseQty
50
- } else {
51
- acc.push(oi)
52
- }
53
- return acc
54
- }, [])
55
-
56
- let pickedOI: OrderInventory[] = targetOIs.filter(
57
- (oi: OrderInventory) => oi.status === ORDER_INVENTORY_STATUS.PENDING_REVERSE
58
- ).reduce((acc, oi) => {
59
- let existingRecordIdx = acc.findIndex(i => i.inventory.id == oi.inventory.id)
60
- if (existingRecordIdx >= 0) {
61
- acc[existingRecordIdx].releaseQty += oi.releaseQty
62
- acc[existingRecordIdx].releaseUomValue += oi.releaseQty
63
- } else {
64
- acc.push(oi)
65
- }
66
- return acc
67
- }, [])
68
-
69
- let replacedOI: OrderInventory[] = targetOIs.filter(
70
- (oi: OrderInventory) => oi.status === ORDER_INVENTORY_STATUS.REPLACED
71
- ).reduce((acc, oi) => {
72
- let existingRecordIdx = acc.findIndex(i => i.inventory.id == oi.inventory.id)
73
- if (existingRecordIdx >= 0) {
74
- acc[existingRecordIdx].releaseQty += oi.releaseQty
75
- acc[existingRecordIdx].releaseUomValue += oi.releaseQty
76
- } else {
77
- acc.push(oi)
78
- }
79
- return acc
80
- }, [])
81
-
82
- if (pickedOI && pickedOI?.length) {
83
- await tx.getRepository(OrderInventory).save(
84
- await Promise.all(
85
- pickedOI.map(async (orderInventory: OrderInventory) => {
86
- let inventory: Inventory = orderInventory.inventory
87
- let location: Location = inventory.location
88
-
89
- let cancelledTargetInventory: OrderInventory = Object.assign({}, orderInventory)
90
- cancelledTargetInventory.status = ORDER_INVENTORY_STATUS.CANCELLED
91
- cancelledTargetInventory.updater = user
92
-
93
- if (inventory) {
94
- inventory = await tx.getRepository(Inventory).findOne({ id: inventory.id })
95
- inventory.qty += orderInventory.releaseQty
96
- inventory.uomValue += orderInventory.releaseUomValue
97
- inventory.status = INVENTORY_STATUS.STORED
98
- inventory.updater = user
99
- inventory = await tx.getRepository(Inventory).save(inventory)
100
-
101
- await generateInventoryHistory(
102
- inventory,
103
- releaseGood,
104
- INVENTORY_TRANSACTION_TYPE.CANCEL_ORDER,
105
- orderInventory.releaseQty,
106
- orderInventory.releaseUomValue,
107
- user,
108
- tx
109
- )
110
- }
111
-
112
- // Update status of location
113
- if (location.status === LOCATION_STATUS.EMPTY) {
114
- location.status = LOCATION_STATUS.OCCUPIED
115
- location.updater = user
116
- await tx.getRepository(Location).save(location)
117
- }
118
-
119
- return cancelledTargetInventory
120
- })
121
- )
38
+ // 1a. separate into three groups, group 1: pending cancel, group 2: picked, group 3: replaced
39
+ let cancelOIs: OrderInventory[] = _filterOrderInventoriesByStatus(targetOIs, ORDER_INVENTORY_STATUS.PENDING_CANCEL)
40
+ let pickedOIs: OrderInventory[] = _filterOrderInventoriesByStatus(targetOIs, ORDER_INVENTORY_STATUS.PENDING_REVERSE)
41
+ let replacedOIs: OrderInventory[] = _filterOrderInventoriesByStatus(targetOIs, ORDER_INVENTORY_STATUS.REPLACED)
42
+
43
+ if (pickedOIs && pickedOIs.length) {
44
+ await Promise.all(
45
+ pickedOIs.map(async (orderInventory: OrderInventory) => {
46
+ let inventory: Inventory = orderInventory.inventory
47
+ let location: Location = inventory?.location
48
+
49
+ if (inventory && inventory.id) {
50
+ await tx
51
+ .createQueryBuilder()
52
+ .update(Inventory)
53
+ .set({
54
+ qty: () => `COALESCE("qty", 0) + ${orderInventory.releaseQty}`,
55
+ uomValue: () => `COALESCE("uom_value", 0) + ${orderInventory.releaseUomValue}`,
56
+ status: INVENTORY_STATUS.STORED,
57
+ updater: user
58
+ })
59
+ .where('id = :id', { id: inventory.id })
60
+ .execute()
61
+
62
+ await generateInventoryHistory(
63
+ inventory,
64
+ releaseGood,
65
+ INVENTORY_TRANSACTION_TYPE.CANCEL_ORDER,
66
+ orderInventory.releaseQty,
67
+ orderInventory.releaseUomValue,
68
+ user,
69
+ tx
70
+ )
71
+ }
72
+
73
+ return orderInventory
74
+ })
122
75
  )
76
+
77
+ await tx
78
+ .getRepository(OrderInventory)
79
+ .update(pickedOIs, { status: ORDER_INVENTORY_STATUS.CANCELLED, updater: user })
123
80
  }
124
81
 
125
- // change status to cancelled for order inventory that has not executed yet
126
- if (cancelOI && cancelOI?.length) {
127
- await tx.getRepository(OrderInventory).save(
128
- await Promise.all(
129
- cancelOI.map(async (orderInventory: OrderInventory) => {
130
- let inventory: Inventory = orderInventory.inventory
131
-
132
- if (inventory) {
133
- inventory = await tx.getRepository(Inventory).findOne({ id: inventory.id })
134
- inventory.lockedQty -= orderInventory.releaseQty
135
- inventory.lockedUomValue -= orderInventory.releaseUomValue
136
- await tx.getRepository(Inventory).save(inventory)
137
-
138
- await generateInventoryHistory(
139
- inventory,
140
- releaseGood,
141
- INVENTORY_TRANSACTION_TYPE.CANCEL_ORDER,
142
- 0,
143
- 0,
144
- user,
145
- tx
146
- )
147
- }
148
-
149
- let cancelledTargetInventory: OrderInventory = Object.assign({}, orderInventory)
150
- cancelledTargetInventory.status = ORDER_INVENTORY_STATUS.CANCELLED
151
- cancelledTargetInventory.updater = user
152
-
153
- return cancelledTargetInventory
154
- })
155
- )
82
+ // change status to cancelled for order inventory that has not executed yet and remove locked qty
83
+ if (cancelOIs && cancelOIs.length) {
84
+ await Promise.all(
85
+ cancelOIs.map(async (orderInventory: OrderInventory) => {
86
+ let inventory: Inventory = orderInventory.inventory
87
+
88
+ if (inventory && inventory.id) {
89
+ await tx
90
+ .createQueryBuilder()
91
+ .update(Inventory)
92
+ .set({
93
+ lockedQty: () => `COALESCE("locked_qty", 0) - ${orderInventory.releaseQty}`,
94
+ lockedUomValue: () => `COALESCE("locked_uom_value", 0) - ${orderInventory.releaseUomValue}`,
95
+ updater: user
96
+ })
97
+ .where('id = :id', { id: inventory.id })
98
+ .execute()
99
+ }
100
+
101
+ return orderInventory
102
+ })
156
103
  )
104
+
105
+ await tx
106
+ .getRepository(OrderInventory)
107
+ .update(cancelOIs, { status: ORDER_INVENTORY_STATUS.CANCELLED, updater: user })
157
108
  }
158
109
 
159
- if (replacedOI && replacedOI?.length) {
160
- replacedOI = replacedOI.map((orderInventory: OrderInventory) => {
161
- return {
162
- ...orderInventory,
163
- status: ORDER_INVENTORY_STATUS.CANCELLED,
164
- updater: user
165
- }
166
- })
167
- await tx.getRepository(OrderInventory).save(replacedOI)
110
+ if (replacedOIs && replacedOIs.length) {
111
+ await tx
112
+ .getRepository(OrderInventory)
113
+ .update(replacedOIs, { status: ORDER_INVENTORY_STATUS.CANCELLED, updater: user })
168
114
  }
169
115
 
170
116
  if (foundOVs && foundOVs?.length) {
@@ -234,3 +180,18 @@ export const confirmCancellationReleaseOrder = {
234
180
  return
235
181
  }
236
182
  }
183
+
184
+ function _filterOrderInventoriesByStatus(orderInventories: OrderInventory[], status: string): OrderInventory[] {
185
+ return orderInventories
186
+ .filter((oi: OrderInventory) => oi.status === status)
187
+ .reduce((acc, oi) => {
188
+ let existingInvIdx = !oi.inventory ? -1 : acc.findIndex(i => i.inventory?.id == oi.inventory?.id)
189
+ if (existingInvIdx >= 0) {
190
+ acc[existingInvIdx].releaseQty += oi.releaseQty
191
+ acc[existingInvIdx].releaseUomValue += oi.releaseQty
192
+ } else {
193
+ acc.push(oi)
194
+ }
195
+ return acc
196
+ }, [])
197
+ }
@@ -0,0 +1,193 @@
1
+ import _ from 'lodash'
2
+ import FormData from 'form-data'
3
+ import fetch from 'node-fetch'
4
+ import { Equal, getRepository, In } from 'typeorm'
5
+
6
+ import { Partner } from '@things-factory/auth-base'
7
+ import { Bizplace, ContactPoint } from '@things-factory/biz-base'
8
+ import { DeliveryOrder, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
9
+ import { Domain } from '@things-factory/shell'
10
+ import { Inventory, Pallet } from '@things-factory/warehouse-base'
11
+ import { InventoryItem } from '@things-factory/warehouse-base'
12
+ import { TEMPLATE_TYPE, WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
13
+ import { Worksheet, WorksheetDetail } from '../../../entities'
14
+ import { DateTimeConverter } from '../../../utils'
15
+
16
+ export const fetchDeliveryOrderROResolver = {
17
+ async fetchDeliveryOrderRO(_: any, { name }, context: any) {
18
+ const domain: Domain = await getRepository(Domain).findOne({
19
+ where: { id: context.state.domain.id }
20
+ })
21
+
22
+ const foundDO: DeliveryOrder = await getRepository(DeliveryOrder).findOne({
23
+ where: { domain, name },
24
+ relations: [
25
+ 'domain',
26
+ 'bizplace',
27
+ 'bizplace.company',
28
+ 'bizplace.domain',
29
+ 'transportDriver',
30
+ 'transportVehicle',
31
+ 'releaseGood',
32
+ 'creator',
33
+ 'updater'
34
+ ]
35
+ })
36
+
37
+ const ownTransportFlag: Boolean = foundDO.ownCollection
38
+
39
+ let foundCP: ContactPoint = null
40
+ if (foundDO?.contactPointRefId) {
41
+ foundCP = await getRepository(ContactPoint).findOne({
42
+ where: { domain, id: foundDO.contactPointRefId }
43
+ })
44
+ }
45
+
46
+ const foundRO: ReleaseGood = foundDO.releaseGood
47
+ const partnerBiz: Bizplace = foundDO.bizplace //customer bizplace
48
+ const ownRefNo = foundRO.refNo
49
+
50
+ //find list of loaded inventory
51
+ const targetInventories: OrderInventory[] = await getRepository(OrderInventory).find({
52
+ where: { domain, deliveryOrder: foundDO },
53
+ relations: ['inventory']
54
+ })
55
+ const orderInvIds: string[] = targetInventories.map((oi: any) => oi.id)
56
+
57
+ const foundWSD: WorksheetDetail[] = await getRepository(WorksheetDetail).find({
58
+ where: {
59
+ domain,
60
+ targetInventory: In(orderInvIds),
61
+ type: WORKSHEET_TYPE.LOADING,
62
+ status: Equal(WORKSHEET_STATUS.DONE)
63
+ },
64
+ relations: [
65
+ 'targetInventory',
66
+ 'targetInventory.inventory',
67
+ 'targetInventory.inventory.location',
68
+ 'targetInventory.inventory.product',
69
+ 'targetInventory.inventory.product.productDetails',
70
+ 'targetInventory.inventory.reusablePallet',
71
+ 'updater'
72
+ ]
73
+ })
74
+
75
+ let foundDriver: any = null
76
+ if (foundDO.status !== ORDER_STATUS.READY_TO_DISPATCH) {
77
+ if (foundDO?.ownCollection && foundDO?.otherDriver) {
78
+ foundDriver = foundDO.otherDriver
79
+ } else {
80
+ foundDriver = foundDO.transportDriver.name
81
+ }
82
+ }
83
+
84
+ let productList: any[] = []
85
+ productList = foundWSD
86
+ .map((wsd: WorksheetDetail) => {
87
+ const targetInventory: OrderInventory = wsd.targetInventory
88
+ const inventory: Inventory = targetInventory.inventory
89
+ const productDetails: any[] = inventory.product.productDetails
90
+ const matchedProductDetail: any = productDetails.find(
91
+ productDetail => productDetail.packingType === inventory.packingType
92
+ )
93
+ return {
94
+ product_name: `${inventory.product.name} (${inventory.product.description})`,
95
+ product_desc: `${inventory.product?.description || ''}`,
96
+ product_nameOnly: `${inventory.product.name}`,
97
+ product_sku: `${inventory.product.sku}`,
98
+ product_type: inventory.packingType,
99
+ product_size: matchedProductDetail ? matchedProductDetail.packingSize : inventory.packingSize,
100
+ product_batch: inventory.batchId,
101
+ product_batch_ref: inventory.batchIdRef,
102
+ product_qty: targetInventory.releaseQty,
103
+ product_weight: targetInventory.releaseWeight,
104
+ product_gross_weight: inventory.product.grossWeight,
105
+ product_uom_value: targetInventory.releaseUomValue,
106
+ product_uom: inventory.uom,
107
+ remark: targetInventory.remark,
108
+ inventory_remark: inventory.remark,
109
+ cross_docking: targetInventory.crossDocking,
110
+ pallet: inventory?.reusablePallet && inventory?.reusablePallet?.name ? inventory.reusablePallet.name : ''
111
+ }
112
+ })
113
+ .reduce((newItem, item) => {
114
+ var foundItem = newItem.find(
115
+ newItem =>
116
+ newItem.product_name === item.product_name &&
117
+ newItem.product_batch === item.product_batch &&
118
+ newItem.product_batch_ref === item.product_batch_ref &&
119
+ newItem.cross_docking === item.cross_docking &&
120
+ newItem.pallet === item.pallet
121
+ )
122
+ if (!foundItem) {
123
+ foundItem = {
124
+ product_sku: item.product_sku,
125
+ product_name: item.product_name,
126
+ product_type: item.product_type,
127
+ product_size: item.product_size,
128
+ product_batch: item.product_batch,
129
+ product_batch_ref: item.product_batch_ref,
130
+ product_qty: item.product_qty,
131
+ product_weight: item.product_weight,
132
+ product_gross_weight: item.product_gross_weight,
133
+ product_uom_value: item.product_uom_value,
134
+ product_uom: item.product_uom,
135
+ product_desc: item.product_desc,
136
+ product_nameOnly: item.product_nameOnly,
137
+ remark: item.remark,
138
+ inventory_remark: item.inventory_remark,
139
+ palletQty: 1,
140
+ cross_docking: item.cross_docking,
141
+ pallet: item.pallet
142
+ }
143
+
144
+ newItem.push(foundItem)
145
+ return newItem
146
+ } else {
147
+ return newItem.map(ni => {
148
+ if (
149
+ ni.product_name === item.product_name &&
150
+ ni.product_batch === item.product_batch &&
151
+ ni.product_batch_ref === item.product_batch_ref &&
152
+ ni.cross_docking === item.cross_docking &&
153
+ ni.pallet === item.pallet
154
+ ) {
155
+ return {
156
+ ...ni,
157
+ palletQty: ni.palletQty + 1,
158
+ product_qty: ni.product_qty + item.product_qty,
159
+ product_weight: ni.product_weight + item.product_weight,
160
+ product_uom_value: ni.product_uom_value + item.product_uom_value
161
+ }
162
+ } else {
163
+ return ni
164
+ }
165
+ })
166
+ }
167
+ }, [])
168
+
169
+ const data = {
170
+ roNo: foundRO.name,
171
+ doNo: foundDO.name,
172
+ roRef: foundRO.refNo,
173
+ roRef2: foundRO.refNo2,
174
+ roRef3: foundRO.refNo3,
175
+ companyDomain: foundDO.bizplace.name,
176
+ recipientBiz: foundRO.attentionTo || '',
177
+ doDate: DateTimeConverter.date(foundDO.createdAt),
178
+ productList: productList.map((prod: any, idx) => {
179
+ return {
180
+ batchNo: prod.product_batch,
181
+ sku: prod.product_sku,
182
+ name: prod.product_name,
183
+ type: prod.product_type,
184
+ loadedQty: prod.product_qty,
185
+ uom: prod.product_uom,
186
+ uomValue: `${Math.round(prod.product_uom_value * 100) / 100}`
187
+ }
188
+ })
189
+ }
190
+
191
+ return data
192
+ }
193
+ }