@things-factory/sales-base 4.0.11 → 4.0.16

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 (92) hide show
  1. package/dist-server/constants/order.js +9 -1
  2. package/dist-server/constants/order.js.map +1 -1
  3. package/dist-server/constants/validation-error-code.js +2 -1
  4. package/dist-server/constants/validation-error-code.js.map +1 -1
  5. package/dist-server/controllers/ecommerce/sellercraft-controller.js +3 -3
  6. package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
  7. package/dist-server/service/arrival-notice/arrival-notice-mutation.js +21 -0
  8. package/dist-server/service/arrival-notice/arrival-notice-mutation.js.map +1 -1
  9. package/dist-server/service/arrival-notice/arrival-notice-query.js +74 -77
  10. package/dist-server/service/arrival-notice/arrival-notice-query.js.map +1 -1
  11. package/dist-server/service/delivery-order/delivery-order-query.js +21 -5
  12. package/dist-server/service/delivery-order/delivery-order-query.js.map +1 -1
  13. package/dist-server/service/goods-receival-note/goods-receival-note-query.js +93 -43
  14. package/dist-server/service/goods-receival-note/goods-receival-note-query.js.map +1 -1
  15. package/dist-server/service/index.js +4 -0
  16. package/dist-server/service/index.js.map +1 -1
  17. package/dist-server/service/manifest/index.js +9 -0
  18. package/dist-server/service/manifest/index.js.map +1 -0
  19. package/dist-server/service/manifest/manifest-mutation.js +111 -0
  20. package/dist-server/service/manifest/manifest-mutation.js.map +1 -0
  21. package/dist-server/service/manifest/manifest-query.js +128 -0
  22. package/dist-server/service/manifest/manifest-query.js.map +1 -0
  23. package/dist-server/service/manifest/manifest-type.js +125 -0
  24. package/dist-server/service/manifest/manifest-type.js.map +1 -0
  25. package/dist-server/service/manifest/manifest.js +122 -0
  26. package/dist-server/service/manifest/manifest.js.map +1 -0
  27. package/dist-server/service/order-inventory/order-inventory-mutation.js +24 -0
  28. package/dist-server/service/order-inventory/order-inventory-mutation.js.map +1 -1
  29. package/dist-server/service/order-inventory/order-inventory-query.js +20 -19
  30. package/dist-server/service/order-inventory/order-inventory-query.js.map +1 -1
  31. package/dist-server/service/order-inventory/order-inventory-types.js +17 -13
  32. package/dist-server/service/order-inventory/order-inventory-types.js.map +1 -1
  33. package/dist-server/service/order-inventory/order-inventory.js +24 -2
  34. package/dist-server/service/order-inventory/order-inventory.js.map +1 -1
  35. package/dist-server/service/others/other-query.js +1 -0
  36. package/dist-server/service/others/other-query.js.map +1 -1
  37. package/dist-server/service/others/other-types.js +4 -0
  38. package/dist-server/service/others/other-types.js.map +1 -1
  39. package/dist-server/service/release-good/release-good-mutation.js +393 -1
  40. package/dist-server/service/release-good/release-good-mutation.js.map +1 -1
  41. package/dist-server/service/release-good/release-good-query.js +160 -0
  42. package/dist-server/service/release-good/release-good-query.js.map +1 -1
  43. package/dist-server/service/release-good/release-good-types.js +34 -2
  44. package/dist-server/service/release-good/release-good-types.js.map +1 -1
  45. package/dist-server/service/release-good/release-good.js +28 -1
  46. package/dist-server/service/release-good/release-good.js.map +1 -1
  47. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-mutation.js +110 -30
  48. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-mutation.js.map +1 -1
  49. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-query.js +94 -21
  50. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-query.js.map +1 -1
  51. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-type.js +144 -1
  52. package/dist-server/service/reverse-kitting-order/reverse-kitting-order-type.js.map +1 -1
  53. package/dist-server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.js +17 -7
  54. package/dist-server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.js.map +1 -1
  55. package/dist-server/utils/inventory-util.js +26 -7
  56. package/dist-server/utils/inventory-util.js.map +1 -1
  57. package/dist-server/utils/order-no-generator.js +35 -31
  58. package/dist-server/utils/order-no-generator.js.map +1 -1
  59. package/package.json +12 -12
  60. package/server/constants/index.ts +1 -1
  61. package/server/constants/order.ts +10 -0
  62. package/server/constants/validation-error-code.ts +3 -2
  63. package/server/controllers/ecommerce/sellercraft-controller.ts +4 -3
  64. package/server/service/arrival-notice/arrival-notice-mutation.ts +20 -0
  65. package/server/service/arrival-notice/arrival-notice-query.ts +82 -78
  66. package/server/service/delivery-order/delivery-order-query.ts +26 -7
  67. package/server/service/goods-receival-note/goods-receival-note-query.ts +116 -53
  68. package/server/service/index.ts +4 -0
  69. package/server/service/manifest/index.ts +6 -0
  70. package/server/service/manifest/manifest-mutation.ts +102 -0
  71. package/server/service/manifest/manifest-query.ts +99 -0
  72. package/server/service/manifest/manifest-type.ts +78 -0
  73. package/server/service/manifest/manifest.ts +103 -0
  74. package/server/service/order-inventory/order-inventory-mutation.ts +26 -1
  75. package/server/service/order-inventory/order-inventory-query.ts +17 -18
  76. package/server/service/order-inventory/order-inventory-types.ts +15 -10
  77. package/server/service/order-inventory/order-inventory.ts +24 -5
  78. package/server/service/others/other-query.ts +2 -6
  79. package/server/service/others/other-types.ts +3 -0
  80. package/server/service/release-good/release-good-mutation.ts +557 -0
  81. package/server/service/release-good/release-good-query.ts +197 -2
  82. package/server/service/release-good/release-good-types.ts +31 -7
  83. package/server/service/release-good/release-good.ts +26 -0
  84. package/server/service/reverse-kitting-order/reverse-kitting-order-mutation.ts +145 -35
  85. package/server/service/reverse-kitting-order/reverse-kitting-order-query.ts +103 -19
  86. package/server/service/reverse-kitting-order/reverse-kitting-order-type.ts +106 -1
  87. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.ts +31 -14
  88. package/server/utils/inventory-util.ts +30 -7
  89. package/server/utils/order-no-generator.ts +43 -36
  90. package/dist-server/middlewares/index.js +0 -1
  91. package/dist-server/middlewares/index.js.map +0 -1
  92. package/server/middlewares/index.ts +0 -0
