@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.
- package/dist-server/constants/order.js +10 -5
- package/dist-server/constants/order.js.map +1 -1
- package/dist-server/controllers/ecommerce/sellercraft-controller.js +5 -0
- package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
- package/dist-server/errors/validation-error.js +3 -3
- package/dist-server/errors/validation-error.js.map +1 -1
- package/dist-server/service/draft-release-good/draft-release-good-query.js +24 -2
- package/dist-server/service/draft-release-good/draft-release-good-query.js.map +1 -1
- package/dist-server/service/index.js +7 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/order-inventory/order-inventory.js +14 -0
- package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
- package/dist-server/service/order-product/order-product.js +10 -0
- package/dist-server/service/order-product/order-product.js.map +1 -1
- package/dist-server/service/purchase-order/purchase-order-mutation.js +21 -35
- package/dist-server/service/purchase-order/purchase-order-mutation.js.map +1 -1
- package/dist-server/service/release-good/release-good-query.js +3 -0
- package/dist-server/service/release-good/release-good-query.js.map +1 -1
- package/dist-server/service/release-good/release-good.js +6 -1
- package/dist-server/service/release-good/release-good.js.map +1 -1
- package/dist-server/service/replenishment/index.js +9 -0
- package/dist-server/service/replenishment/index.js.map +1 -0
- package/dist-server/service/replenishment/replenishment-mutation.js +226 -0
- package/dist-server/service/replenishment/replenishment-mutation.js.map +1 -0
- package/dist-server/service/replenishment/replenishment-query.js +114 -0
- package/dist-server/service/replenishment/replenishment-query.js.map +1 -0
- package/dist-server/service/replenishment/replenishment-type.js +119 -0
- package/dist-server/service/replenishment/replenishment-type.js.map +1 -0
- package/dist-server/service/replenishment/replenishment.js +104 -0
- package/dist-server/service/replenishment/replenishment.js.map +1 -0
- package/dist-server/utils/datetime-util.js +13 -1
- package/dist-server/utils/datetime-util.js.map +1 -1
- package/dist-server/utils/inventory-util.js +17 -2
- package/dist-server/utils/inventory-util.js.map +1 -1
- package/dist-server/utils/order-no-generator.js +4 -0
- package/dist-server/utils/order-no-generator.js.map +1 -1
- package/package.json +3 -3
- package/server/constants/order.ts +10 -5
- package/server/controllers/ecommerce/sellercraft-controller.ts +9 -0
- package/server/service/draft-release-good/draft-release-good-query.ts +29 -2
- package/server/service/index.ts +7 -0
- package/server/service/order-inventory/order-inventory.ts +12 -1
- package/server/service/order-product/order-product.ts +8 -0
- package/server/service/release-good/release-good-query.ts +3 -0
- package/server/service/release-good/release-good.ts +6 -2
- package/server/service/replenishment/index.ts +6 -0
- package/server/service/replenishment/replenishment-mutation.ts +309 -0
- package/server/service/replenishment/replenishment-query.ts +76 -0
- package/server/service/replenishment/replenishment-type.ts +78 -0
- package/server/service/replenishment/replenishment.ts +87 -0
- package/server/utils/datetime-util.ts +14 -0
- package/server/utils/inventory-util.ts +19 -2
- 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'
|
|
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({
|
package/server/service/index.ts
CHANGED
|
@@ -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
|
+
}
|