@things-factory/sales-base 4.3.332 → 4.3.335

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.
@@ -1,9 +1,37 @@
1
- import { FileUpload, GraphQLUpload } from 'graphql-upload'
2
- import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
3
- import { EntityManager, getConnection, getRepository, In, Not, Repository } from 'typeorm'
1
+ import {
2
+ FileUpload,
3
+ GraphQLUpload
4
+ } from 'graphql-upload'
5
+ import {
6
+ Arg,
7
+ Ctx,
8
+ Directive,
9
+ Mutation,
10
+ Resolver
11
+ } from 'type-graphql'
12
+ import {
13
+ Brackets,
14
+ EntityManager,
15
+ getConnection,
16
+ getRepository,
17
+ ILike,
18
+ In,
19
+ Not,
20
+ Repository,
21
+ SelectQueryBuilder
22
+ } from 'typeorm'
4
23
 
5
- import { Attachment, createAttachments } from '@things-factory/attachment-base'
6
- import { Application, ApplicationType, Partner, Role, User } from '@things-factory/auth-base'
24
+ import {
25
+ Attachment,
26
+ createAttachments
27
+ } from '@things-factory/attachment-base'
28
+ import {
29
+ Application,
30
+ ApplicationType,
31
+ Partner,
32
+ Role,
33
+ User
34
+ } from '@things-factory/auth-base'
7
35
  import {
8
36
  Bizplace,
9
37
  getCompanyBizplace,
@@ -14,15 +42,27 @@ import {
14
42
  } from '@things-factory/biz-base'
15
43
  import { GeoCountry } from '@things-factory/geography'
16
44
  import { generateId } from '@things-factory/id-rule-base'
45
+ import { LastMileDelivery } from '@things-factory/integration-lmd'
17
46
  import { MarketplaceStore } from '@things-factory/integration-marketplace'
18
- import { Sellercraft, SellercraftStatus } from '@things-factory/integration-sellercraft'
47
+ import {
48
+ Sellercraft,
49
+ SellercraftStatus
50
+ } from '@things-factory/integration-sellercraft'
19
51
  import { MarketplaceOrder } from '@things-factory/marketplace-base'
20
52
  // import { sendNotification } from '@things-factory/notification'
21
- import { Product, ProductBundleSetting, ProductDetail } from '@things-factory/product-base'
22
- import { PartnerSetting, Setting } from '@things-factory/setting-base'
53
+ import {
54
+ ProductBundleSetting,
55
+ ProductDetail
56
+ } from '@things-factory/product-base'
57
+ import {
58
+ PartnerSetting,
59
+ Setting
60
+ } from '@things-factory/setting-base'
23
61
  import { Domain } from '@things-factory/shell'
24
- import { Inventory, ProductDetailStock } from '@things-factory/warehouse-base'
25
- import { editVas } from '../vas'
62
+ import {
63
+ Inventory,
64
+ ProductDetailStock
65
+ } from '@things-factory/warehouse-base'
26
66
 
27
67
  // import { NewOrderProduct } from '../order-product/order-product-types'
28
68
  import {
@@ -33,27 +73,40 @@ import {
33
73
  ORDER_NUMBER_SETTING_KEY,
34
74
  ORDER_PRODUCT_STATUS,
35
75
  ORDER_STATUS,
36
- ORDER_TYPES,
37
76
  ORDER_VAS_STATUS,
38
77
  PRODUCT_GROUP_TYPE
39
78
  } from '../../constants'
40
- import { EcommerceController, PowrupController, SellercraftController } from '../../controllers'
79
+ import {
80
+ EcommerceController,
81
+ PowrupController,
82
+ SellercraftController
83
+ } from '../../controllers'
41
84
  import { ValidationError } from '../../errors'
42
- import { InventoryUtil, OrderNoGenerator } from '../../utils'
85
+ import {
86
+ InventoryUtil,
87
+ OrderNoGenerator
88
+ } from '../../utils'
43
89
  import { ArrivalNotice } from '../arrival-notice/arrival-notice'
44
- import { confirmArrivalNoticeFunction, deleteArrivalNotice } from '../arrival-notice/arrival-notice-mutation'
90
+ import {
91
+ confirmArrivalNoticeFunction,
92
+ deleteArrivalNotice
93
+ } from '../arrival-notice/arrival-notice-mutation'
45
94
  import { OrderInventory } from '../order-inventory/order-inventory'
46
95
  import { OrderPackage } from '../order-package/order-package'
47
96
  import { OrderProduct } from '../order-product/order-product'
48
97
  import { OrderVasItem } from '../order-vas-item/order-vas-item'
49
98
  import { OrderVas } from '../order-vas/order-vas'
50
- import { NewReleaseGood, ReleaseGoodPatch, ShippingOrderInfoPatch } from '../release-good/release-good-types'
99
+ import { OrderVasPatch } from '../order-vas/order-vas-types'
100
+ import {
101
+ NewReleaseGood,
102
+ ReleaseGoodPatch,
103
+ ShippingOrderInfoPatch
104
+ } from '../release-good/release-good-types'
51
105
  import { ShippingOrder } from '../shipping-order/shipping-order'
52
106
  import { ShippingOrderPatch } from '../shipping-order/shipping-order-types'
53
- import { Vas } from '../vas/vas'
107
+ import { editVas } from '../vas'
54
108
  import { ReleaseGood } from './release-good'
55
109
  import { bulkReleaseGoodsAvailableItemsFunction } from './release-good-query'
56
- import { OrderVasPatch } from '../order-vas/order-vas-types'
57
110
 
58
111
  @Resolver(ReleaseGood)
59
112
  export class ReleaseGoodMutation {
@@ -203,6 +256,8 @@ export class ReleaseGoodMutation {
203
256
  async generateReleaseGood(
204
257
  @Ctx() context: any,
205
258
  @Arg('attachments', type => [GraphQLUpload], { nullable: true }) attachments?: FileUpload[],
259
+ @Arg('invoiceAttachment', type => [GraphQLUpload], { nullable: true }) invoiceAttachment?: FileUpload[],
260
+ @Arg('awbAttachment', type => [GraphQLUpload], { nullable: true }) awbAttachment?: FileUpload[],
206
261
  @Arg('releaseGood', type => NewReleaseGood, { nullable: true }) releaseGood?: NewReleaseGood,
207
262
  @Arg('orderVasPatch', type => [OrderVasPatch], { nullable: true }) orderVasPatch?: OrderVasPatch[],
208
263
  @Arg('shippingOrder', type => ShippingOrderPatch, { nullable: true }) shippingOrder?: ShippingOrderPatch,
@@ -218,7 +273,9 @@ export class ReleaseGoodMutation {
218
273
  attachments,
219
274
  context,
220
275
  tx,
221
- orderVasPatch
276
+ orderVasPatch,
277
+ invoiceAttachment,
278
+ awbAttachment
222
279
  )
223
280
 
224
281
  return createdReleaseGood
@@ -501,7 +558,9 @@ export async function generateReleaseGoodFunction(
501
558
  attachments: FileUpload[],
502
559
  context: any,
503
560
  tx?: EntityManager,
504
- orderVasPatch?: OrderVasPatch[]
561
+ orderVasPatch?: OrderVasPatch[],
562
+ invoiceAttachment?: FileUpload[],
563
+ awbAttachment?: FileUpload[]
505
564
  ): Promise<ReleaseGood> {
506
565
  try {
507
566
  const { domain, user }: { domain: Domain; user: User } = context.state
@@ -643,6 +702,19 @@ export async function generateReleaseGoodFunction(
643
702
  }
644
703
  })
645
704
 
705
+ let lmd: any = null
706
+ if (releaseGood?.lmdOption) {
707
+ const geoCountryRepo: Repository<GeoCountry> = tx?.getRepository(GeoCountry) || getRepository(GeoCountry)
708
+ let deliveryCountry: GeoCountry = releaseGood?.country
709
+ ? await geoCountryRepo.findOne({
710
+ where: [{ name: ILike(releaseGood?.country) }, { description: ILike(releaseGood?.country) }]
711
+ })
712
+ : null
713
+
714
+ //Assign LMD
715
+ lmd = await autoAssignLmd(domain, deliveryCountry?.id, releaseGood?.postalCode, bizplace)
716
+ }
717
+
646
718
  newReleaseGood = {
647
719
  ...newReleaseGood,
648
720
  name: roNoSetting
@@ -653,7 +725,7 @@ export async function generateReleaseGoodFunction(
653
725
  collectionOrderNo: releaseGood.collectionOrderNo,
654
726
  courierOption: releaseGood.courierOption,
655
727
  exportOption: releaseGood.exportOption,
656
- ownTransport: releaseGood.ownTransport,
728
+ ownTransport: releaseGood.ownTransport || false,
657
729
  packingOption: releaseGood.packingOption,
658
730
  recall: releaseGood.recall,
659
731
  marketplaceOrderStatus: releaseGood?.marketplaceOrderStatus || null,
@@ -684,6 +756,7 @@ export async function generateReleaseGoodFunction(
684
756
  : shippingOrderInfo.billingPostalCode || null,
685
757
  billingState:
686
758
  releaseGood.type == 'b2c' ? releaseGood?.billingState || null : shippingOrderInfo.billingState || null,
759
+ district: releaseGood.type == 'b2c' ? releaseGood?.city : null,
687
760
  transporter: releaseGood?.transporter,
688
761
  trackingNo: releaseGood?.trackingNo,
689
762
  airwayBill: releaseGood?.airwayBill,
@@ -708,6 +781,8 @@ export async function generateReleaseGoodFunction(
708
781
  storeId: releaseGood?.storeId,
709
782
  routeId: releaseGood?.routeId,
710
783
  stopId: releaseGood?.stopId,
784
+ lmdOption: releaseGood?.lmdOption || null,
785
+ lastMileDelivery: lmd || null,
711
786
  creator: user,
712
787
  updater: user
713
788
  }
@@ -892,10 +967,13 @@ export async function generateReleaseGoodFunction(
892
967
  }
893
968
 
894
969
  // VAS
895
- orderVasPatch = orderVasPatch.map(itm => {
896
- return { ...itm, releaseGood: newReleaseGood }
897
- })
898
- await editVas(orderVasPatch, null, context)
970
+ if (orderVasPatch) {
971
+ orderVasPatch = orderVasPatch.map(itm => {
972
+ return { ...itm, releaseGood: newReleaseGood }
973
+ })
974
+ await editVas(orderVasPatch, null, context)
975
+ }
976
+
899
977
  // if (orderVass?.length) {
900
978
  // orderVass = await Promise.all(
901
979
  // orderVass.map(async orderVas => {
@@ -938,6 +1016,28 @@ export async function generateReleaseGoodFunction(
938
1016
  await createAttachments(_, { attachments: files }, context)
939
1017
  }
940
1018
 
1019
+ if (invoiceAttachment && invoiceAttachment.length > 0) {
1020
+ const file: Attachment = {
1021
+ file: invoiceAttachment[0],
1022
+ refBy: newReleaseGood.id,
1023
+ category: ATTACHMENT_TYPE.INVOICE
1024
+ }
1025
+ const invoiceAttachmentResult = await createAttachments(_, { attachments: [file] }, context)
1026
+ await tx
1027
+ .getRepository(ReleaseGood)
1028
+ .update({ id: newReleaseGood.id }, { invoice: invoiceAttachmentResult[0].path })
1029
+ }
1030
+
1031
+ if (awbAttachment && awbAttachment.length > 0) {
1032
+ const file: Attachment = {
1033
+ file: awbAttachment[0],
1034
+ refBy: newReleaseGood.id,
1035
+ category: ATTACHMENT_TYPE.AWB
1036
+ }
1037
+ const awbAttachmentResult = await createAttachments(_, { attachments: [file] }, context)
1038
+ await tx.getRepository(ReleaseGood).update({ id: newReleaseGood.id }, { airwayBill: awbAttachmentResult[0].path })
1039
+ }
1040
+
941
1041
  const directReceiveSetting: Setting = await tx.getRepository(Setting).findOne({
942
1042
  where: { domain, category: 'id-rule', name: 'enable-direct-receive-release-order' }
943
1043
  })
@@ -1826,3 +1926,68 @@ function formRawReleaseGoods(releaseGood, errorMsg) {
1826
1926
  }
1827
1927
  return rawReleaseGoods
1828
1928
  }
1929
+
1930
+ async function autoAssignLmd(domain, countryId, postalCode, bizplace) {
1931
+ let lmdResult: LastMileDelivery
1932
+ const qb: SelectQueryBuilder<LastMileDelivery> = getRepository(LastMileDelivery)
1933
+ .createQueryBuilder('lmd')
1934
+ .leftJoinAndSelect('lmd.lastMileDeliverySettings', 'lmds')
1935
+ .innerJoinAndSelect('lmds.geoCountry', 'gc')
1936
+ .leftJoinAndSelect(`lmd.lastMileDeliveryBizplaces`, `lmdb`)
1937
+ .leftJoinAndSelect('lmdb.bizplace', 'bz')
1938
+ .where('lmd.domain_id = :domainId', { domainId: domain.id })
1939
+ .andWhere('lower(lmd.status) = :status', { status: 'active' })
1940
+ .andWhere('gc.id = :gcId', { gcId: countryId })
1941
+ .andWhere(
1942
+ new Brackets(qb => {
1943
+ qb.where(`lmds.include_postal_code = ''`)
1944
+ .orWhere('lmds.include_postal_code is null')
1945
+ .orWhere('lmds.include_postal_code like :includePostCode', { includePostCode: `%${postalCode}%` })
1946
+ })
1947
+ )
1948
+ .andWhere(
1949
+ new Brackets(qb => {
1950
+ qb.where(`lmds.exclude_postal_code = ''`)
1951
+ .orWhere('lmds.exclude_postal_code is null')
1952
+ .orWhere('lmds.exclude_postal_code not like :excludePostCode', { excludePostCode: `%${postalCode}%` })
1953
+ })
1954
+ )
1955
+ .andWhere('lmdb.bizplace_id = :bzId', { bzId: bizplace.id })
1956
+ .orderBy('lmdb.bizplace_id', 'ASC')
1957
+ .addOrderBy('lmds.include_postal_code')
1958
+ .addOrderBy('lmd.rank', 'ASC')
1959
+
1960
+ lmdResult = await qb.getOne()
1961
+
1962
+ if (!lmdResult) {
1963
+ const newQb: SelectQueryBuilder<LastMileDelivery> = getRepository(LastMileDelivery)
1964
+ .createQueryBuilder('lmd')
1965
+ .leftJoinAndSelect('lmd.lastMileDeliverySettings', 'lmds')
1966
+ .innerJoinAndSelect('lmds.geoCountry', 'gc')
1967
+ .leftJoinAndSelect(`lmd.lastMileDeliveryBizplaces`, `lmdb`)
1968
+ .leftJoinAndSelect('lmdb.bizplace', 'bz')
1969
+ .where('lmd.domain_id = :domainId', { domainId: domain.id })
1970
+ .andWhere('lower(lmd.status) = :status', { status: 'active' })
1971
+ .andWhere('gc.id = :gcId', { gcId: countryId })
1972
+ .andWhere(
1973
+ new Brackets(qb => {
1974
+ qb.where(`lmds.include_postal_code = ''`)
1975
+ .orWhere('lmds.include_postal_code is null')
1976
+ .orWhere('lmds.include_postal_code like :includePostCode', { includePostCode: `%${postalCode}%` })
1977
+ })
1978
+ )
1979
+ .andWhere(
1980
+ new Brackets(qb => {
1981
+ qb.where(`lmds.exclude_postal_code = ''`)
1982
+ .orWhere('lmds.exclude_postal_code is null')
1983
+ .orWhere('lmds.exclude_postal_code not like :excludePostCode', { excludePostCode: `%${postalCode}%` })
1984
+ })
1985
+ )
1986
+ .orderBy('lmds.include_postal_code')
1987
+ .addOrderBy('lmd.rank', 'ASC')
1988
+
1989
+ lmdResult = await newQb.getOne()
1990
+ }
1991
+
1992
+ return lmdResult
1993
+ }
@@ -1,19 +1,60 @@
1
- import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
- import { EntityManager, getRepository, In, Repository, 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
+ Repository,
16
+ SelectQueryBuilder
17
+ } from 'typeorm'
3
18
 
4
19
  import { Attachment } from '@things-factory/attachment-base'
5
- import { checkUserBelongsDomain, User } from '@things-factory/auth-base'
6
- import { Bizplace, getCompanyBizplace, getMyBizplace, getPermittedBizplaceIds } from '@things-factory/biz-base'
20
+ import {
21
+ checkUserBelongsDomain,
22
+ User
23
+ } from '@things-factory/auth-base'
24
+ import {
25
+ Bizplace,
26
+ getCompanyBizplace,
27
+ getMyBizplace,
28
+ getPermittedBizplaceIds
29
+ } from '@things-factory/biz-base'
7
30
  import { logger } from '@things-factory/env'
8
- import { buildQuery, Domain, Filter, ListParam, Pagination, Sorting } from '@things-factory/shell'
9
- import { Inventory, LOCATION_TYPE } from '@things-factory/warehouse-base'
10
-
11
- import { ATTACHMENT_TYPE, ORDER_INVENTORY_STATUS, ORDER_STATUS } from '../../constants'
31
+ import {
32
+ buildQuery,
33
+ Domain,
34
+ Filter,
35
+ ListParam,
36
+ Pagination,
37
+ Sorting
38
+ } from '@things-factory/shell'
39
+ import {
40
+ Inventory,
41
+ LOCATION_TYPE
42
+ } from '@things-factory/warehouse-base'
43
+
44
+ import {
45
+ ATTACHMENT_TYPE,
46
+ ORDER_INVENTORY_STATUS,
47
+ ORDER_STATUS
48
+ } from '../../constants'
12
49
  import { OrderInventory } from '../order-inventory/order-inventory'
13
50
  import { OrderPackage } from '../order-package/order-package'
14
51
  import { ShippingOrder } from '../shipping-order/shipping-order'
15
52
  import { ReleaseGood } from './release-good'
16
- import { NewReleaseGood, ReleasableInventoryList, ReleaseGoodList } from './release-good-types'
53
+ import {
54
+ NewReleaseGood,
55
+ ReleasableInventoryList,
56
+ ReleaseGoodList
57
+ } from './release-good-types'
17
58
 
18
59
  @Resolver(ReleaseGood)
19
60
  export class ReleaseGoodQuery {
@@ -224,6 +265,20 @@ export class ReleaseGoodQuery {
224
265
  category: ATTACHMENT_TYPE.DELIVERY_ORDER
225
266
  }
226
267
  })
268
+ const foundInvoiceAttachments: Attachment = await tx.getRepository(Attachment).findOne({
269
+ where: {
270
+ domain,
271
+ refBy: releaseGood.id,
272
+ category: ATTACHMENT_TYPE.INVOICE
273
+ }
274
+ })
275
+ const foundAwbAttachments: Attachment = await tx.getRepository(Attachment).findOne({
276
+ where: {
277
+ domain,
278
+ refBy: releaseGood.id,
279
+ category: ATTACHMENT_TYPE.AWB
280
+ }
281
+ })
227
282
 
228
283
  let invInfos = await Promise.all(
229
284
  orderInventories.map(async (orderInv: OrderInventory) => {
@@ -260,6 +315,8 @@ export class ReleaseGoodQuery {
260
315
  const result = {
261
316
  ...releaseGood,
262
317
  attachment: foundAttachments,
318
+ invoiceAttachment: foundInvoiceAttachments,
319
+ awbAttachment: foundAwbAttachments,
263
320
  shippingOrderInfo: {
264
321
  containerNo: shippingOrder?.containerNo || '',
265
322
  containerSize: shippingOrder?.containerSize || '',
@@ -298,6 +355,7 @@ export class ReleaseGoodQuery {
298
355
  const manifestedFilter = params.filters.find(param => param.name === 'manifested')
299
356
  const orderInfoFilter = params.filters.find(param => param.name === 'name')
300
357
  const typeFilter = params.filters.find(param => param.name === 'type')?.value
358
+ const lmdFilter = params.filters.find(param => param.name === 'lmdOption')
301
359
 
302
360
  if (await checkUserBelongsDomain(domain, user)) {
303
361
  if (!statusFilter && !params.filters.some(e => e.name === 'name')) {
@@ -382,6 +440,27 @@ export class ReleaseGoodQuery {
382
440
  }
383
441
  }
384
442
 
443
+ if (lmdFilter) {
444
+ const lmdIdx = params.filters.findIndex(param => param.name === 'lmdOption')
445
+ if (lmdFilter.value == true) {
446
+ params.filters.splice(lmdIdx, 1)
447
+ params.filters.push({
448
+ name: 'lmdOption',
449
+ operator: 'is_not_null',
450
+ value: null,
451
+ relation: false
452
+ })
453
+ } else {
454
+ params.filters.splice(lmdIdx, 1)
455
+ params.filters.push({
456
+ name: 'lmdOption',
457
+ operator: 'is_null',
458
+ value: null,
459
+ relation: false
460
+ })
461
+ }
462
+ }
463
+
385
464
  const fromDateParamIdx = params.filters.findIndex(param => param.name === 'fromDate')
386
465
  if (fromDateParamIdx >= 0) {
387
466
  let fromDateVal = new Date(params.filters[fromDateParamIdx].value)
@@ -1,6 +1,15 @@
1
- import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'
2
-
3
- import { Product, ProductDetail } from '@things-factory/product-base'
1
+ import {
2
+ Field,
3
+ Float,
4
+ InputType,
5
+ Int,
6
+ ObjectType
7
+ } from 'type-graphql'
8
+
9
+ import {
10
+ Product,
11
+ ProductDetail
12
+ } from '@things-factory/product-base'
4
13
  import { ObjectRef } from '@things-factory/shell'
5
14
  import { Location } from '@things-factory/warehouse-base'
6
15
 
@@ -398,6 +407,9 @@ export class NewReleaseGood {
398
407
 
399
408
  @Field({ nullable: true })
400
409
  ward: string
410
+
411
+ @Field({ nullable: true })
412
+ lmdOption: Boolean
401
413
  }
402
414
 
403
415
  @InputType()
@@ -1,4 +1,8 @@
1
- import { Field, ID, ObjectType } from 'type-graphql'
1
+ import {
2
+ Field,
3
+ ID,
4
+ ObjectType
5
+ } from 'type-graphql'
2
6
  import {
3
7
  Column,
4
8
  CreateDateColumn,
@@ -15,7 +19,10 @@ import {
15
19
 
16
20
  import { Attachment } from '@things-factory/attachment-base'
17
21
  import { User } from '@things-factory/auth-base'
18
- import { Bizplace, ContactPoint } from '@things-factory/biz-base'
22
+ import {
23
+ Bizplace,
24
+ ContactPoint
25
+ } from '@things-factory/biz-base'
19
26
  import { config } from '@things-factory/env'
20
27
  import { LastMileDelivery } from '@things-factory/integration-lmd'
21
28
  import { Domain } from '@things-factory/shell'
@@ -411,6 +418,12 @@ export class ReleaseGood {
411
418
  @Field(type => [Attachment], { nullable: true })
412
419
  attachment?: Attachment[]
413
420
 
421
+ @Field(type => Attachment, { nullable: true })
422
+ invoiceAttachment?: Attachment[]
423
+
424
+ @Field(type => Attachment, { nullable: true })
425
+ awbAttachment?: Attachment[]
426
+
414
427
  @Field(type => [InventoryInfos], { nullable: true })
415
428
  inventoryInfos?: InventoryInfos[]
416
429