@things-factory/sales-base 4.3.603 → 4.3.607

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist-server/service/arrival-notice/arrival-notice-query.js +70 -66
  2. package/dist-server/service/arrival-notice/arrival-notice-query.js.map +1 -1
  3. package/dist-server/service/draft-release-good/draft-release-good-create.js +22 -12
  4. package/dist-server/service/draft-release-good/draft-release-good-create.js.map +1 -1
  5. package/dist-server/service/draft-release-good/draft-release-good-type.js +12 -0
  6. package/dist-server/service/draft-release-good/draft-release-good-type.js.map +1 -1
  7. package/dist-server/service/goods-receival-note/goods-receival-note-query.js +7 -10
  8. package/dist-server/service/goods-receival-note/goods-receival-note-query.js.map +1 -1
  9. package/dist-server/service/goods-receival-note/goods-receival-note-types.js +1 -1
  10. package/dist-server/service/goods-receival-note/goods-receival-note-types.js.map +1 -1
  11. package/dist-server/service/release-good/release-good-query.js +11 -2
  12. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  13. package/dist-server/utils/datetime-util.js +22 -1
  14. package/dist-server/utils/datetime-util.js.map +1 -1
  15. package/dist-server/utils/inventory-util.js +2 -0
  16. package/dist-server/utils/inventory-util.js.map +1 -1
  17. package/package.json +2 -2
  18. package/server/service/arrival-notice/arrival-notice-query.ts +116 -77
  19. package/server/service/draft-release-good/draft-release-good-create.ts +73 -18
  20. package/server/service/draft-release-good/draft-release-good-type.ts +10 -6
  21. package/server/service/goods-receival-note/goods-receival-note-query.ts +34 -14
  22. package/server/service/goods-receival-note/goods-receival-note-types.ts +8 -1
  23. package/server/service/release-good/release-good-query.ts +15 -7
  24. package/server/utils/datetime-util.ts +23 -0
  25. package/server/utils/inventory-util.ts +25 -4
@@ -1,16 +1,52 @@
1
- import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
- import { EntityManager, getRepository, In, Raw, SelectQueryBuilder } from 'typeorm'
1
+ import {
2
+ Arg,
3
+ Args,
4
+ Ctx,
5
+ Directive,
6
+ FieldResolver,
7
+ Query,
8
+ Resolver,
9
+ Root
10
+ } from 'type-graphql'
11
+ import {
12
+ EntityManager,
13
+ getRepository,
14
+ In,
15
+ SelectQueryBuilder
16
+ } from 'typeorm'
3
17
 
4
18
  import { Attachment } from '@things-factory/attachment-base'
5
- import { checkUserBelongsDomain, User } from '@things-factory/auth-base'
6
- import { Bizplace, getCompanyBizplace, getPermittedBizplaceIds } from '@things-factory/biz-base'
7
- import { buildQuery, Domain, ListParam } from '@things-factory/shell'
8
-
9
- import { ArrivalNoticeList, NewArrivalNotice, RawArrivalNotice } from '../'
10
- import { ATTACHMENT_TYPE, ORDER_STATUS } from '../../constants'
11
- import { OrderInventory, OrderProduct } from '../../service'
12
- import { ArrivalNotice } from './arrival-notice'
19
+ import {
20
+ checkUserBelongsDomain,
21
+ User
22
+ } from '@things-factory/auth-base'
23
+ import {
24
+ Bizplace,
25
+ getCompanyBizplace,
26
+ getPermittedBizplaceIds
27
+ } from '@things-factory/biz-base'
13
28
  import { Setting } from '@things-factory/setting-base'
29
+ import {
30
+ buildQuery,
31
+ Domain,
32
+ ListParam
33
+ } from '@things-factory/shell'
34
+
35
+ import {
36
+ ArrivalNoticeList,
37
+ NewArrivalNotice,
38
+ RawArrivalNotice
39
+ } from '../'
40
+ import {
41
+ ATTACHMENT_TYPE,
42
+ ORDER_STATUS
43
+ } from '../../constants'
44
+ import {
45
+ OrderInventory,
46
+ OrderProduct
47
+ } from '../../service'
48
+ import { convertExcelDateToISO } from '../../utils/datetime-util'
49
+ import { ArrivalNotice } from './arrival-notice'
14
50
 
