@things-factory/sales-base 8.0.2 → 8.0.5
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/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/server/constants/attachment-type.ts +0 -9
- package/server/constants/index.ts +0 -7
- package/server/constants/load-type.ts +0 -4
- package/server/constants/order.ts +0 -203
- package/server/constants/product-group-type.ts +0 -4
- package/server/constants/release-good.ts +0 -9
- package/server/constants/transfer-order-type.ts +0 -6
- package/server/constants/validation-error-code.ts +0 -3
- package/server/constants/vas-target-type.ts +0 -25
- package/server/controllers/ecommerce/ecommerce-controller.ts +0 -122
- package/server/controllers/ecommerce/index.ts +0 -2
- package/server/controllers/ecommerce/sellercraft-controller.ts +0 -182
- package/server/controllers/index.ts +0 -2
- package/server/controllers/order-controller.ts +0 -296
- package/server/errors/index.ts +0 -1
- package/server/errors/validation-error.ts +0 -25
- package/server/index.ts +0 -5
- package/server/migrations/index.ts +0 -9
- package/server/service/arrival-notice/arrival-notice-mutation.ts +0 -1152
- package/server/service/arrival-notice/arrival-notice-query.ts +0 -549
- package/server/service/arrival-notice/arrival-notice-types.ts +0 -310
- package/server/service/arrival-notice/arrival-notice.ts +0 -202
- package/server/service/arrival-notice/index.ts +0 -9
- package/server/service/claim/claim-mutation.ts +0 -308
- package/server/service/claim/claim-query.ts +0 -122
- package/server/service/claim/claim-types.ts +0 -130
- package/server/service/claim/claim.ts +0 -140
- package/server/service/claim/index.ts +0 -9
- package/server/service/claim-detail/claim-detail-mutation.ts +0 -102
- package/server/service/claim-detail/claim-detail-query.ts +0 -55
- package/server/service/claim-detail/claim-detail-types.ts +0 -47
- package/server/service/claim-detail/claim-detail.ts +0 -69
- package/server/service/claim-detail/index.ts +0 -9
- package/server/service/claim-order/claim-order-mutation.ts +0 -101
- package/server/service/claim-order/claim-order-query.ts +0 -47
- package/server/service/claim-order/claim-order-types.ts +0 -35
- package/server/service/claim-order/claim-order.ts +0 -81
- package/server/service/claim-order/index.ts +0 -9
- package/server/service/collection-order/collection-order-mutation.ts +0 -245
- package/server/service/collection-order/collection-order-query.ts +0 -97
- package/server/service/collection-order/collection-order-types.ts +0 -165
- package/server/service/collection-order/collection-order.ts +0 -135
- package/server/service/collection-order/index.ts +0 -9
- package/server/service/delivery-order/delivery-order-mutation.ts +0 -967
- package/server/service/delivery-order/delivery-order-query.ts +0 -631
- package/server/service/delivery-order/delivery-order-types.ts +0 -268
- package/server/service/delivery-order/delivery-order.ts +0 -258
- package/server/service/delivery-order/index.ts +0 -9
- package/server/service/draft-release-good/draft-release-good-mutation.ts +0 -765
- package/server/service/draft-release-good/draft-release-good-query.ts +0 -354
- package/server/service/draft-release-good/draft-release-good-type.ts +0 -261
- package/server/service/draft-release-good/draft-release-good.ts +0 -284
- package/server/service/draft-release-good/index.ts +0 -9
- package/server/service/goods-receival-note/goods-receival-note-mutation.ts +0 -129
- package/server/service/goods-receival-note/goods-receival-note-query.ts +0 -280
- package/server/service/goods-receival-note/goods-receival-note-types.ts +0 -105
- package/server/service/goods-receival-note/goods-receival-note.ts +0 -127
- package/server/service/goods-receival-note/index.ts +0 -9
- package/server/service/index.ts +0 -238
- package/server/service/inventory-check/index.ts +0 -9
- package/server/service/inventory-check/inventory-check-mutation.ts +0 -149
- package/server/service/inventory-check/inventory-check-query.ts +0 -48
- package/server/service/inventory-check/inventory-check-types.ts +0 -48
- package/server/service/inventory-check/inventory-check.ts +0 -90
- package/server/service/invoice/index.ts +0 -9
- package/server/service/invoice/invoice-mutation.ts +0 -95
- package/server/service/invoice/invoice-query.ts +0 -53
- package/server/service/invoice/invoice-types.ts +0 -279
- package/server/service/invoice/invoice.ts +0 -230
- package/server/service/invoice-product/index.ts +0 -9
- package/server/service/invoice-product/invoice-product-mutation.ts +0 -54
- package/server/service/invoice-product/invoice-product-query.ts +0 -54
- package/server/service/invoice-product/invoice-product-types.ts +0 -84
- package/server/service/invoice-product/invoice-product.ts +0 -92
- package/server/service/job-sheet/index.ts +0 -9
- package/server/service/job-sheet/job-sheet-mutation.ts +0 -92
- package/server/service/job-sheet/job-sheet-query.ts +0 -112
- package/server/service/job-sheet/job-sheet-types.ts +0 -78
- package/server/service/job-sheet/job-sheet.ts +0 -102
- package/server/service/manifest/index.ts +0 -6
- package/server/service/manifest/manifest-mutation.ts +0 -190
- package/server/service/manifest/manifest-query.ts +0 -149
- package/server/service/manifest/manifest-type.ts +0 -84
- package/server/service/manifest/manifest.ts +0 -114
- package/server/service/order-inventory/index.ts +0 -9
- package/server/service/order-inventory/order-inventory-mutation.ts +0 -54
- package/server/service/order-inventory/order-inventory-query.ts +0 -722
- package/server/service/order-inventory/order-inventory-types.ts +0 -238
- package/server/service/order-inventory/order-inventory.ts +0 -401
- package/server/service/order-product/index.ts +0 -9
- package/server/service/order-product/order-product-mutation.ts +0 -48
- package/server/service/order-product/order-product-query.ts +0 -89
- package/server/service/order-product/order-product-types.ts +0 -335
- package/server/service/order-product/order-product.ts +0 -362
- package/server/service/order-tote/index.ts +0 -9
- package/server/service/order-tote/order-tote-mutation.ts +0 -31
- package/server/service/order-tote/order-tote-query.ts +0 -112
- package/server/service/order-tote/order-tote-types.ts +0 -47
- package/server/service/order-tote/order-tote.ts +0 -73
- package/server/service/order-tote-item/index.ts +0 -9
- package/server/service/order-tote-item/order-tote-item-mutation.ts +0 -31
- package/server/service/order-tote-item/order-tote-item-query.ts +0 -82
- package/server/service/order-tote-item/order-tote-item-types.ts +0 -56
- package/server/service/order-tote-item/order-tote-item.ts +0 -72
- package/server/service/order-tote-seal/index.ts +0 -9
- package/server/service/order-tote-seal/order-tote-seal-mutation.ts +0 -31
- package/server/service/order-tote-seal/order-tote-seal-query.ts +0 -59
- package/server/service/order-tote-seal/order-tote-seal-types.ts +0 -41
- package/server/service/order-tote-seal/order-tote-seal.ts +0 -46
- package/server/service/order-vas/index.ts +0 -9
- package/server/service/order-vas/order-vas-mutation.ts +0 -20
- package/server/service/order-vas/order-vas-query.ts +0 -72
- package/server/service/order-vas/order-vas-types.ts +0 -159
- package/server/service/order-vas/order-vas.ts +0 -207
- package/server/service/others/index.ts +0 -5
- package/server/service/others/other-query.ts +0 -563
- package/server/service/others/other-types.ts +0 -115
- package/server/service/purchase-order/index.ts +0 -9
- package/server/service/purchase-order/purchase-order-mutation.ts +0 -458
- package/server/service/purchase-order/purchase-order-query.ts +0 -90
- package/server/service/purchase-order/purchase-order-types.ts +0 -154
- package/server/service/purchase-order/purchase-order.ts +0 -172
- package/server/service/purchase-order-other-charge/index.ts +0 -9
- package/server/service/purchase-order-other-charge/purchase-order-other-charge-mutation.ts +0 -31
- package/server/service/purchase-order-other-charge/purchase-order-other-charge-query.ts +0 -52
- package/server/service/purchase-order-other-charge/purchase-order-other-charge-types.ts +0 -44
- package/server/service/purchase-order-other-charge/purchase-order-other-charge.ts +0 -68
- package/server/service/release-good/index.ts +0 -9
- package/server/service/release-good/release-good-mutation.ts +0 -1686
- package/server/service/release-good/release-good-query.ts +0 -980
- package/server/service/release-good/release-good-types.ts +0 -662
- package/server/service/release-good/release-good.ts +0 -490
- package/server/service/retail-replenishment-order/index.ts +0 -9
- package/server/service/retail-replenishment-order/retail-replenishment-order-mutation.ts +0 -382
- package/server/service/retail-replenishment-order/retail-replenishment-order-query.ts +0 -54
- package/server/service/retail-replenishment-order/retail-replenishment-order-types.ts +0 -101
- package/server/service/retail-replenishment-order/retail-replenishment-order.ts +0 -115
- package/server/service/return-order/index.ts +0 -9
- package/server/service/return-order/return-order-mutation.ts +0 -516
- package/server/service/return-order/return-order-query.ts +0 -226
- package/server/service/return-order/return-order-types.ts +0 -196
- package/server/service/return-order/return-order.ts +0 -127
- package/server/service/reverse-kitting-order/index.ts +0 -9
- package/server/service/reverse-kitting-order/reverse-kitting-order-mutation.ts +0 -500
- package/server/service/reverse-kitting-order/reverse-kitting-order-query.ts +0 -197
- package/server/service/reverse-kitting-order/reverse-kitting-order-type.ts +0 -173
- package/server/service/reverse-kitting-order/reverse-kitting-order.ts +0 -121
- package/server/service/reverse-kitting-order-inventory/index.ts +0 -9
- package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.ts +0 -129
- package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-query.ts +0 -52
- package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-type.ts +0 -95
- package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.ts +0 -143
- package/server/service/shipping-order/index.ts +0 -9
- package/server/service/shipping-order/shipping-order-mutation.ts +0 -61
- package/server/service/shipping-order/shipping-order-query.ts +0 -61
- package/server/service/shipping-order/shipping-order-types.ts +0 -89
- package/server/service/shipping-order/shipping-order.ts +0 -129
- package/server/service/transfer-order/index.ts +0 -9
- package/server/service/transfer-order/transfer-order-mutation.ts +0 -309
- package/server/service/transfer-order/transfer-order-query.ts +0 -66
- package/server/service/transfer-order/transfer-order-types.ts +0 -97
- package/server/service/transfer-order/transfer-order.ts +0 -117
- package/server/service/vas/index.ts +0 -9
- package/server/service/vas/vas-mutation.ts +0 -106
- package/server/service/vas/vas-query.ts +0 -60
- package/server/service/vas/vas-types.ts +0 -71
- package/server/service/vas/vas.ts +0 -77
- package/server/service/vas-order/index.ts +0 -9
- package/server/service/vas-order/vas-order-mutation.ts +0 -259
- package/server/service/vas-order/vas-order-query.ts +0 -119
- package/server/service/vas-order/vas-order-types.ts +0 -49
- package/server/service/vas-order/vas-order.ts +0 -81
- package/server/utils/datetime-util.ts +0 -54
- package/server/utils/index.ts +0 -3
- package/server/utils/inventory-util.ts +0 -1155
- package/server/utils/order-no-generator.ts +0 -146
|
@@ -1,1686 +0,0 @@
|
|
|
1
|
-
import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'
|
|
2
|
-
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
|
|
3
|
-
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
4
|
-
import { EntityManager, getConnection, In, Not, Repository } from 'typeorm'
|
|
5
|
-
|
|
6
|
-
import { Attachment, createAttachments } from '@things-factory/attachment-base'
|
|
7
|
-
import { ApplicationType, Partner, Role, User } from '@things-factory/auth-base'
|
|
8
|
-
import {
|
|
9
|
-
Bizplace,
|
|
10
|
-
ContactPoint,
|
|
11
|
-
getDomainUsers,
|
|
12
|
-
getMyBizplace,
|
|
13
|
-
getOutletBizplace,
|
|
14
|
-
getPermittedBizplaces
|
|
15
|
-
} from '@things-factory/biz-base'
|
|
16
|
-
import { logger } from '@things-factory/env'
|
|
17
|
-
import { generateId } from '@things-factory/id-rule-base'
|
|
18
|
-
import { MarketplaceStore } from '@things-factory/integration-marketplace'
|
|
19
|
-
import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
|
|
20
|
-
import { MarketplaceOrder, MarketplaceProductVariation } from '@things-factory/marketplace-base'
|
|
21
|
-
import { Product, ProductBundleSetting } from '@things-factory/product-base'
|
|
22
|
-
import { PartnerSetting, Setting } from '@things-factory/setting-base'
|
|
23
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
|
24
|
-
import { Inventory } from '@things-factory/warehouse-base'
|
|
25
|
-
|
|
26
|
-
// import { NewOrderProduct } from '../order-product/order-product-types'
|
|
27
|
-
import {
|
|
28
|
-
ATTACHMENT_TYPE,
|
|
29
|
-
ORDER_INVENTORY_STATUS,
|
|
30
|
-
ORDER_METHOD,
|
|
31
|
-
ORDER_NUMBER_RULE_TYPE,
|
|
32
|
-
ORDER_NUMBER_SETTING_KEY,
|
|
33
|
-
ORDER_PRODUCT_STATUS,
|
|
34
|
-
ORDER_STATUS,
|
|
35
|
-
ORDER_TYPES,
|
|
36
|
-
ORDER_VAS_STATUS,
|
|
37
|
-
PRODUCT_GROUP_TYPE
|
|
38
|
-
} from '../../constants'
|
|
39
|
-
import { EcommerceController, SellercraftController } from '../../controllers'
|
|
40
|
-
import { ValidationError } from '../../errors'
|
|
41
|
-
import { InventoryUtil, OrderNoGenerator } from '../../utils'
|
|
42
|
-
import { ArrivalNotice } from '../arrival-notice/arrival-notice'
|
|
43
|
-
import { confirmArrivalNoticeFunction, deleteArrivalNotice } from '../arrival-notice/arrival-notice-mutation'
|
|
44
|
-
import { OrderInventory } from '../order-inventory/order-inventory'
|
|
45
|
-
import { OrderProduct } from '../order-product/order-product'
|
|
46
|
-
import { OrderVas } from '../order-vas/order-vas'
|
|
47
|
-
import { NewReleaseGood, ReleaseGoodPatch, ShippingOrderInfoPatch } from '../release-good/release-good-types'
|
|
48
|
-
import { ShippingOrder } from '../shipping-order/shipping-order'
|
|
49
|
-
import { ShippingOrderPatch } from '../shipping-order/shipping-order-types'
|
|
50
|
-
import { Vas } from '../vas/vas'
|
|
51
|
-
import { ReleaseGood } from './release-good'
|
|
52
|
-
import { bulkReleaseGoodsAvailableItemsFunction } from './release-good-query'
|
|
53
|
-
|
|
54
|
-
@Resolver(ReleaseGood)
|
|
55
|
-
export class ReleaseGoodMutation {
|
|
56
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
57
|
-
@Directive('@transaction')
|
|
58
|
-
@Mutation(returns => [ReleaseGood])
|
|
59
|
-
async bulkAddReleaseGoods(
|
|
60
|
-
@Ctx() context: ResolverContext,
|
|
61
|
-
@Arg('rawReleaseGoods', type => [NewReleaseGood], { nullable: true }) rawReleaseGoods: NewReleaseGood[],
|
|
62
|
-
@Arg('bizplaceId', type => String) bizplaceId: string
|
|
63
|
-
): Promise<ReleaseGood[]> {
|
|
64
|
-
const { domain, user, tx } = context.state
|
|
65
|
-
|
|
66
|
-
if (!bizplaceId) throw new Error('company ID is not provided')
|
|
67
|
-
|
|
68
|
-
let createdReleaseGoods: ReleaseGood[] = []
|
|
69
|
-
const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
|
|
70
|
-
|
|
71
|
-
const roNoSetting: Setting = await settingRepo.findOne({
|
|
72
|
-
where: {
|
|
73
|
-
domain: { id: domain.id },
|
|
74
|
-
name: ORDER_NUMBER_SETTING_KEY.RO_NUMBER_RULE
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
let releaseGoods: Partial<ReleaseGood[]> = extractRawReleaseGoods(rawReleaseGoods)
|
|
79
|
-
|
|
80
|
-
let errorsCaught: any[] = []
|
|
81
|
-
for (let i = 0, l = releaseGoods.length; i < l; i++) {
|
|
82
|
-
// generate release good by group to avoid duplication
|
|
83
|
-
// if this function is called simultaneously by different users
|
|
84
|
-
try {
|
|
85
|
-
await getConnection().transaction(async (childTx: EntityManager) => {
|
|
86
|
-
const existingReleaseGood: ReleaseGood = await childTx.getRepository(ReleaseGood).findOne({
|
|
87
|
-
where: {
|
|
88
|
-
...Object.fromEntries(
|
|
89
|
-
Object.entries(releaseGoods[i]).filter(([_, val]) => !/^\s*$/.test(val) && _ != 'orderInventories')
|
|
90
|
-
),
|
|
91
|
-
domain: { id: domain.id }
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
if (existingReleaseGood) throw new Error('this order is already exist in the system')
|
|
95
|
-
|
|
96
|
-
let availableItems: any[] = await bulkReleaseGoodsAvailableItemsFunction(
|
|
97
|
-
[...releaseGoods[i].orderInventories],
|
|
98
|
-
bizplaceId,
|
|
99
|
-
context,
|
|
100
|
-
childTx
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
if (availableItems.some(item => !item.releaseQty || item.releaseQty > item.assignedQty))
|
|
104
|
-
throw new ValidationError({
|
|
105
|
-
...ValidationError.ERROR_CODES.INSUFFICIENT_STOCK,
|
|
106
|
-
detail: { data: JSON.stringify(availableItems) }
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
// update orderInventories if availableItems are valid
|
|
110
|
-
releaseGoods[i].orderInventories = availableItems
|
|
111
|
-
|
|
112
|
-
const createdReleaseGood: ReleaseGood = await bulkGenerateReleaseGood(
|
|
113
|
-
releaseGoods[i],
|
|
114
|
-
bizplaceId,
|
|
115
|
-
roNoSetting,
|
|
116
|
-
domain,
|
|
117
|
-
user,
|
|
118
|
-
childTx
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
createdReleaseGoods.push(createdReleaseGood)
|
|
122
|
-
})
|
|
123
|
-
} catch (error) {
|
|
124
|
-
let rawReleaseGoods = formRawReleaseGoods(releaseGoods[i], error.message)
|
|
125
|
-
errorsCaught.push(...rawReleaseGoods)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
let confirmedReleaseGoods: ReleaseGood[] = []
|
|
130
|
-
|
|
131
|
-
if (createdReleaseGoods.length)
|
|
132
|
-
try {
|
|
133
|
-
confirmedReleaseGoods = await bulkConfirmReleaseGoods(
|
|
134
|
-
createdReleaseGoods.map(rg => rg.name),
|
|
135
|
-
domain,
|
|
136
|
-
user,
|
|
137
|
-
context,
|
|
138
|
-
tx
|
|
139
|
-
)
|
|
140
|
-
} catch (error) {}
|
|
141
|
-
|
|
142
|
-
if (errorsCaught.length)
|
|
143
|
-
throw new ValidationError({
|
|
144
|
-
...ValidationError.ERROR_CODES.INVALID_DATA_FOUND,
|
|
145
|
-
detail: { data: JSON.stringify(errorsCaught) }
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
return confirmedReleaseGoods
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
152
|
-
@Directive('@transaction')
|
|
153
|
-
@Mutation(returns => Boolean)
|
|
154
|
-
async deleteReleaseGood(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Boolean> {
|
|
155
|
-
const { tx, user, domain } = context.state
|
|
156
|
-
return await deleteReleaseGood(tx, name, user, domain)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
160
|
-
@Directive('@transaction')
|
|
161
|
-
@Mutation(returns => Boolean)
|
|
162
|
-
async deleteReleaseGoods(
|
|
163
|
-
@Arg('names', type => [String]) names: string[],
|
|
164
|
-
@Ctx() context: ResolverContext
|
|
165
|
-
): Promise<Boolean> {
|
|
166
|
-
const { tx } = context.state
|
|
167
|
-
await tx.getRepository(ReleaseGood).delete({
|
|
168
|
-
domain: { id: context.state.domain.id },
|
|
169
|
-
name: In(names)
|
|
170
|
-
})
|
|
171
|
-
return true
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
175
|
-
@Directive('@transaction')
|
|
176
|
-
@Mutation(returns => ReleaseGood)
|
|
177
|
-
async generateReleaseGood(
|
|
178
|
-
@Ctx() context: ResolverContext,
|
|
179
|
-
@Arg('attachments', type => [GraphQLUpload], { nullable: true }) attachments?: FileUpload[],
|
|
180
|
-
@Arg('releaseGood', type => NewReleaseGood, { nullable: true }) releaseGood?: NewReleaseGood,
|
|
181
|
-
@Arg('shippingOrder', type => ShippingOrderPatch, { nullable: true }) shippingOrder?: ShippingOrderPatch,
|
|
182
|
-
@Arg('shippingOrderInfo', type => ShippingOrderInfoPatch, { nullable: true })
|
|
183
|
-
shippingOrderInfo?: ShippingOrderInfoPatch
|
|
184
|
-
): Promise<ReleaseGood> {
|
|
185
|
-
const { tx } = context.state
|
|
186
|
-
const createdReleaseGood: ReleaseGood = await generateReleaseGoodFunction(
|
|
187
|
-
null,
|
|
188
|
-
releaseGood,
|
|
189
|
-
shippingOrder,
|
|
190
|
-
shippingOrderInfo,
|
|
191
|
-
attachments,
|
|
192
|
-
context,
|
|
193
|
-
tx
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
return createdReleaseGood
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
200
|
-
@Directive('@transaction')
|
|
201
|
-
@Mutation(returns => ReleaseGood)
|
|
202
|
-
async updateReleaseGoodDetails(
|
|
203
|
-
@Ctx() context: ResolverContext,
|
|
204
|
-
@Arg('releaseGood', type => ReleaseGoodPatch, { nullable: true }) releaseGood?: ReleaseGoodPatch,
|
|
205
|
-
@Arg('shippingOrder', type => ShippingOrderPatch, { nullable: true }) shippingOrder?: ShippingOrderPatch,
|
|
206
|
-
@Arg('shippingOrderInfo', type => ShippingOrderInfoPatch, { nullable: true })
|
|
207
|
-
shippingOrderInfo?: ShippingOrderInfoPatch
|
|
208
|
-
): Promise<ReleaseGood> {
|
|
209
|
-
const { tx, domain, user } = context.state
|
|
210
|
-
let foundReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
211
|
-
where: { id: releaseGood.id, domain: { id: domain.id } },
|
|
212
|
-
relations: ['shippingOrder']
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
if (!foundReleaseGood) {
|
|
216
|
-
throw new Error(`Release order ${releaseGood.id} is not found.`)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// case to update existing shippingOrder
|
|
220
|
-
if (shippingOrder !== null) {
|
|
221
|
-
shippingOrder.remark = shippingOrder.exportRemark
|
|
222
|
-
shippingOrder.containerClosureDateTime = new Date(shippingOrder.containerClosureDate)
|
|
223
|
-
delete shippingOrder.exportRemark
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (foundReleaseGood.shippingOrder && shippingOrder) {
|
|
227
|
-
await tx.getRepository(ShippingOrder).update(foundReleaseGood.shippingOrder.id, shippingOrder)
|
|
228
|
-
}
|
|
229
|
-
// case for new shippingOrder
|
|
230
|
-
else if (!foundReleaseGood.shippingOrder && shippingOrder) {
|
|
231
|
-
let newShippingOrder: ShippingOrder = await tx.getRepository(ShippingOrder).save({
|
|
232
|
-
...shippingOrder,
|
|
233
|
-
name: OrderNoGenerator.shippingOrder(),
|
|
234
|
-
domain,
|
|
235
|
-
bizplace: await getMyBizplace(domain, user),
|
|
236
|
-
status: ORDER_STATUS.PENDING,
|
|
237
|
-
creator: user,
|
|
238
|
-
updater: user
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
releaseGood.shippingOrder = newShippingOrder
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
foundReleaseGood = await tx.getRepository(ReleaseGood).save({
|
|
245
|
-
...(foundReleaseGood as any),
|
|
246
|
-
...releaseGood,
|
|
247
|
-
...shippingOrderInfo,
|
|
248
|
-
remark: releaseGood?.remark ? releaseGood.remark : null
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
return foundReleaseGood
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
255
|
-
@Directive('@transaction')
|
|
256
|
-
@Mutation(returns => ReleaseGood)
|
|
257
|
-
async confirmReleaseGood(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<ReleaseGood> {
|
|
258
|
-
const { tx } = context.state
|
|
259
|
-
const releaseGood: ReleaseGood = await confirmReleaseGood(name, context, tx)
|
|
260
|
-
|
|
261
|
-
// If current RO has cross docking
|
|
262
|
-
if (releaseGood.crossDocking) {
|
|
263
|
-
const { arrivalNotice } = await tx.getRepository(ReleaseGood).findOne({
|
|
264
|
-
where: { id: releaseGood.id },
|
|
265
|
-
relations: ['arrivalNotice']
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
// If status of related GAN is not equal to PENDING_RECEIVE (i.e. Wasn't confirmed yet.)
|
|
269
|
-
if (arrivalNotice.status !== ORDER_STATUS.PENDING_RECEIVE) {
|
|
270
|
-
await confirmArrivalNoticeFunction(arrivalNotice.name, context, tx)
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return releaseGood
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
278
|
-
@Directive('@transaction')
|
|
279
|
-
@Mutation(returns => ReleaseGood)
|
|
280
|
-
async receiveReleaseGood(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<ReleaseGood> {
|
|
281
|
-
const { tx } = context.state
|
|
282
|
-
const releaseGood: ReleaseGood = await receiveReleaseGood(name, context, tx)
|
|
283
|
-
return releaseGood
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
@Directive('@privilege(category: "order_warehouse", privilege: "mutation")')
|
|
287
|
-
@Directive('@transaction')
|
|
288
|
-
@Mutation(returns => ReleaseGood)
|
|
289
|
-
async rejectReleaseGood(
|
|
290
|
-
@Arg('name') name: string,
|
|
291
|
-
@Arg('patch', type => ReleaseGoodPatch) patch: ReleaseGoodPatch,
|
|
292
|
-
@Ctx() context: ResolverContext
|
|
293
|
-
): Promise<ReleaseGood> {
|
|
294
|
-
const { tx } = context.state
|
|
295
|
-
|
|
296
|
-
return await rejectReleaseGood(tx, context, name, patch.remark)
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
@Directive('@transaction')
|
|
300
|
-
@Mutation(returns => ReleaseGood)
|
|
301
|
-
async addReleaseGood(
|
|
302
|
-
@Ctx() context: ResolverContext,
|
|
303
|
-
@Arg('releaseGood', type => NewReleaseGood, { nullable: true }) releaseGood: NewReleaseGood,
|
|
304
|
-
@Arg('shippingOrder', type => ShippingOrderPatch, { nullable: true }) shippingOrder: ShippingOrderPatch,
|
|
305
|
-
@Arg('file', type => GraphQLUpload, { nullable: true }) file: FileUpload
|
|
306
|
-
): Promise<ReleaseGood> {
|
|
307
|
-
const { tx } = context.state
|
|
308
|
-
const createdRO: ReleaseGood = await generateReleaseGoodFunction(
|
|
309
|
-
null,
|
|
310
|
-
releaseGood,
|
|
311
|
-
shippingOrder,
|
|
312
|
-
null,
|
|
313
|
-
file,
|
|
314
|
-
context,
|
|
315
|
-
tx
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
const confirmedRO: ReleaseGood = await confirmReleaseGood(createdRO.name, context, tx)
|
|
319
|
-
|
|
320
|
-
const receivedRO: ReleaseGood = await receiveReleaseGood(confirmedRO.name, context, tx)
|
|
321
|
-
|
|
322
|
-
return receivedRO
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
@Directive('@privilege(category: "order_customer", privilege: "mutation")')
|
|
326
|
-
@Directive('@transaction')
|
|
327
|
-
@Mutation(returns => Boolean)
|
|
328
|
-
async executeOrderRemark(
|
|
329
|
-
@Arg('releaseGoodNo') releaseGoodNo: string,
|
|
330
|
-
@Ctx() context: ResolverContext
|
|
331
|
-
): Promise<boolean> {
|
|
332
|
-
const { domain, tx, user } = context.state
|
|
333
|
-
|
|
334
|
-
await tx.getRepository(ReleaseGood).update(
|
|
335
|
-
{
|
|
336
|
-
domain: { id: domain.id },
|
|
337
|
-
name: releaseGoodNo
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
checkedRemarkAt: new Date(),
|
|
341
|
-
checkedRemarkUser: user,
|
|
342
|
-
checkedRemarkBy: user.name
|
|
343
|
-
}
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
return true
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
export async function deleteReleaseGood(tx: EntityManager, name: string, user: User, domain: Domain): Promise<boolean> {
|
|
351
|
-
let foundReleaseOrder: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
352
|
-
where: { domain: { id: domain.id }, name },
|
|
353
|
-
relations: [
|
|
354
|
-
'arrivalNotice',
|
|
355
|
-
'orderInventories',
|
|
356
|
-
'orderInventories.orderProduct',
|
|
357
|
-
'orderInventories.inventory',
|
|
358
|
-
'orderVass',
|
|
359
|
-
'shippingOrder',
|
|
360
|
-
'creator',
|
|
361
|
-
'updater'
|
|
362
|
-
]
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
if (!foundReleaseOrder) throw new Error(`Release order doesn't exists.`)
|
|
366
|
-
const foundOIs: OrderInventory[] = foundReleaseOrder.orderInventories
|
|
367
|
-
const foundOVs: OrderVas[] = foundReleaseOrder.orderVass
|
|
368
|
-
const foundSO: ShippingOrder = foundReleaseOrder.shippingOrder
|
|
369
|
-
|
|
370
|
-
let foundAttachment: Attachment
|
|
371
|
-
if (foundReleaseOrder?.ownTransport) {
|
|
372
|
-
foundAttachment = await tx.getRepository(Attachment).findOne({
|
|
373
|
-
where: {
|
|
374
|
-
domain: { id: domain.id },
|
|
375
|
-
refBy: foundReleaseOrder.id,
|
|
376
|
-
category: ATTACHMENT_TYPE.DELIVERY_ORDER
|
|
377
|
-
}
|
|
378
|
-
})
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// Delete order inventories by ids
|
|
382
|
-
await Promise.all(
|
|
383
|
-
foundOIs.map(async (oi: OrderInventory) => {
|
|
384
|
-
if (oi?.inventory?.id) {
|
|
385
|
-
oi.inventory = await tx.getRepository(Inventory).findOneBy({ id: oi.inventory.id })
|
|
386
|
-
|
|
387
|
-
await tx.getRepository(Inventory).save({
|
|
388
|
-
...oi.inventory,
|
|
389
|
-
lockedQty: oi.inventory.lockedQty - oi.releaseQty,
|
|
390
|
-
lockedUomValue: oi.inventory.lockedUomValue - oi.releaseUomValue,
|
|
391
|
-
updater: user
|
|
392
|
-
})
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
await tx.getRepository(OrderInventory).delete({ id: oi.id })
|
|
396
|
-
|
|
397
|
-
if (oi?.orderProduct?.id) {
|
|
398
|
-
await tx.getRepository(OrderProduct).delete({ id: oi.orderProduct.id })
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return oi
|
|
402
|
-
})
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
// 2. delete order vass
|
|
406
|
-
const vasIds = foundOVs.map((vas: OrderVas) => vas.id)
|
|
407
|
-
if (vasIds.length) {
|
|
408
|
-
await tx.getRepository(OrderVas).delete({ id: In(vasIds) })
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (foundAttachment) {
|
|
412
|
-
await tx.getRepository(Attachment).delete({ domain: { id: domain.id }, id: foundAttachment.id })
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// 4. Remove relation with GAN if it's cross docking
|
|
416
|
-
if (foundReleaseOrder.crossDocking && foundReleaseOrder.arrivalNotice?.id) {
|
|
417
|
-
let arrivalNotice: ArrivalNotice = foundReleaseOrder.arrivalNotice
|
|
418
|
-
arrivalNotice.releaseGood = null
|
|
419
|
-
arrivalNotice = await tx.getRepository(ArrivalNotice).save(arrivalNotice)
|
|
420
|
-
|
|
421
|
-
await tx.getRepository(ReleaseGood).delete({ domain: { id: domain.id }, name })
|
|
422
|
-
await deleteArrivalNotice(tx, arrivalNotice.name, user, domain)
|
|
423
|
-
} else {
|
|
424
|
-
await tx.getRepository(ReleaseGood).delete({ domain: { id: domain.id }, name })
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// 5. if there is SO, delete SO
|
|
428
|
-
if (foundSO) {
|
|
429
|
-
await tx.getRepository(ShippingOrder).delete({ domain: { id: domain.id }, id: foundSO.id })
|
|
430
|
-
}
|
|
431
|
-
return true
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
export async function generateReleaseGoodFunction(
|
|
435
|
-
_: any,
|
|
436
|
-
releaseGood: any,
|
|
437
|
-
shippingOrder: ShippingOrderPatch,
|
|
438
|
-
shippingOrderInfo: any,
|
|
439
|
-
attachments: FileUpload[],
|
|
440
|
-
context: ResolverContext,
|
|
441
|
-
tx?: EntityManager
|
|
442
|
-
): Promise<ReleaseGood> {
|
|
443
|
-
try {
|
|
444
|
-
const { domain, user } = context.state
|
|
445
|
-
const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
|
|
446
|
-
|
|
447
|
-
// let orderInventories: OrderInventory[] = releaseGood.orderInventories
|
|
448
|
-
// let orderVass: OrderVas[] = releaseGood.orderVass
|
|
449
|
-
|
|
450
|
-
let { orderInventories, orderVass }: { orderInventories: OrderInventory[]; orderVass: OrderVas[] } = releaseGood
|
|
451
|
-
|
|
452
|
-
let bizplace: Bizplace
|
|
453
|
-
let warehouseDomain: Domain = domain
|
|
454
|
-
let finalOrderInventories: OrderInventory[] = []
|
|
455
|
-
|
|
456
|
-
if (releaseGood.deliverTo) {
|
|
457
|
-
const deliverTo: ContactPoint = await tx.getRepository(ContactPoint).findOne({
|
|
458
|
-
where: { id: releaseGood.deliverTo.id },
|
|
459
|
-
relations: ['bizplace']
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
if (!deliverTo) throw new Error('contact point does not exist')
|
|
463
|
-
|
|
464
|
-
releaseGood.deliverTo = deliverTo
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/** Validate user permitted Bizplace */
|
|
468
|
-
if (releaseGood.warehouseId) {
|
|
469
|
-
bizplace = await getOutletBizplace(releaseGood.warehouseId)
|
|
470
|
-
} else if (releaseGood.customerBizplaceId) {
|
|
471
|
-
const permittedBizplaces: Bizplace[] = await getPermittedBizplaces(domain, user)
|
|
472
|
-
let foundPermittedBizplace: Bizplace = permittedBizplaces.find(biz => biz.id == releaseGood.customerBizplaceId)
|
|
473
|
-
|
|
474
|
-
if (!foundPermittedBizplace) throw new Error(`This user does not permitted for this company`)
|
|
475
|
-
|
|
476
|
-
bizplace = await tx.getRepository(Bizplace).findOne({
|
|
477
|
-
where: {
|
|
478
|
-
id: releaseGood.customerBizplaceId
|
|
479
|
-
},
|
|
480
|
-
relations: ['domain']
|
|
481
|
-
})
|
|
482
|
-
const customerPartner: Partner = await tx.getRepository(Partner).findOne({
|
|
483
|
-
where: { partnerDomain: { id: bizplace.domain.id }, domain: { id: domain.id } },
|
|
484
|
-
relations: ['domain']
|
|
485
|
-
})
|
|
486
|
-
warehouseDomain = customerPartner.domain
|
|
487
|
-
} else if (releaseGood.partnerBizplaceId) {
|
|
488
|
-
const permittedBizplaces: Bizplace[] = await getPermittedBizplaces(domain, user)
|
|
489
|
-
let foundPermittedBizplace: Bizplace = permittedBizplaces.find(biz => biz.id == releaseGood.partnerBizplaceId)
|
|
490
|
-
|
|
491
|
-
if (!foundPermittedBizplace) throw new Error(`This user does not permitted for this company`)
|
|
492
|
-
|
|
493
|
-
bizplace = await tx.getRepository(Bizplace).findOne({
|
|
494
|
-
where: {
|
|
495
|
-
id: releaseGood.partnerBizplaceId
|
|
496
|
-
},
|
|
497
|
-
relations: ['domain']
|
|
498
|
-
})
|
|
499
|
-
warehouseDomain = domain
|
|
500
|
-
} else {
|
|
501
|
-
bizplace = await getMyBizplace(domain, user)
|
|
502
|
-
}
|
|
503
|
-
/** End Validate user permitted Bizplace Section */
|
|
504
|
-
|
|
505
|
-
/** Validate Release Order Product Quantity */
|
|
506
|
-
await InventoryUtil.validateWarehousePartnersProductsQuantity(domain, bizplace, orderInventories, context, tx)
|
|
507
|
-
/** End Validate Release Order Product Quantity Section */
|
|
508
|
-
|
|
509
|
-
const orderSource: string = releaseGood.source
|
|
510
|
-
switch (orderSource) {
|
|
511
|
-
case ApplicationType.SELLERCRAFT:
|
|
512
|
-
const sellercraft: Sellercraft = await tx
|
|
513
|
-
.getRepository(Sellercraft)
|
|
514
|
-
.findOneBy({ domain: { id: bizplace.domain.id }, status: SellercraftStatus.ACTIVE })
|
|
515
|
-
|
|
516
|
-
if (sellercraft) {
|
|
517
|
-
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
518
|
-
await sellercraftCtrl.checkExistingReleaseGood(sellercraft, releaseGood)
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
break
|
|
522
|
-
|
|
523
|
-
case ApplicationType.MMS:
|
|
524
|
-
const refNo: string = releaseGood.refNo
|
|
525
|
-
const foundReleaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
526
|
-
where: {
|
|
527
|
-
domain: { id: warehouseDomain.id },
|
|
528
|
-
refNo,
|
|
529
|
-
status: Not(In([ORDER_STATUS.CANCELLED, ORDER_STATUS.PENDING_CANCEL]))
|
|
530
|
-
},
|
|
531
|
-
relations: ['bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
|
|
532
|
-
})
|
|
533
|
-
|
|
534
|
-
if (foundReleaseGood) {
|
|
535
|
-
const customerCompanyDomain: Domain = foundReleaseGood.bizplace.company.domain
|
|
536
|
-
const marketplaceOrder: MarketplaceOrder = await tx.getRepository(MarketplaceOrder).findOne({
|
|
537
|
-
where: { orderNo: refNo, domain: { id: customerCompanyDomain.id } }
|
|
538
|
-
})
|
|
539
|
-
|
|
540
|
-
// Need to restructure the validation
|
|
541
|
-
if (marketplaceOrder?.isSplitted) {
|
|
542
|
-
const refNo2: string = releaseGood.refNo2
|
|
543
|
-
const foundSplittedReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
544
|
-
where: {
|
|
545
|
-
domain: { id: warehouseDomain.id },
|
|
546
|
-
refNo2,
|
|
547
|
-
status: Not(In([ORDER_STATUS.CANCELLED, ORDER_STATUS.PENDING_CANCEL]))
|
|
548
|
-
},
|
|
549
|
-
relations: ['bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
|
|
550
|
-
})
|
|
551
|
-
|
|
552
|
-
if (foundSplittedReleaseGood) throw new Error('Existing release order found')
|
|
553
|
-
} else {
|
|
554
|
-
throw new Error('Existing release order found')
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
break
|
|
558
|
-
|
|
559
|
-
default:
|
|
560
|
-
break
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
let newReleaseGood: ReleaseGood = new ReleaseGood()
|
|
564
|
-
|
|
565
|
-
/** Generate Shipping Order */
|
|
566
|
-
if (shippingOrder) {
|
|
567
|
-
shippingOrder.remark = shippingOrder.exportRemark
|
|
568
|
-
if (shippingOrder.containerClosureDate !== undefined) {
|
|
569
|
-
shippingOrder.containerClosureDateTime = new Date(shippingOrder.containerClosureDate)
|
|
570
|
-
}
|
|
571
|
-
delete shippingOrder.exportRemark
|
|
572
|
-
|
|
573
|
-
const createdSO: ShippingOrder = await tx.getRepository(ShippingOrder).save({
|
|
574
|
-
...shippingOrder,
|
|
575
|
-
name: OrderNoGenerator.shippingOrder(),
|
|
576
|
-
domain,
|
|
577
|
-
bizplace,
|
|
578
|
-
status: ORDER_STATUS.PENDING,
|
|
579
|
-
creator: user,
|
|
580
|
-
updater: user
|
|
581
|
-
})
|
|
582
|
-
|
|
583
|
-
newReleaseGood.shippingOrder = createdSO
|
|
584
|
-
}
|
|
585
|
-
/** End Generate Shipping Order Section */
|
|
586
|
-
|
|
587
|
-
// find RO number rule setting
|
|
588
|
-
const roNoSetting: Setting = await settingRepo.findOne({
|
|
589
|
-
where: {
|
|
590
|
-
domain: { id: domain.id },
|
|
591
|
-
name: ORDER_NUMBER_SETTING_KEY.RO_NUMBER_RULE
|
|
592
|
-
}
|
|
593
|
-
})
|
|
594
|
-
|
|
595
|
-
newReleaseGood = {
|
|
596
|
-
...newReleaseGood,
|
|
597
|
-
name: roNoSetting
|
|
598
|
-
? await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.RO_NUMBER, seed: {} })
|
|
599
|
-
: OrderNoGenerator.releaseGood(),
|
|
600
|
-
domain: warehouseDomain,
|
|
601
|
-
bizplace: bizplace,
|
|
602
|
-
collectionOrderNo: releaseGood.collectionOrderNo,
|
|
603
|
-
courierOption: releaseGood.courierOption,
|
|
604
|
-
exportOption: releaseGood.exportOption,
|
|
605
|
-
ownTransport: releaseGood.ownTransport,
|
|
606
|
-
packingOption: releaseGood.packingOption,
|
|
607
|
-
recall: releaseGood.recall,
|
|
608
|
-
marketplaceOrderStatus: releaseGood?.marketplaceOrderStatus || null,
|
|
609
|
-
deliverTo: releaseGood.deliverTo,
|
|
610
|
-
billingAddress:
|
|
611
|
-
releaseGood.type == 'b2c' ? releaseGood?.billingAddress || null : shippingOrderInfo.billingAddress || null,
|
|
612
|
-
deliveryAddress1: releaseGood?.deliveryAddress1 || shippingOrderInfo.deliveryAddress1 || null,
|
|
613
|
-
deliveryAddress2: releaseGood?.deliveryAddress2 || null,
|
|
614
|
-
deliveryAddress3: releaseGood?.deliveryAddress3 || null,
|
|
615
|
-
deliveryAddress4: releaseGood?.deliveryAddress4 || null,
|
|
616
|
-
deliveryAddress5: releaseGood?.deliveryAddress5 || null,
|
|
617
|
-
attentionTo: releaseGood.type == 'b2c' ? releaseGood?.attentionTo || null : shippingOrderInfo.attentionTo || null,
|
|
618
|
-
attentionCompany:
|
|
619
|
-
releaseGood.type == 'b2c' ? releaseGood?.companyName || null : shippingOrderInfo.attentionCompany || null,
|
|
620
|
-
city: releaseGood.type == 'b2c' ? releaseGood?.city || null : shippingOrderInfo.city || null,
|
|
621
|
-
state: releaseGood.type == 'b2c' ? releaseGood?.state || null : shippingOrderInfo.state || null,
|
|
622
|
-
postalCode: releaseGood.type == 'b2c' ? releaseGood?.postalCode || null : shippingOrderInfo.postalCode || null,
|
|
623
|
-
country: releaseGood.type == 'b2c' ? releaseGood?.country || null : shippingOrderInfo.country || null,
|
|
624
|
-
phone1: releaseGood.type == 'b2c' ? releaseGood?.phone1 || null : shippingOrderInfo.phone1 || null,
|
|
625
|
-
phone2: releaseGood?.phone2 || null,
|
|
626
|
-
email: releaseGood?.email || null,
|
|
627
|
-
billingCity: releaseGood.type == 'b2c' ? releaseGood?.billingCity || null : shippingOrderInfo.billingCity || null,
|
|
628
|
-
billingCountry:
|
|
629
|
-
releaseGood.type == 'b2c' ? releaseGood?.billingCountry || null : shippingOrderInfo.billingCountry || null,
|
|
630
|
-
billingPostalCode:
|
|
631
|
-
releaseGood.type == 'b2c'
|
|
632
|
-
? releaseGood?.billingPostalCode || null
|
|
633
|
-
: shippingOrderInfo.billingPostalCode || null,
|
|
634
|
-
billingState:
|
|
635
|
-
releaseGood.type == 'b2c' ? releaseGood?.billingState || null : shippingOrderInfo.billingState || null,
|
|
636
|
-
transporter: releaseGood?.transporter,
|
|
637
|
-
trackingNo: releaseGood?.trackingNo,
|
|
638
|
-
airwayBill: releaseGood?.airwayBill,
|
|
639
|
-
invoice: releaseGood?.invoice,
|
|
640
|
-
refNo: releaseGood.refNo,
|
|
641
|
-
refNo2: releaseGood.refNo2,
|
|
642
|
-
refNo3: releaseGood.refNo3,
|
|
643
|
-
remark: releaseGood?.remark || null,
|
|
644
|
-
releaseDate: releaseGood.releaseDate,
|
|
645
|
-
truckNo: releaseGood.truckNo,
|
|
646
|
-
bundleInfo: releaseGood?.bundleInfo || [],
|
|
647
|
-
orderInventories: releaseGood.orderInventories,
|
|
648
|
-
type: releaseGood?.type ? releaseGood.type : 'b2b',
|
|
649
|
-
orderMethod: releaseGood?.orderMethod
|
|
650
|
-
? releaseGood.orderMethod
|
|
651
|
-
: releaseGood.orderInventories[0]?.inventory?.id
|
|
652
|
-
? ORDER_METHOD.SELECT_BY_PALLET
|
|
653
|
-
: ORDER_METHOD.SELECT_BY_PRODUCT,
|
|
654
|
-
status: ORDER_STATUS.PENDING,
|
|
655
|
-
packageId: releaseGood?.packageId,
|
|
656
|
-
storeName: releaseGood?.storeName,
|
|
657
|
-
storeId: releaseGood?.storeId,
|
|
658
|
-
routeId: releaseGood?.routeId,
|
|
659
|
-
stopId: releaseGood?.stopId,
|
|
660
|
-
creator: user,
|
|
661
|
-
updater: user
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// Make relation with GAN for cross docking
|
|
665
|
-
let crossDockingGAN: ArrivalNotice = undefined
|
|
666
|
-
if (releaseGood.crossDocking && releaseGood.ganNo) {
|
|
667
|
-
crossDockingGAN = await tx.getRepository(ArrivalNotice).findOne({
|
|
668
|
-
where: {
|
|
669
|
-
domain: { id: domain.id },
|
|
670
|
-
bizplace: { id: bizplace.id },
|
|
671
|
-
name: releaseGood.ganNo,
|
|
672
|
-
status: ORDER_STATUS.PENDING
|
|
673
|
-
}
|
|
674
|
-
})
|
|
675
|
-
if (!crossDockingGAN) throw new Error(`Failed to find GAN (${releaseGood.ganNo}) for cross docking`)
|
|
676
|
-
|
|
677
|
-
newReleaseGood.arrivalNotice = crossDockingGAN
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// Make relation with RO for cross docking
|
|
681
|
-
if (newReleaseGood.crossDocking) {
|
|
682
|
-
crossDockingGAN.releaseGood = newReleaseGood
|
|
683
|
-
await tx.getRepository(ArrivalNotice).save(crossDockingGAN)
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// Check if there is bundle item in orderInventories
|
|
687
|
-
const bundledOIs: OrderInventory[] = orderInventories.filter(
|
|
688
|
-
oi => (oi.product as any).groupType === PRODUCT_GROUP_TYPE.BUNDLE
|
|
689
|
-
)
|
|
690
|
-
|
|
691
|
-
const singleProductOIs: OrderInventory[] = orderInventories.filter(
|
|
692
|
-
oi => (oi.product as any).groupType !== PRODUCT_GROUP_TYPE.BUNDLE
|
|
693
|
-
)
|
|
694
|
-
|
|
695
|
-
const splitBundleOIs: OrderInventory[] = []
|
|
696
|
-
|
|
697
|
-
// If there is bundle item, split each item in that bundle into into each product
|
|
698
|
-
if (bundledOIs && bundledOIs.length > 0) {
|
|
699
|
-
await Promise.all(
|
|
700
|
-
bundledOIs.map(async (oi: OrderInventory) => {
|
|
701
|
-
let splitOI: OrderInventory = null
|
|
702
|
-
|
|
703
|
-
const pbSettings: ProductBundleSetting[] = await tx.getRepository(ProductBundleSetting).find({
|
|
704
|
-
where: { productBundle: { id: oi.product.id } },
|
|
705
|
-
relations: ['product', 'productBundle']
|
|
706
|
-
})
|
|
707
|
-
|
|
708
|
-
pbSettings.forEach(pbs => {
|
|
709
|
-
splitOI = {
|
|
710
|
-
...oi,
|
|
711
|
-
releaseQty: oi.releaseQty * pbs.bundleQty,
|
|
712
|
-
releaseUomValue: oi.releaseUomValue * pbs.bundleQty * pbs.product.primaryValue,
|
|
713
|
-
packingType: pbs.product.packingType,
|
|
714
|
-
batchId: '',
|
|
715
|
-
product: {
|
|
716
|
-
id: pbs.product.id,
|
|
717
|
-
name: pbs.product.name,
|
|
718
|
-
groupType: PRODUCT_GROUP_TYPE.SINGLE
|
|
719
|
-
} as any
|
|
720
|
-
}
|
|
721
|
-
splitBundleOIs.push(splitOI)
|
|
722
|
-
})
|
|
723
|
-
})
|
|
724
|
-
)
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
orderInventories = [...singleProductOIs, ...splitBundleOIs]
|
|
728
|
-
|
|
729
|
-
newReleaseGood.noOfItems = orderInventories.length
|
|
730
|
-
newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
|
|
731
|
-
|
|
732
|
-
for (let oi of orderInventories) {
|
|
733
|
-
let newOrderInv: OrderInventory = Object.assign({}, oi)
|
|
734
|
-
newOrderInv = {
|
|
735
|
-
...newOrderInv,
|
|
736
|
-
domain: warehouseDomain,
|
|
737
|
-
bizplace: bizplace,
|
|
738
|
-
status: ORDER_INVENTORY_STATUS.PENDING,
|
|
739
|
-
name: OrderNoGenerator.orderInventory(),
|
|
740
|
-
releaseGood: newReleaseGood,
|
|
741
|
-
product: await tx.getRepository(Product).findOneBy({ id: oi.product.id }),
|
|
742
|
-
creator: user,
|
|
743
|
-
updater: user
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
let newOrderProduct: OrderProduct = Object.assign(new OrderProduct(), newOrderInv)
|
|
747
|
-
newOrderProduct = {
|
|
748
|
-
...newOrderProduct,
|
|
749
|
-
packQty: 0,
|
|
750
|
-
actualPackQty: 0,
|
|
751
|
-
palletQty: 0,
|
|
752
|
-
actualPalletQty: 0,
|
|
753
|
-
status: ORDER_PRODUCT_STATUS.ASSIGNED
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
newOrderProduct = await tx.getRepository(OrderProduct).save(newOrderProduct)
|
|
757
|
-
|
|
758
|
-
if (newOrderInv.inventory?.id) {
|
|
759
|
-
const foundInv: Inventory = await tx.getRepository(Inventory).findOneBy({ id: newOrderInv.inventory.id })
|
|
760
|
-
newOrderInv.inventory = foundInv
|
|
761
|
-
newOrderInv.orderProduct = newOrderProduct
|
|
762
|
-
|
|
763
|
-
finalOrderInventories.push(newOrderInv)
|
|
764
|
-
} else {
|
|
765
|
-
// Preassign Inventories
|
|
766
|
-
const inventoryAssignmentSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
767
|
-
where: { domain: { id: domain.id }, name: 'rule-for-inventory-assignment' }
|
|
768
|
-
})
|
|
769
|
-
|
|
770
|
-
let locationSortingRules = []
|
|
771
|
-
if (inventoryAssignmentSetting) {
|
|
772
|
-
let locationSetting = JSON.parse(inventoryAssignmentSetting.value)
|
|
773
|
-
for (const key in locationSetting) {
|
|
774
|
-
locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
let assignedOrderInventories: OrderInventory[] = await InventoryUtil.autoAssignInventoryForRelease(
|
|
779
|
-
newOrderInv.product,
|
|
780
|
-
oi,
|
|
781
|
-
oi.packingType,
|
|
782
|
-
locationSortingRules,
|
|
783
|
-
bizplace,
|
|
784
|
-
warehouseDomain,
|
|
785
|
-
tx,
|
|
786
|
-
oi.batchId
|
|
787
|
-
)
|
|
788
|
-
|
|
789
|
-
assignedOrderInventories = assignedOrderInventories.map(aoi => {
|
|
790
|
-
return {
|
|
791
|
-
...aoi,
|
|
792
|
-
orderProduct: newOrderProduct
|
|
793
|
-
}
|
|
794
|
-
})
|
|
795
|
-
|
|
796
|
-
finalOrderInventories.push(...assignedOrderInventories)
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
for (let oi of finalOrderInventories) {
|
|
801
|
-
let generatedOI: OrderInventory = Object.assign(new OrderInventory(), oi)
|
|
802
|
-
generatedOI = {
|
|
803
|
-
...generatedOI,
|
|
804
|
-
domain: warehouseDomain,
|
|
805
|
-
bizplace,
|
|
806
|
-
status: ORDER_INVENTORY_STATUS.PENDING,
|
|
807
|
-
name: OrderNoGenerator.orderInventory(),
|
|
808
|
-
releaseGood: newReleaseGood,
|
|
809
|
-
creator: user,
|
|
810
|
-
updater: user
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
await tx.getRepository(OrderInventory).save({ ...generatedOI })
|
|
814
|
-
|
|
815
|
-
// update inventory locked qty and uom value
|
|
816
|
-
await tx.getRepository(Inventory).update({ id: oi.inventory.id }, {
|
|
817
|
-
lockedQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
|
|
818
|
-
lockedUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
|
|
819
|
-
updater: user
|
|
820
|
-
} as any)
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
if (orderVass?.length) {
|
|
824
|
-
orderVass = await Promise.all(
|
|
825
|
-
orderVass.map(async orderVas => {
|
|
826
|
-
if (orderVas?.targetProduct?.id) {
|
|
827
|
-
orderVas.targetProduct = await tx.getRepository(Product).findOneBy({ id: orderVas.targetProduct.id })
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
let newOrderVas: OrderVas = {
|
|
831
|
-
...orderVas,
|
|
832
|
-
domain: warehouseDomain,
|
|
833
|
-
bizplace,
|
|
834
|
-
name: OrderNoGenerator.releaseVas(),
|
|
835
|
-
vas: await tx.getRepository(Vas).findOneBy({ id: orderVas.vas.id }),
|
|
836
|
-
type: ORDER_TYPES.RELEASE_OF_GOODS,
|
|
837
|
-
releaseGood: newReleaseGood,
|
|
838
|
-
status: ORDER_VAS_STATUS.PENDING,
|
|
839
|
-
creator: user,
|
|
840
|
-
updater: user
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
if (orderVas?.inventory?.id) {
|
|
844
|
-
newOrderVas.inventory = await tx.getRepository(Inventory).findOneBy({ id: orderVas.inventory.id })
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
return newOrderVas
|
|
848
|
-
})
|
|
849
|
-
)
|
|
850
|
-
|
|
851
|
-
await tx.getRepository(OrderVas).save(orderVass)
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
if (attachments?.length > 0) {
|
|
855
|
-
const files: Partial<Attachment>[] = attachments.map(attachment => {
|
|
856
|
-
return {
|
|
857
|
-
file: attachment,
|
|
858
|
-
refType: ATTACHMENT_TYPE.DELIVERY_ORDER,
|
|
859
|
-
refBy: newReleaseGood.id,
|
|
860
|
-
category: ATTACHMENT_TYPE.DELIVERY_ORDER /* TODO use refType */
|
|
861
|
-
}
|
|
862
|
-
})
|
|
863
|
-
await createAttachments(_, { attachments: files }, context)
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
const directReceiveSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
867
|
-
where: { domain: { id: domain.id }, category: 'id-rule', name: 'enable-direct-receive-release-order' }
|
|
868
|
-
})
|
|
869
|
-
|
|
870
|
-
if (directReceiveSetting) {
|
|
871
|
-
const partnerDirectReceiveSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
|
|
872
|
-
where: {
|
|
873
|
-
setting: { id: directReceiveSetting?.id },
|
|
874
|
-
domain: { id: domain.id },
|
|
875
|
-
partnerDomain: { id: bizplace?.domain.id }
|
|
876
|
-
}
|
|
877
|
-
})
|
|
878
|
-
|
|
879
|
-
// If status of create RO is PENDING then directly CONFIRM -> RECEIVE
|
|
880
|
-
if (
|
|
881
|
-
!isNaN(Number(partnerDirectReceiveSetting?.value)) &&
|
|
882
|
-
!isNaN(parseFloat(partnerDirectReceiveSetting?.value)) &&
|
|
883
|
-
newReleaseGood.status === ORDER_STATUS.PENDING
|
|
884
|
-
) {
|
|
885
|
-
let partnerDirectReceiveSettingValue = parseFloat(partnerDirectReceiveSetting.value)
|
|
886
|
-
|
|
887
|
-
// CONFIRM if setting value is > 0
|
|
888
|
-
if (partnerDirectReceiveSettingValue > 0) await confirmReleaseGood(newReleaseGood.name, context, tx)
|
|
889
|
-
|
|
890
|
-
// RECEIVE if setting value is > 1
|
|
891
|
-
if (partnerDirectReceiveSettingValue > 1) await receiveReleaseGood(newReleaseGood.name, context, tx)
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
return newReleaseGood
|
|
896
|
-
} catch (error) {
|
|
897
|
-
throw error
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
export async function confirmReleaseGood(name: string, context: any, tx?: EntityManager): Promise<ReleaseGood> {
|
|
902
|
-
const { user, domain } = context.state
|
|
903
|
-
|
|
904
|
-
let foundReleaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
905
|
-
where: { name, status: ORDER_STATUS.PENDING },
|
|
906
|
-
relations: ['domain', 'bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain', 'orderVass']
|
|
907
|
-
})
|
|
908
|
-
|
|
909
|
-
if (!foundReleaseGood) throw new Error(`Release good order doesn't exists.`)
|
|
910
|
-
|
|
911
|
-
// query orderInventories separately from releaseGood to reduce resource usage
|
|
912
|
-
let foundOIs: OrderInventory[] = await tx.getRepository(OrderInventory).find({
|
|
913
|
-
where: { domain: { id: domain.id }, releaseGood: { id: foundReleaseGood.id } },
|
|
914
|
-
relations: ['product']
|
|
915
|
-
})
|
|
916
|
-
|
|
917
|
-
// query orderProducts separately from releaseGood to reduce resource usage
|
|
918
|
-
let foundOPs: OrderProduct[] = await tx.getRepository(OrderProduct).find({
|
|
919
|
-
where: { domain: { id: domain.id }, releaseGood: { id: foundReleaseGood.id } },
|
|
920
|
-
relations: ['bizplace', 'product', 'product.productDetails']
|
|
921
|
-
})
|
|
922
|
-
|
|
923
|
-
let foundBundleInfo: any[] = JSON.parse(foundReleaseGood.bundleInfo)
|
|
924
|
-
let foundOVs: OrderVas[] = foundReleaseGood.orderVass
|
|
925
|
-
let customerBizplace: Bizplace = foundReleaseGood.bizplace
|
|
926
|
-
const companyDomain: Domain = customerBizplace?.company.domain
|
|
927
|
-
|
|
928
|
-
const sellercraft: Sellercraft = await tx.getRepository(Sellercraft).findOne({
|
|
929
|
-
where: { domain: { id: foundReleaseGood.bizplace.domain.id }, status: SellercraftStatus.ACTIVE },
|
|
930
|
-
relations: ['domain']
|
|
931
|
-
})
|
|
932
|
-
|
|
933
|
-
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
934
|
-
|
|
935
|
-
let updateSCStock = async sellercraft => {
|
|
936
|
-
if (sellercraft) {
|
|
937
|
-
await sellercraftCtrl.updateSellercraftStock(sellercraft, foundOPs, 'CONFIRM_ORDER')
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
const orderSource: string = foundReleaseGood.source
|
|
942
|
-
switch (orderSource) {
|
|
943
|
-
case ApplicationType.SELLERCRAFT:
|
|
944
|
-
if (foundReleaseGood.type == 'b2c' && sellercraft) {
|
|
945
|
-
try {
|
|
946
|
-
let rg = await sellercraftCtrl.packOrder(sellercraft, {
|
|
947
|
-
...foundReleaseGood,
|
|
948
|
-
orderProducts: foundOPs
|
|
949
|
-
})
|
|
950
|
-
foundReleaseGood = rg
|
|
951
|
-
} catch (error) {
|
|
952
|
-
logger.error(
|
|
953
|
-
`release-good-mutation[confirmReleaseGood]:(data:${JSON.stringify({
|
|
954
|
-
sellercraft,
|
|
955
|
-
foundReleaseGood,
|
|
956
|
-
domain,
|
|
957
|
-
user
|
|
958
|
-
})}) ${error} `
|
|
959
|
-
)
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
break
|
|
963
|
-
|
|
964
|
-
case ApplicationType.MMS:
|
|
965
|
-
// find for any existing marketplace store connections
|
|
966
|
-
let marketplaceStores: MarketplaceStore[] = await tx.getRepository(MarketplaceStore).find({
|
|
967
|
-
where: { domain: { id: companyDomain.id }, status: 'ACTIVE' },
|
|
968
|
-
relations: ['marketplaceDistributors']
|
|
969
|
-
})
|
|
970
|
-
|
|
971
|
-
const foundMarketplaceOrder: MarketplaceOrder = await tx.getRepository(MarketplaceOrder).findOne({
|
|
972
|
-
where: { domain: { id: companyDomain.id }, orderNo: foundReleaseGood.refNo },
|
|
973
|
-
relations: ['marketplaceStore']
|
|
974
|
-
})
|
|
975
|
-
|
|
976
|
-
let matchedMarketplaceStore: MarketplaceStore
|
|
977
|
-
if (foundMarketplaceOrder) {
|
|
978
|
-
matchedMarketplaceStore = marketplaceStores.filter(
|
|
979
|
-
marketplaceStore => marketplaceStore.id == foundMarketplaceOrder.marketplaceStore.id
|
|
980
|
-
)[0]
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
let combinedOrderInventories: any[] = foundOIs.map(oi => {
|
|
984
|
-
return {
|
|
985
|
-
sku: oi.product.sku,
|
|
986
|
-
releaseQty: oi.releaseQty
|
|
987
|
-
}
|
|
988
|
-
})
|
|
989
|
-
|
|
990
|
-
if (foundBundleInfo?.length) {
|
|
991
|
-
foundBundleInfo.map(bundle => {
|
|
992
|
-
combinedOrderInventories.push({
|
|
993
|
-
sku: bundle.sku,
|
|
994
|
-
releaseQty: bundle.releaseQty
|
|
995
|
-
})
|
|
996
|
-
})
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
for (let oi of combinedOrderInventories) {
|
|
1000
|
-
let foundMarketplaceProductVariations: MarketplaceProductVariation[] = await tx
|
|
1001
|
-
.getRepository(MarketplaceProductVariation)
|
|
1002
|
-
.find({
|
|
1003
|
-
where: { domain: { id: companyDomain.id }, sku: oi.sku },
|
|
1004
|
-
relations: ['marketplaceProduct', 'marketplaceProduct.marketplaceStore']
|
|
1005
|
-
})
|
|
1006
|
-
|
|
1007
|
-
if (foundMarketplaceProductVariations) {
|
|
1008
|
-
await Promise.all(
|
|
1009
|
-
foundMarketplaceProductVariations.map(async variation => {
|
|
1010
|
-
if (variation.marketplaceProduct.marketplaceStore.reserveEnabled) {
|
|
1011
|
-
variation.reserveQty -= oi.releaseQty
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
await tx.getRepository(MarketplaceProductVariation).save(variation)
|
|
1015
|
-
})
|
|
1016
|
-
)
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
if (marketplaceStores?.length && marketplaceStores.some(store => store.isAutoUpdateStockQty)) {
|
|
1021
|
-
marketplaceStores = marketplaceStores.filter(marketplaceStore => marketplaceStore.isAutoUpdateStockQty)
|
|
1022
|
-
let productIds: string[] = foundOIs.map(oi => oi.product.id)
|
|
1023
|
-
productIds = Array.from(new Set([...productIds]))
|
|
1024
|
-
const ecommerceCtrl: EcommerceController = new EcommerceController(tx, domain, user)
|
|
1025
|
-
await ecommerceCtrl.updateProductVariationStock(marketplaceStores, productIds, companyDomain)
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
updateSCStock(sellercraft)
|
|
1029
|
-
break
|
|
1030
|
-
|
|
1031
|
-
default:
|
|
1032
|
-
updateSCStock(sellercraft)
|
|
1033
|
-
break
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
// 1. RO Status change (PENDING => PENDING_RECEIVE)
|
|
1037
|
-
const releaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).save({
|
|
1038
|
-
...foundReleaseGood,
|
|
1039
|
-
status: ORDER_STATUS.PENDING_RECEIVE,
|
|
1040
|
-
updater: user
|
|
1041
|
-
})
|
|
1042
|
-
|
|
1043
|
-
// 1. Update status of order inventories
|
|
1044
|
-
foundOIs = foundOIs.map((orderInventory: OrderInventory) => {
|
|
1045
|
-
return {
|
|
1046
|
-
...orderInventory,
|
|
1047
|
-
status: ORDER_INVENTORY_STATUS.PENDING_RECEIVE,
|
|
1048
|
-
updater: user
|
|
1049
|
-
}
|
|
1050
|
-
})
|
|
1051
|
-
await tx.getRepository(OrderInventory).save(foundOIs)
|
|
1052
|
-
|
|
1053
|
-
// 2. Update status of order vass
|
|
1054
|
-
if (foundOVs && foundOVs.length) {
|
|
1055
|
-
foundOVs = foundOVs.map((orderVas: OrderVas) => {
|
|
1056
|
-
return {
|
|
1057
|
-
...orderVas,
|
|
1058
|
-
status: ORDER_VAS_STATUS.PENDING_RECEIVE,
|
|
1059
|
-
updater: user
|
|
1060
|
-
}
|
|
1061
|
-
})
|
|
1062
|
-
await tx.getRepository(OrderVas).save(foundOVs)
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
// notification logics
|
|
1066
|
-
// get Office Admin Users
|
|
1067
|
-
if (context?.state?.type != 'api') {
|
|
1068
|
-
const users: any[] = await tx
|
|
1069
|
-
.getRepository('users_roles')
|
|
1070
|
-
.createQueryBuilder('ur')
|
|
1071
|
-
.select('ur.users_id', 'id')
|
|
1072
|
-
.where(qb => {
|
|
1073
|
-
const subQuery = qb
|
|
1074
|
-
.subQuery()
|
|
1075
|
-
.select('role.id')
|
|
1076
|
-
.from(Role, 'role')
|
|
1077
|
-
.where("role.name = 'Office Admin'")
|
|
1078
|
-
.andWhere('role.domain_id = :domain', { domain: domain.id })
|
|
1079
|
-
.getQuery()
|
|
1080
|
-
return 'ur.roles_id IN ' + subQuery
|
|
1081
|
-
})
|
|
1082
|
-
.getRawMany()
|
|
1083
|
-
|
|
1084
|
-
// send notification to Office Admin Users
|
|
1085
|
-
if (users?.length && context.header?.referer) {
|
|
1086
|
-
const receivers: any[] = users.map(user => user.id)
|
|
1087
|
-
const msg = {
|
|
1088
|
-
title: `New Release Order from ${customerBizplace.name}`,
|
|
1089
|
-
body: `New incoming order, ${foundReleaseGood.name} is pending for receiving`,
|
|
1090
|
-
url: context.header.referer,
|
|
1091
|
-
data: { url: context.header.referer }
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
/**
|
|
1095
|
-
* @notes Temporary off sendNotification due to suspect of causing wms down
|
|
1096
|
-
*/
|
|
1097
|
-
|
|
1098
|
-
// await sendNotification({
|
|
1099
|
-
// receivers,
|
|
1100
|
-
// message: { ...msg }
|
|
1101
|
-
// })
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
return releaseGood
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
export async function receiveReleaseGood(name: string, context: any, tx: EntityManager): Promise<ReleaseGood> {
|
|
1109
|
-
const { domain, user } = context.state
|
|
1110
|
-
|
|
1111
|
-
const foundReleaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
1112
|
-
where: { domain: { id: domain.id }, name, status: ORDER_STATUS.PENDING_RECEIVE },
|
|
1113
|
-
relations: ['bizplace', 'orderInventories', 'orderVass']
|
|
1114
|
-
})
|
|
1115
|
-
|
|
1116
|
-
if (!foundReleaseGood) throw new Error(`Release good order doesn't exists.`)
|
|
1117
|
-
let foundOIs: OrderInventory[] = foundReleaseGood.orderInventories
|
|
1118
|
-
let foundOVs: OrderVas[] = foundReleaseGood.orderVass
|
|
1119
|
-
let customerBizplace: Bizplace = foundReleaseGood.bizplace
|
|
1120
|
-
|
|
1121
|
-
// 1. RO Status change (PENDING_RECEIVE => PENDING_WORKSHEET)
|
|
1122
|
-
const releaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).save({
|
|
1123
|
-
...foundReleaseGood,
|
|
1124
|
-
status: ORDER_STATUS.PENDING_WORKSHEET,
|
|
1125
|
-
acceptedBy: user,
|
|
1126
|
-
acceptedAt: new Date(),
|
|
1127
|
-
updater: user
|
|
1128
|
-
})
|
|
1129
|
-
|
|
1130
|
-
// 1. Update status of order inventories
|
|
1131
|
-
foundOIs = foundOIs.map((orderInventory: OrderInventory) => {
|
|
1132
|
-
return {
|
|
1133
|
-
...orderInventory,
|
|
1134
|
-
status: ORDER_INVENTORY_STATUS.PENDING_WORKSHEET,
|
|
1135
|
-
updater: user
|
|
1136
|
-
}
|
|
1137
|
-
})
|
|
1138
|
-
await tx.getRepository(OrderInventory).save(foundOIs)
|
|
1139
|
-
|
|
1140
|
-
// 2. Update status of order vass
|
|
1141
|
-
if (foundOVs && foundOVs.length) {
|
|
1142
|
-
foundOVs = foundOVs.map((orderVas: OrderVas) => {
|
|
1143
|
-
return {
|
|
1144
|
-
...orderVas,
|
|
1145
|
-
status: ORDER_VAS_STATUS.READY_TO_PROCESS,
|
|
1146
|
-
updater: user
|
|
1147
|
-
}
|
|
1148
|
-
})
|
|
1149
|
-
await tx.getRepository(OrderVas).save(foundOVs)
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
// notification logics
|
|
1153
|
-
// get Office Admin Users
|
|
1154
|
-
if (context?.state?.type != 'api') {
|
|
1155
|
-
const users: any[] = await tx
|
|
1156
|
-
.getRepository('users_roles')
|
|
1157
|
-
.createQueryBuilder('ur')
|
|
1158
|
-
.select('ur.users_id', 'id')
|
|
1159
|
-
.where(qb => {
|
|
1160
|
-
const subQuery = qb
|
|
1161
|
-
.subQuery()
|
|
1162
|
-
.select('role.id')
|
|
1163
|
-
.from(Role, 'role')
|
|
1164
|
-
.where("role.name = 'Office Admin'")
|
|
1165
|
-
.andWhere('role.domain_id = :domain', { domain: domain.id })
|
|
1166
|
-
.getQuery()
|
|
1167
|
-
return 'ur.roles_id IN ' + subQuery
|
|
1168
|
-
})
|
|
1169
|
-
.getRawMany()
|
|
1170
|
-
|
|
1171
|
-
// send notification to Office Admin Users
|
|
1172
|
-
if (users?.length && context.header?.referer) {
|
|
1173
|
-
const receivers: any[] = users.map(user => user.id)
|
|
1174
|
-
const msg = {
|
|
1175
|
-
title: `New Release Order from ${customerBizplace.name}`,
|
|
1176
|
-
body: `New incoming order, ${foundReleaseGood.name} is pending for receiving`,
|
|
1177
|
-
url: context.header.referer,
|
|
1178
|
-
data: { url: context.header.referer }
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
/**
|
|
1182
|
-
* @notes Temporary off sendNotification due to suspect of causing wms down
|
|
1183
|
-
*/
|
|
1184
|
-
|
|
1185
|
-
// await sendNotification({
|
|
1186
|
-
// receivers,
|
|
1187
|
-
// message: { ...msg }
|
|
1188
|
-
// })
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
return releaseGood
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
export async function rejectReleaseGood(
|
|
1196
|
-
tx: EntityManager,
|
|
1197
|
-
context: ResolverContext,
|
|
1198
|
-
name: string,
|
|
1199
|
-
remark: string
|
|
1200
|
-
): Promise<ReleaseGood> {
|
|
1201
|
-
const { domain, user } = context.state
|
|
1202
|
-
|
|
1203
|
-
const releaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
1204
|
-
where: { domain: { id: domain.id }, name, status: ORDER_STATUS.PENDING_RECEIVE },
|
|
1205
|
-
relations: [
|
|
1206
|
-
'bizplace',
|
|
1207
|
-
'bizplace.domain',
|
|
1208
|
-
'orderProducts',
|
|
1209
|
-
'orderProducts.product',
|
|
1210
|
-
'orderProducts.product.productDetails',
|
|
1211
|
-
'orderInventories',
|
|
1212
|
-
'orderInventories.inventory',
|
|
1213
|
-
'orderVass',
|
|
1214
|
-
'shippingOrder'
|
|
1215
|
-
]
|
|
1216
|
-
})
|
|
1217
|
-
|
|
1218
|
-
if (!releaseGood) throw new Error(`Release good doesn't exists.`)
|
|
1219
|
-
if (!remark) throw new Error('Remark is not exist.')
|
|
1220
|
-
|
|
1221
|
-
let foundOIs: OrderInventory[] = releaseGood.orderInventories
|
|
1222
|
-
let foundOVs: OrderVas[] = releaseGood.orderVass
|
|
1223
|
-
let foundOPs: OrderProduct[] = releaseGood.orderProducts
|
|
1224
|
-
|
|
1225
|
-
// 1. Update status of order products (PENDING_RECEIVE => REJECTED)
|
|
1226
|
-
if (foundOIs && foundOIs.length) {
|
|
1227
|
-
await tx.getRepository(OrderInventory).save(
|
|
1228
|
-
await Promise.all(
|
|
1229
|
-
foundOIs.map(async (oi: OrderInventory) => {
|
|
1230
|
-
if (oi?.inventory?.id) {
|
|
1231
|
-
oi.inventory = await tx.getRepository(Inventory).findOneBy({ id: oi.inventory.id })
|
|
1232
|
-
|
|
1233
|
-
await tx.getRepository(Inventory).save({
|
|
1234
|
-
...oi.inventory,
|
|
1235
|
-
lockedQty: oi.inventory.lockedQty - oi.releaseQty,
|
|
1236
|
-
lockedUomValue: oi.inventory.lockedUomValue - oi.releaseUomValue,
|
|
1237
|
-
updater: user
|
|
1238
|
-
})
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
oi.status = ORDER_INVENTORY_STATUS.REJECTED
|
|
1242
|
-
oi.updater = user
|
|
1243
|
-
return oi
|
|
1244
|
-
})
|
|
1245
|
-
)
|
|
1246
|
-
)
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
if (foundOPs && foundOPs.length) {
|
|
1250
|
-
const orderSource: string = releaseGood.source
|
|
1251
|
-
switch (orderSource) {
|
|
1252
|
-
case ApplicationType.SELLERCRAFT:
|
|
1253
|
-
const sellercraft: Sellercraft = await tx
|
|
1254
|
-
.getRepository(Sellercraft)
|
|
1255
|
-
.findOneBy({ domain: { id: releaseGood.bizplace.domain.id }, status: SellercraftStatus.ACTIVE })
|
|
1256
|
-
|
|
1257
|
-
if (sellercraft) {
|
|
1258
|
-
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
1259
|
-
await sellercraftCtrl.updateSellercraftStock(sellercraft, foundOPs, 'REJECT_ORDER')
|
|
1260
|
-
}
|
|
1261
|
-
break
|
|
1262
|
-
|
|
1263
|
-
default:
|
|
1264
|
-
break
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
await tx.getRepository(OrderProduct).save(
|
|
1268
|
-
await Promise.all(
|
|
1269
|
-
foundOPs.map(async (op: OrderProduct) => {
|
|
1270
|
-
op.status = ORDER_PRODUCT_STATUS.REJECTED
|
|
1271
|
-
op.updater = user
|
|
1272
|
-
return op
|
|
1273
|
-
})
|
|
1274
|
-
)
|
|
1275
|
-
)
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
// 2. Update status of order vass if it exists (PENDING_RECEIVE => REJECTED)
|
|
1279
|
-
if (foundOVs && foundOVs.length) {
|
|
1280
|
-
foundOVs = foundOVs.map((ov: OrderVas) => {
|
|
1281
|
-
ov.status = ORDER_VAS_STATUS.REJECTED
|
|
1282
|
-
ov.updater = user
|
|
1283
|
-
return ov
|
|
1284
|
-
})
|
|
1285
|
-
await tx.getRepository(OrderVas).save(foundOVs)
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
if (releaseGood.shippingOrder) {
|
|
1289
|
-
// 2. 1) if it's yes update status of collection order
|
|
1290
|
-
const shippingOrder: ShippingOrder = await tx.getRepository(ShippingOrder).findOne({
|
|
1291
|
-
where: { domain: { id: domain.id }, name: releaseGood.shippingOrder.name }
|
|
1292
|
-
})
|
|
1293
|
-
|
|
1294
|
-
shippingOrder.status = ORDER_STATUS.REJECTED
|
|
1295
|
-
shippingOrder.updater = user
|
|
1296
|
-
await tx.getRepository(ShippingOrder).save(shippingOrder)
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
releaseGood.remark = remark
|
|
1300
|
-
releaseGood.status = ORDER_STATUS.REJECTED
|
|
1301
|
-
releaseGood.updater = user
|
|
1302
|
-
await tx.getRepository(ReleaseGood).save(releaseGood)
|
|
1303
|
-
|
|
1304
|
-
// notification logics
|
|
1305
|
-
const users: any[] = await getDomainUsers(releaseGood?.bizplace, tx)
|
|
1306
|
-
|
|
1307
|
-
if (users?.length && context.header?.referer) {
|
|
1308
|
-
const receivers: any[] = users.map(user => user.id)
|
|
1309
|
-
const msg = {
|
|
1310
|
-
title: `Latest status for ${releaseGood.name}`,
|
|
1311
|
-
body: `Your RO has been rejected.`,
|
|
1312
|
-
url: context.header.referer,
|
|
1313
|
-
data: { url: context.header.referer }
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
/**
|
|
1317
|
-
* @notes Temporary off sendNotification due to suspect of causing wms down
|
|
1318
|
-
*/
|
|
1319
|
-
|
|
1320
|
-
// await sendNotification({
|
|
1321
|
-
// receivers,
|
|
1322
|
-
// message: { ...msg }
|
|
1323
|
-
// })
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
return releaseGood
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
export async function bulkGenerateReleaseGood(
|
|
1330
|
-
releaseGood: any,
|
|
1331
|
-
bizplaceId: string,
|
|
1332
|
-
roNoSetting: any,
|
|
1333
|
-
domain: Domain,
|
|
1334
|
-
user: User,
|
|
1335
|
-
tx?: EntityManager
|
|
1336
|
-
): Promise<ReleaseGood> {
|
|
1337
|
-
try {
|
|
1338
|
-
let warehouseDomain: Domain = domain
|
|
1339
|
-
let { orderInventories, shippingOrder } = releaseGood
|
|
1340
|
-
|
|
1341
|
-
let bizplace: Bizplace = await tx.getRepository(Bizplace).findOneBy({ id: bizplaceId })
|
|
1342
|
-
|
|
1343
|
-
let newReleaseGood: ReleaseGood = {
|
|
1344
|
-
...releaseGood,
|
|
1345
|
-
name: roNoSetting
|
|
1346
|
-
? await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.RO_NUMBER, seed: {} })
|
|
1347
|
-
: OrderNoGenerator.releaseGood(),
|
|
1348
|
-
domain: warehouseDomain,
|
|
1349
|
-
bizplace: bizplace,
|
|
1350
|
-
deliveryAddress1: releaseGood?.deliveryAddress1 || null,
|
|
1351
|
-
deliveryAddress2: releaseGood?.deliveryAddress2 || null,
|
|
1352
|
-
deliveryAddress3: releaseGood?.deliveryAddress3 || null,
|
|
1353
|
-
deliveryAddress4: releaseGood?.deliveryAddress4 || null,
|
|
1354
|
-
attentionTo: releaseGood?.attentionTo || null,
|
|
1355
|
-
attentionCompany: releaseGood?.attentionCompany || null,
|
|
1356
|
-
city: releaseGood?.city || null,
|
|
1357
|
-
state: releaseGood?.state || null,
|
|
1358
|
-
postalCode: releaseGood?.postalCode || null,
|
|
1359
|
-
country: releaseGood?.country || null,
|
|
1360
|
-
phone1: releaseGood?.phone1 || null,
|
|
1361
|
-
phone2: releaseGood?.phone2 || null,
|
|
1362
|
-
email: releaseGood?.email || null,
|
|
1363
|
-
source: releaseGood?.source || null,
|
|
1364
|
-
airwayBill: releaseGood?.airwayBill,
|
|
1365
|
-
refNo: releaseGood.refNo,
|
|
1366
|
-
refNo2: releaseGood.refNo2,
|
|
1367
|
-
refNo3: releaseGood.refNo3,
|
|
1368
|
-
releaseDate: releaseGood.releaseDate,
|
|
1369
|
-
ownTransport: releaseGood?.ownTransport || false,
|
|
1370
|
-
orderMethod: ORDER_METHOD.SELECT_BY_PRODUCT,
|
|
1371
|
-
status: ORDER_STATUS.PENDING,
|
|
1372
|
-
creator: releaseGood?.creator || user,
|
|
1373
|
-
updater: releaseGood?.updater || user
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
newReleaseGood = await tx.getRepository(ReleaseGood).save(newReleaseGood)
|
|
1377
|
-
|
|
1378
|
-
/** Generate Shipping Order */
|
|
1379
|
-
if (shippingOrder) {
|
|
1380
|
-
shippingOrder.remark = shippingOrder.exportRemark
|
|
1381
|
-
if (shippingOrder.containerClosureDate !== undefined) {
|
|
1382
|
-
shippingOrder.containerClosureDateTime = new Date(shippingOrder.containerClosureDate)
|
|
1383
|
-
}
|
|
1384
|
-
delete shippingOrder.exportRemark
|
|
1385
|
-
|
|
1386
|
-
const createdSO: ShippingOrder = await tx.getRepository(ShippingOrder).save({
|
|
1387
|
-
...shippingOrder,
|
|
1388
|
-
name: OrderNoGenerator.shippingOrder(),
|
|
1389
|
-
domain,
|
|
1390
|
-
bizplace,
|
|
1391
|
-
status: ORDER_STATUS.PENDING,
|
|
1392
|
-
creator: user,
|
|
1393
|
-
updater: user
|
|
1394
|
-
})
|
|
1395
|
-
|
|
1396
|
-
newReleaseGood.shippingOrder = createdSO
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
let finalOrderInventories: Partial<OrderInventory>[] = []
|
|
1400
|
-
|
|
1401
|
-
// pre assign inventory to orderInventories
|
|
1402
|
-
for (let oi of orderInventories) {
|
|
1403
|
-
const pickingProductSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
1404
|
-
where: { domain: { id: domain.id }, name: 'rule-for-picking-product' }
|
|
1405
|
-
})
|
|
1406
|
-
|
|
1407
|
-
let locationSortingRules = []
|
|
1408
|
-
if (pickingProductSetting) {
|
|
1409
|
-
let locationSetting = JSON.parse(pickingProductSetting.value)
|
|
1410
|
-
for (const key in locationSetting) {
|
|
1411
|
-
locationSortingRules.push({ name: key, desc: locationSetting[key] == 'ASC' ? false : true })
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
const product: Product = await tx.getRepository(Product).findOneBy({ id: oi.productId })
|
|
1416
|
-
|
|
1417
|
-
let assignedResult = await InventoryUtil.autoAssignInventoryForRelease(
|
|
1418
|
-
product,
|
|
1419
|
-
oi,
|
|
1420
|
-
oi.packingType,
|
|
1421
|
-
locationSortingRules,
|
|
1422
|
-
bizplace,
|
|
1423
|
-
warehouseDomain,
|
|
1424
|
-
tx
|
|
1425
|
-
)
|
|
1426
|
-
|
|
1427
|
-
finalOrderInventories.push(
|
|
1428
|
-
...assignedResult.map(itm => {
|
|
1429
|
-
return {
|
|
1430
|
-
...itm,
|
|
1431
|
-
orderProduct: oi?.orderProduct
|
|
1432
|
-
}
|
|
1433
|
-
})
|
|
1434
|
-
)
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
for (let oi of finalOrderInventories) {
|
|
1438
|
-
let generatedOI: OrderInventory = Object.assign(new OrderInventory(), oi)
|
|
1439
|
-
generatedOI = {
|
|
1440
|
-
...generatedOI,
|
|
1441
|
-
domain: warehouseDomain,
|
|
1442
|
-
bizplace,
|
|
1443
|
-
status: ORDER_INVENTORY_STATUS.PENDING,
|
|
1444
|
-
name: OrderNoGenerator.orderInventory(),
|
|
1445
|
-
releaseGood: newReleaseGood,
|
|
1446
|
-
creator: newReleaseGood?.creator || user,
|
|
1447
|
-
updater: newReleaseGood?.updater || user
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
let newOrderProduct: Partial<OrderProduct>
|
|
1451
|
-
if (!oi?.orderProduct) {
|
|
1452
|
-
newOrderProduct = {
|
|
1453
|
-
name: generatedOI.name,
|
|
1454
|
-
product: generatedOI.product,
|
|
1455
|
-
batchId: generatedOI.batchId,
|
|
1456
|
-
packingType: generatedOI.packingType,
|
|
1457
|
-
packingSize: generatedOI.packingSize,
|
|
1458
|
-
uom: generatedOI.uom,
|
|
1459
|
-
domain: warehouseDomain,
|
|
1460
|
-
bizplace,
|
|
1461
|
-
releaseQty: generatedOI.releaseQty,
|
|
1462
|
-
releaseUomValue: generatedOI.releaseUomValue,
|
|
1463
|
-
packQty: 0,
|
|
1464
|
-
actualPackQty: 0,
|
|
1465
|
-
palletQty: 0,
|
|
1466
|
-
actualPalletQty: 0,
|
|
1467
|
-
status: ORDER_PRODUCT_STATUS.ASSIGNED,
|
|
1468
|
-
releaseGood: newReleaseGood,
|
|
1469
|
-
creator: newReleaseGood?.creator || user,
|
|
1470
|
-
updater: newReleaseGood?.updater || user
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
newOrderProduct = await tx.getRepository(OrderProduct).save(newOrderProduct)
|
|
1474
|
-
} else {
|
|
1475
|
-
newOrderProduct = await tx.getRepository(OrderProduct).save({
|
|
1476
|
-
...oi.orderProduct,
|
|
1477
|
-
totalUomValue: `${oi.orderProduct.releaseUomValue} ${oi.orderProduct.uom}`,
|
|
1478
|
-
status: ORDER_PRODUCT_STATUS.ASSIGNED,
|
|
1479
|
-
updater: newReleaseGood?.updater || user
|
|
1480
|
-
})
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
await tx.getRepository(OrderInventory).save({ ...generatedOI, orderProduct: newOrderProduct })
|
|
1484
|
-
|
|
1485
|
-
// update inventory locked qty and uom value
|
|
1486
|
-
await tx.getRepository(Inventory).update(oi.inventory.id, {
|
|
1487
|
-
lockedQty: (oi.inventory?.lockedQty || 0) + generatedOI.releaseQty,
|
|
1488
|
-
lockedUomValue: (oi.inventory?.lockedUomValue || 0) + generatedOI.releaseUomValue,
|
|
1489
|
-
updater: user
|
|
1490
|
-
} as any)
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
return newReleaseGood
|
|
1494
|
-
} catch (error) {
|
|
1495
|
-
throw error
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
export async function bulkConfirmReleaseGoods(
|
|
1500
|
-
releaseGoodsNo: string[],
|
|
1501
|
-
domain: Domain,
|
|
1502
|
-
user: User,
|
|
1503
|
-
context: any,
|
|
1504
|
-
tx?: EntityManager
|
|
1505
|
-
): Promise<ReleaseGood[]> {
|
|
1506
|
-
let foundReleaseGoods: ReleaseGood[] = await tx.getRepository(ReleaseGood).find({
|
|
1507
|
-
where: { name: In(releaseGoodsNo), status: ORDER_STATUS.PENDING },
|
|
1508
|
-
relations: ['bizplace']
|
|
1509
|
-
})
|
|
1510
|
-
|
|
1511
|
-
if (!foundReleaseGoods.length) throw new Error(`release good order doesn't exists.`)
|
|
1512
|
-
let customerBizplace: Bizplace = foundReleaseGoods[0].bizplace
|
|
1513
|
-
|
|
1514
|
-
let foundOrderInventories: OrderInventory[] = await tx.getRepository(OrderInventory).find({
|
|
1515
|
-
where: { domain: { id: domain.id }, releaseGood: { id: In(foundReleaseGoods.map((rg: ReleaseGood) => rg.id)) } }
|
|
1516
|
-
})
|
|
1517
|
-
|
|
1518
|
-
await tx
|
|
1519
|
-
.getRepository(ReleaseGood)
|
|
1520
|
-
.update({ id: In(foundReleaseGoods.map(rg => rg.id)) }, { status: ORDER_STATUS.PENDING_RECEIVE, updater: user })
|
|
1521
|
-
|
|
1522
|
-
await tx
|
|
1523
|
-
.getRepository(OrderInventory)
|
|
1524
|
-
.update(
|
|
1525
|
-
{ id: In(foundOrderInventories.map(oi => oi.id)) },
|
|
1526
|
-
{ status: ORDER_INVENTORY_STATUS.PENDING_RECEIVE, updater: user }
|
|
1527
|
-
)
|
|
1528
|
-
|
|
1529
|
-
if (context?.state?.type != 'api') {
|
|
1530
|
-
const users: any[] = await tx
|
|
1531
|
-
.getRepository('users_roles')
|
|
1532
|
-
.createQueryBuilder('ur')
|
|
1533
|
-
.select('ur.users_id', 'id')
|
|
1534
|
-
.where(qb => {
|
|
1535
|
-
const subQuery = qb
|
|
1536
|
-
.subQuery()
|
|
1537
|
-
.select('role.id')
|
|
1538
|
-
.from(Role, 'role')
|
|
1539
|
-
.where("role.name = 'Office Admin'")
|
|
1540
|
-
.andWhere('role.domain_id = :domain', { domain: domain.id })
|
|
1541
|
-
.getQuery()
|
|
1542
|
-
return 'ur.roles_id IN ' + subQuery
|
|
1543
|
-
})
|
|
1544
|
-
.getRawMany()
|
|
1545
|
-
|
|
1546
|
-
// send notification to Office Admin Users
|
|
1547
|
-
if (users?.length && context.header?.referer) {
|
|
1548
|
-
const receivers: any[] = users.map(user => user.id)
|
|
1549
|
-
const message = {
|
|
1550
|
-
title: `New Release Order from ${customerBizplace.name}`,
|
|
1551
|
-
body: `New incoming bulk release orders are pending for receiving`,
|
|
1552
|
-
url: context.header.referer,
|
|
1553
|
-
data: { url: context.header.referer }
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
/**
|
|
1557
|
-
* @notes Temporary off sendNotification due to suspect of causing wms down
|
|
1558
|
-
*/
|
|
1559
|
-
|
|
1560
|
-
// await sendNotification({
|
|
1561
|
-
// receivers,
|
|
1562
|
-
// message
|
|
1563
|
-
// })
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
|
-
return Promise.all(
|
|
1568
|
-
foundReleaseGoods.map(async (releaseGood: ReleaseGood) => {
|
|
1569
|
-
return {
|
|
1570
|
-
...releaseGood,
|
|
1571
|
-
orderInventories: await tx
|
|
1572
|
-
.getRepository(OrderInventory)
|
|
1573
|
-
.find({ where: { releaseGood: { id: releaseGood.id } } }) /* CONFIRMME regarding TYPEORM */,
|
|
1574
|
-
status: ORDER_STATUS.PENDING_RECEIVE,
|
|
1575
|
-
updater: user
|
|
1576
|
-
}
|
|
1577
|
-
})
|
|
1578
|
-
)
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
function extractRawReleaseGoods(rawReleaseGoods): Partial<ReleaseGood[]> {
|
|
1582
|
-
return rawReleaseGoods.reduce((releaseGoods, item) => {
|
|
1583
|
-
const idx: number = releaseGoods.findIndex(rg => {
|
|
1584
|
-
// consider these attributes if they are exist in "item"
|
|
1585
|
-
const comparison = [
|
|
1586
|
-
'refNo2',
|
|
1587
|
-
'refNo3',
|
|
1588
|
-
'attentionTo',
|
|
1589
|
-
'phone1',
|
|
1590
|
-
'deliveryAddress1',
|
|
1591
|
-
'deliveryAddress2',
|
|
1592
|
-
'deliveryAddress3',
|
|
1593
|
-
'deliveryAddress4',
|
|
1594
|
-
'postalCode'
|
|
1595
|
-
]
|
|
1596
|
-
|
|
1597
|
-
let a: any = {},
|
|
1598
|
-
b: any = {}
|
|
1599
|
-
|
|
1600
|
-
comparison.forEach(cc => {
|
|
1601
|
-
if (item[cc]) {
|
|
1602
|
-
a[cc] = item[cc]
|
|
1603
|
-
b[cc] = rg[cc]
|
|
1604
|
-
}
|
|
1605
|
-
})
|
|
1606
|
-
|
|
1607
|
-
a = JSON.stringify(Object.fromEntries(Object.entries(a).sort()))
|
|
1608
|
-
b = JSON.stringify(Object.fromEntries(Object.entries(b).sort()))
|
|
1609
|
-
|
|
1610
|
-
return rg.refNo == item.refNo && rg.releaseDate == item.releaseDate && a === b
|
|
1611
|
-
})
|
|
1612
|
-
|
|
1613
|
-
if (idx >= 0) {
|
|
1614
|
-
const duplicateSkuIdx: number = releaseGoods[idx].orderInventories.findIndex(
|
|
1615
|
-
oi => oi.sku === item.sku && oi.packingType === item.packingType && oi.packingSize === item.packingSize
|
|
1616
|
-
)
|
|
1617
|
-
|
|
1618
|
-
// if there is duplicated SKU, merge them and sum up the releaseQty
|
|
1619
|
-
if (duplicateSkuIdx >= 0) {
|
|
1620
|
-
releaseGoods[idx].orderInventories[duplicateSkuIdx].releaseQty += item.releaseQty
|
|
1621
|
-
} else {
|
|
1622
|
-
releaseGoods[idx].orderInventories.push({
|
|
1623
|
-
sku: item.sku,
|
|
1624
|
-
productId: item.productId,
|
|
1625
|
-
packingType: item.packingType,
|
|
1626
|
-
packingSize: item.packingSize,
|
|
1627
|
-
uom: item.uom,
|
|
1628
|
-
releaseQty: item.releaseQty,
|
|
1629
|
-
releaseUomValue: item.releaseUomValue
|
|
1630
|
-
})
|
|
1631
|
-
}
|
|
1632
|
-
} else {
|
|
1633
|
-
releaseGoods.push({
|
|
1634
|
-
releaseDate: item.releaseDate,
|
|
1635
|
-
refNo: item.refNo,
|
|
1636
|
-
refNo2: item.refNo2,
|
|
1637
|
-
refNo3: item.refNo3,
|
|
1638
|
-
attentionTo: item.attentionTo,
|
|
1639
|
-
phone1: item.phone1,
|
|
1640
|
-
deliveryAddress1: item.deliveryAddress1,
|
|
1641
|
-
deliveryAddress2: item.deliveryAddress2,
|
|
1642
|
-
deliveryAddress3: item.deliveryAddress3,
|
|
1643
|
-
deliveryAddress4: item.deliveryAddress4,
|
|
1644
|
-
billingAddress: item.billingAddress,
|
|
1645
|
-
billingCity: item.billingPostalCode,
|
|
1646
|
-
billingState: item.billingState,
|
|
1647
|
-
billingCountry: item.billingCountry,
|
|
1648
|
-
billingPostalCode: item.billingPostalCode,
|
|
1649
|
-
city: item.city,
|
|
1650
|
-
postalCode: item.postalCode,
|
|
1651
|
-
state: item.state,
|
|
1652
|
-
country: item.country,
|
|
1653
|
-
orderInventories: [
|
|
1654
|
-
{
|
|
1655
|
-
sku: item.sku,
|
|
1656
|
-
productId: item.productId,
|
|
1657
|
-
packingType: item.packingType,
|
|
1658
|
-
packingSize: item.packingSize,
|
|
1659
|
-
uom: item.uom,
|
|
1660
|
-
releaseQty: item.releaseQty,
|
|
1661
|
-
releaseUomValue: item.releaseUomValue
|
|
1662
|
-
}
|
|
1663
|
-
]
|
|
1664
|
-
})
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
return releaseGoods
|
|
1668
|
-
}, [])
|
|
1669
|
-
}
|
|
1670
|
-
|
|
1671
|
-
function formRawReleaseGoods(releaseGood, errorMsg) {
|
|
1672
|
-
let rawReleaseGoods = []
|
|
1673
|
-
for (let i = 0, l = releaseGood.orderInventories.length; i < l; i++) {
|
|
1674
|
-
let rawReleaseGood = {
|
|
1675
|
-
...releaseGood,
|
|
1676
|
-
...releaseGood.orderInventories[i],
|
|
1677
|
-
errorMsg
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
delete rawReleaseGood.orderInventories
|
|
1681
|
-
delete rawReleaseGood.product
|
|
1682
|
-
|
|
1683
|
-
rawReleaseGoods.push(rawReleaseGood)
|
|
1684
|
-
}
|
|
1685
|
-
return rawReleaseGoods
|
|
1686
|
-
}
|