@things-factory/sales-base 4.3.656 → 4.3.660
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/service/arrival-notice/arrival-notice-mutation.js +485 -120
- package/dist-server/service/arrival-notice/arrival-notice-mutation.js.map +1 -1
- package/dist-server/service/arrival-notice/arrival-notice-query.js +5 -1
- package/dist-server/service/arrival-notice/arrival-notice-query.js.map +1 -1
- package/dist-server/service/order-product/order-product-types.js +67 -11
- package/dist-server/service/order-product/order-product-types.js.map +1 -1
- package/dist-server/service/order-product/order-product.js +49 -3
- package/dist-server/service/order-product/order-product.js.map +1 -1
- package/dist-server/service/others/other-query.js +88 -19
- package/dist-server/service/others/other-query.js.map +1 -1
- package/dist-server/service/others/other-types.js +18 -1
- package/dist-server/service/others/other-types.js.map +1 -1
- package/dist-server/service/release-good/release-good-query.js +1 -0
- package/dist-server/service/release-good/release-good-query.js.map +1 -1
- package/package.json +8 -8
- package/server/service/arrival-notice/arrival-notice-mutation.ts +560 -147
- package/server/service/arrival-notice/arrival-notice-query.ts +5 -1
- package/server/service/order-product/order-product-types.ts +45 -0
- package/server/service/order-product/order-product.ts +37 -1
- package/server/service/others/other-query.ts +97 -3
- package/server/service/others/other-types.ts +14 -0
- package/server/service/release-good/release-good-query.ts +1 -0
|
@@ -51,7 +51,7 @@ export class ArrivalNoticeQuery {
|
|
|
51
51
|
//separate query to improve typeorm mapping performance. Search for Related Order Product
|
|
52
52
|
let orderProducts = await getRepository(OrderProduct).find({
|
|
53
53
|
where: { arrivalNotice: foundGAN },
|
|
54
|
-
relations: ['product', 'productDetail', 'productDetail.productBarcodes']
|
|
54
|
+
relations: ['product', 'productDetail', 'productDetail.productBarcodes', 'warehouse', 'location', 'adjustedWarehouse','adjustedLocation']
|
|
55
55
|
})
|
|
56
56
|
foundGAN.orderProducts = await Promise.all(
|
|
57
57
|
orderProducts.map(async orderProduct => {
|
|
@@ -59,6 +59,10 @@ export class ArrivalNoticeQuery {
|
|
|
59
59
|
orderProduct.adjustedUnitPrice = orderProduct?.adjustedUnitPrice
|
|
60
60
|
? parseFloat(orderProduct.adjustedUnitPrice.toFixed(2))
|
|
61
61
|
: null
|
|
62
|
+
orderProduct.warehouse = orderProduct?.warehouse
|
|
63
|
+
orderProduct.location = orderProduct?.location
|
|
64
|
+
orderProduct.adjustedWarehouse = orderProduct?.adjustedWarehouse
|
|
65
|
+
orderProduct.adjustedLocation = orderProduct?.adjustedLocation
|
|
62
66
|
return orderProduct
|
|
63
67
|
})
|
|
64
68
|
)
|
|
@@ -4,6 +4,8 @@ import { ObjectRef, ScalarDate } from '@things-factory/shell'
|
|
|
4
4
|
|
|
5
5
|
import { OrderProduct } from './order-product'
|
|
6
6
|
|
|
7
|
+
import { Warehouse, Location } from '@things-factory/warehouse-base'
|
|
8
|
+
|
|
7
9
|
@ObjectType()
|
|
8
10
|
export class OrderProductList {
|
|
9
11
|
@Field(type => [OrderProduct], { nullable: true })
|
|
@@ -197,6 +199,25 @@ export class OrderProductPatch {
|
|
|
197
199
|
|
|
198
200
|
@Field({ nullable: true })
|
|
199
201
|
cuFlag: string
|
|
202
|
+
|
|
203
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
204
|
+
expDate: Date
|
|
205
|
+
|
|
206
|
+
@Field(type =>ScalarDate, { nullable: true })
|
|
207
|
+
adjustedExpDate: Date
|
|
208
|
+
|
|
209
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
210
|
+
warehouse: ObjectRef
|
|
211
|
+
|
|
212
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
213
|
+
location: ObjectRef
|
|
214
|
+
|
|
215
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
216
|
+
adjustedWarehouse: ObjectRef
|
|
217
|
+
|
|
218
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
219
|
+
adjustedLocation: ObjectRef
|
|
220
|
+
|
|
200
221
|
}
|
|
201
222
|
|
|
202
223
|
@InputType()
|
|
@@ -342,6 +363,12 @@ export class NewOrderProduct {
|
|
|
342
363
|
@Field({ nullable: true })
|
|
343
364
|
status: string
|
|
344
365
|
|
|
366
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
367
|
+
expDate: Date
|
|
368
|
+
|
|
369
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
370
|
+
adjustedExpDate: Date
|
|
371
|
+
|
|
345
372
|
@Field(type => ScalarDate, { nullable: true })
|
|
346
373
|
manufactureDate: Date
|
|
347
374
|
|
|
@@ -350,4 +377,22 @@ export class NewOrderProduct {
|
|
|
350
377
|
|
|
351
378
|
@Field(type => Float, { nullable: true })
|
|
352
379
|
paidAmount: number
|
|
380
|
+
|
|
381
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
382
|
+
warehouse: ObjectRef
|
|
383
|
+
|
|
384
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
385
|
+
adjustedWarehouse: ObjectRef
|
|
386
|
+
|
|
387
|
+
@Field(type => String, { nullable: true })
|
|
388
|
+
warehouseName: String
|
|
389
|
+
|
|
390
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
391
|
+
location: ObjectRef
|
|
392
|
+
|
|
393
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
394
|
+
adjustedLocation: ObjectRef
|
|
395
|
+
|
|
396
|
+
@Field(type => String, { nullable: true })
|
|
397
|
+
locationName: String
|
|
353
398
|
}
|
|
@@ -15,7 +15,7 @@ import { User } from '@things-factory/auth-base'
|
|
|
15
15
|
import { Bizplace } from '@things-factory/biz-base'
|
|
16
16
|
import { Product, ProductBundle, ProductDetail } from '@things-factory/product-base'
|
|
17
17
|
import { Domain, ScalarDate } from '@things-factory/shell'
|
|
18
|
-
import { Inventory } from '@things-factory/warehouse-base'
|
|
18
|
+
import { Inventory, Warehouse, Location } from '@things-factory/warehouse-base'
|
|
19
19
|
|
|
20
20
|
import { ArrivalNotice } from '../arrival-notice/arrival-notice'
|
|
21
21
|
import { CollectionOrder } from '../collection-order/collection-order'
|
|
@@ -238,6 +238,42 @@ export class OrderProduct {
|
|
|
238
238
|
@Field(type => ScalarDate, { nullable: true })
|
|
239
239
|
manufactureDate: Date
|
|
240
240
|
|
|
241
|
+
@Column('date', { nullable: true })
|
|
242
|
+
@Field(type => ScalarDate, { nullable: true })
|
|
243
|
+
expDate: Date
|
|
244
|
+
|
|
245
|
+
@Column('date', { nullable: true })
|
|
246
|
+
@Field( type => ScalarDate, { nullable: true })
|
|
247
|
+
adjustedExpDate: Date
|
|
248
|
+
|
|
249
|
+
@ManyToOne(type => Warehouse, { nullable: true })
|
|
250
|
+
@Field(type => Warehouse, { nullable: true })
|
|
251
|
+
warehouse: Warehouse
|
|
252
|
+
|
|
253
|
+
@RelationId((orderProduct: OrderProduct) => orderProduct.warehouse)
|
|
254
|
+
warehouseId: string
|
|
255
|
+
|
|
256
|
+
@ManyToOne(type=> Warehouse, { nullable: true })
|
|
257
|
+
@Field(type=> Warehouse, { nullable: true })
|
|
258
|
+
adjustedWarehouse: Warehouse
|
|
259
|
+
|
|
260
|
+
@RelationId((orderProduct: OrderProduct) => orderProduct.adjustedWarehouse)
|
|
261
|
+
adjustedWarehouseId: string
|
|
262
|
+
|
|
263
|
+
@ManyToOne(type => Location, { nullable: true })
|
|
264
|
+
@Field(type => Location, { nullable: true })
|
|
265
|
+
location: Location
|
|
266
|
+
|
|
267
|
+
@RelationId((orderProduct: OrderProduct) => orderProduct.location)
|
|
268
|
+
locationId: string
|
|
269
|
+
|
|
270
|
+
@ManyToOne(type => Location, { nullable: true })
|
|
271
|
+
@Field(type => Location, { nullable: true })
|
|
272
|
+
adjustedLocation: Location
|
|
273
|
+
|
|
274
|
+
@RelationId((orderProduct: OrderProduct) => orderProduct.adjustedLocation)
|
|
275
|
+
adjustedLocationId: string
|
|
276
|
+
|
|
241
277
|
@Column({ nullable: true })
|
|
242
278
|
@Field({ nullable: true })
|
|
243
279
|
uom: string
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
OrderProduct
|
|
19
19
|
} from '../'
|
|
20
20
|
import { InventoryUtil } from '../../utils'
|
|
21
|
+
import { Location } from '@things-factory/warehouse-base'
|
|
21
22
|
|
|
22
23
|
@Resolver()
|
|
23
24
|
export class OtherQuery {
|
|
@@ -292,8 +293,8 @@ export class OtherQuery {
|
|
|
292
293
|
@Query(returns => [InventoryProductGroup])
|
|
293
294
|
async bulkUploadValidateOrderProducts(
|
|
294
295
|
@Ctx() context: any,
|
|
295
|
-
@Arg('
|
|
296
|
-
@Arg('
|
|
296
|
+
@Arg('orderProducts', type => [NewOrderProduct], { nullable: true }) orderProducts: NewOrderProduct[],
|
|
297
|
+
@Arg('partnerBizplaceId', { nullable: true }) partnerBizplaceId?: string
|
|
297
298
|
): Promise<OrderProduct[]> {
|
|
298
299
|
try {
|
|
299
300
|
const { domain, user, tx, bizplace }: { domain: Domain; user: User; tx: EntityManager; bizplace: Bizplace } =
|
|
@@ -334,8 +335,16 @@ export class OtherQuery {
|
|
|
334
335
|
|
|
335
336
|
if (partnerStrictProductSelectionSetting) strictProduct = partnerStrictProductSelectionSetting.value
|
|
336
337
|
|
|
338
|
+
const directGanOrderSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
339
|
+
where: { domain, category: 'id-rule', name: 'enable-direct-gan-order' }
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
let directGanOrder = 'false'
|
|
343
|
+
if (directGanOrderSetting) directGanOrder = directGanOrderSetting.value
|
|
344
|
+
|
|
337
345
|
const json_op = JSON.stringify(
|
|
338
346
|
orderProducts.map(orderProduct => {
|
|
347
|
+
|
|
339
348
|
return {
|
|
340
349
|
sku: orderProduct.productSKU,
|
|
341
350
|
packing_type: orderProduct.packingType,
|
|
@@ -348,7 +357,12 @@ export class OtherQuery {
|
|
|
348
357
|
uom_value: orderProduct.uomValue,
|
|
349
358
|
manufacture_date: orderProduct.manufactureDate,
|
|
350
359
|
batch_id_ref: orderProduct.batchIdRef,
|
|
351
|
-
remark: orderProduct.remark
|
|
360
|
+
remark: orderProduct.remark,
|
|
361
|
+
...(directGanOrder && {
|
|
362
|
+
warehouse_name: orderProduct.warehouseName,
|
|
363
|
+
location_name: orderProduct.location ? orderProduct.location.name : orderProduct.locationName,
|
|
364
|
+
location_id: orderProduct.location? orderProduct.location.id : ''
|
|
365
|
+
})
|
|
352
366
|
}
|
|
353
367
|
})
|
|
354
368
|
)
|
|
@@ -366,6 +380,13 @@ export class OtherQuery {
|
|
|
366
380
|
uom VARCHAR(10),
|
|
367
381
|
uom_value FLOAT,
|
|
368
382
|
manufacture_date DATE,
|
|
383
|
+
${
|
|
384
|
+
directGanOrder.toLocaleLowerCase() === 'true'
|
|
385
|
+
? `warehouse_name VARCHAR(150),
|
|
386
|
+
location_name VARCHAR(150),
|
|
387
|
+
location_id VARCHAR(150),`
|
|
388
|
+
: ``
|
|
389
|
+
}
|
|
369
390
|
batch_id_ref VARCHAR(50),
|
|
370
391
|
remark VARCHAR(50)
|
|
371
392
|
);
|
|
@@ -380,6 +401,61 @@ export class OtherQuery {
|
|
|
380
401
|
[json_op]
|
|
381
402
|
)
|
|
382
403
|
|
|
404
|
+
//validate and show error message in popup
|
|
405
|
+
if (directGanOrder && partnerBizplaceId == undefined) {
|
|
406
|
+
let results = await tx.query(
|
|
407
|
+
`
|
|
408
|
+
SELECT
|
|
409
|
+
rop.*,
|
|
410
|
+
TRIM(BOTH ' | ' FROM -- Trim leading/trailing ' | ' from the concatenated error messages
|
|
411
|
+
COALESCE(CASE WHEN p.sku IS NULL THEN 'Invalid SKU or Packing Type | ' ELSE '' END, '') ||
|
|
412
|
+
COALESCE(CASE WHEN pd.uom IS NULL THEN 'Invalid UOM or UOM Value | ' ELSE '' END, '') ||
|
|
413
|
+
COALESCE(CASE WHEN rop.manufacture_date > CURRENT_DATE THEN 'Manufacture Date in Future | ' ELSE '' END, '') ||
|
|
414
|
+
COALESCE(CASE WHEN rop.unit_price <= 0 THEN 'Unit Price must be greater than 0 | ' ELSE '' END, '') ||
|
|
415
|
+
COALESCE(CASE WHEN rop.pack_qty <= 0 THEN 'Pack Quantity must be greater than 0 | ' ELSE '' END, '') ||
|
|
416
|
+
COALESCE(CASE WHEN rop.pallet_qty < 0 THEN 'Pallet Quantity must be positive | ' ELSE '' END, '') ||
|
|
417
|
+
COALESCE(CASE WHEN w.name IS NULL THEN 'Location not found in Master Data | ' ELSE '' END, '') ||
|
|
418
|
+
COALESCE(CASE WHEN l.name IS NULL OR l.warehouse_id IS DISTINCT FROM w.id THEN 'Location-Warehouse Mismatch | ' ELSE '' END, '')
|
|
419
|
+
) AS error_message -- The new column containing concatenated error messages
|
|
420
|
+
FROM
|
|
421
|
+
raw_order_products rop
|
|
422
|
+
LEFT JOIN
|
|
423
|
+
products p ON LOWER(rop.sku) = LOWER(p.sku) AND rop.packing_type = p.packing_type
|
|
424
|
+
LEFT JOIN
|
|
425
|
+
product_details pd ON pd.product_id = p.id AND rop.uom = pd.uom AND rop.uom_value = pd.uom_value
|
|
426
|
+
LEFT JOIN
|
|
427
|
+
warehouses w ON rop.warehouse_name = w.name and w.domain_id = $1
|
|
428
|
+
LEFT JOIN
|
|
429
|
+
locations l ON l.warehouse_id = w.id AND rop.location_name = l.name
|
|
430
|
+
`,
|
|
431
|
+
[domain.id]
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
await tx.query(`DROP TABLE raw_order_products`)
|
|
435
|
+
|
|
436
|
+
const newOrderProducts: any[] = results.map(result => {
|
|
437
|
+
return {
|
|
438
|
+
// Remapping keys to the new spelling
|
|
439
|
+
packingType: result.packing_type,
|
|
440
|
+
uom: result.uom,
|
|
441
|
+
uomValue: result.uom_value,
|
|
442
|
+
packQty: result.pack_qty,
|
|
443
|
+
palletQty: result.pallet_qty,
|
|
444
|
+
manufactureDate: result.manufacture_date,
|
|
445
|
+
batchId: result.batch_id,
|
|
446
|
+
batchIdRef: result.batch_id_ref,
|
|
447
|
+
unitPrice: result.unit_price,
|
|
448
|
+
remark: result.remark,
|
|
449
|
+
productSKU: result.sku, // 'sku' from results maps to 'productSKU'
|
|
450
|
+
errMsg: result.error_message, // 'error_message' from results maps to 'errMsg'
|
|
451
|
+
pallet_id: result.pallet_id, // Keeping original key for pallet_id as it's not in new key spelling list
|
|
452
|
+
warehouseName: result.warehouse_name,
|
|
453
|
+
location: {name:result.location_name, id:result.location_id }
|
|
454
|
+
}
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
return newOrderProducts
|
|
458
|
+
}
|
|
383
459
|
// find closest matching product details from input data
|
|
384
460
|
await tx.query(
|
|
385
461
|
`
|
|
@@ -450,6 +526,24 @@ export class OtherQuery {
|
|
|
450
526
|
await tx.query(`DROP TABLE matching_product_details`)
|
|
451
527
|
await tx.query(`DROP TABLE raw_order_products`)
|
|
452
528
|
|
|
529
|
+
if (directGanOrder == 'true') {
|
|
530
|
+
let location: Location
|
|
531
|
+
for (let i = 0; i < results.length; i++) {
|
|
532
|
+
location = await tx.getRepository(Location).findOne({
|
|
533
|
+
where: {
|
|
534
|
+
domain: domain,
|
|
535
|
+
name: orderProducts[i].location.name
|
|
536
|
+
},
|
|
537
|
+
relations: ['warehouse']
|
|
538
|
+
})
|
|
539
|
+
results[i].location = location
|
|
540
|
+
results[i].warehouse = location.warehouse
|
|
541
|
+
if (!location) {
|
|
542
|
+
throw new Error(`Location not found for ${orderProducts[i]?.location?.name} `)
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
453
547
|
// build output structure
|
|
454
548
|
const newOrderProducts: any[] = results.map(result => {
|
|
455
549
|
return {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Field, Float, Int, ObjectType } from 'type-graphql'
|
|
2
2
|
import { Product, ProductDetail } from '@things-factory/product-base'
|
|
3
|
+
import { Location, Warehouse } from '@things-factory/warehouse-base'
|
|
4
|
+
|
|
3
5
|
import { ScalarDate } from '@things-factory/shell'
|
|
4
6
|
|
|
5
7
|
@ObjectType()
|
|
@@ -120,4 +122,16 @@ export class InventoryProductGroup {
|
|
|
120
122
|
|
|
121
123
|
@Field(type => ProductDetail, { nullable: true })
|
|
122
124
|
productDetail: ProductDetail
|
|
125
|
+
|
|
126
|
+
@Field(type => Location, { nullable: true })
|
|
127
|
+
location: Location
|
|
128
|
+
|
|
129
|
+
@Field(type => Warehouse, { nullable: true })
|
|
130
|
+
warehouse: Warehouse
|
|
131
|
+
|
|
132
|
+
@Field(type => String, { nullable: true })
|
|
133
|
+
warehouseName: String
|
|
134
|
+
|
|
135
|
+
@Field(type => String, { nullable: true })
|
|
136
|
+
errMsg: String
|
|
123
137
|
}
|
|
@@ -1048,6 +1048,7 @@ export async function bulkReleaseGoodsAvailableItemsFunction(
|
|
|
1048
1048
|
AND i.domain_id = $1
|
|
1049
1049
|
AND i.bizplace_id = $2
|
|
1050
1050
|
WHERE l.type NOT IN ($3, $4)
|
|
1051
|
+
AND i.status = 'STORED'
|
|
1051
1052
|
AND i.obsolete = false
|
|
1052
1053
|
AND i.transfer_qty <= 0
|
|
1053
1054
|
AND i.transfer_uom_value <= 0
|