@things-factory/sales-base 8.0.0-beta.9 → 8.0.1

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 (178) hide show
  1. package/dist-server/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +13 -13
  3. package/server/constants/attachment-type.ts +9 -0
  4. package/server/constants/index.ts +7 -0
  5. package/server/constants/load-type.ts +4 -0
  6. package/server/constants/order.ts +203 -0
  7. package/server/constants/product-group-type.ts +4 -0
  8. package/server/constants/release-good.ts +9 -0
  9. package/server/constants/transfer-order-type.ts +6 -0
  10. package/server/constants/validation-error-code.ts +3 -0
  11. package/server/constants/vas-target-type.ts +25 -0
  12. package/server/controllers/ecommerce/ecommerce-controller.ts +122 -0
  13. package/server/controllers/ecommerce/index.ts +2 -0
  14. package/server/controllers/ecommerce/sellercraft-controller.ts +182 -0
  15. package/server/controllers/index.ts +2 -0
  16. package/server/controllers/order-controller.ts +296 -0
  17. package/server/errors/index.ts +1 -0
  18. package/server/errors/validation-error.ts +25 -0
  19. package/server/index.ts +5 -0
  20. package/server/migrations/index.ts +9 -0
  21. package/server/service/arrival-notice/arrival-notice-mutation.ts +1152 -0
  22. package/server/service/arrival-notice/arrival-notice-query.ts +549 -0
  23. package/server/service/arrival-notice/arrival-notice-types.ts +310 -0
  24. package/server/service/arrival-notice/arrival-notice.ts +202 -0
  25. package/server/service/arrival-notice/index.ts +9 -0
  26. package/server/service/claim/claim-mutation.ts +308 -0
  27. package/server/service/claim/claim-query.ts +122 -0
  28. package/server/service/claim/claim-types.ts +130 -0
  29. package/server/service/claim/claim.ts +140 -0
  30. package/server/service/claim/index.ts +9 -0
  31. package/server/service/claim-detail/claim-detail-mutation.ts +102 -0
  32. package/server/service/claim-detail/claim-detail-query.ts +55 -0
  33. package/server/service/claim-detail/claim-detail-types.ts +47 -0
  34. package/server/service/claim-detail/claim-detail.ts +69 -0
  35. package/server/service/claim-detail/index.ts +9 -0
  36. package/server/service/claim-order/claim-order-mutation.ts +101 -0
  37. package/server/service/claim-order/claim-order-query.ts +47 -0
  38. package/server/service/claim-order/claim-order-types.ts +35 -0
  39. package/server/service/claim-order/claim-order.ts +81 -0
  40. package/server/service/claim-order/index.ts +9 -0
  41. package/server/service/collection-order/collection-order-mutation.ts +245 -0
  42. package/server/service/collection-order/collection-order-query.ts +97 -0
  43. package/server/service/collection-order/collection-order-types.ts +165 -0
  44. package/server/service/collection-order/collection-order.ts +135 -0
  45. package/server/service/collection-order/index.ts +9 -0
  46. package/server/service/delivery-order/delivery-order-mutation.ts +967 -0
  47. package/server/service/delivery-order/delivery-order-query.ts +631 -0
  48. package/server/service/delivery-order/delivery-order-types.ts +268 -0
  49. package/server/service/delivery-order/delivery-order.ts +258 -0
  50. package/server/service/delivery-order/index.ts +9 -0
  51. package/server/service/draft-release-good/draft-release-good-mutation.ts +765 -0
  52. package/server/service/draft-release-good/draft-release-good-query.ts +354 -0
  53. package/server/service/draft-release-good/draft-release-good-type.ts +261 -0
  54. package/server/service/draft-release-good/draft-release-good.ts +284 -0
  55. package/server/service/draft-release-good/index.ts +9 -0
  56. package/server/service/goods-receival-note/goods-receival-note-mutation.ts +129 -0
  57. package/server/service/goods-receival-note/goods-receival-note-query.ts +280 -0
  58. package/server/service/goods-receival-note/goods-receival-note-types.ts +105 -0
  59. package/server/service/goods-receival-note/goods-receival-note.ts +127 -0
  60. package/server/service/goods-receival-note/index.ts +9 -0
  61. package/server/service/index.ts +238 -0
  62. package/server/service/inventory-check/index.ts +9 -0
  63. package/server/service/inventory-check/inventory-check-mutation.ts +149 -0
  64. package/server/service/inventory-check/inventory-check-query.ts +48 -0
  65. package/server/service/inventory-check/inventory-check-types.ts +48 -0
  66. package/server/service/inventory-check/inventory-check.ts +90 -0
  67. package/server/service/invoice/index.ts +9 -0
  68. package/server/service/invoice/invoice-mutation.ts +95 -0
  69. package/server/service/invoice/invoice-query.ts +53 -0
  70. package/server/service/invoice/invoice-types.ts +279 -0
  71. package/server/service/invoice/invoice.ts +230 -0
  72. package/server/service/invoice-product/index.ts +9 -0
  73. package/server/service/invoice-product/invoice-product-mutation.ts +54 -0
  74. package/server/service/invoice-product/invoice-product-query.ts +54 -0
  75. package/server/service/invoice-product/invoice-product-types.ts +84 -0
  76. package/server/service/invoice-product/invoice-product.ts +92 -0
  77. package/server/service/job-sheet/index.ts +9 -0
  78. package/server/service/job-sheet/job-sheet-mutation.ts +92 -0
  79. package/server/service/job-sheet/job-sheet-query.ts +112 -0
  80. package/server/service/job-sheet/job-sheet-types.ts +78 -0
  81. package/server/service/job-sheet/job-sheet.ts +102 -0
  82. package/server/service/manifest/index.ts +6 -0
  83. package/server/service/manifest/manifest-mutation.ts +190 -0
  84. package/server/service/manifest/manifest-query.ts +149 -0
  85. package/server/service/manifest/manifest-type.ts +84 -0
  86. package/server/service/manifest/manifest.ts +114 -0
  87. package/server/service/order-inventory/index.ts +9 -0
  88. package/server/service/order-inventory/order-inventory-mutation.ts +54 -0
  89. package/server/service/order-inventory/order-inventory-query.ts +722 -0
  90. package/server/service/order-inventory/order-inventory-types.ts +238 -0
  91. package/server/service/order-inventory/order-inventory.ts +401 -0
  92. package/server/service/order-product/index.ts +9 -0
  93. package/server/service/order-product/order-product-mutation.ts +48 -0
  94. package/server/service/order-product/order-product-query.ts +89 -0
  95. package/server/service/order-product/order-product-types.ts +335 -0
  96. package/server/service/order-product/order-product.ts +362 -0
  97. package/server/service/order-tote/index.ts +9 -0
  98. package/server/service/order-tote/order-tote-mutation.ts +31 -0
  99. package/server/service/order-tote/order-tote-query.ts +112 -0
  100. package/server/service/order-tote/order-tote-types.ts +47 -0
  101. package/server/service/order-tote/order-tote.ts +73 -0
  102. package/server/service/order-tote-item/index.ts +9 -0
  103. package/server/service/order-tote-item/order-tote-item-mutation.ts +31 -0
  104. package/server/service/order-tote-item/order-tote-item-query.ts +82 -0
  105. package/server/service/order-tote-item/order-tote-item-types.ts +56 -0
  106. package/server/service/order-tote-item/order-tote-item.ts +72 -0
  107. package/server/service/order-tote-seal/index.ts +9 -0
  108. package/server/service/order-tote-seal/order-tote-seal-mutation.ts +31 -0
  109. package/server/service/order-tote-seal/order-tote-seal-query.ts +59 -0
  110. package/server/service/order-tote-seal/order-tote-seal-types.ts +41 -0
  111. package/server/service/order-tote-seal/order-tote-seal.ts +46 -0
  112. package/server/service/order-vas/index.ts +9 -0
  113. package/server/service/order-vas/order-vas-mutation.ts +20 -0
  114. package/server/service/order-vas/order-vas-query.ts +72 -0
  115. package/server/service/order-vas/order-vas-types.ts +159 -0
  116. package/server/service/order-vas/order-vas.ts +207 -0
  117. package/server/service/others/index.ts +5 -0
  118. package/server/service/others/other-query.ts +563 -0
  119. package/server/service/others/other-types.ts +115 -0
  120. package/server/service/purchase-order/index.ts +9 -0
  121. package/server/service/purchase-order/purchase-order-mutation.ts +458 -0
  122. package/server/service/purchase-order/purchase-order-query.ts +90 -0
  123. package/server/service/purchase-order/purchase-order-types.ts +154 -0
  124. package/server/service/purchase-order/purchase-order.ts +172 -0
  125. package/server/service/purchase-order-other-charge/index.ts +9 -0
  126. package/server/service/purchase-order-other-charge/purchase-order-other-charge-mutation.ts +31 -0
  127. package/server/service/purchase-order-other-charge/purchase-order-other-charge-query.ts +52 -0
  128. package/server/service/purchase-order-other-charge/purchase-order-other-charge-types.ts +44 -0
  129. package/server/service/purchase-order-other-charge/purchase-order-other-charge.ts +68 -0
  130. package/server/service/release-good/index.ts +9 -0
  131. package/server/service/release-good/release-good-mutation.ts +1686 -0
  132. package/server/service/release-good/release-good-query.ts +980 -0
  133. package/server/service/release-good/release-good-types.ts +662 -0
  134. package/server/service/release-good/release-good.ts +490 -0
  135. package/server/service/retail-replenishment-order/index.ts +9 -0
  136. package/server/service/retail-replenishment-order/retail-replenishment-order-mutation.ts +382 -0
  137. package/server/service/retail-replenishment-order/retail-replenishment-order-query.ts +54 -0
  138. package/server/service/retail-replenishment-order/retail-replenishment-order-types.ts +101 -0
  139. package/server/service/retail-replenishment-order/retail-replenishment-order.ts +115 -0
  140. package/server/service/return-order/index.ts +9 -0
  141. package/server/service/return-order/return-order-mutation.ts +516 -0
  142. package/server/service/return-order/return-order-query.ts +226 -0
  143. package/server/service/return-order/return-order-types.ts +196 -0
  144. package/server/service/return-order/return-order.ts +127 -0
  145. package/server/service/reverse-kitting-order/index.ts +9 -0
  146. package/server/service/reverse-kitting-order/reverse-kitting-order-mutation.ts +500 -0
  147. package/server/service/reverse-kitting-order/reverse-kitting-order-query.ts +197 -0
  148. package/server/service/reverse-kitting-order/reverse-kitting-order-type.ts +173 -0
  149. package/server/service/reverse-kitting-order/reverse-kitting-order.ts +121 -0
  150. package/server/service/reverse-kitting-order-inventory/index.ts +9 -0
  151. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-mutation.ts +129 -0
  152. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-query.ts +52 -0
  153. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory-type.ts +95 -0
  154. package/server/service/reverse-kitting-order-inventory/reverse-kitting-order-inventory.ts +143 -0
  155. package/server/service/shipping-order/index.ts +9 -0
  156. package/server/service/shipping-order/shipping-order-mutation.ts +61 -0
  157. package/server/service/shipping-order/shipping-order-query.ts +61 -0
  158. package/server/service/shipping-order/shipping-order-types.ts +89 -0
  159. package/server/service/shipping-order/shipping-order.ts +129 -0
  160. package/server/service/transfer-order/index.ts +9 -0
  161. package/server/service/transfer-order/transfer-order-mutation.ts +309 -0
  162. package/server/service/transfer-order/transfer-order-query.ts +66 -0
  163. package/server/service/transfer-order/transfer-order-types.ts +97 -0
  164. package/server/service/transfer-order/transfer-order.ts +117 -0
  165. package/server/service/vas/index.ts +9 -0
  166. package/server/service/vas/vas-mutation.ts +106 -0
  167. package/server/service/vas/vas-query.ts +60 -0
  168. package/server/service/vas/vas-types.ts +71 -0
  169. package/server/service/vas/vas.ts +77 -0
  170. package/server/service/vas-order/index.ts +9 -0
  171. package/server/service/vas-order/vas-order-mutation.ts +259 -0
  172. package/server/service/vas-order/vas-order-query.ts +119 -0
  173. package/server/service/vas-order/vas-order-types.ts +49 -0
  174. package/server/service/vas-order/vas-order.ts +81 -0
  175. package/server/utils/datetime-util.ts +54 -0
  176. package/server/utils/index.ts +3 -0
  177. package/server/utils/inventory-util.ts +1155 -0
  178. package/server/utils/order-no-generator.ts +146 -0
