@things-factory/warehouse-base 4.1.33 → 4.1.34
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/inventory.js +8 -2
- package/dist-server/constants/inventory.js.map +1 -1
- package/dist-server/service/index.js +5 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/inventory-item/index.js +9 -0
- package/dist-server/service/inventory-item/index.js.map +1 -0
- package/dist-server/service/inventory-item/inventory-item-mutation.js +207 -0
- package/dist-server/service/inventory-item/inventory-item-mutation.js.map +1 -0
- package/dist-server/service/inventory-item/inventory-item-query.js +150 -0
- package/dist-server/service/inventory-item/inventory-item-query.js.map +1 -0
- package/dist-server/service/inventory-item/inventory-item-type.js +115 -0
- package/dist-server/service/inventory-item/inventory-item-type.js.map +1 -0
- package/dist-server/service/inventory-item/inventory-item.js +124 -0
- package/dist-server/service/inventory-item/inventory-item.js.map +1 -0
- package/dist-server/service/inventory-product/index.js +9 -0
- package/dist-server/service/inventory-product/index.js.map +1 -0
- package/dist-server/service/inventory-product/inventory-product-mutation.js +120 -0
- package/dist-server/service/inventory-product/inventory-product-mutation.js.map +1 -0
- package/dist-server/service/inventory-product/inventory-product-query.js +87 -0
- package/dist-server/service/inventory-product/inventory-product-query.js.map +1 -0
- package/dist-server/service/inventory-product/inventory-product-type.js +95 -0
- package/dist-server/service/inventory-product/inventory-product-type.js.map +1 -0
- package/dist-server/service/inventory-product/inventory-product.js +107 -0
- package/dist-server/service/inventory-product/inventory-product.js.map +1 -0
- package/dist-server/utils/inventory-no-generator.js +3 -0
- package/dist-server/utils/inventory-no-generator.js.map +1 -1
- package/package.json +4 -4
- package/server/constants/inventory.ts +8 -1
- package/server/service/index.ts +5 -0
- package/server/service/inventory-item/index.ts +6 -0
- package/server/service/inventory-item/inventory-item-mutation.ts +210 -0
- package/server/service/inventory-item/inventory-item-query.ts +118 -0
- package/server/service/inventory-item/inventory-item-type.ts +74 -0
- package/server/service/inventory-item/inventory-item.ts +99 -0
- package/server/service/inventory-product/index.ts +6 -0
- package/server/service/inventory-product/inventory-product-mutation.ts +112 -0
- package/server/service/inventory-product/inventory-product-query.ts +43 -0
- package/server/service/inventory-product/inventory-product-type.ts +59 -0
- package/server/service/inventory-product/inventory-product.ts +88 -0
- package/server/utils/inventory-no-generator.ts +4 -0
package/server/service/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { entities as InventoryEntities, resolvers as InventoryResolvers } from './inventory'
|
|
2
2
|
import { entities as InventoryChangeEntities, resolvers as InventoryChangeResolvers } from './inventory-change'
|
|
3
3
|
import { entities as InventoryHistoryEntities, resolvers as InventoryHistoryResvolers } from './inventory-history'
|
|
4
|
+
import { entities as InventoryItemEntities, resolvers as InventoryItemResolvers } from './inventory-item'
|
|
4
5
|
import { entities as LocationEntities, resolvers as LocationResolvers } from './location'
|
|
5
6
|
import { entities as MovementEntities, resolvers as MovementResolvers } from './movement'
|
|
6
7
|
import { entities as PalletEntities, resolvers as PalletResolvers } from './pallet'
|
|
@@ -10,6 +11,7 @@ import { entities as ReducedInventoryHistoryEntities } from './reduced-inventory
|
|
|
10
11
|
import { entities as WarehouseEntities, resolvers as WarehouseResolvers } from './warehouse'
|
|
11
12
|
|
|
12
13
|
/* EXPORT ENTITY TYPES */
|
|
14
|
+
export * from './inventory-item/inventory-item'
|
|
13
15
|
export * from './inventory/inventory'
|
|
14
16
|
export * from './inventory-change/inventory-change'
|
|
15
17
|
export * from './inventory-history/inventory-history'
|
|
@@ -24,6 +26,7 @@ export * from './reduced-inventory-history/reduced-inventory-history'
|
|
|
24
26
|
/* EXPORT TYPES */
|
|
25
27
|
export * from './inventory/inventory-types'
|
|
26
28
|
export * from './inventory/inventory-types'
|
|
29
|
+
export * from './inventory-item/inventory-item'
|
|
27
30
|
export * from './inventory-change/inventory-change-types'
|
|
28
31
|
export * from './inventory-history/inventory-history-types'
|
|
29
32
|
export * from './location/location-types'
|
|
@@ -37,6 +40,7 @@ export const entities = [
|
|
|
37
40
|
...InventoryEntities,
|
|
38
41
|
...InventoryChangeEntities,
|
|
39
42
|
...InventoryHistoryEntities,
|
|
43
|
+
...InventoryItemEntities,
|
|
40
44
|
...LocationEntities,
|
|
41
45
|
...MovementEntities,
|
|
42
46
|
...PalletEntities,
|
|
@@ -51,6 +55,7 @@ export const schema = {
|
|
|
51
55
|
...InventoryResolvers,
|
|
52
56
|
...InventoryChangeResolvers,
|
|
53
57
|
...InventoryHistoryResvolers,
|
|
58
|
+
...InventoryItemResolvers,
|
|
54
59
|
...LocationResolvers,
|
|
55
60
|
...MovementResolvers,
|
|
56
61
|
...PalletResolvers,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InventoryItem } from './inventory-item'
|
|
2
|
+
import { InventoryItemMutation } from './inventory-item-mutation'
|
|
3
|
+
import { InventoryItemQuery } from './inventory-item-query'
|
|
4
|
+
|
|
5
|
+
export const entities = [InventoryItem]
|
|
6
|
+
export const resolvers = [InventoryItemQuery, InventoryItemMutation]
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
|
2
|
+
import { In } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
import { Product } from '@things-factory/product-base'
|
|
5
|
+
|
|
6
|
+
import { INVENTORY_STATUS } from '../../constants'
|
|
7
|
+
import { InventoryNoGenerator } from '../../utils'
|
|
8
|
+
import { InventoryItem } from './inventory-item'
|
|
9
|
+
import { InventoryItemPatch, NewInventoryItem } from './inventory-item-type'
|
|
10
|
+
|
|
11
|
+
@Resolver(InventoryItem)
|
|
12
|
+
export class InventoryItemMutation {
|
|
13
|
+
@Directive('@transaction')
|
|
14
|
+
@Mutation(returns => InventoryItem, { description: 'To create new InventoryItem' })
|
|
15
|
+
async createInventoryItem(
|
|
16
|
+
@Arg('inventoryItem') inventoryItem: NewInventoryItem,
|
|
17
|
+
@Ctx() context: any
|
|
18
|
+
): Promise<InventoryItem> {
|
|
19
|
+
const { domain, user, tx } = context.state
|
|
20
|
+
|
|
21
|
+
return await tx.getRepository(InventoryItem).save({
|
|
22
|
+
...inventoryItem,
|
|
23
|
+
domain,
|
|
24
|
+
creator: user,
|
|
25
|
+
updater: user
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Directive('@transaction')
|
|
30
|
+
@Mutation(returns => InventoryItem, { description: 'To modify InventoryItem information' })
|
|
31
|
+
async updateInventoryItem(
|
|
32
|
+
@Arg('id') id: string,
|
|
33
|
+
@Arg('patch') patch: InventoryItemPatch,
|
|
34
|
+
@Ctx() context: any
|
|
35
|
+
): Promise<InventoryItem> {
|
|
36
|
+
const { domain, user, tx } = context.state
|
|
37
|
+
|
|
38
|
+
const repository = tx.getRepository(InventoryItem)
|
|
39
|
+
const inventoryItem = await repository.findOne({
|
|
40
|
+
where: { domain, id }
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return await repository.save({
|
|
44
|
+
...inventoryItem,
|
|
45
|
+
...patch,
|
|
46
|
+
updater: user
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Directive('@transaction')
|
|
51
|
+
@Mutation(returns => Boolean, { description: 'To modify InventoryItem serial number' })
|
|
52
|
+
async updateInventoryItemSerialNumber(
|
|
53
|
+
@Arg('id') id: string,
|
|
54
|
+
@Arg('serialNumber') serialNumber: string,
|
|
55
|
+
@Ctx() context: any
|
|
56
|
+
): Promise<boolean> {
|
|
57
|
+
try {
|
|
58
|
+
const { domain, user, tx } = context.state
|
|
59
|
+
|
|
60
|
+
const repository = tx.getRepository(InventoryItem)
|
|
61
|
+
|
|
62
|
+
const inventoryItem = await repository.findOne({
|
|
63
|
+
where: { domain, id },
|
|
64
|
+
relations: ['product']
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const product: Product = inventoryItem.product
|
|
68
|
+
const duplicatedSerialNumberCnt: number = await repository.count({
|
|
69
|
+
domain,
|
|
70
|
+
product,
|
|
71
|
+
serialNumber
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
if (duplicatedSerialNumberCnt) throw new Error(`Serial Number ${serialNumber} is duplicated`)
|
|
75
|
+
|
|
76
|
+
await repository.update({ id }, { serialNumber, updater: user })
|
|
77
|
+
|
|
78
|
+
return true
|
|
79
|
+
} catch (error) {
|
|
80
|
+
throw error
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Directive('@transaction')
|
|
85
|
+
@Mutation(returns => [InventoryItem], { description: "To modify multiple InventoryItems' information" })
|
|
86
|
+
async updateMultipleInventoryItem(
|
|
87
|
+
@Arg('patches', type => [InventoryItemPatch]) patches: InventoryItemPatch[],
|
|
88
|
+
@Ctx() context: any
|
|
89
|
+
): Promise<InventoryItem[]> {
|
|
90
|
+
const { domain, user, tx } = context.state
|
|
91
|
+
|
|
92
|
+
let results = []
|
|
93
|
+
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
|
94
|
+
const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
95
|
+
const inventoryItemRepo = tx.getRepository(InventoryItem)
|
|
96
|
+
|
|
97
|
+
if (_createRecords.length > 0) {
|
|
98
|
+
for (let i = 0; i < _createRecords.length; i++) {
|
|
99
|
+
const newRecord = _createRecords[i]
|
|
100
|
+
|
|
101
|
+
const result = await inventoryItemRepo.save({
|
|
102
|
+
...newRecord,
|
|
103
|
+
domain,
|
|
104
|
+
creator: user,
|
|
105
|
+
updater: user
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
results.push({ ...result, cuFlag: '+' })
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (_updateRecords.length > 0) {
|
|
113
|
+
for (let i = 0; i < _updateRecords.length; i++) {
|
|
114
|
+
const newRecord = _updateRecords[i]
|
|
115
|
+
const inventoryItem = await inventoryItemRepo.findOne(newRecord.id)
|
|
116
|
+
|
|
117
|
+
const result = await inventoryItemRepo.save({
|
|
118
|
+
...inventoryItem,
|
|
119
|
+
...newRecord,
|
|
120
|
+
updater: user
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
results.push({ ...result, cuFlag: 'M' })
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return results
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@Directive('@transaction')
|
|
131
|
+
@Mutation(returns => Boolean, { description: 'To delete InventoryItem' })
|
|
132
|
+
async deleteInventoryItem(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
|
|
133
|
+
const { domain, tx } = context.state
|
|
134
|
+
|
|
135
|
+
await tx.getRepository(InventoryItem).delete({ domain, id })
|
|
136
|
+
|
|
137
|
+
return true
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Directive('@transaction')
|
|
141
|
+
@Mutation(returns => Boolean, { description: 'To delete multiple inventoryItems' })
|
|
142
|
+
async deleteInventoryItems(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
|
|
143
|
+
const { domain, tx } = context.state
|
|
144
|
+
|
|
145
|
+
await tx.getRepository(InventoryItem).delete({
|
|
146
|
+
domain,
|
|
147
|
+
id: In(ids)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@Directive('@transaction')
|
|
154
|
+
@Mutation(returns => InventoryItem, { description: 'To update picked InventoryItem with new IventoryItem' })
|
|
155
|
+
async replacePickedInventoryItem(
|
|
156
|
+
@Arg('selectedSerialNumber') selectedSerialNumber: InventoryItemPatch,
|
|
157
|
+
@Arg('newSerialNumber') newSerialNumber: string,
|
|
158
|
+
@Ctx() context: any
|
|
159
|
+
): Promise<InventoryItem> {
|
|
160
|
+
const { domain, user, tx } = context.state
|
|
161
|
+
|
|
162
|
+
const repository = tx.getRepository(InventoryItem)
|
|
163
|
+
const foundSerialNumber = await repository.findOne({
|
|
164
|
+
where: { domain, serialNumber: newSerialNumber }
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
await repository.update(
|
|
168
|
+
{
|
|
169
|
+
domain,
|
|
170
|
+
id: selectedSerialNumber.id
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
status: INVENTORY_STATUS.STORED,
|
|
174
|
+
outboundOrderId: null,
|
|
175
|
+
updater: user
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if (foundSerialNumber) {
|
|
180
|
+
if (foundSerialNumber.productId !== selectedSerialNumber.product?.id) {
|
|
181
|
+
throw new Error('Invalid Serial Number')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (foundSerialNumber.inventoryId !== selectedSerialNumber.inventory?.id) {
|
|
185
|
+
throw new Error('Serial Number Registered Under Different Inventory')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (foundSerialNumber.status !== INVENTORY_STATUS.STORED) {
|
|
189
|
+
throw new Error('Inventory Item is not available')
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
foundSerialNumber.status = INVENTORY_STATUS.PICKED
|
|
193
|
+
foundSerialNumber.updater = user
|
|
194
|
+
foundSerialNumber.outboundOrderId = selectedSerialNumber.outboundOrderId
|
|
195
|
+
|
|
196
|
+
return await repository.save(foundSerialNumber)
|
|
197
|
+
} else {
|
|
198
|
+
let inventoryItem: InventoryItem = new InventoryItem()
|
|
199
|
+
inventoryItem.name = InventoryNoGenerator.inventoryItemName()
|
|
200
|
+
inventoryItem.serialNumber = newSerialNumber
|
|
201
|
+
inventoryItem.status = INVENTORY_STATUS.PICKED
|
|
202
|
+
inventoryItem.outboundOrderId = selectedSerialNumber.outboundOrderId
|
|
203
|
+
inventoryItem.product = selectedSerialNumber.product
|
|
204
|
+
inventoryItem.inventory = selectedSerialNumber.inventory
|
|
205
|
+
inventoryItem.domain = domain
|
|
206
|
+
|
|
207
|
+
return await repository.save(inventoryItem)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
|
2
|
+
import { Brackets, getRepository, SelectQueryBuilder } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
import { User } from '@things-factory/auth-base'
|
|
5
|
+
import { convertListParams, Domain, ListParam } from '@things-factory/shell'
|
|
6
|
+
|
|
7
|
+
import { INVENTORY_STATUS } from '../../constants'
|
|
8
|
+
import { Inventory } from '../inventory/inventory'
|
|
9
|
+
import { InventoryItem } from './inventory-item'
|
|
10
|
+
import { InventoryItemList } from './inventory-item-type'
|
|
11
|
+
|
|
12
|
+
@Resolver(InventoryItem)
|
|
13
|
+
export class InventoryItemQuery {
|
|
14
|
+
@Query(returns => InventoryItem, { description: 'To fetch a InventoryItem' })
|
|
15
|
+
async inventoryItem(@Arg('id') id: string, @Ctx() context: any): Promise<InventoryItem> {
|
|
16
|
+
const { domain } = context.state
|
|
17
|
+
|
|
18
|
+
return await getRepository(InventoryItem).findOne({
|
|
19
|
+
where: { domain, id }
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Query(returns => InventoryItemList, { description: 'To fetch multiple InventoryItems' })
|
|
24
|
+
async inventoryItems(@Args() params: ListParam, @Ctx() context: any): Promise<InventoryItemList> {
|
|
25
|
+
const { domain } = context.state
|
|
26
|
+
|
|
27
|
+
const convertedParams = convertListParams(params, domain.id)
|
|
28
|
+
const [items, total] = await getRepository(InventoryItem).findAndCount(convertedParams)
|
|
29
|
+
|
|
30
|
+
return { items, total }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Query(returns => InventoryItemList, { description: 'To fetch multiple InventoryItems by inventory' })
|
|
34
|
+
async inventoryItemsByInventory(@Args() params: ListParam, @Ctx() context: any): Promise<InventoryItemList> {
|
|
35
|
+
const { domain } = context.state
|
|
36
|
+
|
|
37
|
+
const page = params.pagination.page
|
|
38
|
+
const limit = params.pagination.limit
|
|
39
|
+
const sortings = params.sortings
|
|
40
|
+
|
|
41
|
+
let inventoryInfoFilter = params.filters.find(filter => filter.name == 'inventory_info')
|
|
42
|
+
let orderTypeFilter = params.filters.find(filter => filter.name == 'orderType')
|
|
43
|
+
let orderIdFilter = params.filters.find(filter => filter.name == 'orderId')
|
|
44
|
+
let productIdFilter = params.filters.find(filter => filter.name == 'productId')
|
|
45
|
+
|
|
46
|
+
let qb: SelectQueryBuilder<InventoryItem> = getRepository(InventoryItem).createQueryBuilder('ivi')
|
|
47
|
+
qb.leftJoinAndSelect('ivi.product', 'product').leftJoinAndSelect('ivi.inventory', 'inventory')
|
|
48
|
+
qb.where('ivi.product_id=:productId', { productId: productIdFilter.value })
|
|
49
|
+
qb.andWhere('inventory.status!=:inventoryStatus', { inventoryStatus: INVENTORY_STATUS.PARTIALLY_UNLOADED })
|
|
50
|
+
|
|
51
|
+
if (orderTypeFilter.value == 'inbound') {
|
|
52
|
+
qb.andWhere('ivi.inbound_order_id=:orderId', { orderId: orderIdFilter.value })
|
|
53
|
+
} else {
|
|
54
|
+
qb.andWhere('ivi.outbound_order_id=:orderId', { orderId: orderIdFilter.value })
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (inventoryInfoFilter) {
|
|
58
|
+
qb.andWhere(qb => {
|
|
59
|
+
const subQuery = qb
|
|
60
|
+
.subQuery()
|
|
61
|
+
.select()
|
|
62
|
+
.from(Inventory, `inventories`)
|
|
63
|
+
.where(`inventories.id = ivi.inventory_id`)
|
|
64
|
+
.andWhere(
|
|
65
|
+
new Brackets(qb => {
|
|
66
|
+
qb.where('Lower(inventories.pallet_id) LIKE :inventoryInfo', {
|
|
67
|
+
inventoryInfo: '%' + inventoryInfoFilter.value.toLowerCase() + '%'
|
|
68
|
+
})
|
|
69
|
+
.orWhere('Lower(inventories.carton_id) LIKE :inventoryInfo', {
|
|
70
|
+
inventoryInfo: '%' + inventoryInfoFilter.value.toLowerCase() + '%'
|
|
71
|
+
})
|
|
72
|
+
.orWhere('Lower(ivi.serial_number) LIKE :inventoryInfo', {
|
|
73
|
+
inventoryInfo: '%' + inventoryInfoFilter.value.toLowerCase() + '%'
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
.getQuery()
|
|
78
|
+
return `EXISTS ${subQuery}`
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (sortings?.length !== 0) {
|
|
83
|
+
const arrChildSortData = ['serial_number']
|
|
84
|
+
const sort = (sortings || []).reduce(
|
|
85
|
+
(acc, sort) => ({
|
|
86
|
+
...acc,
|
|
87
|
+
[arrChildSortData.indexOf(sort.name) >= 0 ? sort.name + '.name' : 'ivi.' + sort.name]: sort.desc
|
|
88
|
+
? 'DESC'
|
|
89
|
+
: 'ASC'
|
|
90
|
+
}),
|
|
91
|
+
{}
|
|
92
|
+
)
|
|
93
|
+
qb.orderBy(sort)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
qb.limit(limit)
|
|
97
|
+
qb.offset(limit * (page - 1))
|
|
98
|
+
|
|
99
|
+
let [items, total] = await qb.getManyAndCount()
|
|
100
|
+
|
|
101
|
+
return { items, total }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@FieldResolver(type => Domain)
|
|
105
|
+
async domain(@Root() inventoryItem: InventoryItem): Promise<Domain> {
|
|
106
|
+
return await getRepository(Domain).findOne(inventoryItem.domainId)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@FieldResolver(type => User)
|
|
110
|
+
async updater(@Root() inventoryItem: InventoryItem): Promise<User> {
|
|
111
|
+
return await getRepository(User).findOne(inventoryItem.updaterId)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@FieldResolver(type => User)
|
|
115
|
+
async creator(@Root() inventoryItem: InventoryItem): Promise<User> {
|
|
116
|
+
return await getRepository(User).findOne(inventoryItem.creatorId)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
|
|
2
|
+
|
|
3
|
+
import { ObjectRef } from '@things-factory/shell'
|
|
4
|
+
|
|
5
|
+
import { InventoryItem } from './inventory-item'
|
|
6
|
+
|
|
7
|
+
@InputType()
|
|
8
|
+
export class NewInventoryItem {
|
|
9
|
+
@Field()
|
|
10
|
+
name: string
|
|
11
|
+
|
|
12
|
+
@Field({ nullable: true })
|
|
13
|
+
serialNumber?: string
|
|
14
|
+
|
|
15
|
+
@Field({ nullable: true })
|
|
16
|
+
status?: string
|
|
17
|
+
|
|
18
|
+
@Field({ nullable: true })
|
|
19
|
+
source?: string
|
|
20
|
+
|
|
21
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
22
|
+
product?: ObjectRef
|
|
23
|
+
|
|
24
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
25
|
+
inventory?: ObjectRef
|
|
26
|
+
|
|
27
|
+
@Field({ nullable: true })
|
|
28
|
+
inboundOrderId?: string
|
|
29
|
+
|
|
30
|
+
@Field({ nullable: true })
|
|
31
|
+
outboundOrderId?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@InputType()
|
|
35
|
+
export class InventoryItemPatch {
|
|
36
|
+
@Field(type => ID, { nullable: true })
|
|
37
|
+
id?: string
|
|
38
|
+
|
|
39
|
+
@Field({ nullable: true })
|
|
40
|
+
name?: string
|
|
41
|
+
|
|
42
|
+
@Field({ nullable: true })
|
|
43
|
+
serialNumber?: string
|
|
44
|
+
|
|
45
|
+
@Field({ nullable: true })
|
|
46
|
+
status?: string
|
|
47
|
+
|
|
48
|
+
@Field({ nullable: true })
|
|
49
|
+
source?: string
|
|
50
|
+
|
|
51
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
52
|
+
product?: ObjectRef
|
|
53
|
+
|
|
54
|
+
@Field(type => ObjectRef, { nullable: true })
|
|
55
|
+
inventory?: ObjectRef
|
|
56
|
+
|
|
57
|
+
@Field({ nullable: true })
|
|
58
|
+
inboundOrderId?: string
|
|
59
|
+
|
|
60
|
+
@Field({ nullable: true })
|
|
61
|
+
outboundOrderId?: string
|
|
62
|
+
|
|
63
|
+
@Field({ nullable: true })
|
|
64
|
+
cuFlag: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@ObjectType()
|
|
68
|
+
export class InventoryItemList {
|
|
69
|
+
@Field(type => [InventoryItem])
|
|
70
|
+
items: InventoryItem[]
|
|
71
|
+
|
|
72
|
+
@Field(type => Int)
|
|
73
|
+
total: number
|
|
74
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Field, ID, ObjectType } from 'type-graphql'
|
|
2
|
+
import {
|
|
3
|
+
Column,
|
|
4
|
+
CreateDateColumn,
|
|
5
|
+
Entity,
|
|
6
|
+
Index,
|
|
7
|
+
ManyToOne,
|
|
8
|
+
PrimaryGeneratedColumn,
|
|
9
|
+
RelationId,
|
|
10
|
+
UpdateDateColumn
|
|
11
|
+
} from 'typeorm'
|
|
12
|
+
|
|
13
|
+
import { User } from '@things-factory/auth-base'
|
|
14
|
+
import { Product } from '@things-factory/product-base'
|
|
15
|
+
import { Domain } from '@things-factory/shell'
|
|
16
|
+
|
|
17
|
+
import { Inventory } from '../inventory/inventory'
|
|
18
|
+
|
|
19
|
+
@Entity()
|
|
20
|
+
@Index('ix_inventory_item_0', (inventoryItem: InventoryItem) => [inventoryItem.domain, inventoryItem.name], {
|
|
21
|
+
unique: true
|
|
22
|
+
})
|
|
23
|
+
@ObjectType({ description: 'Entity for InventoryItem' })
|
|
24
|
+
export class InventoryItem {
|
|
25
|
+
@PrimaryGeneratedColumn('uuid')
|
|
26
|
+
@Field(type => ID)
|
|
27
|
+
readonly id: string
|
|
28
|
+
|
|
29
|
+
@ManyToOne(type => Domain)
|
|
30
|
+
@Field({ nullable: true })
|
|
31
|
+
domain?: Domain
|
|
32
|
+
|
|
33
|
+
@RelationId((inventoryItem: InventoryItem) => inventoryItem.domain)
|
|
34
|
+
domainId?: string
|
|
35
|
+
|
|
36
|
+
@Column()
|
|
37
|
+
@Field()
|
|
38
|
+
name: string
|
|
39
|
+
|
|
40
|
+
@Column({ nullable: true })
|
|
41
|
+
@Field({ nullable: true })
|
|
42
|
+
serialNumber?: string
|
|
43
|
+
|
|
44
|
+
@Column({ nullable: true })
|
|
45
|
+
@Field({ nullable: true })
|
|
46
|
+
status?: string
|
|
47
|
+
|
|
48
|
+
@Column({ nullable: true })
|
|
49
|
+
@Field({ nullable: true })
|
|
50
|
+
source?: string
|
|
51
|
+
|
|
52
|
+
@Column({ nullable: true })
|
|
53
|
+
@Field({ nullable: true })
|
|
54
|
+
inboundOrderId: string
|
|
55
|
+
|
|
56
|
+
@Column({ nullable: true })
|
|
57
|
+
@Field({ nullable: true })
|
|
58
|
+
outboundOrderId: string
|
|
59
|
+
|
|
60
|
+
@ManyToOne(type => Product)
|
|
61
|
+
@Field(type => Product, { nullable: true })
|
|
62
|
+
product?: Product
|
|
63
|
+
|
|
64
|
+
@RelationId((inventoryItem: InventoryItem) => inventoryItem.product)
|
|
65
|
+
productId?: string
|
|
66
|
+
|
|
67
|
+
@ManyToOne(type => Inventory)
|
|
68
|
+
@Field(type => Inventory)
|
|
69
|
+
inventory?: Inventory
|
|
70
|
+
|
|
71
|
+
@RelationId((inventoryItem: InventoryItem) => inventoryItem.inventory)
|
|
72
|
+
inventoryId?: string
|
|
73
|
+
|
|
74
|
+
@CreateDateColumn()
|
|
75
|
+
@Field({ nullable: true })
|
|
76
|
+
createdAt?: Date
|
|
77
|
+
|
|
78
|
+
@UpdateDateColumn()
|
|
79
|
+
@Field({ nullable: true })
|
|
80
|
+
updatedAt?: Date
|
|
81
|
+
|
|
82
|
+
@ManyToOne(type => User, {
|
|
83
|
+
nullable: true
|
|
84
|
+
})
|
|
85
|
+
@Field({ nullable: true })
|
|
86
|
+
creator?: User
|
|
87
|
+
|
|
88
|
+
@RelationId((inventoryItem: InventoryItem) => inventoryItem.creator)
|
|
89
|
+
creatorId?: string
|
|
90
|
+
|
|
91
|
+
@ManyToOne(type => User, {
|
|
92
|
+
nullable: true
|
|
93
|
+
})
|
|
94
|
+
@Field({ nullable: true })
|
|
95
|
+
updater?: User
|
|
96
|
+
|
|
97
|
+
@RelationId((inventoryItem: InventoryItem) => inventoryItem.creator)
|
|
98
|
+
updaterId?: string
|
|
99
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InventoryProduct } from './inventory-product'
|
|
2
|
+
import { InventoryProductQuery } from './inventory-product-query'
|
|
3
|
+
import { InventoryProductMutation } from './inventory-product-mutation'
|
|
4
|
+
|
|
5
|
+
export const entities = [InventoryProduct]
|
|
6
|
+
export const resolvers = [InventoryProductQuery, InventoryProductMutation]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
+
import { getRepository, In } from 'typeorm'
|
|
3
|
+
import { InventoryProduct } from './inventory-product'
|
|
4
|
+
import { NewInventoryProduct, InventoryProductPatch } from './inventory-product-type'
|
|
5
|
+
|
|
6
|
+
@Resolver(InventoryProduct)
|
|
7
|
+
export class InventoryProductMutation {
|
|
8
|
+
@Directive('@transaction')
|
|
9
|
+
@Mutation(returns => InventoryProduct, { description: 'To create new InventoryProduct' })
|
|
10
|
+
async createInventoryProduct(@Arg('inventoryProduct') inventoryProduct: NewInventoryProduct, @Ctx() context: any): Promise<InventoryProduct> {
|
|
11
|
+
const { domain, user, tx } = context.state
|
|
12
|
+
|
|
13
|
+
return await tx.getRepository(InventoryProduct).save({
|
|
14
|
+
...inventoryProduct,
|
|
15
|
+
domain,
|
|
16
|
+
creator: user,
|
|
17
|
+
updater: user
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Directive('@transaction')
|
|
22
|
+
@Mutation(returns => InventoryProduct, { description: 'To modify InventoryProduct information' })
|
|
23
|
+
async updateInventoryProduct(
|
|
24
|
+
@Arg('id') id: string,
|
|
25
|
+
@Arg('patch') patch: InventoryProductPatch,
|
|
26
|
+
@Ctx() context: any
|
|
27
|
+
): Promise<InventoryProduct> {
|
|
28
|
+
const { domain, user, tx } = context.state
|
|
29
|
+
|
|
30
|
+
const repository = tx.getRepository(InventoryProduct)
|
|
31
|
+
const inventoryProduct = await repository.findOne({
|
|
32
|
+
where: { domain, id }
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return await repository.save({
|
|
36
|
+
...inventoryProduct,
|
|
37
|
+
...patch,
|
|
38
|
+
updater: user
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Directive('@transaction')
|
|
43
|
+
@Mutation(returns => [InventoryProduct], { description: "To modify multiple InventoryProducts' information" })
|
|
44
|
+
async updateMultipleInventoryProduct(
|
|
45
|
+
@Arg('patches', type => [InventoryProductPatch]) patches: InventoryProductPatch[],
|
|
46
|
+
@Ctx() context: any
|
|
47
|
+
): Promise<InventoryProduct[]> {
|
|
48
|
+
const { domain, user, tx } = context.state
|
|
49
|
+
|
|
50
|
+
let results = []
|
|
51
|
+
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
|
52
|
+
const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
53
|
+
const inventoryProductRepo = tx.getRepository(InventoryProduct)
|
|
54
|
+
|
|
55
|
+
if (_createRecords.length > 0) {
|
|
56
|
+
for (let i = 0; i < _createRecords.length; i++) {
|
|
57
|
+
const newRecord = _createRecords[i]
|
|
58
|
+
|
|
59
|
+
const result = await inventoryProductRepo.save({
|
|
60
|
+
...newRecord,
|
|
61
|
+
domain,
|
|
62
|
+
creator: user,
|
|
63
|
+
updater: user
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
results.push({ ...result, cuFlag: '+' })
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (_updateRecords.length > 0) {
|
|
71
|
+
for (let i = 0; i < _updateRecords.length; i++) {
|
|
72
|
+
const newRecord = _updateRecords[i]
|
|
73
|
+
const inventoryProduct = await inventoryProductRepo.findOne(newRecord.id)
|
|
74
|
+
|
|
75
|
+
const result = await inventoryProductRepo.save({
|
|
76
|
+
...inventoryProduct,
|
|
77
|
+
...newRecord,
|
|
78
|
+
updater: user
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
results.push({ ...result, cuFlag: 'M' })
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return results
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Directive('@transaction')
|
|
89
|
+
@Mutation(returns => Boolean, { description: 'To delete InventoryProduct' })
|
|
90
|
+
async deleteInventoryProduct(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
|
|
91
|
+
const { domain, tx } = context.state
|
|
92
|
+
|
|
93
|
+
await tx.getRepository(InventoryProduct).delete({ domain, id })
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@Directive('@transaction')
|
|
98
|
+
@Mutation(returns => Boolean, { description: 'To delete multiple inventoryProducts' })
|
|
99
|
+
async deleteInventoryProducts(
|
|
100
|
+
@Arg('ids', type => [String]) ids: string[],
|
|
101
|
+
@Ctx() context: any
|
|
102
|
+
): Promise<boolean> {
|
|
103
|
+
const { domain, tx } = context.state
|
|
104
|
+
|
|
105
|
+
await tx.getRepository(InventoryProduct).delete({
|
|
106
|
+
domain,
|
|
107
|
+
id: In(ids)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
return true
|
|
111
|
+
}
|
|
112
|
+
}
|