@things-factory/sales-base 4.3.186 → 4.3.188

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 (53) hide show
  1. package/dist-server/constants/order.js +10 -5
  2. package/dist-server/constants/order.js.map +1 -1
  3. package/dist-server/controllers/ecommerce/sellercraft-controller.js +5 -0
  4. package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
  5. package/dist-server/errors/validation-error.js +3 -3
  6. package/dist-server/errors/validation-error.js.map +1 -1
  7. package/dist-server/service/draft-release-good/draft-release-good-query.js +24 -2
  8. package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
  9. package/dist-server/service/index.js +7 -0
  10. package/dist-server/service/index.js.map +1 -1
  11. package/dist-server/service/order-inventory/order-inventory.js +14 -0
  12. package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
  13. package/dist-server/service/order-product/order-product.js +10 -0
  14. package/dist-server/service/order-product/order-product.js.map +1 -1
  15. package/dist-server/service/purchase-order/purchase-order-mutation.js +21 -35
  16. package/dist-server/service/purchase-order/purchase-order-mutation.js.map +1 -1
  17. package/dist-server/service/release-good/release-good-query.js +3 -0
  18. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  19. package/dist-server/service/release-good/release-good.js +6 -1
  20. package/dist-server/service/release-good/release-good.js.map +1 -1
  21. package/dist-server/service/replenishment/index.js +9 -0
  22. package/dist-server/service/replenishment/index.js.map +1 -0
  23. package/dist-server/service/replenishment/replenishment-mutation.js +226 -0
  24. package/dist-server/service/replenishment/replenishment-mutation.js.map +1 -0
  25. package/dist-server/service/replenishment/replenishment-query.js +114 -0
  26. package/dist-server/service/replenishment/replenishment-query.js.map +1 -0
  27. package/dist-server/service/replenishment/replenishment-type.js +119 -0
  28. package/dist-server/service/replenishment/replenishment-type.js.map +1 -0
  29. package/dist-server/service/replenishment/replenishment.js +104 -0
  30. package/dist-server/service/replenishment/replenishment.js.map +1 -0
  31. package/dist-server/utils/datetime-util.js +13 -1
  32. package/dist-server/utils/datetime-util.js.map +1 -1
  33. package/dist-server/utils/inventory-util.js +17 -2
  34. package/dist-server/utils/inventory-util.js.map +1 -1
  35. package/dist-server/utils/order-no-generator.js +4 -0
  36. package/dist-server/utils/order-no-generator.js.map +1 -1
  37. package/package.json +3 -3
  38. package/server/constants/order.ts +10 -5
  39. package/server/controllers/ecommerce/sellercraft-controller.ts +9 -0
  40. package/server/service/draft-release-good/draft-release-good-query.ts +29 -2
  41. package/server/service/index.ts +7 -0
  42. package/server/service/order-inventory/order-inventory.ts +12 -1
  43. package/server/service/order-product/order-product.ts +8 -0
  44. package/server/service/release-good/release-good-query.ts +3 -0
  45. package/server/service/release-good/release-good.ts +6 -2
  46. package/server/service/replenishment/index.ts +6 -0
  47. package/server/service/replenishment/replenishment-mutation.ts +309 -0
  48. package/server/service/replenishment/replenishment-query.ts +76 -0
  49. package/server/service/replenishment/replenishment-type.ts +78 -0
  50. package/server/service/replenishment/replenishment.ts +87 -0
  51. package/server/utils/datetime-util.ts +14 -0
  52. package/server/utils/inventory-util.ts +19 -2
  53. package/server/utils/order-no-generator.ts +7 -0
@@ -129,7 +129,8 @@ export const ORDER_INVENTORY_STATUS = {
129
129
  TERMINATED: 'TERMINATED',
130
130
  DONE: 'DONE',
131
131
  RECEIVED: 'RECEIVED',
132
- NOT_RECEIVED: 'NOT_RECEIVED'
132
+ NOT_RECEIVED: 'NOT_RECEIVED',
133
+ PUTTING_AWAY: 'PUTTING_AWAY'
133
134
  }
134
135
 