@@ -38,6 +38,16 @@ export const ORDER_STATUS = {
38
38
  PARTIAL_RECEIVED: 'PARTIAL_RECEIVED'
39
39
  }
40
40
 
41
+ export const DISPATCHMENT_STATUS = {
42
+ READY_TO_DISPATCH: 'READY_TO_DISPATCH',
43
+ DISPATCHED: 'DISPATCHED'
44
+ }
45
+
46
+ export const MANIFEST_STATUS = {
47
+ OPEN: 'OPEN',
48
+ CLOSED: 'CLOSED'
49
+ }
50
+
41
51
  export const ORDER_INVENTORY_TYPE = {
42
52
  RELEASE_OF_GOODS: 'RELEASE_OF_GOODS',
43
53
  ARRIVAL_NOTICE: 'ARRIVAL_NOTICE',
@@ -1,2 +1,3 @@
1
- export const INVALID_DATA_FOUND = { errorCode: 'ivd1', message:'invalid data found'}
2
- export const RELEASE_QTY_OVER_LIMIT = { errorCode: 'rol1', message:'release qty over limit'}
1
+ export const INVALID_DATA_FOUND = { errorCode: 'ivd1', message: 'invalid data found' }
2
+ export const RELEASE_QTY_OVER_LIMIT = { errorCode: 'rol1', message: 'release qty over limit' }
3
+ export const INSUFFICIENT_STOCK = { errorCode: 'ins1', message: 'insufficient stock' }
@@ -1,5 +1,6 @@
1
1
  import { Sellercraft, SellercraftAPI } from '@things-factory/integration-sellercraft'
2
2
  import { Product } from '@things-factory/product-base'
3
+
3
4
  import { OrderProduct, ReleaseGood } from '../../service'
4
5
  import { OrderController } from '../order-controller'
5
6
 
@@ -20,7 +21,7 @@ export class SellercraftController extends OrderController {
20
21
 
21
22
  const orderInformation: any = {
22
23
  accountId: sellercraft.accountId,
23
- orderId: releaseGood.collectionOrderNo,
24
+ orderId: releaseGood.refNo2,
24
25
  sellercraftOPs
25
26
  }
26
27
  const packageId: string = await SellercraftAPI.packMarketplaceOrder(sellercraft, { ...orderInformation })
@@ -31,9 +32,9 @@ export class SellercraftController extends OrderController {
31
32
  }
32
33
 
33
34
  async checkExistingReleaseGood(sellercraft: Sellercraft, releaseGood: ReleaseGood): Promise<void> {
34
- const { refNo, collectionOrderNo } = releaseGood
35
+ const { refNo, refNo2 } = releaseGood
35
36
  const foundReleaseGood: ReleaseGood = await this.trxMgr.getRepository(ReleaseGood).findOne({
36
- where: { domain: sellercraft.domain, refNo, collectionOrderNo }
37
+ where: { domain: sellercraft.domain, refNo, refNo2 }
37
38
  })
38
39
 
39
40
  if (foundReleaseGood)
@@ -210,6 +210,26 @@ export class ArrivalNoticeMutation {
210
210
 
211
211
  return confirmedGAN
212
212
  }
213
+
214
+ @Directive('@privilege(category: "order_customer", privilege: "mutation")')
215
+ @Directive('@transaction')
216
+ @Mutation(returns => ArrivalNotice)
217
+ async updateArrivalNoticeDetails(
218
+ @Ctx() context: any,
219
+ @Arg('arrivalNotice', type => ArrivalNoticePatch) arrivalNotice: ArrivalNoticePatch
220
+ ): Promise<ArrivalNotice> {
221
+ const { domain, tx } = context.state
222
+ let existingArrivalNotice = await tx
223
+ .getRepository(ArrivalNotice)
224
+ .findOne({ where: { name: arrivalNotice.name, domain } })
225
+
226
+ if (!existingArrivalNotice) {
227
+ throw new Error('Existing Arrival Notice not found.')
228
+ }
229
+
230
+ await tx.getRepository(ArrivalNotice).update(existingArrivalNotice.id, arrivalNotice)
231
+ return await tx.getRepository(ArrivalNotice).findOne(existingArrivalNotice.id)
232
+ }
213
233
  }
214
234
 
215
235
  export async function deleteArrivalNotice(
@@ -4,10 +4,12 @@ import { getRepository, In, SelectQueryBuilder } from 'typeorm'
4
4
  import { Attachment } from '@things-factory/attachment-base'
5
5
  import { User } from '@things-factory/auth-base'
6
6
  import { Bizplace, getPermittedBizplaceIds } from '@things-factory/biz-base'
7
+ import { ProductDetail } from '@things-factory/product-base'
7
8
  import { buildQuery, Domain, ListParam } from '@things-factory/shell'
8
9
 
9
10
  import { ArrivalNoticeList } from '../'
10
11
  import { ATTACHMENT_TYPE, ORDER_STATUS } from '../../constants'
12
+ import { OrderInventory, OrderProduct } from '../../service'
11
13
  import { ArrivalNotice } from './arrival-notice'
12
14
 
13
15
  @Resolver(ArrivalNotice)
@@ -21,89 +23,93 @@ export class ArrivalNoticeQuery {
21
23
  ): Promise<ArrivalNotice> {
22
24
  const { domain, user, bizplace }: { domain: Domain; user: User; bizplace: Bizplace } = context.state
23
25
 
24
- let foundGAN: ArrivalNotice
25
-
26
- if (context?.state?.bizplace) {
27
- let param: any
28
-
29
- if (name) param = { domain, name, bizplace }
30
- else param = { domain, refNo, bizplace }
31
-
32
- foundGAN = await getRepository(ArrivalNotice).findOne({
33
- where: { ...param },
34
- relations: [
35
- 'domain',
36
- 'bizplace',
37
- 'releaseGood',
38
- 'purchaseOrder',
39
- 'purchaseOrder.bufferLocation',
40
- 'orderProducts',
41
- 'orderProducts.product',
42
- 'orderInventories',
43
- 'orderInventories.inventory',
44
- 'orderInventories.inventory.product',
45
- 'orderInventories.inventory.location',
46
- 'orderVass',
47
- 'orderVass.vas',
48
- 'orderVass.targetProduct',
49
- 'supplier',
50
- 'creator',
51
- 'updater'
52
- ]
53
- })
54
- } else {
55
- let param: any
56
-
57
- if (name) param = { domain, name, bizplace: In(await getPermittedBizplaceIds(domain, user)) }
58
- else param = { domain, refNo, bizplace: In(await getPermittedBizplaceIds(domain, user)) }
59
-
60
- foundGAN = await getRepository(ArrivalNotice).findOne({
61
- where: { ...param },
62
- relations: [
63
- 'domain',
64
- 'bizplace',
65
- 'releaseGood',
66
- 'purchaseOrder',
67
- 'purchaseOrder.bufferLocation',
68
- 'orderProducts',
69
- 'orderProducts.product',
70
- 'orderInventories',
71
- 'orderInventories.inventory',
72
- 'orderInventories.inventory.product',
73
- 'orderInventories.inventory.location',
74
- 'orderVass',
75
- 'orderVass.vas',
76
- 'orderVass.targetProduct',
77
- 'creator',
78
- 'updater'
79
- ]
80
- })
81
- }
26
+ let param: any = { domain, bizplace: bizplace ? bizplace : In(await getPermittedBizplaceIds(domain, user)) }
27
+
28
+ if (name) param = { ...param, name }
29
+ else if (refNo) param = { ...param, refNo }
30
+ else return
31
+
32
+ let foundGAN: ArrivalNotice = await getRepository(ArrivalNotice).findOne({
33
+ where: { ...param },
34
+ relations: [
35
+ 'domain',
36
+ 'bizplace',
37
+ 'releaseGood',
38
+ 'purchaseOrder',
39
+ 'purchaseOrder.bufferLocation',
40
+ 'orderProducts',
41
+ 'orderProducts.product',
42
+ 'orderInventories',
43
+ 'orderInventories.inventory',
44
+ 'orderInventories.inventory.product',
45
+ 'orderInventories.inventory.location',
46
+ 'orderVass',
47
+ 'orderVass.vas',
48
+ 'orderVass.targetProduct',
49
+ 'supplier',
50
+ 'creator',
51
+ 'updater'
52
+ ]
53
+ })
82
54
 
83
55
  if (name && !foundGAN) throw new Error(`Failed to find arrival notice with ${name}`)
84
56
 
85
- const foundAttachments: Attachment[] = await getRepository(Attachment).find({
86
- where: {
87
- domain,
88
- refBy: foundGAN?.id,
89
- category: ATTACHMENT_TYPE.GAN
90
- }
91
- })
57
+ if (foundGAN) {
58
+ const foundAttachments: Attachment[] = await getRepository(Attachment).find({
59
+ where: {
60
+ domain,
61
+ refBy: foundGAN?.id,
62
+ category: ATTACHMENT_TYPE.GAN
63
+ }
64
+ })
92
65
 
93
- const foundPOAttachments: Attachment[] = foundGAN?.purchaseOrder?.id
94
- ? await getRepository(Attachment).find({
95
- where: {
96
- domain,
97
- refBy: foundGAN.purchaseOrder?.id,
98
- category: ATTACHMENT_TYPE.PO
99
- }
66
+ const foundPOAttachments: Attachment[] = foundGAN?.purchaseOrder?.id
67
+ ? await getRepository(Attachment).find({
68
+ where: {
69
+ domain,
70
+ refBy: foundGAN.purchaseOrder?.id,
71
+ category: ATTACHMENT_TYPE.PO
72
+ }
73
+ })
74
+ : []
75
+
76
+ // add productDetails data to orderProduct.product
77
+ foundGAN.orderProducts = await Promise.all(
78
+ foundGAN.orderProducts.map(async (orderProduct: OrderProduct) => {
79
+ orderProduct.product['productDetails'] = await getRepository(ProductDetail).find({
80
+ where: {
81
+ product: orderProduct.product.id,
82
+ packingType: orderProduct.packingType,
83
+ packingSize: orderProduct.packingSize
84
+ }
85
+ })
86
+ return orderProduct
100
87
  })
101
- : []
88
+ )
102
89
 
103
- const attachments: Attachment[] = [...foundPOAttachments, ...foundAttachments]
104
- if (attachments.length) foundGAN.attachment = attachments
90
+ // add productDetails data to orderInventory.inventory.product if orderInventory is exist
91
+ if (foundGAN.orderInventories && foundGAN.orderInventories.length) {
92
+ foundGAN.orderInventories = await Promise.all(
93
+ foundGAN.orderInventories.map(async (orderInventory: OrderInventory) => {
94
+ orderInventory.inventory.product['productDetails'] = await getRepository(ProductDetail).find({
95
+ where: {
96
+ product: orderInventory.inventory.product.id,
97
+ packingType: orderInventory.inventory.packingType,
98
+ packingSize: orderInventory.inventory.packingSize
99
+ }
100
+ })
101
+ return orderInventory
102
+ })
103
+ )
104
+ }
105
105
 
106
- return foundGAN
106
+ return {
107
+ ...foundGAN,
108
+ attachment: [...foundPOAttachments, ...foundAttachments]
109
+ }
110
+ } else {
111
+ return
112
+ }
107
113
  }
108
114
 
109
115
  @Directive('@privilege(category: "order_customer", privilege: "query")')
@@ -276,8 +282,6 @@ export class ArrivalNoticeQuery {
276
282
  const [items, total] = await qb.getManyAndCount()
277
283
 
278
284
  return { items, total }
279
-
280
- return { items, total }
281
285
  } catch (error) {
282
286
  throw error
283
287
  }
@@ -86,12 +86,18 @@ export class DeliveryOrderQuery {
86
86
  })
87
87
  }
88
88
 
89
+ let refNoFilter = params.filters.find(x => x.name == 'refNo')
90
+ let refNo2Filter = params.filters.find(x => x.name == 'refNo2')
91
+ let refNo3Filter = params.filters.find(x => x.name == 'refNo3')
92
+
93
+ params.filters = params.filters.filter(x => x.name != 'refNo' && x.name != 'refNo2' && x.name != 'refNo3')
94
+
89
95
  const qb: any = getRepository(DeliveryOrder).createQueryBuilder('do')
90
96
  buildQuery(qb, params, context)
91
97
  qb.addSelect('COALESCE("cc".rank, 99999)', 'rank')
92
98
  qb.leftJoinAndSelect('do.domain', 'domain')
93
99
  qb.leftJoinAndSelect('do.bizplace', 'bizplace')
94
- qb.leftJoinAndSelect('do.releaseGood', 'rg')
100
+ qb.leftJoinAndSelect('do.releaseGood', 'releaseGood')
95
101
  qb.leftJoinAndSelect('do.transportDriver', 'td')
96
102
  qb.leftJoinAndSelect('do.transportVehicle', 'th')
97
103
  qb.leftJoinAndSelect('do.orderInventories', 'oi')
@@ -113,20 +119,33 @@ export class DeliveryOrderQuery {
113
119
  'cc.status = do.status'
114
120
  )
115
121
 
116
- const arrChildSortData = ['bizplace', 'releaseGood']
122
+ if (refNoFilter?.value) {
123
+ qb.andWhere('releaseGood.ref_no ilike :refNo', { refNo: refNoFilter.value })
124
+ }
125
+ if (refNo2Filter?.value) {
126
+ qb.andWhere('releaseGood.ref_no_2 ilike :refNo2', { refNo2: refNo2Filter.value })
127
+ }
128
+ if (refNo3Filter?.value) {
129
+ qb.andWhere('releaseGood.ref_no_3 ilike :refNo3', { refNo3: refNo3Filter.value })
130
+ }
131
+
132
+ const arrChildSortData = ['refNo', 'refNo2', 'refNo3']
133
+ const arrNameSortData = ['bizplace', 'releaseGood', 'updater']
117
134
  const sort = (params.sortings || []).reduce(
118
135
  (acc, sort) => ({
119
136
  ...acc,
120
- [arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'do.' + sort.name]: sort.desc
121
- ? 'DESC'
122
- : 'ASC'
137
+ [arrChildSortData.indexOf(sort.name) >= 0
138
+ ? 'releaseGood.' + sort.name
139
+ : arrNameSortData.indexOf(sort.name) >= 0
140
+ ? sort.name + '.name'
141
+ : 'do.' + sort.name]: sort.desc ? 'DESC' : 'ASC'
123
142
  }),
124
- !params.sortings.some(e => e.name === 'status') ? { rank: 'ASC' } : {}
143
+ params.sortings.length < 1 ? { rank: 'ASC', 'do.createdAt': 'DESC' } : {}
125
144
  )
126
145
 
127
146
  qb.orderBy(sort)
128
- const [items, total] = await qb.getManyAndCount()
129
147
 
148
+ const [items, total] = await qb.getManyAndCount()
130
149
  return { items, total }
131
150
  } catch (error) {
132
151
  debug('deliveryOrders', error.toString())
@@ -1,73 +1,136 @@
1
+ import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { getRepository, SelectQueryBuilder } from 'typeorm'
3
+
1
4
  import { User } from '@things-factory/auth-base'
2
- import { Bizplace, getPermittedBizplaceIds } from '@things-factory/biz-base'
3
- import { convertListParams, Domain, Filter, Pagination, Sorting } from '@things-factory/shell'
4
- import { Arg, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
5
- import { getRepository, In, IsNull } from 'typeorm'
6
- import { ArrivalNotice, GoodsReceivalNoteList } from '../'
5
+ import { getPermittedBizplaceIds } from '@things-factory/biz-base'
6
+ import { buildQuery, Domain, ListParam } from '@things-factory/shell'
7
+
8
+ import { GoodsReceivalNoteList } from '../'
7
9
  import { GoodsReceivalNote } from './goods-receival-note'
8
10
 
9
11
  @Resolver(GoodsReceivalNote)
10
12
  export class GoodsReceivalNoteQuery {
11
13
  @Query(returns => GoodsReceivalNoteList)
12
- async goodsReceivalNotes(
13
- @Ctx() context: any,
14
- @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
15
- @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
16
- @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: [Sorting]
17
- ): Promise<GoodsReceivalNoteList> {
14
+ async goodsReceivalNotes(@Ctx() context: any, @Args() params: ListParam): Promise<GoodsReceivalNoteList> {
18
15
  const { domain, user }: { domain: Domain; user: User } = context.state
19
16
 
20
- const convertedParams = convertListParams({ filters, pagination, sortings })
21
-
22
- const arrivalNoticeParam: any = filters.find((param: any) => param.name === 'arrivalNoticeNo')
23
- const arrivalNoticeRefNoParam = filters.find(param => param.name === 'arrivalNoticeRefNo')
17
+ const fromDateParamIdx = params.filters.findIndex(param => param.name === 'fromDate')
18
+ if (fromDateParamIdx >= 0) {
19
+ let fromDateVal = new Date(params.filters[fromDateParamIdx].value)
20
+ params.filters.splice(fromDateParamIdx, 1)
24
21
 
25
- const bizplaceParam = filters.find(param => param.name === 'bizplaceName')
26
- if (bizplaceParam) {
27
- const foundBizplaces: Bizplace[] = await getRepository(Bizplace).find({
28
- where: {
29
- ...convertListParams({ filters: [{ ...bizplaceParam, name: 'name' }] }).where
30
- }
22
+ params.filters.push({
23
+ name: 'createdAt',
24
+ operator: 'gte',
25
+ value: fromDateVal.toISOString(),
26
+ relation: false
31
27
  })
32
-
33
- // remove non-column params
34
- delete convertedParams.where.bizplaceName
35
-
36
- if (foundBizplaces && foundBizplaces.length) {
37
- convertedParams.where.bizplace = In(foundBizplaces.map((foundBizplace: Bizplace) => foundBizplace.id))
38
- } else {
39
- convertedParams.where.bizplace = IsNull()
40
- }
41
- } else {
42
- convertedParams.where.bizplace = In(await getPermittedBizplaceIds(domain, user))
43
- convertedParams.where.domain = domain
44
28
  }
45
29
 
46
- if (arrivalNoticeParam || arrivalNoticeRefNoParam) {
47
- let arrFilters = []
48
- if (arrivalNoticeParam) {
49
- arrFilters.push({ ...arrivalNoticeParam, name: 'name' })
50
- }
51
- if (arrivalNoticeRefNoParam) arrFilters.push({ ...arrivalNoticeRefNoParam, name: 'refNo' })
52
- const foundArrivalNotices: ArrivalNotice[] = await getRepository(ArrivalNotice).find({
53
- ...convertListParams({ filters: arrFilters })
30
+ const toDateParamIdx = params.filters.findIndex(param => param.name === 'toDate')
31
+ if (toDateParamIdx >= 0) {
32
+ let toDateVal = new Date(params.filters[toDateParamIdx].value)
33
+ params.filters.splice(toDateParamIdx, 1)
34
+
35
+ params.filters.push({
36
+ name: 'createdAt',
37
+ operator: 'lt',
38
+ value: new Date(toDateVal.setDate(toDateVal.getDate() + 1)).toISOString(),
39
+ relation: false
54
40
  })
41
+ }
42
+
43
+ let refNoFilter = params.filters.find(x => x.name == 'refNo')
44
+ let refNo2Filter = params.filters.find(x => x.name == 'refNo2')
45
+ let refNo3Filter = params.filters.find(x => x.name == 'refNo3')
46
+ let ganNameFilter = params.filters.find(x => x.name == 'arrivalNoticeNo')
47
+ let bizplaceFilter = params.filters.find(x => x.name == 'bizplaceName')
48
+ let ganStatusFilter = params.filters.find(x => x.name == 'ganStatus')
49
+ let grnStatusFilter = params.filters.find(x => x.name == 'grnStatus')
50
+
51
+ params.filters = params.filters.filter(
52
+ x =>
53
+ x.name != 'refNo' &&
54
+ x.name != 'refNo2' &&
55
+ x.name != 'refNo3' &&
56
+ x.name != 'arrivalNoticeNo' &&
57
+ x.name != 'bizplaceName' &&
58
+ x.name != 'ganStatus' &&
59
+ x.name != 'grnStatus'
60
+ )
55
61
 
56
- // remove non-column params
57
- delete convertedParams.where.arrivalNoticeNo
58
- delete convertedParams.where.arrivalNoticeRefNo
62
+ const qb: SelectQueryBuilder<GoodsReceivalNote> = getRepository(GoodsReceivalNote).createQueryBuilder('grn')
63
+ buildQuery(qb, params, context)
64
+ qb.addSelect('COALESCE("cc".rank, 9999)', 'rank')
65
+ qb.leftJoinAndSelect('grn.domain', 'domain')
66
+ qb.leftJoinAndSelect('grn.bizplace', 'bizplace')
67
+ qb.leftJoinAndSelect('grn.creator', 'creator')
68
+ qb.leftJoinAndSelect('grn.updater', 'updater')
69
+ qb.innerJoinAndSelect('grn.arrivalNotice', 'arrivalNotice')
70
+ qb.leftJoin(
71
+ subQuery => {
72
+ return subQuery
73
+ .select(`ccd.rank`, 'rank')
74
+ .addSelect(`ccd.name`, 'status')
75
+ .from(`common_code_details`, 'ccd')
76
+ .innerJoin(`ccd.commonCode`, 'cc')
77
+ .where(`ccd.domain_id = :domainId`, { domainId: domain.id })
78
+ .andWhere(`cc.name = 'GRN_STATUS'`)
79
+ .andWhere(`cc.name = 'GAN_REQUESTS_STATUS'`)
80
+ },
81
+ 'cc',
82
+ 'cc.status = arrivalNotice.status'
83
+ )
59
84
 
60
- if (foundArrivalNotices && foundArrivalNotices.length) {
61
- convertedParams.where.arrivalNotice = In(foundArrivalNotices.map((foundAN: ArrivalNotice) => foundAN.id))
62
- } else {
63
- convertListParams.where.arrivalNotice = IsNull()
64
- }
85
+ let permittedBizplaceIds = await getPermittedBizplaceIds(domain, user)
86
+ qb.andWhere('grn.bizplace_id IN (:...bizplaceIds)', { bizplaceIds: permittedBizplaceIds })
87
+
88
+ if (refNoFilter?.value) {
89
+ qb.andWhere('arrivalNotice.ref_no ilike :refNo', { refNo: refNoFilter.value })
90
+ }
91
+ if (refNo2Filter?.value) {
92
+ qb.andWhere('arrivalNotice.ref_no_2 ilike :refNo2', { refNo2: refNo2Filter.value })
93
+ }
94
+ if (refNo3Filter?.value) {
95
+ qb.andWhere('arrivalNotice.ref_no_3 ilike :refNo3', { refNo3: refNo3Filter.value })
96
+ }
97
+ if (ganNameFilter?.value) {
98
+ qb.andWhere('arrivalNotice.name ilike :ganName', { ganName: ganNameFilter.value })
99
+ }
100
+ if (bizplaceFilter?.value) {
101
+ qb.andWhere('bizplace.name ilike :bizName', { bizName: bizplaceFilter.value })
65
102
  }
66
103
 
67
- let [items, total] = await getRepository(GoodsReceivalNote).findAndCount({
68
- ...convertedParams,
69
- relations: ['domain', 'arrivalNotice', 'bizplace', 'creator', 'updater']
70
- })
104
+ if (ganStatusFilter?.value) {
105
+ qb.andWhere('arrivalNotice.status ilike :ganStatus', { ganStatus: ganStatusFilter.value })
106
+ }
107
+ if (grnStatusFilter?.value) {
108
+ qb.andWhere('grn.status ilike :grnStatus', { grnStatus: grnStatusFilter.value })
109
+ }
110
+
111
+ const arrChildSortData = ['refNo', 'refNo2', 'refNo3']
112
+ const arrNameSortData = ['bizplace', 'arrivalNotice', 'updater']
113
+ const arrGanStatusSortData = ['ganStatus']
114
+ const arrGrnStatuSortData = ['status']
115
+ const sort = (params.sortings || []).reduce(
116
+ (acc, sort) => ({
117
+ ...acc,
118
+ [arrChildSortData.indexOf(sort.name) >= 0
119
+ ? 'arrivalNotice.' + sort.name
120
+ : arrNameSortData.indexOf(sort.name) >= 0
121
+ ? sort.name + '.name'
122
+ : arrGanStatusSortData.indexOf(sort.name) >= 0
123
+ ? 'arrivalNotice.status'
124
+ : arrGrnStatuSortData.indexOf(sort.name) >= 0
125
+ ? 'grn.status'
126
+ : 'grn.' + sort.name]: sort.desc ? 'DESC' : 'ASC'
127
+ }),
128
+ !params.sortings.some(e => e.name === 'status') ? { rank: 'ASC' } : {}
129
+ )
130
+
131
+ qb.orderBy(sort)
132
+
133
+ const [items, total] = await qb.getManyAndCount()
71
134
 
72
135
  return { items, total }
73
136
  }
@@ -1,4 +1,5 @@
1
1
  /* IMPORT ENTITIES AND RESOLVERS */
2
+ import { entities as ManifestEntities, resolvers as ManifestResolvers } from './manifest'
2
3
  import {
3
4
  entities as ReverseKittingOrderInventoryEntities,
4
5
  resolvers as ReverseKittingOrderInventoryResolvers
@@ -38,6 +39,7 @@ import { entities as VasEntity, resolvers as VasResolvers } from './vas'
38
39
  import { entities as VasOrderEntity, resolvers as VasOrderResolvers } from './vas-order'
39
40
 
40
41
  /* EXPORT ENTITY TYPES */
42
+ export * from './manifest/manifest'
41
43
  export * from './reverse-kitting-order-inventory/reverse-kitting-order-inventory'
42
44
  export * from './reverse-kitting-order/reverse-kitting-order'
43
45
  export * from './arrival-notice/arrival-notice'
@@ -139,6 +141,7 @@ export * from './vas/vas-query'
139
141
 
140
142
  export const entities = [
141
143
  /* ENTITIES */
144
+ ...ManifestEntities,
142
145
  ...ReverseKittingOrderInventoryEntities,
143
146
  ...ReverseKittingOrderEntities,
144
147
  ...ArrivalNoticeEntity,
@@ -168,6 +171,7 @@ export const entities = [
168
171
  export const schema = {
169
172
  resolverClasses: [
170
173
  /* RESOLVER CLASSES */
174
+ ...ManifestResolvers,
171
175
  ...ReverseKittingOrderInventoryResolvers,
172
176
  ...ReverseKittingOrderResolvers,
173
177
  ...ArrivalNoticeResolvers,
@@ -0,0 +1,6 @@
1
+ import { Manifest } from './manifest'
2
+ import { ManifestQuery } from './manifest-query'
3
+ import { ManifestMutation } from './manifest-mutation'
4
+
5
+ export const entities = [Manifest]
6
+ export const resolvers = [ManifestQuery, ManifestMutation]
@@ -0,0 +1,102 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { DISPATCHMENT_STATUS } from '../../constants'
4
+ import { OrderNoGenerator } from '../../utils'
5
+ import { ReleaseGood } from '../release-good/release-good'
6
+ import { Manifest, ManifestStatus } from './manifest'
7
+ import { ManifestPatch, NewManifest } from './manifest-type'
8
+
9
+ @Resolver(Manifest)
10
+ export class ManifestMutation {
11
+ @Directive('@transaction')
12
+ @Mutation(returns => Boolean, { description: 'To delete Manifest' })
13
+ async deleteManifest(@Arg('name') name: string, @Ctx() context: any): Promise<boolean> {
14
+ const { domain, tx } = context.state
15
+
16
+ await tx.getRepository(Manifest).delete({ domain, name })
17
+ return true
18
+ }
19
+
20
+ @Directive('@transaction')
21
+ @Mutation(returns => Boolean, { description: 'To generate new Manifest' })
22
+ async generateManifest(@Arg('manifest') manifest: NewManifest, @Ctx() context: any): Promise<boolean> {
23
+ const { domain, user, tx } = context.state
24
+ const manifestItems: any[] = manifest.manifestItems
25
+
26
+ // regroup array of object by transporter
27
+ let shippingProviderGrouping: any = manifestItems.reduce((a, b) => {
28
+ a[b.transporter] = [...(a[b.transporter] || []), b]
29
+ return a
30
+ }, {})
31
+
32
+ for (const transporter in shippingProviderGrouping) {
33
+ const items: any[] = shippingProviderGrouping[transporter]
34
+
35
+ const openManifest: Manifest = await tx
36
+ .getRepository(Manifest)
37
+ .findOne({ domain, shippingProvider: transporter, status: ManifestStatus.OPEN })
38
+
39
+ let manifest: Manifest
40
+
41
+ if (openManifest) {
42
+ manifest = openManifest
43
+ } else {
44
+ manifest = new Manifest()
45
+ manifest.domain = domain
46
+ manifest.shippingProvider = transporter
47
+ manifest.name = OrderNoGenerator.manifest()
48
+ manifest.creator = user
49
+ manifest = await tx.getRepository(Manifest).save(manifest)
50
+ }
51
+
52
+ await Promise.all(
53
+ items.map(async item => {
54
+ let releaseOrder: ReleaseGood = await tx
55
+ .getRepository(ReleaseGood)
56
+ .findOne({ domain, refNo: item.refNo, trackingNo: item.trackingNo })
57
+ releaseOrder.manifest = manifest
58
+ releaseOrder.updater = user
59
+ await tx.getRepository(ReleaseGood).save(releaseOrder)
60
+ })
61
+ )
62
+ }
63
+
64
+ return true
65
+ }
66
+
67
+ @Directive('@transaction')
68
+ @Mutation(returns => Manifest, { description: 'To dispatch Manifest when courier service collect packages' })
69
+ async dispatchManifest(
70
+ @Arg('name') name: string,
71
+ @Arg('patch') patch: ManifestPatch,
72
+ @Ctx() context: any
73
+ ): Promise<Manifest> {
74
+ const { domain, user, tx } = context.state
75
+
76
+ const manifest: Manifest = await tx.getRepository(Manifest).findOne({
77
+ where: { domain, name, status: ManifestStatus.OPEN }
78
+ })
79
+ if (!manifest) throw new Error(`Unable to find ${name}`)
80
+
81
+ let releaseGoods: any[] = await tx.getRepository(ReleaseGood).find({ where: { domain, manifest } })
82
+
83
+ releaseGoods = await Promise.all(
84
+ releaseGoods.map((releaseGood: ReleaseGood) => {
85
+ return {
86
+ ...releaseGood,
87
+ dispatchmentStatus: DISPATCHMENT_STATUS.DISPATCHED,
88
+ updater: user
89
+ }
90
+ })
91
+ )
92
+ await tx.getRepository(ReleaseGood).save(releaseGoods)
93
+
94
+ return await tx.getRepository(Manifest).save({
95
+ ...manifest,
96
+ ...patch,
97
+ status: ManifestStatus.CLOSED,
98
+ dispatchedAt: new Date(),
99
+ updater: user
100
+ })
101
+ }
102
+ }