15
51
  @Resolver(ArrivalNotice)
16
52
  export class ArrivalNoticeQuery {
@@ -335,21 +371,16 @@ export async function validateBulkArrivalNoticesFunction(
335
371
  trxMgr: EntityManager
336
372
  ): Promise<RawArrivalNotice[]> {
337
373
  const companyBizplace: Bizplace = await getCompanyBizplace(null, null, bizplaceId)
338
-
339
374
  const json_oi = JSON.stringify(
340
375
  rawArrivalNotices.map(raw => {
341
- // -1 and -2 acts as code to display error.
342
- // if (raw.unitPrice < 0) {
343
- // raw.unitPrice = -1
344
- // }
345
- // if ((raw.unitPrice === undefined) == false && raw.unitPrice == null) {
346
- // raw.unitPrice = -2
347
- // }
376
+ let etaDate = convertExcelDateToISO(raw.etaDate)
377
+ let manufactureDate = convertExcelDateToISO(raw.manufactureDate)
378
+
348
379
  return {
349
380
  ref_no: raw.refNo || null,
350
381
  ref_no_2: raw.refNo2 || null,
351
382
  ref_no_3: raw.refNo3 || null,
352
- eta_date: raw.etaDate || null,
383
+ eta_date: etaDate || null,
353
384
  truck_no: raw.truckNo || null,
354
385
  own_transport: !!raw.truckNo || false,
355
386
  loose_item: raw.looseItem || false,
@@ -367,7 +398,7 @@ export async function validateBulkArrivalNoticesFunction(
367
398
  pallet_qty: raw.palletQty || null,
368
399
  pallet_id: raw.palletId || null,
369
400
  unit_price: raw.unitPrice === undefined ? (isNaN(raw.unitPrice) ? '' : null) : raw.unitPrice,
370
- manufacture_date: raw.manufactureDate || null
401
+ manufacture_date: manufactureDate || null
371
402
  }
372
403
  })
373
404
  )
@@ -423,7 +454,7 @@ export async function validateBulkArrivalNoticesFunction(
423
454
  pallet_qty INT,
424
455
  pallet_id VARCHAR(50),
425
456
  unit_price VARCHAR(50),
426
- manufacture_date DATE
457
+ manufacture_date VARCHAR(24)
427
458
  );
428
459
  `
429
460
  )
@@ -475,61 +506,61 @@ export async function validateBulkArrivalNoticesFunction(
475
506
  let validatedItems = await trxMgr.query(
476
507
  `
477
508
  WITH foo AS (
478
- SELECT
479
- an.name AS gan_name,
480
- an.ref_no AS gan_ref_no,
481
- raw.ref_no,
482
- raw.ref_no_2,
483
- raw.ref_no_3,
484
- raw.eta_date,
485
- raw.truck_no,
486
- raw.own_transport,
487
- raw.container,
488
- raw.container_no,
489
- raw.container_size,
490
- raw.import_cargo,
491
- raw.loose_item,
492
- pr.id AS product_id,
493
- pd.id AS product_detail_id,
494
- raw.sku AS sku,
495
- CASE WHEN pr.description NOT IN (NULL, '', '-') THEN CONCAT(pr.name, '(', pr.description, ')') ELSE pr.name END AS product_info,
496
- raw.batch_id,
497
- raw.batch_id_ref,
498
- pd.packing_type,
499
- pd.packing_size,
509
+ SELECT
510
+ an.name AS gan_name,
511
+ an.ref_no AS gan_ref_no,
512
+ raw.ref_no,
513
+ raw.ref_no_2,
514
+ raw.ref_no_3,
515
+ raw.eta_date,
516
+ raw.truck_no,
517
+ raw.own_transport,
518
+ raw.container,
519
+ raw.container_no,
520
+ raw.container_size,
521
+ raw.import_cargo,
522
+ raw.loose_item,
523
+ pr.id AS product_id,
524
+ pd.id AS product_detail_id,
525
+ raw.sku AS sku,
526
+ CASE WHEN pr.description NOT IN (NULL, '', '-') THEN CONCAT(pr.name, '(', pr.description, ')') ELSE pr.name END AS product_info,
527
+ raw.batch_id,
528
+ raw.batch_id_ref,
529
+ pd.packing_type,
530
+ pd.packing_size,
500
531
  pd.cost_price,
501
- sum(raw.pack_qty) AS pack_qty,
532
+ sum(raw.pack_qty) AS pack_qty,
502
533
  raw.pallet_id,
503
- sum(pd.uom_value) AS uom_value,
504
- pd.uom,
505
- sum(raw.pallet_qty) AS pallet_qty,
506
- CASE WHEN raw.unit_price = '' THEN pd.cost_price::varchar ELSE raw.unit_price::varchar END AS unit_price,
507
- raw.manufacture_date
508
- FROM
509
- raw_arrival_notices raw
510
- LEFT JOIN temp_gan an ON raw.ref_no = an.ref_no
511
- AND raw.ref_no_2 = an.ref_no_2
512
- AND raw.ref_no_3 = an.ref_no_3
513
- AND raw.eta_date::date = an.eta_date::date
514
- AND raw.truck_no = an.truck_no
515
- AND raw.own_transport = an.own_transport
516
- AND raw.container = an.container
517
- AND raw.container_no = an.container_no
518
- AND raw.container_size = an.container_size
519
- AND raw.loose_item = an.loose_item
520
- AND raw.import_cargo = an.import_cargo
521
- LEFT JOIN products pr ON LOWER(pr.sku) = LOWER(raw.sku)
522
- LEFT JOIN product_details pd ON pr.id = pd.product_id
523
- AND CASE WHEN raw.packing_type NOTNULL AND raw.packing_size NOTNULL AND raw.uom NOTNULL
524
- THEN pd.packing_type = raw.packing_type AND pd.packing_size = raw.packing_size AND pd.uom = raw.uom
525
- WHEN raw.packing_type NOTNULL AND raw.packing_size NOTNULL AND raw.uom ISNULL
526
- THEN pd.packing_type = raw.packing_type AND pd.packing_size = raw.packing_size AND pd.is_default IS TRUE
527
- WHEN raw.packing_type ISNULL AND raw.packing_size ISNULL AND raw.uom NOTNULL
528
- THEN pd.uom = raw.uom AND pd.is_default IS TRUE ELSE pd.is_default IS TRUE
529
- END
534
+ sum(pd.uom_value) AS uom_value,
535
+ pd.uom,
536
+ sum(raw.pallet_qty) AS pallet_qty,
537
+ CASE WHEN raw.unit_price = '' THEN pd.cost_price::varchar ELSE raw.unit_price::varchar END AS unit_price,
538
+ raw.manufacture_date
539
+ FROM
540
+ raw_arrival_notices raw
541
+ LEFT JOIN temp_gan an ON raw.ref_no = an.ref_no
542
+ AND raw.ref_no_2 = an.ref_no_2
543
+ AND raw.ref_no_3 = an.ref_no_3
544
+ AND raw.eta_date = an.eta_date
545
+ AND raw.truck_no = an.truck_no
546
+ AND raw.own_transport = an.own_transport
547
+ AND raw.container = an.container
548
+ AND raw.container_no = an.container_no
549
+ AND raw.container_size = an.container_size
550
+ AND raw.loose_item = an.loose_item
551
+ AND raw.import_cargo = an.import_cargo
552
+ LEFT JOIN products pr ON LOWER(pr.sku) = LOWER(raw.sku)
553
+ LEFT JOIN product_details pd ON pr.id = pd.product_id
554
+ AND CASE WHEN raw.packing_type NOTNULL AND raw.packing_size NOTNULL AND raw.uom NOTNULL
555
+ THEN pd.packing_type = raw.packing_type AND pd.packing_size = raw.packing_size AND pd.uom = raw.uom
556
+ WHEN raw.packing_type NOTNULL AND raw.packing_size NOTNULL AND raw.uom ISNULL
557
+ THEN pd.packing_type = raw.packing_type AND pd.packing_size = raw.packing_size AND pd.is_default IS TRUE
558
+ WHEN raw.packing_type ISNULL AND raw.packing_size ISNULL AND raw.uom NOTNULL
559
+ THEN pd.uom = raw.uom AND pd.is_default IS TRUE ELSE pd.is_default IS TRUE
560
+ END
530
561
  WHERE pr.bizplace_id = $1
531
- GROUP BY raw.ref_no, raw.ref_no_2, raw.ref_no_3, raw.eta_date, raw.truck_no, raw.own_transport, raw.container, raw.container_no, raw.container_size, raw.import_cargo, raw.loose_item,
532
- pr.id, pd.id, raw.sku, pr.name, pr.description, raw.batch_id, raw.batch_id_ref, raw.packing_type, raw.pallet_id, raw.packing_size, raw.uom, raw.unit_price, raw.manufacture_date, an.ref_no, an.name
562
+ GROUP BY raw.ref_no, raw.ref_no_2, raw.ref_no_3, raw.eta_date, raw.truck_no, raw.own_transport, raw.container, raw.container_no, raw.container_size, raw.import_cargo, raw.loose_item,
563
+ pr.id, pd.id, raw.sku, pr.name, pr.description, raw.batch_id, raw.batch_id_ref, raw.packing_type, raw.pallet_id, raw.packing_size, raw.uom, raw.unit_price, raw.manufacture_date, an.ref_no, an.name
533
564
  ), foo_duplicates AS (
534
565
  SELECT
535
566
  pallet_id,
@@ -545,9 +576,13 @@ export async function validateBulkArrivalNoticesFunction(
545
576
  WHEN foo.gan_ref_no IS NOT NULL THEN 'order duplicated with ' || foo.gan_name || ','
546
577
  ELSE ''
547
578
  END ||
548
- CASE
549
- WHEN foo.manufacture_date > current_date THEN 'invalid manufacture date,'
550
- ELSE ''
579
+ CASE
580
+ WHEN (SUBSTRING(foo.manufacture_date,5,1) = '-' AND SUBSTRING(foo.manufacture_date,8,1) = '-') OR foo.manufacture_date IS NULL THEN
581
+ CASE
582
+ WHEN TO_DATE(foo.manufacture_date, 'YYYY-MM-DD') > current_date THEN 'invalid manufacture date,'
583
+ ELSE ''
584
+ END
585
+ ELSE 'invalid manufacture date format. please use dd/mm/yyyy,'
551
586
  END ||
552
587
  CASE
553
588
  WHEN foo.product_id IS NULL OR foo.product_detail_id IS NULL OR foo.sku IS NULL THEN 'product not found,'
@@ -569,6 +604,10 @@ export async function validateBulkArrivalNoticesFunction(
569
604
  WHEN foo.eta_date IS NULL THEN 'eta date is required,'
570
605
  ELSE ''
571
606
  END ||
607
+ CASE
608
+ WHEN NOT(SUBSTRING(foo.eta_date,5,1) = '-' AND SUBSTRING(foo.eta_date,8,1) = '-') THEN 'invalid eta date format. please use dd/mm/yyyy,'
609
+ ELSE ''
610
+ END ||
572
611
  CASE
573
612
  WHEN foo.unit_price IS NULL THEN 'invalid unit price (not a number),'
574
613
  ELSE ''
@@ -606,7 +645,7 @@ FROM foo
606
645
  )
607
646
 
608
647
  await trxMgr.query('DROP TABLE raw_arrival_notices, temp_gan')
609
-
648
+
610
649
  return validatedItems.map(item => {
611
650
  return {
612
651
  refNo: item.ref_no,
@@ -1,19 +1,54 @@
1
- import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
- import { EntityManager, getConnection, getRepository, In, Repository } from 'typeorm'
1
+ import {
2
+ Arg,
3
+ Ctx,
4
+ Directive,
5
+ Mutation,
6
+ Resolver
7
+ } from 'type-graphql'
8
+ import {
9
+ EntityManager,
10
+ getConnection,
11
+ getRepository,
12
+ In,
13
+ Repository
14
+ } from 'typeorm'
3
15
 
4
16
  import { Bizplace } from '@things-factory/biz-base'
5
17
  import { logger } from '@things-factory/env'
18
+ import {
19
+ WebhookEventsEnum,
20
+ webhookHandler
21
+ } from '@things-factory/integration-base'
6
22
  import { ProductBundle } from '@things-factory/product-base'
7
- import { webhookHandler, WebhookEventsEnum } from '@things-factory/integration-base'
8
- import { PartnerSetting, Setting } from '@things-factory/setting-base'
23
+ import {
24
+ PartnerSetting,
25
+ Setting
26
+ } from '@things-factory/setting-base'
9
27
  import { Domain } from '@things-factory/shell'
10
- import { bulkReleaseGoodsAvailableItemsFunction, DraftReleaseGood, DraftReleaseGoodInfos, OrderProduct } from '../'
11
- import { DRAFT_RELEASE_ORDER_STATUS, ORDER_NUMBER_SETTING_KEY, ORDER_STATUS } from '../../constants'
28
+
29
+ import {
30
+ bulkReleaseGoodsAvailableItemsFunction,
31
+ DraftReleaseGood,
32
+ DraftReleaseGoodInfos,
33
+ OrderProduct
34
+ } from '../'
35
+ import {
36
+ DRAFT_RELEASE_ORDER_STATUS,
37
+ ORDER_NUMBER_SETTING_KEY,
38
+ ORDER_STATUS
39
+ } from '../../constants'
12
40
  import { ValidationError } from '../../errors'
13
- import { InventoryUtil, OrderNoGenerator } from '../../utils'
41
+ import {
42
+ InventoryUtil,
43
+ OrderNoGenerator
44
+ } from '../../utils'
14
45
  import { ReleaseGood } from '../release-good/release-good'
46
+ import {
47
+ bulkGenerateReleaseGood,
48
+ confirmReleaseGood,
49
+ receiveReleaseGood
50
+ } from '../release-good/release-good-mutation'
15
51
  import { SuccessReleasedDraftOrder } from './draft-release-good-type'
16
- import { bulkGenerateReleaseGood, confirmReleaseGood, receiveReleaseGood } from '../release-good/release-good-mutation'
17
52
 
18
53
  @Resolver(DraftReleaseGood)
19
54
  export class DraftReleaseGoodCreate {
@@ -71,6 +106,7 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
71
106
  relations: [
72
107
  'orderProducts',
73
108
  'orderProducts.product',
109
+ 'orderProducts.productDetail',
74
110
  'orderProducts.productBundle',
75
111
  'orderProducts.productBundle.productBundleSettings',
76
112
  'orderProducts.productBundle.productBundleSettings.product',
@@ -85,6 +121,7 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
85
121
  ]
86
122
  })
87
123
  let failReleaseOrder = []
124
+ let successReleaseOrder = []
88
125
 
89
126
  if (updatableDraftOrders.length > 0) {
90
127
  const settingRepo: Repository<Setting> = tx?.getRepository(Setting) || getRepository(Setting)
@@ -142,7 +179,8 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
142
179
  name: 'productId',
143
180
  operator: 'in',
144
181
  value: productIds
145
- }
182
+ },
183
+ { name: 'deleted_at', operator: 'eq', value: true }
146
184
  ]
147
185
  },
148
186
  context,
@@ -178,8 +216,11 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
178
216
  }
179
217
  })
180
218
 
181
- let insufficient = draftOrder.orderProducts.find(op => op.status == 'insufficient')
182
- if (!insufficient) {
219
+ let failedInventory = draftOrder.orderProducts.find(
220
+ op => op.status == 'insufficient' || op.productDetail.deletedAt != null
221
+ )
222
+
223
+ if (!failedInventory) {
183
224
  //create RO
184
225
  let releaseGood = { ...draftOrder }
185
226
  delete releaseGood.id
@@ -266,6 +307,14 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
266
307
  context,
267
308
  innerTx2
268
309
  )
310
+
311
+ if (availableItems.some(item => item.orderProduct.productDetail.deletedAt != null)) {
312
+ throw new ValidationError({
313
+ ...ValidationError.ERROR_CODES.DELETED_PRODUCT_DETAIL,
314
+ detail: { data: JSON.stringify(availableItems) }
315
+ })
316
+ }
317
+
269
318
  if (availableItems.some(item => !item.releaseQty || item.releaseQty > item.assignedQty))
270
319
  throw new ValidationError({
271
320
  ...ValidationError.ERROR_CODES.INSUFFICIENT_STOCK,
@@ -303,6 +352,7 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
303
352
  if (existingReleaseGood.length > 1) {
304
353
  throw new Error('generating release orders')
305
354
  }
355
+ // successReleaseOrder.push({ draftName: draftOrder?.name, status: 'success' })
306
356
  })
307
357
 
308
358
  await innerTx2
@@ -332,6 +382,7 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
332
382
 
333
383
  createdReleaseGood = await confirmReleaseGood(createdReleaseGood.name, context, innerTx2)
334
384
 
385
+ successReleaseOrder.push({ draftName: draftOrder?.name, status: 'success' })
335
386
  if (settingValue > 1) {
336
387
  createdReleaseGood = await receiveReleaseGood(createdReleaseGood.name, context, innerTx2)
337
388
  }
@@ -340,8 +391,12 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
340
391
  webhookHandler(createdReleaseGood, createdReleaseGood.bizplace, WebhookEventsEnum.ReleaseOrderCreated)
341
392
  })