@@ -0,0 +1,60 @@
1
+ import { Arg, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { SelectQueryBuilder } from 'typeorm'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import { buildQuery, Domain, Filter, getRepository, Pagination, Sorting } from '@things-factory/shell'
6
+
7
+ import { VasList } from '../'
8
+ import { Vas } from './vas'
9
+
10
+ @Resolver(Vas)
11
+ export class VasQuery {
12
+ @Directive('@privilege(category: "vas", privilege: "query", domainOwnerGranted: true)')
13
+ @Query(returns => VasList)
14
+ async vass(
15
+ @Ctx() context: ResolverContext,
16
+ @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
17
+ @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
18
+ @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
19
+ ): Promise<VasList> {
20
+ const qb: SelectQueryBuilder<Vas> = getRepository(Vas).createQueryBuilder()
21
+ buildQuery(qb, { filters, pagination, sortings }, context)
22
+
23
+ const [items, total] = await qb
24
+ .leftJoinAndSelect('Vas.domain', 'Domain')
25
+ .leftJoinAndSelect('Vas.creator', 'Creator')
26
+ .leftJoinAndSelect('Vas.updater', 'Updater')
27
+ .getManyAndCount()
28
+
29
+ return { items, total }
30
+ }
31
+
32
+ @Directive('@privilege(category: "vas", privilege: "query") ')
33
+ @Query(returns => Vas)
34
+ async vas(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Vas> {
35
+ const { domain } = context.state
36
+
37
+ return await getRepository(Vas).findOne({
38
+ where: {
39
+ domain: { id: domain.id },
40
+ name
41
+ },
42
+ relations: ['domain', 'creator', 'updater']
43
+ })
44
+ }
45
+
46
+ @FieldResolver(type => Domain)
47
+ async domain(@Root() vas: Vas): Promise<Domain> {
48
+ return await getRepository(Domain).findOneBy({ id: vas.domainId })
49
+ }
50
+
51
+ @FieldResolver(type => User)
52
+ async creator(@Root() vas: Vas): Promise<User> {
53
+ return await getRepository(User).findOneBy({ id: vas.creatorId })
54
+ }
55
+
56
+ @FieldResolver(type => User)
57
+ async updater(@Root() vas: Vas): Promise<User> {
58
+ return await getRepository(User).findOneBy({ id: vas.updaterId })
59
+ }
60
+ }
@@ -0,0 +1,71 @@
1
+ import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'
2
+ import { Vas } from './vas'
3
+
4
+ @ObjectType()
5
+ export class VasList {
6
+ @Field(type => [Vas], { nullable: true })
7
+ items: Vas[]
8
+
9
+ @Field(type => Int, { nullable: true })
10
+ total: number
11
+ }
12
+
13
+ @InputType()
14
+ export class NewVas {
15
+ @Field()
16
+ name: string
17
+
18
+ @Field({ nullable: true })
19
+ description: string
20
+
21
+ @Field(type => Float)
22
+ defaultPrice: number
23
+
24
+ @Field({ nullable: true })
25
+ currency: string
26
+
27
+ @Field({ nullable: true })
28
+ uom: string
29
+
30
+ @Field({ nullable: true })
31
+ type: string
32
+
33
+ @Field({ nullable: true })
34
+ operationGuideType: string
35
+
36
+ @Field({ nullable: true })
37
+ operationGuide: string
38
+ }
39
+
40
+ @InputType()
41
+ export class VasPatch {
42
+ @Field({ nullable: true })
43
+ id: string
44
+
45
+ @Field({ nullable: true })
46
+ name: string
47
+
48
+ @Field({ nullable: true })
49
+ description: string
50
+
51
+ @Field({ nullable: true })
52
+ uom: string
53
+
54
+ @Field({ nullable: true })
55
+ type: string
56
+
57
+ @Field({ nullable: true })
58
+ currency: string
59
+
60
+ @Field(type => Float, { nullable: true })
61
+ defaultPrice: number
62
+
63
+ @Field({ nullable: true })
64
+ operationGuideType: string
65
+
66
+ @Field({ nullable: true })
67
+ operationGuide: string
68
+
69
+ @Field({ nullable: true })
70
+ cuFlag: string
71
+ }
@@ -0,0 +1,77 @@
1
+ import { User } from '@things-factory/auth-base'
2
+ import { Domain, roundTransformer } from '@things-factory/shell'
3
+ import { Field, ID, ObjectType } from 'type-graphql'
4
+ import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
5
+
6
+ @Entity('vass')
7
+ @Index('ix_vas_0', (vas: Vas) => [vas.domain, vas.name], { unique: true })
8
+ @ObjectType()
9
+ export class Vas {
10
+ @PrimaryGeneratedColumn('uuid')
11
+ @Field(type => ID)
12
+ readonly id: string
13
+
14
+ @ManyToOne(type => Domain)
15
+ @Field(type => Domain, { nullable: true })
16
+ domain: Domain
17
+
18
+ @RelationId((vas: Vas) => vas.domain)
19
+ domainId: string
20
+
21
+ @Column()
22
+ @Field()
23
+ name: string
24
+
25
+ @Column({ nullable: true })
26
+ @Field({ nullable: true })
27
+ description: string
28
+
29
+ @Column()
30
+ @Field()
31
+ currency: string
32
+
33
+ @Column({ nullable: true })
34
+ @Field({ nullable: true })
35
+ uom: string
36
+
37
+ @Column({ nullable: true })
38
+ @Field({ nullable: true })
39
+ type: string
40
+
41
+ @Column('float', { transformer: roundTransformer })
42
+ @Field()
43
+ defaultPrice: number
44
+
45
+ @Column({ nullable: true })
46
+ @Field({ nullable: true })
47
+ operationGuideType: string
48
+
49
+ @Column({ nullable: true })
50
+ @Field({ nullable: true })
51
+ operationGuide: string
52
+
53
+ @CreateDateColumn()
54
+ @Field()
55
+ createdAt: Date
56
+
57
+ @UpdateDateColumn()
58
+ @Field()
59
+ updatedAt: Date
60
+
61
+ @ManyToOne(type => User)
62
+ @Field(type => User, { nullable: true })
63
+ creator: User
64
+
65
+ @RelationId((vas: Vas) => vas.creator)
66
+ creatorId: string
67
+
68
+ @ManyToOne(type => User)
69
+ @Field(type => User, { nullable: true })
70
+ updater: User
71
+
72
+ @RelationId((vas: Vas) => vas.updater)
73
+ updaterId: string
74
+
75
+ @Field({ nullable: true })
76
+ cuFlag: string
77
+ }
@@ -0,0 +1,9 @@
1
+ import { VasOrder } from './vas-order'
2
+ import { VasOrderMutation } from './vas-order-mutation'
3
+ import { VasOrderQuery } from './vas-order-query'
4
+
5
+ export const entities = [VasOrder]
6
+ export const resolvers = [VasOrderQuery, VasOrderMutation]
7
+
8
+ export * from './vas-order-mutation'
9
+ export * from './vas-order-query'
@@ -0,0 +1,259 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { Role } from '@things-factory/auth-base'
5
+ import { Bizplace } from '@things-factory/biz-base'
6
+ import { Product } from '@things-factory/product-base'
7
+
8
+ import { NewOrderVas, NewVasOrder, OrderVas, Vas, VasOrderPatch } from '../'
9
+ import { ORDER_STATUS, ORDER_TYPES, ORDER_VAS_STATUS } from '../../constants'
10
+ import { OrderNoGenerator } from '../../utils'
11
+ import { VasOrder } from './vas-order'
12
+
13
+ @Resolver(VasOrder)
14
+ export class VasOrderMutation {
15
+ @Directive('@transaction')
16
+ @Mutation(returns => Boolean)
17
+ async deleteVasOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<boolean> {
18
+ const { tx, domain } = context.state
19
+
20
+ let foundVasOrder: VasOrder = await tx.getRepository(VasOrder).findOne({
21
+ where: { domain: { id: domain.id }, name },
22
+ relations: ['orderVass', 'creator', 'updater']
23
+ })
24
+
25
+ if (!foundVasOrder) throw new Error(`Vas order doesn't exists.`)
26
+ const foundOVs: OrderVas[] = foundVasOrder.orderVass
27
+
28
+ // 1. delete order vass
29
+ const vasIds = foundOVs.map((vas: OrderVas) => vas.id)
30
+ if (vasIds.length) {
31
+ await tx.getRepository(OrderVas).delete({ id: In(vasIds) })
32
+ }
33
+
34
+ await tx.getRepository(VasOrder).delete({ domain: { id: domain.id }, name })
35
+ return true
36
+ }
37
+
38
+ @Directive('@transaction')
39
+ @Mutation(returns => Boolean)
40
+ async deleteVasOrders(
41
+ @Arg('names', type => [String]) names: string[],
42
+ @Ctx() context: ResolverContext
43
+ ): Promise<boolean> {
44
+ const { tx, domain } = context.state
45
+
46
+ await tx.getRepository(VasOrder).delete({
47
+ domain: { id: domain.id },
48
+ name: In(names)
49
+ })
50
+ return true
51
+ }
52
+
53
+ @Directive('@transaction')
54
+ @Mutation(returns => VasOrder)
55
+ async generateVasOrder(
56
+ @Arg('vasOrder', type => NewVasOrder) vasOrder: NewVasOrder,
57
+ @Ctx() context: ResolverContext
58
+ ): Promise<VasOrder> {
59
+ const { tx, domain, user } = context.state
60
+
61
+ const customerBizplace: Bizplace = await tx.getRepository(Bizplace).findOne({
62
+ where: {
63
+ id: vasOrder.customerBizplaceId
64
+ }
65
+ })
66
+
67
+ if (!customerBizplace) throw new Error('company is not found')
68
+
69
+ let orderVass: NewOrderVas[] = vasOrder.orderVass
70
+
71
+ // 1. Create vas order
72
+ const createdVasOrder: VasOrder = await tx.getRepository(VasOrder).save({
73
+ ...vasOrder,
74
+ name: OrderNoGenerator.vasOrder(),
75
+ domain,
76
+ bizplace: customerBizplace,
77
+ status: ORDER_STATUS.PENDING,
78
+ creator: user,
79
+ updater: user
80
+ })
81
+
82
+ // 2. Create VasOrder vas
83
+ orderVass = await Promise.all(
84
+ orderVass.map(async (ov: OrderVas) => {
85
+ if (ov?.targetProduct?.id) {
86
+ ov.targetProduct = await tx.getRepository(Product).findOneBy({ id: ov.targetProduct.id })
87
+ }
88
+ return {
89
+ ...ov,
90
+ domain,
91
+ name: OrderNoGenerator.orderVas(),
92
+ vas: await tx.getRepository(Vas).findOneBy({ domain: { id: domain.id }, id: ov.vas.id }),
93
+ vasOrder: createdVasOrder,
94
+ bizplace: customerBizplace,
95
+ type: ORDER_TYPES.VAS_ORDER,
96
+ status: ORDER_VAS_STATUS.PENDING,
97
+ creator: user,
98
+ updater: user
99
+ }
100
+ })
101
+ )
102
+ await tx.getRepository(OrderVas).save(orderVass)
103
+
104
+ return createdVasOrder
105
+ }
106
+
107
+ @Directive('@transaction')
108
+ @Mutation(returns => VasOrder)
109
+ async confirmVasOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<VasOrder> {
110
+ const { tx, domain, user } = context.state
111
+
112
+ const foundVasOrder: VasOrder = await tx.getRepository(VasOrder).findOne({
113
+ where: { domain: { id: domain.id }, name },
114
+ relations: ['bizplace', 'orderVass', 'orderVass.vas', 'creator', 'updater']
115
+ })
116
+
117
+ let vasOrder: VasOrder
118
+ let customerBizplace: Bizplace = foundVasOrder.bizplace
119
+ const foundOrderVass: OrderVas[] = foundVasOrder.orderVass
120
+
121
+ if (!foundVasOrder) throw new Error(`Vas order doesn't exists.`)
122
+ if (foundVasOrder.status !== ORDER_STATUS.PENDING) throw new Error('Not confirmable status.')
123
+ if (!foundOrderVass) throw new Error(`Order Vas doesn't exist`)
124
+
125
+ // 1. Update status of Order Vas (PENDING => PENDING_RECEIVE)
126
+ foundOrderVass.forEach(async orderVas => {
127
+ await tx.getRepository(OrderVas).save({
128
+ ...orderVas,
129
+ status: ORDER_VAS_STATUS.PENDING_RECEIVE,
130
+ updater: user
131
+ })
132
+ })
133
+
134
+ // 2. Vas Order Status change (PENDING => PENDING_RECEIVE)
135
+ vasOrder = await tx.getRepository(VasOrder).save({
136
+ ...foundVasOrder,
137
+ status: ORDER_STATUS.PENDING_RECEIVE,
138
+ updater: user
139
+ })
140
+
141
+ // notification logics
142
+ // get Office Admin Users
143
+ const users: any[] = await tx
144
+ .getRepository('users_roles')
145
+ .createQueryBuilder('ur')
146
+ .select('ur.users_id', 'id')
147
+ .where(qb => {
148
+ const subQuery = qb
149
+ .subQuery()
150
+ .select('role.id')
151
+ .from(Role, 'role')
152
+ .where("role.name = 'Office Admin'")
153
+ .andWhere('role.domain_id = :domain', { domain: context.state.domain.id })
154
+ .getQuery()
155
+ return 'ur.roles_id IN ' + subQuery
156
+ })
157
+ .getRawMany()
158
+
159
+ // send notification to Office Admin Users
160
+ if (users?.length && context.header?.referer) {
161
+ const receivers: any[] = users.map(user => user.id)
162
+ const msg = {
163
+ title: `New VAS Order from ${customerBizplace.name}`,
164
+ body: `New incoming order, ${foundVasOrder.name} is pending for receiving`,
165
+ url: context.header.referer,
166
+ data: { url: context.header.referer }
167
+ }
168
+
169
+ /**
170
+ * @notes Temporary off sendNotification due to suspect of causing wms down
171
+ */
172
+
173
+ // await sendNotification({
174
+ // receivers,
175
+ // message: { ...msg }
176
+ // })
177
+ }
178
+
179
+ return vasOrder
180
+ }
181
+
182
+ @Directive('@transaction')
183
+ @Mutation(returns => VasOrder)
184
+ async rejectVasOrder(
185
+ @Arg('name') name: string,
186
+ @Arg('patch', type => VasOrderPatch) patch: VasOrderPatch,
187
+ @Ctx() context: ResolverContext
188
+ ): Promise<VasOrder> {
189
+ try {
190
+ const { tx, domain, user } = context.state
191
+ if (!patch.remark) throw new Error('Remark is not exist.')
192
+
193
+ const vasOrder: VasOrder = await tx.getRepository(VasOrder).findOne({
194
+ where: { domain: { id: domain.id }, name, status: ORDER_STATUS.PENDING_RECEIVE },
195
+ relations: ['bizplace', 'orderVass']
196
+ })
197
+ if (!vasOrder) throw new Error(`Vas order doesn't exists.`)
198
+
199
+ // 1. Update status of order vass (PENDING_RECEIVE => REJECTED)
200
+ const orderVass: OrderVas[] = vasOrder.orderVass.map((orderVas: OrderVas) => {
201
+ return {
202
+ ...orderVas,
203
+ status: ORDER_VAS_STATUS.REJECTED,
204
+ updater: user
205
+ }
206
+ })
207
+ await tx.getRepository(OrderVas).save(orderVass)
208
+
209
+ await tx.getRepository(VasOrder).save({
210
+ ...vasOrder,
211
+ ...patch,
212
+ status: ORDER_STATUS.REJECTED,
213
+ updater: user
214
+ })
215
+
216
+ // notification logics
217
+ // get Office Admin Users
218
+ const users: any[] = await tx
219
+ .getRepository('users_roles')
220
+ .createQueryBuilder('ur')
221
+ .select('ur.users_id', 'id')
222
+ .where(qb => {
223
+ const subQuery = qb
224
+ .subQuery()
225
+ .select('role.id')
226
+ .from(Role, 'role')
227
+ .where("role.name = 'Office Admin'")
228
+ .andWhere('role.domain_id = :domain', { domain: domain.id })
229
+ .getQuery()
230
+ return 'ur.roles_id IN ' + subQuery
231
+ })
232
+ .getRawMany()
233
+
234
+ // send notification to Customer Users
235
+ if (users?.length && context.header?.referer) {
236
+ const receivers: any[] = users.map(user => user.id)
237
+ const msg = {
238
+ title: `Latest status for ${vasOrder.name}`,
239
+ body: `Your VAS order has been rejected.`,
240
+ url: context.header.referer,
241
+ data: { url: context.header.referer }
242
+ }
243
+
244
+ /**
245
+ * @notes Temporary off sendNotification due to suspect of causing wms down
246
+ */
247
+
248
+ // await sendNotification({
249
+ // receivers,
250
+ // message: { ...msg }
251
+ // })
252
+ }
253
+
254
+ return vasOrder
255
+ } catch (e) {
256
+ throw e
257
+ }
258
+ }
259
+ }
@@ -0,0 +1,119 @@
1
+ import { Arg, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import { getPermittedBizplaceIds } from '@things-factory/biz-base'
6
+ import { convertListParams, Domain, Filter, getRepository, Pagination, Sorting } from '@things-factory/shell'
7
+
8
+ import { VasOrderList } from '../'
9
+ import { ORDER_STATUS } from '../../constants'
10
+ import { VasOrder } from './vas-order'
11
+
12
+ @Resolver(VasOrder)
13
+ export class VasOrderQuery {
14
+ @Query(returns => VasOrderList)
15
+ async vasOrders(
16
+ @Ctx() context: ResolverContext,
17
+ @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
18
+ @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
19
+ @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
20
+ ): Promise<VasOrderList> {
21
+ const { domain, user } = context.state
22
+
23
+ const convertedParams = convertListParams({ filters, pagination, sortings })
24
+ convertedParams.where.bizplace = In(await getPermittedBizplaceIds(domain, user))
25
+
26
+ const [items, total] = await getRepository(VasOrder).findAndCount({
27
+ ...convertedParams,
28
+ relations: [
29
+ 'domain',
30
+ 'bizplace',
31
+ 'orderVass',
32
+ 'orderVass.inventory',
33
+ 'orderVass.inventory.product',
34
+ 'creator',
35
+ 'updater'
36
+ ]
37
+ })
38
+ return { items, total }
39
+ }
40
+
41
+ @Query(returns => VasOrder)
42
+ async vasOrder(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<VasOrder> {
43
+ const { domain, user } = context.state
44
+
45
+ return await getRepository(VasOrder).findOne({
46
+ where: {
47
+ domain: { id: domain.id },
48
+ name,
49
+ bizplace: { id: In(await getPermittedBizplaceIds(domain, user)) }
50
+ },
51
+ relations: [
52
+ 'domain',
53
+ 'bizplace',
54
+ 'orderVass',
55
+ 'orderVass.vas',
56
+ 'orderVass.inventory',
57
+ 'orderVass.inventory.product',
58
+ 'orderVass.inventory.location',
59
+ 'orderVass.inventory.warehouse',
60
+ 'orderVass.targetProduct',
61
+ 'creator',
62
+ 'updater'
63
+ ]
64
+ })
65
+ }
66
+
67
+ @Query(returns => VasOrderList)
68
+ async vasOrderRequests(
69
+ @Ctx() context: ResolverContext,
70
+ @Arg('filters', type => [Filter], { nullable: true }) filters?: Filter[],
71
+ @Arg('pagination', type => Pagination, { nullable: true }) pagination?: Pagination,
72
+ @Arg('sortings', type => [Sorting], { nullable: true }) sortings?: Sorting[]
73
+ ): Promise<VasOrderList> {
74
+ const { domain, user } = context.state
75
+
76
+ const convertedParams = convertListParams({ filters, pagination, sortings })
77
+
78
+ if (!convertedParams.where || !convertedParams.where.status) {
79
+ convertedParams.where.status = In([
80
+ ORDER_STATUS.PENDING_RECEIVE,
81
+ ORDER_STATUS.READY_TO_EXECUTE,
82
+ ORDER_STATUS.DONE,
83
+ ORDER_STATUS.EXECUTING,
84
+ ORDER_STATUS.REJECTED
85
+ ])
86
+ }
87
+ convertedParams.where.bizplace = In(await getPermittedBizplaceIds(domain, user))
88
+
89
+ const [items, total] = await getRepository(VasOrder).findAndCount({
90
+ ...convertedParams,
91
+ relations: [
92
+ 'domain',
93
+ 'bizplace',
94
+ 'orderVass',
95
+ 'orderVass.inventory',
96
+ 'orderVass.inventory.product',
97
+ 'creator',
98
+ 'updater'
99
+ ]
100
+ })
101
+
102
+ return { items, total }
103
+ }
104
+
105
+ @FieldResolver(type => Domain)
106
+ async domain(@Root() vasOrder: VasOrder): Promise<Domain> {
107
+ return await getRepository(Domain).findOneBy({ id: vasOrder.domainId })
108
+ }
109
+
110
+ @FieldResolver(type => User)
111
+ async creator(@Root() vasOrder: VasOrder): Promise<User> {
112
+ return await getRepository(User).findOneBy({ id: vasOrder.creatorId })
113
+ }
114
+
115
+ @FieldResolver(type => User)
116
+ async updater(@Root() vasOrder: VasOrder): Promise<User> {
117
+ return await getRepository(User).findOneBy({ id: vasOrder.updaterId })
118
+ }
119
+ }
@@ -0,0 +1,49 @@
1
+ import { ObjectRef } from '@things-factory/shell'
2
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
3
+ import { NewOrderVas } from '../order-vas/order-vas-types'
4
+ import { VasOrder } from './vas-order'
5
+
6
+ @ObjectType()
7
+ export class VasOrderList {
8
+ @Field(type => [VasOrder], { nullable: true })
9
+ items: VasOrder[]
10
+
11
+ @Field(type => Int, { nullable: true })
12
+ total: number
13
+ }
14
+
15
+ @InputType()
16
+ export class NewVasOrder {
17
+ @Field({ nullable: true })
18
+ name: string
19
+
20
+ @Field({ nullable: true })
21
+ customerBizplaceId: string
22
+
23
+ @Field({ nullable: true })
24
+ description: string
25
+
26
+ @Field(type => [NewOrderVas], { nullable: true })
27
+ orderVass: [NewOrderVas]
28
+
29
+ @Field({ nullable: true })
30
+ status: string
31
+ }
32
+
33
+ @InputType()
34
+ export class VasOrderPatch {
35
+ @Field({ nullable: true })
36
+ name: string
37
+
38
+ @Field({ nullable: true })
39
+ description: string
40
+
41
+ @Field(type => ObjectRef, { nullable: true })
42
+ orderVass: [ObjectRef]
43
+
44
+ @Field({ nullable: true })
45
+ status: string
46
+
47
+ @Field({ nullable: true })
48
+ remark: string
49
+ }