135
136
  export const ORDER_VAS_STATUS = {
@@ -156,7 +157,8 @@ export const ORDER_TYPES = {
156
157
  VAS_ORDER: 'VAS_ORDER',
157
158
  CYCLE_COUNT: 'CYCLE_COUNT',
158
159
  STOCK_TAKE: 'STOCK_TAKE',
159
- TRANSFER_ORDER: 'TRANSFER_ORDER'
160
+ TRANSFER_ORDER: 'TRANSFER_ORDER',
161
+ REPLENISHMENT: 'REPLENISHMENT'
160
162
  }
161
163
 
162
164
  export const GRN_STATUS = {
@@ -174,7 +176,8 @@ export const ORDER_NUMBER_SETTING_KEY = {
174
176
  DO_NUMBER_RULE: 'do-number-rule',
175
177
  RR_NUMBER_RULE: 'rr-number-rule',
176
178
  TO_NUMBER_RULE: 'to-number-rule',
177
- DRO_NUMBER_RULE: 'dro-number-rule'
179
+ DRO_NUMBER_RULE: 'dro-number-rule',
180
+ RP_NUMBER_RULE: 'rp-number-rule'
178
181
  }
179
182
 
180
183
  export const ORDER_NUMBER_RULE_TYPE = {
@@ -185,7 +188,8 @@ export const ORDER_NUMBER_RULE_TYPE = {
185
188
  DO_NUMBER: 'do_number',
186
189
  RR_NUMBER: 'rr_number',
187
190
  TO_NUMBER: 'to_number',
188
- DRO_NUMBER: 'dro_number'
191
+ DRO_NUMBER: 'dro_number',
192
+ RP_NUMBER: 'rp_number'
189
193
  }
190
194
 
191
195
  export const PURCHASE_ORDER_STATUS = {
@@ -200,7 +204,8 @@ export const DRAFT_RELEASE_ORDER_STATUS = {
200
204
  DRAFT: 'DRAFT',
201
205
  INSUFFICIENT: 'INSUFFICIENT',
202
206
  SUBMITTED: 'SUBMITTED',
203
- CANCELLED: 'CANCELLED'
207
+ CANCELLED: 'CANCELLED',
208
+ TRANSFER: 'TRANSFER'
204
209
  }
205
210
 
206
211
  export const ORDER_SOURCE_TYPE = {
@@ -7,6 +7,7 @@ import { Inventory, INVENTORY_STATUS, LOCATION_TYPE } from '@things-factory/ware
7
7
  import { ORDER_PRODUCT_STATUS } from '../../constants'
8
8
  import { OrderProduct } from '../../service/order-product/order-product'
9
9
  import { ReleaseGood } from '../../service/release-good/release-good'
10
+ import { DateTimeDifference } from '../../utils/datetime-util'
10
11
  import { OrderController } from '../order-controller'
11
12
 
12
13
  export class SellercraftController extends OrderController {
@@ -34,6 +35,14 @@ export class SellercraftController extends OrderController {
34
35
  orderId: releaseGood.refNo2,
35
36
  sellercraftOPs
36
37
  }
38
+
39
+ if (
40
+ releaseGood?.lastMarketPackCall &&
41
+ DateTimeDifference.timeDifferenceInSeconds(releaseGood.lastMarketPackCall, new Date()) <= 5
42
+ ) {
43
+ return
44
+ }
45
+
37
46
  const packageId: string = await SellercraftAPI.packMarketplaceOrder(sellercraft, {
38
47
  ...orderInformation,
39
48
  context: { state: { domain: this?.domain, user: this?.user } }
@@ -120,14 +120,36 @@ export class DraftReleaseGoodQuery {
120
120
  [domain.id]
121
121
  )
122
122
 
123
+ tx.query(
124
+ `
125
+ create temp table temp_transfer_inv_calculation on commit drop as (
126
+ SELECT drg1.id from draft_release_goods drg1
127
+ left join order_products op on drg1.id = op.draft_release_good_id
128
+ where drg1.status ='DRAFT' AND drg1.domain_id = $1
129
+ AND EXISTS (
130
+ SELECT * FROM warehouse_bizplace_onhand_inventories wboi
131
+ where (wboi."product_id" = op.product_id or wboi."product_bundle_id" = op.product_id)
132
+ and wboi."domain_id" = op.domain_id
133
+ and wboi."bizplace_id" = op.bizplace_id
134
+ AND wboi."transfer_qty" > 0
135
+ ) GROUP BY drg1.id
136
+ )
137
+ `,
138
+ [domain.id]
139
+ )
140
+
123
141
  const qb: SelectQueryBuilder<DraftReleaseGood> = tx.getRepository(DraftReleaseGood).createQueryBuilder('drg')
124
142
  buildQuery(qb, params, context)
125
143
  qb.addSelect('COALESCE("cc".rank, 99999)', 'rank')
126
144
  qb.addSelect(
127
- `CASE WHEN "drg".status = 'DRAFT' and tmp_calc.id IS NOT null then 'INSUFFICIENT' else "drg".status END`,
145
+ `CASE WHEN "drg".status = 'DRAFT' and (tmp_calc.id IS NOT null and tmp_transfer.id IS null) then 'INSUFFICIENT'
146
+ WHEN "drg".status = 'DRAFT' and (tmp_calc.id IS null and tmp_transfer.id IS NOT null) then 'TRANSFER'
147
+ WHEN "drg".status = 'DRAFT' and (tmp_calc.id IS NOT null and tmp_transfer.id IS NOT null) then 'INSUFFICIENT'
148
+ else "drg".status END`,
128
149
  'computed_status'
129
150
  )
130
151
  qb.leftJoin(`temp_op_calculation`, 'tmp_calc', 'tmp_calc.id = drg.id')
152
+ qb.leftJoin(`temp_transfer_inv_calculation`, 'tmp_transfer', 'tmp_transfer.id = drg.id')
131
153
  qb.leftJoinAndSelect('drg.domain', 'domain')
132
154
  qb.leftJoinAndSelect('drg.bizplace', 'bizplace')
133
155
  qb.leftJoinAndSelect('drg.creator', 'creator')
@@ -329,7 +351,12 @@ export async function getDraftReleaseGoodFunction(_: any, name: any, context: an
329
351
  groupType: foundProductInv ? foundProductInv.groupType : 'SINGLE',
330
352
  remainQty: foundProductInv ? foundProductInv.remainQty : 0,
331
353
  remainUomValue: foundProductInv ? foundProductInv.remainUomValue : 0,
332
- remainUomValueWithUom: foundProductInv ? foundProductInv.remainUomValueWithUom : 0
354
+ remainUomValueWithUom: foundProductInv ? foundProductInv.remainUomValueWithUom : 0,
355
+ status: foundProductInv?.transferQty
356
+ ? DRAFT_RELEASE_ORDER_STATUS.TRANSFER
357
+ : foundProductInv?.remainQty <= itm.releaseQty
358
+ ? DRAFT_RELEASE_ORDER_STATUS.INSUFFICIENT
359
+ : DRAFT_RELEASE_ORDER_STATUS.DRAFT
333
360
  }
334
361
  })
335
362
  const foundAttachments: Attachment[] = await tx.getRepository(Attachment).find({
@@ -1,4 +1,5 @@
1
1
  /* IMPORT ENTITIES AND RESOLVERS */
2
+ import { entities as ReplenishmentEntities, resolvers as ReplenishmentResolvers } from './replenishment'
2
3
  import { entities as ArrivalNoticeEntity, resolvers as ArrivalNoticeResolvers } from './arrival-notice'
3
4
  import { entities as ClaimEntity, resolvers as ClaimResolvers } from './claim'
4
5
  import { entities as ClaimDetailEntity, resolvers as ClaimDetailResolvers } from './claim-detail'
@@ -46,6 +47,8 @@ import { entities as VasEntity, resolvers as VasResolvers } from './vas'
46
47
  import { entities as VasOrderEntity, resolvers as VasOrderResolvers } from './vas-order'
47
48
 
48
49
  /* EXPORT ENTITY TYPES */
50
+ export * from './replenishment/replenishment'
51
+ export * from './replenishment/replenishment'
49
52
  export * from './arrival-notice/arrival-notice'
50
53
  export * from './claim-detail/claim-detail'
51
54
  export * from './claim-order/claim-order'
@@ -176,6 +179,8 @@ export * from './vas/vas-query'
176
179
 
177
180
  export const entities = [
178
181
  /* ENTITIES */
182
+ ...ReplenishmentEntities,
183
+ ...ReplenishmentEntities,
179
184
  ...ArrivalNoticeEntity,
180
185
  ...ClaimDetailEntity,
181
186
  ...ClaimEntity,
@@ -213,6 +218,8 @@ export const entities = [
213
218
  export const schema = {
214
219
  resolverClasses: [
215
220
  /* RESOLVER CLASSES */
221
+ ...ReplenishmentResolvers,
222
+ ...ReplenishmentResolvers,
216
223
  ...ArrivalNoticeResolvers,
217
224
  ...ClaimDetailResolvers,
218
225
  ...ClaimOrderResolvers,
@@ -13,7 +13,7 @@ import {
13
13
 
14
14
  import { User } from '@things-factory/auth-base'
15
15
  import { Bizplace } from '@things-factory/biz-base'
16
- import { Product, ProductDetail} from '@things-factory/product-base'
16
+ import { Product, ProductDetail } from '@things-factory/product-base'
17
17
  import { Domain } from '@things-factory/shell'
18
18
  import { Inventory, Location } from '@things-factory/warehouse-base'
19
19
 
@@ -25,6 +25,7 @@ import { OrderToteItem } from '../order-tote-item/order-tote-item'
25
25
  import { ReleaseGood } from '../release-good/release-good'
26
26
  import { ReturnOrder } from '../return-order/return-order'
27
27
  import { TransferOrder } from '../transfer-order/transfer-order'
28
+ import { Replenishment } from '../replenishment/replenishment'
28
29
 
29
30
  @Entity()
30
31
  @Index('ix_order-inventory_0', (orderInventory: OrderInventory) => [orderInventory.domain, orderInventory.name], {
@@ -150,6 +151,13 @@ export class OrderInventory {
150
151
  @RelationId((orderInventory: OrderInventory) => orderInventory.releaseGood)
151
152
  releaseGoodId: string
152
153
 
154
+ @ManyToOne(type => Replenishment)
155
+ @Field(type => Replenishment, { nullable: true })
156
+ replenishment: Replenishment
157
+
158
+ @RelationId((orderInventory: OrderInventory) => orderInventory.replenishment)
159
+ replenishmentId: string
160
+
153
161
  @ManyToOne(type => InventoryCheck)
154
162
  @Field(type => InventoryCheck, { nullable: true })
155
163
  inventoryCheck: InventoryCheck
@@ -432,4 +440,7 @@ export class OrderInventory {
432
440
 
433
441
  @Field({ nullable: true })
434
442
  stopId: string
443
+
444
+ @Field({ nullable: true })
445
+ transferQty: number
435
446
  }
@@ -26,6 +26,7 @@ import { OrderPackageItem } from '../order-package-item/order-package-item'
26
26
  import { PurchaseOrder } from '../purchase-order/purchase-order'
27
27
  import { ReleaseGood } from '../release-good/release-good'
28
28
  import { RetailReplenishmentOrder } from '../retail-replenishment-order/retail-replenishment-order'
29
+ import { Replenishment } from '../replenishment/replenishment'
29
30
 
30
31
  @Entity()
31
32
  @Index('ix_order-product_0', (orderProduct: OrderProduct) => [orderProduct.domain, orderProduct.name], {
@@ -107,6 +108,13 @@ export class OrderProduct {
107
108
  @RelationId((orderProduct: OrderProduct) => orderProduct.releaseGood)
108
109
  releaseGoodId: string
109
110
 
111
+ @ManyToOne(type => Replenishment)
112
+ @Field(type => Replenishment, { nullable: true })
113
+ replenishment: Replenishment
114
+
115
+ @RelationId((orderInventory: OrderInventory) => orderInventory.replenishment)
116
+ replenishmentId: string
117
+
110
118
  @ManyToOne(type => DraftReleaseGood)
111
119
  @Field(type => DraftReleaseGood, { nullable: true })
112
120
  draftReleaseGood: DraftReleaseGood
@@ -859,6 +859,9 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
859
859
  AND i.domain_id = $1
860
860
  AND i.bizplace_id = $2
861
861
  WHERE l.type NOT IN ($3, $4)
862
+ AND i.obsolete = false
863
+ AND i.transfer_qty <= 0
864
+ AND i.transfer_uom_value <= 0
862
865
  GROUP BY i.product_id, foo.product_detail_id, foo.sku,foo.product_info, i.packing_type, i.packing_size, i.uom
863
866
  ORDER BY foo.sku, remain_qty
864
867
  ) SELECT * FROM inv WHERE remain_qty > 0
@@ -17,8 +17,8 @@ import { Attachment } from '@things-factory/attachment-base'
17
17
  import { User } from '@things-factory/auth-base'
18
18
  import { Bizplace, ContactPoint } from '@things-factory/biz-base'
19
19
  import { config } from '@things-factory/env'
20
- import { Domain } from '@things-factory/shell'
21
20
  import { LastMileDelivery } from '@things-factory/integration-lmd'
21
+ import { Domain } from '@things-factory/shell'
22
22
 
23
23
  import {
24
24
  ArrivalNotice,
@@ -508,6 +508,10 @@ export class ReleaseGood {
508
508
  @Field({ nullable: true })
509
509
  marketPackCallSuccess: Date
510
510
 
511
+ @Column({ nullable: true })
512
+ @Field({ nullable: true })
513
+ lastMarketPackCall: Date
514
+
511
515
  @ManyToOne(type => User)
512
516
  @Field(type => User, { nullable: true })
513
517
  manifestedBy: User
@@ -543,7 +547,7 @@ export class ReleaseGood {
543
547
  @Column({ nullable: true })
544
548
  @Field({ nullable: true })
545
549
  lmdOption: Boolean
546
-
550
+
547
551
  @Column({ nullable: true })
548
552
  @Field({ nullable: true })
549
553
  parcelId: String
@@ -0,0 +1,6 @@
1
+ import { Replenishment } from './replenishment'
2
+ import { ReplenishmentQuery } from './replenishment-query'
3
+ import { ReplenishmentMutation } from './replenishment-mutation'
4
+
5
+ export const entities = [Replenishment]
6
+ export const resolvers = [ReplenishmentQuery, ReplenishmentMutation]
@@ -0,0 +1,309 @@
1
+ import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { getRepository, In, EntityManager, Repository } from 'typeorm'
3
+ import { Replenishment } from './replenishment'
4
+ import { NewReplenishment, ReplenishmentPatch, ReplenishmentInventoryPatch } from './replenishment-type'
5
+ import { Domain } from '@things-factory/shell'
6
+ import { User } from '@things-factory/auth-base'
7
+ import { OrderInventory } from '../order-inventory/order-inventory'
8
+ import { OrderProduct } from '../order-product/order-product'
9
+ import { Inventory } from '@things-factory/warehouse-base'
10
+ import { Setting } from '@things-factory/setting-base'
11
+ import {
12
+ ORDER_INVENTORY_STATUS,
13
+ ORDER_NUMBER_RULE_TYPE,
14
+ ORDER_NUMBER_SETTING_KEY,
15
+ ORDER_PRODUCT_STATUS,
16
+ ORDER_STATUS,
17
+ ORDER_TYPES
18
+ } from '../../constants'
19
+ import { generateId } from '@things-factory/id-rule-base'
20
+ import { InventoryUtil, OrderNoGenerator } from '../../utils'
21
+ import { Product, ProductDetail } from '@things-factory/product-base'
22
+
23
+ @Resolver(Replenishment)
24
+ export class ReplenishmentMutation {
25
+ @Directive('@transaction')
26
+ @Mutation(returns => Replenishment, { description: 'To create new Replenishment' })
27
+ async createReplenishment(
28
+ @Arg('replenishInventories', type => [ReplenishmentInventoryPatch])
29
+ replenishmentInventories: ReplenishmentInventoryPatch,
30
+ @Ctx() context: any
31
+ ): Promise<Replenishment> {
32
+ const { tx } = context.state
33
+
34
+ const createdReplenishment: Replenishment = await generateReplenishmentFunction(
35
+ null,
36
+ replenishmentInventories,
37
+ context,
38
+ tx
39
+ )
40
+
41
+ return createdReplenishment
42
+ }
43
+
44
+ @Directive('@transaction')
45
+ @Mutation(returns => Replenishment, { description: 'To modify Replenishment information' })
46
+ async updateReplenishment(
47
+ @Arg('id') id: string,
48
+ @Arg('patch') patch: ReplenishmentPatch,
49
+ @Ctx() context: any
50
+ ): Promise<Replenishment> {
51
+ const { domain, user, tx } = context.state
52
+
53
+ const repository = tx.getRepository(Replenishment)
54
+ const replenishment = await repository.findOne({
55
+ where: { domain, id }
56
+ })
57
+
58
+ return await repository.save({
59
+ ...replenishment,
60
+ ...patch,
61
+ updater: user
62
+ })
63
+ }
64
+
65
+ @Directive('@transaction')
66
+ @Mutation(returns => [Replenishment], { description: "To modify multiple Replenishments' information" })
67
+ async updateMultipleReplenishment(
68
+ @Arg('patches', type => [ReplenishmentPatch]) patches: ReplenishmentPatch[],
69
+ @Ctx() context: any
70
+ ): Promise<Replenishment[]> {
71
+ const { domain, user, tx } = context.state
72
+
73
+ let results = []
74
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
75
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
76
+ const replenishmentRepo = tx.getRepository(Replenishment)
77
+
78
+ if (_createRecords.length > 0) {
79
+ for (let i = 0; i < _createRecords.length; i++) {
80
+ const newRecord = _createRecords[i]
81
+
82
+ const result = await replenishmentRepo.save({
83
+ ...newRecord,
84
+ domain,
85
+ creator: user,
86
+ updater: user
87
+ })
88
+
89
+ results.push({ ...result, cuFlag: '+' })
90
+ }
91
+ }
92
+
93
+ if (_updateRecords.length > 0) {
94
+ for (let i = 0; i < _updateRecords.length; i++) {
95
+ const newRecord = _updateRecords[i]
96
+ const replenishment = await replenishmentRepo.findOne(newRecord.id)
97
+
98
+ const result = await replenishmentRepo.save({
99
+ ...replenishment,
100
+ ...newRecord,
101
+ updater: user
102
+ })
103
+
104
+ results.push({ ...result, cuFlag: 'M' })
105
+ }
106
+ }
107
+
108
+ return results
109
+ }
110
+
111
+ @Directive('@transaction')
112
+ @Mutation(returns => Boolean, { description: 'To delete Replenishment' })
113
+ async deleteReplenishment(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
114
+ const { domain, tx } = context.state
115
+
116
+ await tx.getRepository(Replenishment).delete({ domain, id })
117
+ return true
118
+ }
119
+
120
+ @Directive('@transaction')
121
+ @Mutation(returns => Boolean, { description: 'To delete multiple replenishments' })
122
+ async deleteReplenishments(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
123
+ const { domain, tx } = context.state
124
+
125
+ await tx.getRepository(Replenishment).delete({
126
+ domain,
127
+ id: In(ids)
128
+ })
129
+
130
+ return true
131
+ }
132
+
133
+ @Directive('@transaction')
134
+ @Mutation(returns => Replenishment)
135
+ async confirmReplenishment(@Arg('name') name: string, @Ctx() context: any): Promise<Replenishment> {
136
+ const { tx }: { tx: EntityManager } = context.state
137
+ const replenishment: Replenishment = await confirmReplenishment(name, context, tx)
138
+
139
+ return replenishment
140
+ }
141
+ }
142
+
143
+ export async function generateReplenishmentFunction(
144
+ _: any,
145
+ replenishment: any,
146
+ context: any,
147
+ tx?: EntityManager
148
+ ): Promise<Replenishment> {
149
+ try {
150
+ const { domain, user }: { domain: Domain; user: User } = context.state
151
+
152
+ const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
153
+
154
+ let orderInventories: OrderInventory[] = replenishment
155
+
156
+ let finalOrderInventories: OrderInventory[] = []
157
+
158
+ let newReplenishment: Replenishment = new Replenishment()
159
+
160
+ // find RO number rule setting
161
+ const rpNoSetting: Setting = await settingRepo.findOne({
162
+ where: {
163
+ domain,
164
+ name: ORDER_NUMBER_SETTING_KEY.RP_NUMBER_RULE
165
+ }
166
+ })
167
+
168
+ newReplenishment = {
169
+ ...newReplenishment,
170
+ name: rpNoSetting
171
+ ? await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.RP_NUMBER, seed: {} })
172
+ : OrderNoGenerator.replenishment(),
173
+ domain,
174
+ status: ORDER_STATUS.PENDING,
175
+ creator: user,
176
+ updater: user
177
+ }
178
+
179
+ newReplenishment = await tx.getRepository(Replenishment).save(newReplenishment)
180
+
181
+ for (let oi of orderInventories) {
182
+ let productDetail: any = await tx
183
+ .getRepository(ProductDetail)
184
+ .findOne(oi.productDetailId, { relations: ['product'] })
185
+
186
+ let bizplace = oi.bizplaceId
187
+
188
+ let newOrderInv: OrderInventory = Object.assign({}, oi)
189
+ newOrderInv = {
190
+ ...newOrderInv,
191
+ domain,
192
+ bizplace: { id: bizplace },
193
+ status: ORDER_INVENTORY_STATUS.PENDING,
194
+ name: OrderNoGenerator.orderInventory(),
195
+ replenishment: newReplenishment,
196
+ product: productDetail.product,
197
+ productDetail,
198
+ creator: user,
199
+ updater: user
200
+ }
201
+
202
+ let newOrderProduct: OrderProduct = Object.assign(new OrderProduct(), newOrderInv)
203
+ newOrderProduct = {
204
+ ...newOrderProduct,
205
+ packQty: 0,
206
+ actualPackQty: 0,
207
+ palletQty: 0,
208
+ actualPalletQty: 0,
209
+ status: ORDER_PRODUCT_STATUS.ASSIGNED,
210
+ batchId: ''
211
+ }
212
+
213
+ newOrderProduct = await tx.getRepository(OrderProduct).save(newOrderProduct)
214
+
215
+ // Preassign Inventories
216
+ const inventoryAssignmentSetting: Setting = await tx.getRepository(Setting).findOne({
217
+ where: { domain, name: 'rule-for-inventory-assignment' }
218
+ })
219
+
220
+ let locationSortingRules = []
221
+ if (inventoryAssignmentSetting) {
222
+ let locationSetting = JSON.parse(inventoryAssignmentSetting.value)
223
+ for (const key in locationSetting) {
224
+ locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
225
+ }
226
+ }
227
+
228
+ let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
229
+ oi,
230
+ productDetail.product,
231
+ productDetail,
232
+ locationSortingRules,
233
+ { id: bizplace },
234
+ domain,
235
+ tx,
236
+ oi.batchId,
237
+ 'STORAGE'
238
+ )
239
+
240
+ assignedOrderInventories = assignedOrderInventories.map(aoi => {
241
+ return {
242
+ ...aoi,
243
+ orderProduct: newOrderProduct,
244
+ bizplace: { id: bizplace }
245
+ }
246
+ })
247
+
248
+ finalOrderInventories.push(...assignedOrderInventories)
249
+ }
250
+
251
+ for (let oi of finalOrderInventories) {
252
+ let generatedOI: OrderInventory = Object.assign(new OrderInventory(), oi)
253
+ generatedOI = {
254
+ ...generatedOI,
255
+ domain,
256
+ status: ORDER_INVENTORY_STATUS.PENDING,
257
+ name: OrderNoGenerator.orderInventory(),
258
+ replenishment: newReplenishment,
259
+ creator: user,
260
+ updater: user
261
+ }
262
+
263
+ await tx.getRepository(OrderInventory).save({ ...generatedOI })
264
+
265
+ await tx.getRepository(Inventory).update(oi.inventory.id, {
266
+ transferQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
267
+ transferUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
268
+ updater: user
269
+ })
270
+ }
271
+
272
+ return newReplenishment
273
+ } catch (error) {
274
+ throw error
275
+ }
276
+ }
277
+
278
+ export async function confirmReplenishment(name: string, context: any, tx?: EntityManager): Promise<Replenishment> {
279
+ const { user, domain }: { user: User; domain: Domain } = context.state
280
+
281
+ let foundReplenishment: Replenishment = await tx.getRepository(Replenishment).findOne({
282
+ where: { name, status: ORDER_STATUS.PENDING }
283
+ })
284
+
285
+ if (!foundReplenishment) throw new Error(`Replenisment doesn't exists.`)
286
+
287
+ let foundOIs: OrderInventory[] = await tx.getRepository(OrderInventory).find({
288
+ where: { domain, replenishment: foundReplenishment }
289
+ })
290
+
291
+ // 1. RO Status change (PENDING => PENDING_RECEIVE)
292
+ const replenishment: Replenishment = await tx.getRepository(Replenishment).save({
293
+ ...foundReplenishment,
294
+ status: ORDER_STATUS.PENDING_WORKSHEET,
295
+ updater: user
296
+ })
297
+
298
+ // 1. Update status of order inventories
299
+ foundOIs = foundOIs.map((orderInventory: OrderInventory) => {
300
+ return {
301
+ ...orderInventory,
302
+ status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET,
303
+ updater: user
304
+ }
305
+ })
306
+ await tx.getRepository(OrderInventory).save(foundOIs)
307
+
308
+ return replenishment
309
+ }
@@ -0,0 +1,76 @@
1
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { getRepository, EntityManager, SelectQueryBuilder } from 'typeorm'
3
+ import { Domain, ListParam, convertListParams } from '@things-factory/shell'
4
+ import { User } from '@things-factory/auth-base'
5
+ import { Replenishment } from './replenishment'
6
+ import { ReplenishmentList } from './replenishment-type'
7
+ import { OrderInventory } from '../order-inventory/order-inventory'
8
+ import { Inventory } from '@things-factory/warehouse-base'
9
+ import { ORDER_INVENTORY_STATUS } from 'server/constants'
10
+
11
+ @Resolver(Replenishment)
12
+ export class ReplenishmentQuery {
13
+ @Query(returns => Replenishment, { description: 'To fetch a Replenishment' })
14
+ async replenishment(@Arg('id') id: string, @Ctx() context: any): Promise<Replenishment> {
15
+ const { domain } = context.state
16
+
17
+ return await getRepository(Replenishment).findOne({
18
+ where: { domain, id }
19
+ })
20
+ }
21
+
22
+ @Query(returns => ReplenishmentList, { description: 'To fetch multiple Replenishments' })
23
+ async replenishments(@Args() params: ListParam, @Ctx() context: any): Promise<ReplenishmentList> {
24
+ const { domain } = context.state
25
+
26
+ const convertedParams = convertListParams(params, domain.id)
27
+ const [items, total] = await getRepository(Replenishment).findAndCount(convertedParams)
28
+
29
+ return { items, total }
30
+ }
31
+
32
+ @Query(returns => Replenishment)
33
+ async replenishmentDetail(
34
+ @Ctx() context: any,
35
+ @Arg('name', { nullable: true }) name?: string
36
+ ): Promise<Replenishment> {
37
+ try {
38
+ const { domain }: { domain: Domain } = context.state
39
+ let param: any
40
+
41
+ if (name) param = { domain, name }
42
+
43
+ let replenishment: Replenishment = await getRepository(Replenishment).findOne({
44
+ where: { ...param },
45
+ relations: ['domain', 'orderInventories', 'orderInventories.product', 'orderInventories.bizplace']
46
+ })
47
+
48
+ replenishment.orderInventories = replenishment.orderInventories.map((oi: OrderInventory) => {
49
+ return {
50
+ ...oi,
51
+ transferQty: oi.releaseQty,
52
+ productSKU: oi.product.sku
53
+ }
54
+ })
55
+
56
+ return replenishment
57
+ } catch (error) {
58
+ throw new Error(error)
59
+ }
60
+ }
61
+
62
+ @FieldResolver(type => Domain)
63
+ async domain(@Root() replenishment: Replenishment): Promise<Domain> {
64
+ return await getRepository(Domain).findOne(replenishment.domainId)
65
+ }
66
+
67
+ @FieldResolver(type => User)
68
+ async updater(@Root() replenishment: Replenishment): Promise<User> {
69
+ return await getRepository(User).findOne(replenishment.updaterId)
70
+ }
71
+
72
+ @FieldResolver(type => User)
73
+ async creator(@Root() replenishment: Replenishment): Promise<User> {
74
+ return await getRepository(User).findOne(replenishment.creatorId)
75
+ }
76
+ }