@things-factory/sales-base 4.3.49 → 4.3.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/constants/order.js +2 -1
- package/dist-server/constants/order.js.map +1 -1
- package/dist-server/service/arrival-notice/arrival-notice-mutation.js +93 -21
- package/dist-server/service/arrival-notice/arrival-notice-mutation.js.map +1 -1
- package/dist-server/service/manifest/manifest-mutation.js +78 -1
- package/dist-server/service/manifest/manifest-mutation.js.map +1 -1
- package/dist-server/service/manifest/manifest-query.js +47 -12
- package/dist-server/service/manifest/manifest-query.js.map +1 -1
- package/dist-server/service/manifest/manifest-type.js +8 -0
- package/dist-server/service/manifest/manifest-type.js.map +1 -1
- package/dist-server/service/manifest/manifest.js +5 -0
- package/dist-server/service/manifest/manifest.js.map +1 -1
- package/dist-server/service/purchase-order/purchase-order-mutation.js +8 -4
- package/dist-server/service/purchase-order/purchase-order-mutation.js.map +1 -1
- package/dist-server/service/release-good/release-good-query.js +70 -58
- package/dist-server/service/release-good/release-good-query.js.map +1 -1
- package/package.json +4 -4
- package/server/constants/order.ts +2 -1
- package/server/service/arrival-notice/arrival-notice-mutation.ts +110 -22
- package/server/service/manifest/manifest-mutation.ts +78 -3
- package/server/service/manifest/manifest-query.ts +68 -18
- package/server/service/manifest/manifest-type.ts +6 -0
- package/server/service/manifest/manifest.ts +6 -2
- package/server/service/purchase-order/purchase-order-mutation.ts +10 -5
- package/server/service/release-good/release-good-query.ts +81 -65
- package/translations/en.json +4 -0
- package/translations/ko.json +6 -2
- package/translations/ms.json +5 -1
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { generateId } from '@things-factory/id-rule-base'
|
|
15
15
|
import { sendNotification } from '@things-factory/notification'
|
|
16
16
|
import { Product } from '@things-factory/product-base'
|
|
17
|
-
import { Setting } from '@things-factory/setting-base'
|
|
17
|
+
import { PartnerSetting, Setting } from '@things-factory/setting-base'
|
|
18
18
|
import { Domain } from '@things-factory/shell'
|
|
19
19
|
|
|
20
20
|
import {
|
|
@@ -66,6 +66,7 @@ export class ArrivalNoticeMutation {
|
|
|
66
66
|
const createdArrivalNotice: ArrivalNotice = await generateArrivalNoticeFunction(
|
|
67
67
|
null,
|
|
68
68
|
arrivalNotice,
|
|
69
|
+
false,
|
|
69
70
|
files,
|
|
70
71
|
context,
|
|
71
72
|
tx
|
|
@@ -198,7 +199,7 @@ export class ArrivalNoticeMutation {
|
|
|
198
199
|
@Arg('file', type => GraphQLUpload, { nullable: true }) file?: FileUpload
|
|
199
200
|
): Promise<ArrivalNotice> {
|
|
200
201
|
const { tx }: { tx: EntityManager } = context.state
|
|
201
|
-
const createdGAN: ArrivalNotice = await generateArrivalNoticeFunction(null, arrivalNotice, file, context, tx)
|
|
202
|
+
const createdGAN: ArrivalNotice = await generateArrivalNoticeFunction(null, arrivalNotice, false, file, context, tx)
|
|
202
203
|
|
|
203
204
|
debug('createdGAN', createdGAN)
|
|
204
205
|
|
|
@@ -235,15 +236,20 @@ export class ArrivalNoticeMutation {
|
|
|
235
236
|
async bulkGenerateArrivalNotices(
|
|
236
237
|
@Ctx() context: any,
|
|
237
238
|
@Arg('rawArrivalNotices', type => [NewArrivalNotice], { nullable: true }) rawArrivalNotices: NewArrivalNotice[],
|
|
238
|
-
@Arg('bizplaceId', type => String) bizplaceId: string
|
|
239
|
+
@Arg('bizplaceId', type => String) bizplaceId: string,
|
|
240
|
+
@Arg('bufferLocation', type => String, { nullable: true }) bufferLocation: string
|
|
239
241
|
): Promise<ArrivalNoticeList> {
|
|
240
242
|
const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
|
|
241
243
|
let createdArrivalNoticeIds: string[] = [],
|
|
242
244
|
createdOrderProductIds: string[] = [],
|
|
243
245
|
errorsCaught: any[] = [],
|
|
244
246
|
finalArrivalNoticeList: ArrivalNotice[] = []
|
|
247
|
+
let opStatus = ORDER_PRODUCT_STATUS.PENDING_RECEIVE
|
|
248
|
+
let anStatus = ORDER_STATUS.PENDING_RECEIVE
|
|
245
249
|
|
|
246
|
-
const foundBizplace: Bizplace = await tx
|
|
250
|
+
const foundBizplace: Bizplace = await tx
|
|
251
|
+
.getRepository(Bizplace)
|
|
252
|
+
.findOne({ where: { id: bizplaceId }, relations: ['domain'] })
|
|
247
253
|
|
|
248
254
|
if (!foundBizplace) throw new Error('company not found')
|
|
249
255
|
|
|
@@ -262,6 +268,27 @@ export class ArrivalNoticeMutation {
|
|
|
262
268
|
}
|
|
263
269
|
})
|
|
264
270
|
|
|
271
|
+
const ganProcessingSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
272
|
+
where: { domain, category: 'id-rule', name: 'gan-order-processing' }
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
const partnerGanProcessingSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
|
|
276
|
+
where: { setting: ganProcessingSetting, domain, partnerDomain: foundBizplace.domain.id }
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
// If status of GAN is PENDING_RECEIVE then directly to assign warehouse
|
|
280
|
+
if (ganProcessingSetting) {
|
|
281
|
+
let setting = !isNaN(partnerGanProcessingSetting?.value)
|
|
282
|
+
? partnerGanProcessingSetting?.value
|
|
283
|
+
: ganProcessingSetting.value
|
|
284
|
+
|
|
285
|
+
// CONFIRM to assign if setting value is 1
|
|
286
|
+
if (setting == 1) {
|
|
287
|
+
opStatus = ORDER_PRODUCT_STATUS.ARRIVED
|
|
288
|
+
anStatus = ORDER_STATUS.ARRIVED
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
265
292
|
// extract rawArrivalNotices data into normal ArrivalNotice format
|
|
266
293
|
let arrivalNotices: Partial<ArrivalNotice[]> = extractArrivalNotices(validatedArrivalNotices)
|
|
267
294
|
|
|
@@ -336,12 +363,12 @@ export class ArrivalNoticeMutation {
|
|
|
336
363
|
// update arrivalNotices status to PENDING_RECEIVE
|
|
337
364
|
await childTx
|
|
338
365
|
.getRepository(ArrivalNotice)
|
|
339
|
-
.update({ id: In(createdArrivalNoticeIds) }, { status:
|
|
366
|
+
.update({ id: In(createdArrivalNoticeIds) }, { status: anStatus, updater: user })
|
|
340
367
|
|
|
341
368
|
// update orderProducts status to PENDING_RECEIVE
|
|
342
369
|
await childTx
|
|
343
370
|
.getRepository(OrderProduct)
|
|
344
|
-
.update({ id: In(createdOrderProductIds) }, { status:
|
|
371
|
+
.update({ id: In(createdOrderProductIds) }, { status: opStatus, updater: user })
|
|
345
372
|
|
|
346
373
|
finalArrivalNoticeList = await childTx.getRepository(ArrivalNotice).find({
|
|
347
374
|
where: { id: In(createdArrivalNoticeIds) },
|
|
@@ -423,6 +450,7 @@ export async function deleteArrivalNotice(
|
|
|
423
450
|
export async function generateArrivalNoticeFunction(
|
|
424
451
|
_: any,
|
|
425
452
|
arrivalNotice: any,
|
|
453
|
+
fromPo: Boolean,
|
|
426
454
|
files: FileUpload[],
|
|
427
455
|
context: any,
|
|
428
456
|
tx?: EntityManager
|
|
@@ -474,7 +502,7 @@ export async function generateArrivalNoticeFunction(
|
|
|
474
502
|
domain,
|
|
475
503
|
bizplace: myBizplace,
|
|
476
504
|
looseItem: arrivalNotice?.looseItem ? arrivalNotice.looseItem : false,
|
|
477
|
-
status: ORDER_STATUS.PENDING,
|
|
505
|
+
status: fromPo ? ORDER_STATUS.INTRANSIT : ORDER_STATUS.PENDING,
|
|
478
506
|
creator: user,
|
|
479
507
|
updater: user
|
|
480
508
|
})
|
|
@@ -484,7 +512,7 @@ export async function generateArrivalNoticeFunction(
|
|
|
484
512
|
domain,
|
|
485
513
|
createdArrivalNotice,
|
|
486
514
|
orderProducts.map((op: OrderProduct) => {
|
|
487
|
-
return { ...op, status: ORDER_PRODUCT_STATUS.PENDING }
|
|
515
|
+
return { ...op, status: fromPo ? ORDER_PRODUCT_STATUS.INTRANSIT : ORDER_PRODUCT_STATUS.PENDING }
|
|
488
516
|
}),
|
|
489
517
|
user,
|
|
490
518
|
tx
|
|
@@ -508,7 +536,7 @@ export async function generateArrivalNoticeFunction(
|
|
|
508
536
|
vas: await tx.getRepository(Vas).findOne({ domain, id: ov.vas.id }),
|
|
509
537
|
type: ORDER_TYPES.ARRIVAL_NOTICE,
|
|
510
538
|
arrivalNotice: createdArrivalNotice,
|
|
511
|
-
status: ORDER_VAS_STATUS.PENDING,
|
|
539
|
+
status: fromPo ? ORDER_VAS_STATUS.INTRANSIT : ORDER_VAS_STATUS.PENDING,
|
|
512
540
|
creator: user,
|
|
513
541
|
updater: user
|
|
514
542
|
}
|
|
@@ -542,6 +570,7 @@ export async function confirmArrivalNoticeFunction(
|
|
|
542
570
|
where: { domain, name, status: ORDER_STATUS.PENDING },
|
|
543
571
|
relations: [
|
|
544
572
|
'bizplace',
|
|
573
|
+
'bizplace.domain',
|
|
545
574
|
'releaseGood',
|
|
546
575
|
'orderProducts',
|
|
547
576
|
'orderProducts.product',
|
|
@@ -555,25 +584,56 @@ export async function confirmArrivalNoticeFunction(
|
|
|
555
584
|
let foundOPs: OrderProduct[] = foundArrivalNotice.orderProducts
|
|
556
585
|
let foundOVs: OrderVas[] = foundArrivalNotice.orderVass
|
|
557
586
|
let customerBizplace: Bizplace = foundArrivalNotice.bizplace
|
|
587
|
+
let opStatus = ORDER_PRODUCT_STATUS.PENDING_RECEIVE
|
|
588
|
+
let anStatus = ORDER_STATUS.PENDING_RECEIVE
|
|
589
|
+
let ovStatus = ORDER_VAS_STATUS.PENDING_RECEIVE
|
|
590
|
+
let acceptedByUser = null
|
|
591
|
+
let acceptedTime = null
|
|
592
|
+
|
|
593
|
+
const ganProcessingSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
594
|
+
where: { domain, category: 'id-rule', name: 'gan-order-processing' }
|
|
595
|
+
})
|
|
596
|
+
|
|
597
|
+
const partnerGanProcessingSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
|
|
598
|
+
where: { setting: ganProcessingSetting, domain, partnerDomain: customerBizplace?.domain }
|
|
599
|
+
})
|
|
600
|
+
|
|
601
|
+
// If status of GAN is PENDING_RECEIVE then directly to assign warehouse
|
|
602
|
+
if (ganProcessingSetting) {
|
|
603
|
+
let setting = !isNaN(partnerGanProcessingSetting?.value)
|
|
604
|
+
? partnerGanProcessingSetting?.value
|
|
605
|
+
: ganProcessingSetting.value
|
|
606
|
+
|
|
607
|
+
// CONFIRM to assign if setting value is 1
|
|
608
|
+
if (setting == 1) {
|
|
609
|
+
opStatus = ORDER_PRODUCT_STATUS.ARRIVED
|
|
610
|
+
anStatus = ORDER_STATUS.ARRIVED
|
|
611
|
+
ovStatus = ORDER_VAS_STATUS.ARRIVED
|
|
612
|
+
acceptedByUser = user
|
|
613
|
+
acceptedTime = new Date()
|
|
614
|
+
}
|
|
615
|
+
}
|
|
558
616
|
|
|
559
617
|
if (!foundArrivalNotice) throw new Error(`Arrival notice doesn't exists.`)
|
|
560
618
|
|
|
561
619
|
// 1. GAN Status change (PENDING => PENDING_RECEIVE)
|
|
562
|
-
|
|
620
|
+
let arrivalNotice: ArrivalNotice = await tx.getRepository(ArrivalNotice).save({
|
|
563
621
|
...foundArrivalNotice,
|
|
564
|
-
status:
|
|
565
|
-
updater: user
|
|
622
|
+
status: anStatus,
|
|
623
|
+
updater: user,
|
|
624
|
+
acceptedBy: acceptedByUser,
|
|
625
|
+
acceptedAt: acceptedTime
|
|
566
626
|
})
|
|
567
627
|
|
|
568
628
|
foundOPs = foundOPs.map((op: OrderProduct) => {
|
|
569
|
-
return { ...op, status:
|
|
629
|
+
return { ...op, status: opStatus }
|
|
570
630
|
})
|
|
571
631
|
await tx.getRepository(OrderProduct).save(foundOPs)
|
|
572
632
|
|
|
573
633
|
// 2. Update order vas status if it exists.
|
|
574
634
|
if (foundOVs && foundOVs.length) {
|
|
575
635
|
foundOVs = foundOVs.map((ov: OrderVas) => {
|
|
576
|
-
return { ...ov, status:
|
|
636
|
+
return { ...ov, status: ovStatus }
|
|
577
637
|
})
|
|
578
638
|
|
|
579
639
|
await tx.getRepository(OrderVas).save(foundOVs)
|
|
@@ -623,22 +683,50 @@ export async function receiveArrivalNoticeFunction(_: any, name: String, context
|
|
|
623
683
|
try {
|
|
624
684
|
const foundArrivalNotice: ArrivalNotice = await tx.getRepository(ArrivalNotice).findOne({
|
|
625
685
|
where: { domain, name, status: ORDER_STATUS.PENDING_RECEIVE },
|
|
626
|
-
relations: ['bizplace', 'collectionOrders', 'orderProducts', 'orderVass']
|
|
686
|
+
relations: ['bizplace', 'bizplace.domain', 'collectionOrders', 'orderProducts', 'orderVass']
|
|
627
687
|
})
|
|
628
688
|
|
|
629
|
-
if (!foundArrivalNotice) throw new Error(`Arrival notice doesn't exists.`)
|
|
630
|
-
|
|
631
689
|
let foundOPs: OrderProduct[] = foundArrivalNotice.orderProducts
|
|
632
690
|
let foundOVs: OrderVas[] = foundArrivalNotice.orderVass
|
|
633
691
|
let foundCOs: CollectionOrder[] = await tx.getRepository(CollectionOrder).find({
|
|
634
692
|
where: { domain, refNo: foundArrivalNotice.name }
|
|
635
693
|
})
|
|
694
|
+
let customerBizplace: Bizplace = foundArrivalNotice.bizplace
|
|
695
|
+
let opStatus = ORDER_PRODUCT_STATUS.INTRANSIT
|
|
696
|
+
let anStatus = ORDER_STATUS.INTRANSIT
|
|
697
|
+
let ovStatus = ORDER_VAS_STATUS.INTRANSIT
|
|
698
|
+
let coStatus = ORDER_STATUS.READY_TO_DISPATCH
|
|
699
|
+
|
|
700
|
+
const ganProcessingSetting: Setting = await tx.getRepository(Setting).findOne({
|
|
701
|
+
where: { domain, category: 'id-rule', name: 'gan-order-processing' }
|
|
702
|
+
})
|
|
703
|
+
|
|
704
|
+
const partnerGanProcessingSetting: PartnerSetting = await tx.getRepository(PartnerSetting).findOne({
|
|
705
|
+
where: { setting: ganProcessingSetting, domain, partnerDomain: customerBizplace?.domain }
|
|
706
|
+
})
|
|
707
|
+
|
|
708
|
+
// If status of GAN is INTRANSIT then directly to assign warehouse
|
|
709
|
+
if (ganProcessingSetting) {
|
|
710
|
+
let setting = !isNaN(partnerGanProcessingSetting?.value)
|
|
711
|
+
? partnerGanProcessingSetting?.value
|
|
712
|
+
: ganProcessingSetting.value
|
|
713
|
+
|
|
714
|
+
// RECEIVE to assign if setting value is 2
|
|
715
|
+
if (setting == 2) {
|
|
716
|
+
opStatus = ORDER_PRODUCT_STATUS.ARRIVED
|
|
717
|
+
anStatus = ORDER_STATUS.ARRIVED
|
|
718
|
+
ovStatus = ORDER_VAS_STATUS.ARRIVED
|
|
719
|
+
coStatus = ORDER_STATUS.READY_TO_DISPATCH
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (!foundArrivalNotice) throw new Error(`Arrival notice doesn't exists.`)
|
|
636
724
|
|
|
637
725
|
// 1. Update status of order products (PENDING_RECEIVE => INTRANSIT)
|
|
638
726
|
foundOPs = foundOPs.map((op: OrderProduct) => {
|
|
639
727
|
return {
|
|
640
728
|
...op,
|
|
641
|
-
status:
|
|
729
|
+
status: opStatus,
|
|
642
730
|
updater: user
|
|
643
731
|
}
|
|
644
732
|
})
|
|
@@ -649,7 +737,7 @@ export async function receiveArrivalNoticeFunction(_: any, name: String, context
|
|
|
649
737
|
foundOVs = foundOVs.map((ov: OrderVas) => {
|
|
650
738
|
return {
|
|
651
739
|
...ov,
|
|
652
|
-
status:
|
|
740
|
+
status: ovStatus,
|
|
653
741
|
updater: user
|
|
654
742
|
}
|
|
655
743
|
})
|
|
@@ -661,7 +749,7 @@ export async function receiveArrivalNoticeFunction(_: any, name: String, context
|
|
|
661
749
|
foundCOs = foundCOs.map((co: CollectionOrder) => {
|
|
662
750
|
return {
|
|
663
751
|
...co,
|
|
664
|
-
status:
|
|
752
|
+
status: coStatus,
|
|
665
753
|
updater: user
|
|
666
754
|
}
|
|
667
755
|
})
|
|
@@ -686,9 +774,9 @@ export async function receiveArrivalNoticeFunction(_: any, name: String, context
|
|
|
686
774
|
}
|
|
687
775
|
|
|
688
776
|
// 4. Update status of arrival notice (PENDING_RECEIVE => INTRANSIT)
|
|
689
|
-
await tx.getRepository(ArrivalNotice).save({
|
|
777
|
+
let rcvArrivalNotice = await tx.getRepository(ArrivalNotice).save({
|
|
690
778
|
...foundArrivalNotice,
|
|
691
|
-
status:
|
|
779
|
+
status: anStatus,
|
|
692
780
|
acceptedBy: user,
|
|
693
781
|
acceptedAt: new Date(),
|
|
694
782
|
updater: user
|
|
@@ -1,13 +1,58 @@
|
|
|
1
1
|
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
2
|
-
|
|
3
|
-
import { DISPATCHMENT_STATUS } from '../../constants'
|
|
2
|
+
import { In, Not } from 'typeorm'
|
|
3
|
+
import { DISPATCHMENT_STATUS, MANIFEST_STATUS } from '../../constants'
|
|
4
4
|
import { OrderNoGenerator } from '../../utils'
|
|
5
5
|
import { ReleaseGood } from '../release-good/release-good'
|
|
6
6
|
import { Manifest, ManifestStatus } from './manifest'
|
|
7
7
|
import { ManifestPatch, NewManifest } from './manifest-type'
|
|
8
|
+
import i18next from 'i18next'
|
|
8
9
|
|
|
9
10
|
@Resolver(Manifest)
|
|
10
11
|
export class ManifestMutation {
|
|
12
|
+
@Directive('@transaction')
|
|
13
|
+
@Mutation(returns => Boolean, { description: 'To update Manifest' })
|
|
14
|
+
async updateManifest(
|
|
15
|
+
@Arg('manifestId', { nullable: true }) manifestId: string,
|
|
16
|
+
@Arg('status', { nullable: true }) status: string,
|
|
17
|
+
@Arg('shippingProvider', { nullable: true }) shippingProvider: string,
|
|
18
|
+
@Arg('removeOrders', type => [String], { nullable: true }) removeOrders: string[],
|
|
19
|
+
@Ctx() context: any
|
|
20
|
+
): Promise<boolean> {
|
|
21
|
+
const { domain, tx } = context.state
|
|
22
|
+
const ManifestRepo = tx.getRepository(Manifest)
|
|
23
|
+
//update status
|
|
24
|
+
if (status) {
|
|
25
|
+
if (status == MANIFEST_STATUS.OPEN) {
|
|
26
|
+
//check if there is only one manifest is open, if yes update it to in queue and update current to open
|
|
27
|
+
|
|
28
|
+
let foundOpenOrder = await ManifestRepo.find({
|
|
29
|
+
where: { domain, shippingProvider, status: MANIFEST_STATUS.OPEN }
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
if (foundOpenOrder.length == 1) {
|
|
33
|
+
await ManifestRepo.update({ id: foundOpenOrder[0].id }, { status: MANIFEST_STATUS.IN_QUEUE })
|
|
34
|
+
} else if (foundOpenOrder.length > 1) {
|
|
35
|
+
let manifestNames = foundOpenOrder.map(itm => itm.name)
|
|
36
|
+
throw new Error(i18next.t('error.Manifest(s) (x) already in open status', { x: manifestNames.toString() }))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await ManifestRepo.update({ id: manifestId }, { status })
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//remove orders from manifest
|
|
44
|
+
if (removeOrders?.length > 0) {
|
|
45
|
+
//check if user removing all tracking no, if yes then delete
|
|
46
|
+
let totalTrackingNo = await tx.getRepository(ReleaseGood).count({ where: { manifest: manifestId } })
|
|
47
|
+
await tx.getRepository(ReleaseGood).update({ domain, refNo: In(removeOrders) }, { manifest: null })
|
|
48
|
+
if (removeOrders.length == totalTrackingNo) {
|
|
49
|
+
await tx.getRepository(Manifest).delete(manifestId)
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true
|
|
54
|
+
}
|
|
55
|
+
|
|
11
56
|
@Directive('@transaction')
|
|
12
57
|
@Mutation(returns => Boolean, { description: 'To delete Manifest' })
|
|
13
58
|
async deleteManifest(@Arg('name') name: string, @Ctx() context: any): Promise<boolean> {
|
|
@@ -64,6 +109,36 @@ export class ManifestMutation {
|
|
|
64
109
|
return true
|
|
65
110
|
}
|
|
66
111
|
|
|
112
|
+
@Directive('@transaction')
|
|
113
|
+
@Mutation(returns => Boolean, { description: 'To add tracking no into manifest' })
|
|
114
|
+
async addTrackingNo(
|
|
115
|
+
@Arg('manifestId', { nullable: true }) manifestId: string,
|
|
116
|
+
@Arg('trackingNo', { nullable: true }) trackingNo: string,
|
|
117
|
+
@Arg('shippingProvider', { nullable: true }) shippingProvider: string,
|
|
118
|
+
@Ctx() context: any
|
|
119
|
+
): Promise<boolean> {
|
|
120
|
+
const { domain, tx } = context.state
|
|
121
|
+
const releaseGoodRepo = tx.getRepository(ReleaseGood)
|
|
122
|
+
//check if order belongs to same shipping provider
|
|
123
|
+
let foundReleaseOrder = await releaseGoodRepo.findOne({ where: { trackingNo }, relations: ['manifest'] })
|
|
124
|
+
|
|
125
|
+
if (!foundReleaseOrder) {
|
|
126
|
+
throw new Error(i18next.t('error.release_order_not_found'))
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (foundReleaseOrder.manifest) {
|
|
130
|
+
throw new Error(i18next.t('error.tracking_no_already_scanned_before'))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (foundReleaseOrder.transporter !== shippingProvider) {
|
|
134
|
+
throw new Error(i18next.t('error.tracking_no_belongs_to_x', { x: foundReleaseOrder.transporter }))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
await releaseGoodRepo.update({ id: foundReleaseOrder.id }, { manifest: manifestId })
|
|
138
|
+
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
|
|
67
142
|
@Directive('@transaction')
|
|
68
143
|
@Mutation(returns => Manifest, { description: 'To dispatch Manifest when courier service collect packages' })
|
|
69
144
|
async dispatchManifest(
|
|
@@ -74,7 +149,7 @@ export class ManifestMutation {
|
|
|
74
149
|
const { domain, user, tx } = context.state
|
|
75
150
|
|
|
76
151
|
const manifest: Manifest = await tx.getRepository(Manifest).findOne({
|
|
77
|
-
where: { domain, name, status:
|
|
152
|
+
where: { domain, name, status: Not(MANIFEST_STATUS.CLOSED) }
|
|
78
153
|
})
|
|
79
154
|
if (!manifest) throw new Error(`Unable to find ${name}`)
|
|
80
155
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
|
2
|
-
import { getRepository } from 'typeorm'
|
|
2
|
+
import { getRepository, SelectQueryBuilder } from 'typeorm'
|
|
3
3
|
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
|
5
|
-
import { convertListParams, Domain, ListParam } from '@things-factory/shell'
|
|
5
|
+
import { convertListParams, Domain, ListParam, buildQuery, Sorting } from '@things-factory/shell'
|
|
6
6
|
|
|
7
7
|
import { ReleaseGood } from '../release-good/release-good'
|
|
8
8
|
import { Manifest } from './manifest'
|
|
@@ -11,11 +11,38 @@ import { ManifestList } from './manifest-type'
|
|
|
11
11
|
@Resolver(Manifest)
|
|
12
12
|
export class ManifestQuery {
|
|
13
13
|
@Query(returns => Manifest, { description: 'To fetch a Manifest' })
|
|
14
|
-
async manifest(
|
|
14
|
+
async manifest(
|
|
15
|
+
@Arg('name') name: string,
|
|
16
|
+
@Ctx() context: any,
|
|
17
|
+
@Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
|
|
18
|
+
): Promise<Manifest> {
|
|
19
|
+
const phoneSort = sortings.findIndex(sort => sort.name === 'phone')
|
|
20
|
+
if (phoneSort >= 0) {
|
|
21
|
+
sortings[phoneSort].name = 'phone1'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const deliveryAddressSort = sortings.findIndex(sort => sort.name === 'deliveryAddress')
|
|
25
|
+
if (deliveryAddressSort >= 0) {
|
|
26
|
+
sortings[deliveryAddressSort].name = 'deliveryAddress1'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const orderRemarkSort = sortings.findIndex(sort => sort.name === 'orderRemark')
|
|
30
|
+
if (orderRemarkSort >= 0) {
|
|
31
|
+
sortings[orderRemarkSort].name = 'remark'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const orderStatusSort = sortings.findIndex(sort => sort.name === 'orderStatus')
|
|
35
|
+
if (orderStatusSort >= 0) {
|
|
36
|
+
sortings[orderStatusSort].name = 'status'
|
|
37
|
+
}
|
|
38
|
+
const convertedParams = convertListParams({ sortings })
|
|
15
39
|
const { domain, tx } = context.state
|
|
16
40
|
const manifest: Manifest = await getRepository(Manifest).findOne({ where: { domain, name } })
|
|
17
41
|
|
|
18
|
-
const releaseGoods: ReleaseGood[] = await getRepository(ReleaseGood).find({
|
|
42
|
+
const releaseGoods: ReleaseGood[] = await getRepository(ReleaseGood).find({
|
|
43
|
+
...convertedParams,
|
|
44
|
+
where: { manifest }
|
|
45
|
+
})
|
|
19
46
|
|
|
20
47
|
const trackingNos: any[] = releaseGoods.map(releaseGood => {
|
|
21
48
|
return {
|
|
@@ -26,7 +53,9 @@ export class ManifestQuery {
|
|
|
26
53
|
postalCode: releaseGood.postalCode,
|
|
27
54
|
city: releaseGood.city,
|
|
28
55
|
phone: releaseGood.phone1,
|
|
29
|
-
dispatchmentStatus: releaseGood.dispatchmentStatus
|
|
56
|
+
dispatchmentStatus: releaseGood.dispatchmentStatus,
|
|
57
|
+
orderStatus: releaseGood.status,
|
|
58
|
+
orderRemark: releaseGood.remark
|
|
30
59
|
}
|
|
31
60
|
})
|
|
32
61
|
|
|
@@ -40,6 +69,22 @@ export class ManifestQuery {
|
|
|
40
69
|
async manifests(@Args() params: ListParam, @Ctx() context: any): Promise<ManifestList> {
|
|
41
70
|
const { domain } = context.state
|
|
42
71
|
|
|
72
|
+
let orderInfoFilter
|
|
73
|
+
const orderInfoParamIdx = params.filters.findIndex(param => param.name === 'orderInfo')
|
|
74
|
+
if (orderInfoParamIdx >= 0) {
|
|
75
|
+
orderInfoFilter = params.filters[orderInfoParamIdx].value.toLowerCase().split(',').join('|')
|
|
76
|
+
|
|
77
|
+
params.filters.splice(orderInfoParamIdx, 1)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let trackingNoFilter
|
|
81
|
+
const trackingNoParamIdx = params.filters.findIndex(param => param.name === 'trackingNo')
|
|
82
|
+
if (trackingNoParamIdx >= 0) {
|
|
83
|
+
trackingNoFilter = params.filters[trackingNoParamIdx].value
|
|
84
|
+
|
|
85
|
+
params.filters.splice(trackingNoParamIdx, 1)
|
|
86
|
+
}
|
|
87
|
+
|
|
43
88
|
const fromDateParamIdx = params.filters.findIndex(param => param.name === 'fromDate')
|
|
44
89
|
if (fromDateParamIdx >= 0) {
|
|
45
90
|
let fromDateVal = new Date(params.filters[fromDateParamIdx].value)
|
|
@@ -66,19 +111,24 @@ export class ManifestQuery {
|
|
|
66
111
|
})
|
|
67
112
|
}
|
|
68
113
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
114
|
+
const qb: SelectQueryBuilder<Manifest> = getRepository(Manifest).createQueryBuilder('mf')
|
|
115
|
+
buildQuery(qb, params, context)
|
|
116
|
+
qb.innerJoin('release_goods', 'rg', 'rg.manifest_id = mf.id')
|
|
117
|
+
orderInfoFilter
|
|
118
|
+
? qb.andWhere(
|
|
119
|
+
'(rg.name ~* :orderInfoFilter or rg.ref_no ~* :orderInfoFilter or rg.ref_no_2 ~* :orderInfoFilter or rg.ref_no_3 ~* :orderInfoFilter)',
|
|
120
|
+
{ orderInfoFilter }
|
|
121
|
+
)
|
|
122
|
+
: ''
|
|
123
|
+
trackingNoFilter ? qb.andWhere('rg.tracking_no ilike :trackingNo', { trackingNo: trackingNoFilter }) : ''
|
|
124
|
+
|
|
125
|
+
const [items, total] = await qb.getManyAndCount()
|
|
126
|
+
|
|
127
|
+
await Promise.all(
|
|
128
|
+
items.map(async item => {
|
|
129
|
+
item.totalTrackingNo = await getRepository(ReleaseGood).count({ where: { manifest: item.id } })
|
|
130
|
+
})
|
|
131
|
+
)
|
|
82
132
|
return { items, total }
|
|
83
133
|
}
|
|
84
134
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Field, ID, ObjectType, registerEnumType } from 'type-graphql'
|
|
1
|
+
import { Field, ID, ObjectType, registerEnumType, Int } from 'type-graphql'
|
|
2
2
|
import {
|
|
3
3
|
Column,
|
|
4
4
|
CreateDateColumn,
|
|
@@ -21,7 +21,8 @@ const DATABASE_TYPE = ORMCONFIG.type
|
|
|
21
21
|
|
|
22
22
|
export enum ManifestStatus {
|
|
23
23
|
OPEN = 'OPEN',
|
|
24
|
-
CLOSED = 'CLOSED'
|
|
24
|
+
CLOSED = 'CLOSED',
|
|
25
|
+
IN_QUEUE = 'IN_QUEUE'
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
registerEnumType(ManifestStatus, {
|
|
@@ -80,6 +81,9 @@ export class Manifest {
|
|
|
80
81
|
@Field(type => [TrackingNo], { nullable: true })
|
|
81
82
|
trackingNos?: TrackingNo[]
|
|
82
83
|
|
|
84
|
+
@Field(type => Int, { nullable: true })
|
|
85
|
+
totalTrackingNo?: number
|
|
86
|
+
|
|
83
87
|
@CreateDateColumn()
|
|
84
88
|
@Field({ nullable: true })
|
|
85
89
|
createdAt?: Date
|
|
@@ -23,7 +23,8 @@ import {
|
|
|
23
23
|
ATTACHMENT_TYPE,
|
|
24
24
|
ORDER_NUMBER_RULE_TYPE,
|
|
25
25
|
ORDER_NUMBER_SETTING_KEY,
|
|
26
|
-
PURCHASE_ORDER_STATUS
|
|
26
|
+
PURCHASE_ORDER_STATUS,
|
|
27
|
+
ORDER_STATUS
|
|
27
28
|
} from '../../constants'
|
|
28
29
|
import { OrderNoGenerator } from '../../utils'
|
|
29
30
|
import {
|
|
@@ -109,12 +110,14 @@ export class PurchaseOrderMutation {
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
delete newGANOrder.id
|
|
113
|
+
//change gan status to intransit and call check arrived notice function right
|
|
114
|
+
newGANOrder.status = ORDER_STATUS.INTRANSIT
|
|
112
115
|
|
|
113
|
-
const createdGAN: ArrivalNotice = await generateArrivalNoticeFunction(null, newGANOrder, [], context, tx)
|
|
116
|
+
const createdGAN: ArrivalNotice = await generateArrivalNoticeFunction(null, newGANOrder, true, [], context, tx)
|
|
114
117
|
|
|
115
|
-
await confirmArrivalNoticeFunction(createdGAN.name, context, tx)
|
|
118
|
+
// await confirmArrivalNoticeFunction(createdGAN.name, context, tx)
|
|
116
119
|
|
|
117
|
-
await receiveArrivalNoticeFunction(null, createdGAN.name, context)
|
|
120
|
+
// await receiveArrivalNoticeFunction(null, createdGAN.name, context)
|
|
118
121
|
|
|
119
122
|
await checkArrivedNoticeFunction(createdGAN.name, context, tx)
|
|
120
123
|
|
|
@@ -264,7 +267,9 @@ export async function createPurchaseOrderFunction(
|
|
|
264
267
|
}
|
|
265
268
|
})
|
|
266
269
|
|
|
267
|
-
orderNo = poNoSetting
|
|
270
|
+
orderNo = poNoSetting
|
|
271
|
+
? await generateId({ domain, type: ORDER_NUMBER_RULE_TYPE.PO_NUMBER, seed: {} })
|
|
272
|
+
: OrderNoGenerator.purchaseOrder()
|
|
268
273
|
|
|
269
274
|
// // 1. Create purchase order
|
|
270
275
|
const createdPurchaseOrder: PurchaseOrder = await tx.getRepository(PurchaseOrder).save({
|