342
393
  } else {
343
- if (draftOrder.orderProducts.every(op => op.id === insufficient?.id)) {
344
- failReleaseOrder.push(draftOrder?.name)
394
+ if (
395
+ draftOrder.orderProducts.some(op => op.id === failedInventory?.id && op.productDetail.deletedAt != null)
396
+ ) {
397
+ failReleaseOrder.push({ draftName: draftOrder?.name, status: 'deleted' })
398
+ } else {
399
+ failReleaseOrder.push({ draftName: draftOrder?.name, status: 'insufficient' })
345
400
  }
346
401
  }
347
402
  } catch (e) {
@@ -352,12 +407,12 @@ export async function generateReleaseGoods(_generateReleaseGoodsRecord, context:
352
407
  })
353
408
  }
354
409
  }
355
- releasedOrders = updatableDraftOrders.filter(drg => !drg.name.includes(failReleaseOrder))
356
- releasedOrders = releasedOrders.map(item => {
357
- return {
358
- draftName: item.name
359
- }
410
+ releasedOrders.push({
411
+ successCount: successReleaseOrder.length,
412
+ insufficientCount: failReleaseOrder.filter(fro => fro.status === 'insufficient').length,
413
+ deletedCount: failReleaseOrder.filter(fro => fro.status === 'deleted').length
360
414
  })
415
+
361
416
  return releasedOrders
362
417
  } catch (e) {
363
418
  logger.error(`draft-release-good-mutation[generateReleaseGoodsFromDraft]: ${e?.message}`)
@@ -1,9 +1,4 @@
1
- import {
2
- Field,
3
- InputType,
4
- Int,
5
- ObjectType
6
- } from 'type-graphql'
1
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
7
2
 
8
3
  import { ObjectRef } from '@things-factory/shell'
9
4
 
@@ -287,6 +282,15 @@ export class SuccessReleasedDraftOrder {
287
282
 
288
283
  @Field({ nullable: true })
289
284
  isProductBundle?: Boolean
285
+
286
+ @Field({ nullable: true })
287
+ successCount?: number
288
+
289
+ @Field({ nullable: true })
290
+ insufficientCount?: number
291
+
292
+ @Field({ nullable: true })
293
+ deletedCount?: number
290
294
  }
291
295
 
292
296
  @InputType()
@@ -1,20 +1,40 @@
1
- import { PurchaseOrder } from './../purchase-order/purchase-order'
2
- import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
3
- import { getRepository, SelectQueryBuilder } from 'typeorm'
4
- import { IsNull, Not, In } from 'typeorm'
5
-
6
- import { User } from '@things-factory/auth-base'
7
- import { getPermittedBizplaceIds } from '@things-factory/biz-base'
8
- import { buildQuery, Domain, ListParam } from '@things-factory/shell'
9
- import { InventoryItem } from '@things-factory/warehouse-base'
1
+ import {
2
+ Arg,
3
+ Args,
4
+ Ctx,
5
+ FieldResolver,
6
+ Query,
7
+ Resolver,
8
+ Root
9
+ } from 'type-graphql'
10
+ import {
11
+ getRepository,
12
+ IsNull,
13
+ Not,
14
+ SelectQueryBuilder
15
+ } from 'typeorm'
16
+
17
+ import {
18
+ Partner,
19
+ User
20
+ } from '@things-factory/auth-base'
21
+ import {
22
+ Bizplace,
23
+ ContactPoint,
24
+ getPermittedBizplaceIds
25
+ } from '@things-factory/biz-base'
26
+ import {
27
+ buildQuery,
28
+ Domain,
29
+ ListParam
30
+ } from '@things-factory/shell'
31
+ import { ReducedInventoryHistory } from '@things-factory/warehouse-base'
32
+
10
33
  import { GoodsReceivalNoteList } from '../'
11
- import { GoodsReceivalNote } from './goods-receival-note'
34
+ import { DateTimeConverter } from '../../utils/datetime-util'
12
35
  import { ArrivalNotice } from '../arrival-notice/arrival-notice'
13
- import { Partner } from '@things-factory/auth-base'
14
- import { Bizplace, ContactPoint } from '@things-factory/biz-base'
15
36
  import { OrderProduct } from '../order-product/order-product'
16
- import { ReducedInventoryHistory } from '@things-factory/warehouse-base'
17
- import { DateTimeConverter } from '../../utils/datetime-util'
37
+ import { GoodsReceivalNote } from './goods-receival-note'
18
38
 
19
39
  @Resolver(GoodsReceivalNote)
20
40
  export class GoodsReceivalNoteQuery {
@@ -1,5 +1,12 @@
1
+ import {
2
+ Field,
3
+ InputType,
4
+ Int,
5
+ ObjectType
6
+ } from 'type-graphql'
7
+
1
8
  import { ObjectRef } from '@things-factory/shell'
2
- import { Field, InputType, Int, ObjectType } from 'type-graphql'
9
+
3
10
  import { GoodsReceivalNote } from './goods-receival-note'
4
11
 
5
12
  @ObjectType()
@@ -47,6 +47,7 @@ import {
47
47
  ORDER_STATUS,
48
48
  ORDER_VAS_STATUS
49
49
  } from '../../constants'
50
+ import { convertExcelDateToISO } from '../../utils/datetime-util'
50
51
  import { OrderInventory } from '../order-inventory/order-inventory'
51
52
  import { OrderPackage } from '../order-package/order-package'
52
53
  import { ShippingOrder } from '../shipping-order/shipping-order'
@@ -1105,6 +1106,8 @@ function _extractData(rawData, validatedData) {
1105
1106
  let errMsg
1106
1107
  let comparison = ['packingType', 'packingSize', 'uom']
1107
1108
  let data = validatedData
1109
+ raw.releaseDate = raw.releaseDate ? convertExcelDateToISO(raw.releaseDate) : null
1110
+ raw.expirationDate = raw.expirationDate ? convertExcelDateToISO(raw.expirationDate) : null
1108
1111
  if (raw.batchId) {
1109
1112
  data = data.filter(val => val.batchId === raw.batchId)
1110
1113
  comparison.push('batchId')
@@ -1176,7 +1179,8 @@ function _extractData(rawData, validatedData) {
1176
1179
  raw.productId = null
1177
1180
  }
1178
1181
 
1179
- let releaseDate = _getStdDateStr(new Date(raw.releaseDate || ''))
1182
+
1183
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/
1180
1184
 
1181
1185
  return {
1182
1186
  ...raw,
@@ -1196,17 +1200,19 @@ function _extractData(rawData, validatedData) {
1196
1200
  if (raw.assignedQty < raw.releaseQty) {
1197
1201
  errors.push('insufficient stock');
1198
1202
  }
1203
+ if(!dateRegex.test(raw.releaseDate)){
1204
+ errors.push('invalid release date format. please use dd/mm/yyyy')
1205
+ }
1199
1206
  if (raw.releaseDate === '') {
1200
1207
  errors.push('release date is empty');
1201
1208
  }
1202
- if (releaseDate < _getStdDateStr(new Date())) {
1209
+ if (raw.releaseDate < _getStdDateStr(new Date())) {
1203
1210
  errors.push('backdate is not allowed');
1204
1211
  }
1205
1212
  if (!raw.refNo || raw.refNo === '') {
1206
1213
  errors.push('ref no is empty');
1207
1214
  }
1208
-
1209
- if (raw?.type === 'b2c') {
1215
+ if (raw?.type === 'b2c') {
1210
1216
  if (!raw.attentionTo) errors.push('attention to is empty');
1211
1217
  if (!raw.postalCode) errors.push('postal code is empty');
1212
1218
  if (!raw.country) errors.push('country is empty');
@@ -1217,12 +1223,14 @@ function _extractData(rawData, validatedData) {
1217
1223
  if ((raw.codOption && !raw.paidAmount) || raw.paidAmount < 0 || raw.paidAmount == null) {
1218
1224
  errors.push('invalid paid amount');
1219
1225
  }
1226
+ if(raw?.expirationDate != null && !dateRegex.test(raw?.expirationDate)){
1227
+ errors.push('invalid expiration date format. please use dd/mm/yyyy')
1228
+ }
1220
1229
  if (raw.airwayBill && raw.lmdOption === true) {
1221
1230
  errors.push('kindly remove AWB as LMD is marked as true');
1222
1231
  }
1223
1232
  }
1224
-
1225
- return errors.length > 0 ? errors.join(', ') : ''; // Combine all errors into a single string
1233
+ return errors.length > 0 ? errors.join(', ') : ''// Combine all errors into a single string
1226
1234
  })(),
1227
1235
  };
1228
1236
 
@@ -1252,4 +1260,4 @@ function _getStdDateStr(date) {
1252
1260
  date.setHours(date.getHours() + 8)
1253
1261
  return date.toISOString().split('T')[0]
1254
1262
  }
1255
- }
1263
+ }
@@ -66,3 +66,26 @@ export class DateTimeDifference {
66
66
  return diffInSeconds
67
67
  }
68
68
  }
69
+
70
+ export function isValidExcelDate(excelSerial) {
71
+ // Check if the serial number is a valid positive number
72
+ if (isNaN(excelSerial) || excelSerial <= 0) {
73
+ return false;
74
+ }
75
+ const date = new Date((parseInt(excelSerial) - 25569) * 86400 * 1000)
76
+
77
+ return !isNaN(date.getTime());
78
+ }
79
+
80
+ export function convertExcelDateToISO(excelSerial) {
81
+ if (!isValidExcelDate(excelSerial)) {
82
+ return excelSerial; // Invalid date serial
83
+ }
84
+ const date = new Date((parseInt(excelSerial) - 25569) * 86400 * 1000)
85
+ // Format the date in YYYY-MM-DD format
86
+ const year = date.getFullYear();
87
+ const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-indexed
88
+ const day = String(date.getDate()).padStart(2, '0');
89
+
90
+ return `${year}-${month}-${day}`;
91
+ }
@@ -1,10 +1,29 @@
1
- import { EntityManager, Equal, getRepository, In, Not, Raw, Repository, SelectQueryBuilder } from 'typeorm'
1
+ import {
2
+ EntityManager,
3
+ Equal,
4
+ getRepository,
5
+ In,
6
+ Not,
7
+ Raw,
8
+ Repository,
9
+ SelectQueryBuilder
10
+ } from 'typeorm'
2
11
 
3
12
  import { User } from '@things-factory/auth-base'
4
13
  import { Bizplace } from '@things-factory/biz-base'
5
- import { Product, ProductBundle, ProductDetail } from '@things-factory/product-base'
6
- import { PartnerSetting, Setting } from '@things-factory/setting-base'
7
- import { Domain, ListParam } from '@things-factory/shell'
14
+ import {
15
+ Product,
16
+ ProductBundle,
17
+ ProductDetail
18
+ } from '@things-factory/product-base'
19
+ import {
20
+ PartnerSetting,
21
+ Setting
22
+ } from '@things-factory/setting-base'
23
+ import {
24
+ Domain,
25
+ ListParam
26
+ } from '@things-factory/shell'
8
27
  import {
9
28
  generateInventoryHistory,
10
29
  Inventory,
@@ -57,6 +76,7 @@ export const InventoryUtil = {
57
76
 
58
77
  let productFilter = filters.find(itm => itm.name == 'productName')
59
78
  let inventoryBizplaceFilter = filters.find(itm => itm.name == 'bizplaceId')
79
+ let deletedAt = filters.find(filter => filter.name == 'deleted_at')
60
80
 
61
81
  let queryStrings = `
62
82
  CREATE TEMP TABLE temp_inventory_product_group ON COMMIT DROP AS (
@@ -152,6 +172,7 @@ export const InventoryUtil = {
152
172
  `
153
173
  : ``
154
174
  }
175
+ ${deletedAt && deletedAt.value == true ? `AND pd.deleted_at isnull` : ``}
155
176
  GROUP BY
156
177
  i.lock_inventory,
157
178
  p.id,