@things-factory/worksheet-base 5.0.0-alpha.38 → 5.0.0-alpha.40
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/template.js +1 -0
- package/dist-server/constants/template.js.map +1 -1
- package/dist-server/controllers/ecommerce/sellercraft-controller.js +9 -3
- package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js +9 -3
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/index.js +2 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/render-fm-grn.js +229 -0
- package/dist-server/controllers/render-fm-grn.js.map +1 -0
- package/dist-server/controllers/render-grn.js +18 -18
- package/dist-server/controllers/render-po.js +147 -0
- package/dist-server/controllers/render-po.js.map +1 -0
- package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js +10 -3
- package/dist-server/graphql/resolvers/worksheet/cycle-count-adjustment.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js +13 -3
- package/dist-server/graphql/resolvers/worksheet/loading/complete-loading.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +6 -2
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js +49 -55
- package/dist-server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/worksheets.js +18 -0
- package/dist-server/graphql/resolvers/worksheet/worksheets.js.map +1 -1
- package/dist-server/graphql/types/worksheet/index.js +3 -2
- package/dist-server/graphql/types/worksheet/index.js.map +1 -1
- package/dist-server/graphql/types/worksheet/picking-assignment-status.js +2 -2
- package/dist-server/graphql/types/worksheet/worksheet-patch.js +1 -0
- package/dist-server/graphql/types/worksheet/worksheet-patch.js.map +1 -1
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/routes.js +12 -0
- package/dist-server/routes.js.map +1 -1
- package/package.json +17 -17
- package/server/constants/template.ts +1 -0
- package/server/controllers/ecommerce/sellercraft-controller.ts +10 -3
- package/server/controllers/inbound/unloading-worksheet-controller.ts +14 -3
- package/server/controllers/index.ts +3 -0
- package/server/controllers/render-fm-grn.ts +266 -0
- package/server/controllers/render-grn.ts +18 -18
- package/server/controllers/render-po.ts +170 -0
- package/server/graphql/resolvers/worksheet/cycle-count-adjustment.ts +13 -4
- package/server/graphql/resolvers/worksheet/loading/complete-loading.ts +19 -5
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +5 -2
- package/server/graphql/resolvers/worksheet/picking/picking-assignment-status-by-user.ts +61 -58
- package/server/graphql/resolvers/worksheet/worksheets.ts +26 -0
- package/server/graphql/types/worksheet/index.ts +3 -2
- package/server/graphql/types/worksheet/picking-assignment-status.ts +2 -2
- package/server/graphql/types/worksheet/worksheet-patch.ts +1 -0
- package/server/index.ts +1 -0
- package/server/routes.ts +17 -0
|
@@ -52,25 +52,25 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
|
|
|
52
52
|
})
|
|
53
53
|
|
|
54
54
|
const qbReducedInventory = getRepository(ReducedInventoryHistory)
|
|
55
|
-
.createQueryBuilder(
|
|
56
|
-
.select(
|
|
57
|
-
.addSelect(
|
|
58
|
-
.addSelect(
|
|
59
|
-
.addSelect(
|
|
60
|
-
.addSelect(
|
|
61
|
-
.addSelect(
|
|
62
|
-
.addSelect(
|
|
63
|
-
.addSelect(
|
|
64
|
-
.addSelect(`string_agg(distinct expiration_date::varchar,', ' order by expiration_date::varchar)`,
|
|
65
|
-
.addSelect(`string_agg(distinct pallet_id::varchar,', ' order by pallet_id::varchar)`,
|
|
66
|
-
.where(
|
|
67
|
-
.andWhere(
|
|
55
|
+
.createQueryBuilder('ivh')
|
|
56
|
+
.select('product_id', 'productId')
|
|
57
|
+
.addSelect('batch_id', 'batchId')
|
|
58
|
+
.addSelect('reusable_pallet_id', 'reusablePalletId')
|
|
59
|
+
.addSelect('packing_type', 'packingType')
|
|
60
|
+
.addSelect('sum(qty)', 'qty')
|
|
61
|
+
.addSelect('sum(uom_value)', 'uomValue')
|
|
62
|
+
.addSelect('uom', 'uom')
|
|
63
|
+
.addSelect('count(distinct pallet_id)', 'pallet')
|
|
64
|
+
.addSelect(`string_agg(distinct expiration_date::varchar,', ' order by expiration_date::varchar)`, 'expiryDate')
|
|
65
|
+
.addSelect(`string_agg(distinct pallet_id::varchar,', ' order by pallet_id::varchar)`, 'palletId')
|
|
66
|
+
.where('ivh.domain_id = :domainId', { domainId: domain.id })
|
|
67
|
+
.andWhere('ivh.ref_order_id = :refOrderId', { refOrderId: foundGAN.id })
|
|
68
68
|
.andWhere(`ivh.transaction_type = 'UNLOADING'`)
|
|
69
|
-
.groupBy(
|
|
70
|
-
.addGroupBy(
|
|
71
|
-
.addGroupBy(
|
|
72
|
-
.addGroupBy(
|
|
73
|
-
.addGroupBy(
|
|
69
|
+
.groupBy('reusable_pallet_id')
|
|
70
|
+
.addGroupBy('product_id')
|
|
71
|
+
.addGroupBy('batch_id')
|
|
72
|
+
.addGroupBy('packing_type')
|
|
73
|
+
.addGroupBy('uom')
|
|
74
74
|
.getRawMany()
|
|
75
75
|
|
|
76
76
|
// 5. find domain contact point
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import FormData from 'form-data'
|
|
2
|
+
import fetch from 'node-fetch'
|
|
3
|
+
import { getRepository, SelectQueryBuilder } from 'typeorm'
|
|
4
|
+
|
|
5
|
+
import { Attachment, STORAGE } from '@things-factory/attachment-base'
|
|
6
|
+
import { Bizplace } from '@things-factory/biz-base'
|
|
7
|
+
import { config } from '@things-factory/env'
|
|
8
|
+
import { InvoiceProduct, ReleaseGood, PurchaseOrder, PurchaseOrderOtherCharge, OrderProduct } from '@things-factory/sales-base'
|
|
9
|
+
|
|
10
|
+
import { Domain } from '@things-factory/shell'
|
|
11
|
+
|
|
12
|
+
import { TEMPLATE_TYPE } from '../constants'
|
|
13
|
+
import { DateTimeConverter } from '../utils/datetime-util'
|
|
14
|
+
|
|
15
|
+
const REPORT_API_URL = config.get('reportApiUrl', 'http://localhost:8888/rest/report/show_html')
|
|
16
|
+
|
|
17
|
+
export async function renderPO({ req, timezoneOffSet }, context: any) {
|
|
18
|
+
try {
|
|
19
|
+
const domain: Domain = await getRepository(Domain).findOne({
|
|
20
|
+
where: { id: context.state.domain.id }
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
let result = await Promise.all(
|
|
24
|
+
req.poIds.map(async poId => {
|
|
25
|
+
try {
|
|
26
|
+
const qb: SelectQueryBuilder<PurchaseOrder> = await getRepository(PurchaseOrder)
|
|
27
|
+
.createQueryBuilder('po')
|
|
28
|
+
.innerJoinAndSelect('po.domain', 'domain')
|
|
29
|
+
.innerJoinAndSelect('po.bizplace', 'bizplace')
|
|
30
|
+
.innerJoinAndSelect('bizplace.domain', 'bizplace_domain')
|
|
31
|
+
.innerJoinAndSelect('bizplace.company', 'company')
|
|
32
|
+
.innerJoinAndSelect('company.domain', 'company_domain')
|
|
33
|
+
.leftJoinAndSelect('contact_points', 'cp', 'po.supplier_id = cp.id')
|
|
34
|
+
.where('po.id = :poId')
|
|
35
|
+
.andWhere('po.domain = :domainId')
|
|
36
|
+
.setParameters({ poId, domainId: domain.id })
|
|
37
|
+
|
|
38
|
+
let record: any = await qb.getRawOne()
|
|
39
|
+
|
|
40
|
+
if (record) {
|
|
41
|
+
const partnerBiz: Partial<Bizplace> = {
|
|
42
|
+
id: record.bizplace_id,
|
|
43
|
+
name: record.bizplace_name,
|
|
44
|
+
address: record.bizplace_address,
|
|
45
|
+
domain: { id: record.bizplace_domain_id }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const foundTemplate: Attachment = await getRepository(Attachment).findOne({
|
|
49
|
+
where: { domain: partnerBiz.domain, category: TEMPLATE_TYPE.PO_TEMPLATE }
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const foundLogo: Attachment = await getRepository(Attachment).findOne({
|
|
53
|
+
where: {
|
|
54
|
+
domain: partnerBiz.domain,
|
|
55
|
+
category: TEMPLATE_TYPE.LOGO
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
let logo = null
|
|
60
|
+
if (foundLogo?.path) {
|
|
61
|
+
logo = 'data:' + foundLogo.mimetype + ';base64,' + (await STORAGE.readFile(foundLogo.path, 'base64'))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const template = await STORAGE.readFile(foundTemplate.path, 'utf-8')
|
|
65
|
+
|
|
66
|
+
const poocQb: SelectQueryBuilder<PurchaseOrderOtherCharge> = await getRepository(PurchaseOrderOtherCharge)
|
|
67
|
+
.createQueryBuilder('pooc')
|
|
68
|
+
.where('pooc.purchase_order_id = :poId')
|
|
69
|
+
.andWhere('pooc.apply_in_items = false')
|
|
70
|
+
.setParameters({ poId })
|
|
71
|
+
|
|
72
|
+
let poOtherCharges: any[] = await poocQb.getRawMany()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
const qb: SelectQueryBuilder<OrderProduct> = await getRepository(OrderProduct)
|
|
76
|
+
.createQueryBuilder('op')
|
|
77
|
+
.innerJoin('domains', 'd', 'op.domain_id = d.id')
|
|
78
|
+
.leftJoinAndSelect('purchase_orders', 'po', 'po.id = op.purchase_order_id')
|
|
79
|
+
.leftJoinAndSelect('products', 'p', 'op.product_id = p.id')
|
|
80
|
+
.where('op.purchase_order_id = :poId')
|
|
81
|
+
.andWhere('op.domain = :domainId')
|
|
82
|
+
.setParameters({ poId, domainId: domain.id })
|
|
83
|
+
|
|
84
|
+
let items: any[] = await qb.getRawMany()
|
|
85
|
+
|
|
86
|
+
const product_list = items.map((item, idx) => {
|
|
87
|
+
return {
|
|
88
|
+
list_no: idx + 1,
|
|
89
|
+
product_sku: item.p_sku,
|
|
90
|
+
product_name: item.p_name,
|
|
91
|
+
product_desc: item.p_description,
|
|
92
|
+
product_qty: item.op_pack_qty,
|
|
93
|
+
product_uom: item.op_uom,
|
|
94
|
+
product_other_charges: item.ip_other_charges,
|
|
95
|
+
product_unit_price: (item.op_unit_price).toFixed(2),
|
|
96
|
+
product_total_price: ((((item.op_unit_price || 0) * item.op_pack_qty) - (item.op_discount_amt || 0)) * (1 + (item.op_tax_rate / 100))).toFixed(2),
|
|
97
|
+
product_tax_rate: item.op_tax_rate,
|
|
98
|
+
product_disc_amt: item.op_discount_amt
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
let date = DateTimeConverter.date(new Date(record.po_created_at - timezoneOffSet))
|
|
104
|
+
let eta = DateTimeConverter.date(new Date(record.po_eta_date))
|
|
105
|
+
|
|
106
|
+
let subtotal = getRoundedValue(
|
|
107
|
+
product_list.reduce((init, item) => {
|
|
108
|
+
return (init += parseFloat(item.product_total_price))
|
|
109
|
+
}, 0) || 0
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const data = {
|
|
113
|
+
logo_url: logo,
|
|
114
|
+
company_name: record.company_description,
|
|
115
|
+
company_address: record.company_address,
|
|
116
|
+
company_postal_code: record.company_postal_code,
|
|
117
|
+
po_number: record.po_name,
|
|
118
|
+
po_order_date: date,
|
|
119
|
+
po_delivery_date: eta,
|
|
120
|
+
ref_no: record.po_ref_no,
|
|
121
|
+
cp_company_name: record.cp_company_name,
|
|
122
|
+
cp_address: record.cp_address2 ? [record.cp_address, record.cp_address2].join(', ') : record.cp_address,
|
|
123
|
+
cp_contact_name: record.cp_name,
|
|
124
|
+
cp_email: record.cp_email,
|
|
125
|
+
cp_phone_number: record.cp_phone,
|
|
126
|
+
product_list,
|
|
127
|
+
charges_list: [
|
|
128
|
+
{
|
|
129
|
+
field: 'SUBTOTAL', value: subtotal.toFixed(2)
|
|
130
|
+
},
|
|
131
|
+
...poOtherCharges.map(itm => { return { field: itm.pooc_name.toUpperCase(), value: itm.pooc_total_amt.toFixed(2) } }),
|
|
132
|
+
{
|
|
133
|
+
field: 'TOTAL', value: (poOtherCharges.reduce((init, item) => {
|
|
134
|
+
return init += (item.pooc_total_amt)
|
|
135
|
+
}, subtotal) || 0).toFixed(2),
|
|
136
|
+
},
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const formData = new FormData()
|
|
141
|
+
formData.append('template', template)
|
|
142
|
+
formData.append('jsonString', JSON.stringify(data))
|
|
143
|
+
|
|
144
|
+
const response = await fetch(REPORT_API_URL, {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
body: formData
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
return await response.text()
|
|
150
|
+
}
|
|
151
|
+
return null
|
|
152
|
+
} catch (ex) {
|
|
153
|
+
return null
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if (result.filter(x => x != null).length <= 0) {
|
|
159
|
+
throw Error('No purchase order found!')
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return result.join()
|
|
163
|
+
} catch (ex) {
|
|
164
|
+
throw ex
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getRoundedValue(value = 0) {
|
|
169
|
+
return Math.round((value + Number.EPSILON) * 100) / 100
|
|
170
|
+
}
|
|
@@ -56,7 +56,9 @@ export async function cycleCountAdjustment(
|
|
|
56
56
|
'targetInventory.inventory.product.productDetails',
|
|
57
57
|
'targetInventory.inventory.product.productDetails.childProductDetail',
|
|
58
58
|
'targetInventory.inventory.bizplace',
|
|
59
|
+
'targetInventory.inventory.domain',
|
|
59
60
|
'targetInventory.inventory.bizplace.domain',
|
|
61
|
+
'targetInventory.inventory.warehouse',
|
|
60
62
|
'targetInventory.inventory.location',
|
|
61
63
|
'targetInventory.inspectedLocation',
|
|
62
64
|
'targetInventory.inspectedLocation.warehouse'
|
|
@@ -67,8 +69,8 @@ export async function cycleCountAdjustment(
|
|
|
67
69
|
const targetInventory: OrderInventory = worksheetDetail.targetInventory
|
|
68
70
|
let inventory: Inventory = targetInventory.inventory
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
let transactQty: number = targetInventory.inspectedQty - inventory.qty
|
|
73
|
+
let transactUomValue: number = targetInventory.inspectedUomValue - inventory.uomValue
|
|
72
74
|
|
|
73
75
|
const sellercraft: Sellercraft = await tx.getRepository(Sellercraft).findOne({
|
|
74
76
|
where: { domain: inventory.bizplace.domain, status: SellercraftStatus.ACTIVE }
|
|
@@ -137,16 +139,23 @@ export async function cycleCountAdjustment(
|
|
|
137
139
|
|
|
138
140
|
if (targetInventory.inspectedBatchNo !== inventory.batchId) {
|
|
139
141
|
// generate TERMINATED, ADJUSTMENT history
|
|
142
|
+
const { qty, uomValue }: { qty: number; uomValue: number } = inventory
|
|
140
143
|
inventory.status = INVENTORY_STATUS.TERMINATED
|
|
144
|
+
inventory.qty = 0
|
|
145
|
+
inventory.uomValue = 0
|
|
146
|
+
|
|
141
147
|
await generateInventoryHistory(
|
|
142
148
|
inventory,
|
|
143
149
|
cycleCount,
|
|
144
150
|
INVENTORY_TRANSACTION_TYPE.CC_ADJUSTMENT,
|
|
145
|
-
-
|
|
146
|
-
-
|
|
151
|
+
-qty,
|
|
152
|
+
-uomValue,
|
|
147
153
|
user,
|
|
148
154
|
tx
|
|
149
155
|
)
|
|
156
|
+
|
|
157
|
+
transactQty = targetInventory.inspectedQty
|
|
158
|
+
transactUomValue = targetInventory.inspectedUomValue
|
|
150
159
|
}
|
|
151
160
|
|
|
152
161
|
inventory.batchId = targetInventory.inspectedBatchNo
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm'
|
|
2
|
+
|
|
1
3
|
import { User } from '@things-factory/auth-base'
|
|
2
|
-
import {
|
|
4
|
+
import { Sftp, SftpAPI } from '@things-factory/integration-sftp'
|
|
5
|
+
import { ORDER_INVENTORY_STATUS, ORDER_STATUS, OrderInventory, ReleaseGood } from '@things-factory/sales-base'
|
|
3
6
|
import { Domain } from '@things-factory/shell'
|
|
4
|
-
import {
|
|
7
|
+
import { InventoryItem } from '@things-factory/warehouse-base'
|
|
8
|
+
|
|
5
9
|
import { WORKSHEET_TYPE } from '../../../../constants'
|
|
6
10
|
import { LoadingWorksheetController, ReturningWorksheetController } from '../../../../controllers'
|
|
7
11
|
import { Worksheet, WorksheetDetail } from '../../../../entities'
|
|
8
|
-
import { Sftp, SftpAPI } from '@things-factory/integration-sftp'
|
|
9
12
|
|
|
10
13
|
export const completeLoadingResolver = {
|
|
11
14
|
async completeLoading(_: any, { releaseGoodNo }, context: any) {
|
|
@@ -46,12 +49,23 @@ export async function completeLoading(
|
|
|
46
49
|
where: { domain: customerDomain }
|
|
47
50
|
})
|
|
48
51
|
if (customerAvailableSftp) {
|
|
49
|
-
let
|
|
52
|
+
let inventoryItems: InventoryItem[] = await tx.getRepository(InventoryItem).find({
|
|
53
|
+
where: { domain, outboundOrderId: releaseGood.id }
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
let shipmentResult: Sftp = await SftpAPI.createShipment(customerAvailableSftp, {
|
|
50
57
|
releaseGood,
|
|
51
58
|
orderInventories: targetInventories,
|
|
52
59
|
sftp: customerAvailableSftp
|
|
53
60
|
})
|
|
54
|
-
customerAvailableSftp = await tx.getRepository(Sftp).save(
|
|
61
|
+
customerAvailableSftp = await tx.getRepository(Sftp).save(shipmentResult)
|
|
62
|
+
|
|
63
|
+
let snResult: Sftp = await SftpAPI.createSerialNumber(customerAvailableSftp, {
|
|
64
|
+
releaseGood,
|
|
65
|
+
inventoryItems,
|
|
66
|
+
sftp: customerAvailableSftp
|
|
67
|
+
})
|
|
68
|
+
customerAvailableSftp = await tx.getRepository(Sftp).save(snResult)
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
await worksheetController.completeLoading(releaseGoodNo)
|
|
@@ -205,8 +205,11 @@ export async function completePicking(
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
} else {
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
if (resp?.AWBurl && resp?.TrackingNo)
|
|
209
|
+
await tx
|
|
210
|
+
.getRepository(MarketplaceOrderShipping)
|
|
211
|
+
.update({ id: marketplaceOrderShipping.id }, { airwayBill: resp.AWBurl, trackingNo: resp.TrackingNo })
|
|
212
|
+
else throw resp
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
}
|
|
@@ -1,79 +1,82 @@
|
|
|
1
|
-
import { getDomainUsers, User } from '@things-factory/auth-base'
|
|
2
|
-
import { Domain } from '@things-factory/shell'
|
|
3
|
-
import { FindManyOptions, getRepository, ILike, In } from 'typeorm'
|
|
1
|
+
import { getDomainUsers, User, Role } from '@things-factory/auth-base'
|
|
2
|
+
import { Domain, ListParam, buildQuery, Sorting} from '@things-factory/shell'
|
|
3
|
+
import { FindManyOptions, getRepository, ILike, In, EntityManager, getManager, SelectQueryBuilder } from 'typeorm'
|
|
4
4
|
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../../constants'
|
|
5
5
|
import { Worksheet } from '../../../../entities'
|
|
6
6
|
|
|
7
|
-
type AssignmentStatusByUserType = { user: User; pending?:
|
|
7
|
+
type AssignmentStatusByUserType = { user: User; pending?: String; picking?: String }
|
|
8
8
|
|
|
9
9
|
export const pickingAssignmentStatusByUsersResolver = {
|
|
10
10
|
async pickingAssignmentStatusByUsers(
|
|
11
11
|
_: void,
|
|
12
|
-
|
|
12
|
+
params: ListParam,
|
|
13
13
|
context: any
|
|
14
14
|
): Promise<AssignmentStatusByUserType[]> {
|
|
15
|
+
|
|
15
16
|
const { domain }: { domain: Domain } = context.state
|
|
16
|
-
const domainUsers: User[] = await getDomainUsers(domain)
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const nameFilter = params.filters.find(p=>{return p.name == "name"});
|
|
19
|
+
const emailFilter = params.filters.find(p=>{return p.name == "email"});
|
|
20
|
+
const roleFilter = params.filters.find(p=>{return p.name == 'roles'});
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
if (email) findOneOption.where.email = ILike(`%${email}%`)
|
|
22
|
+
const pendingSorter = params.sortings.find(p=>{return p.name == 'pending'});
|
|
23
|
+
const pickingSorter = params.sortings.find(p=>{return p.name == 'picking'});
|
|
25
24
|
|
|
26
|
-
const users: User[] = await getRepository(User).find(findOneOption)
|
|
27
25
|
|
|
28
|
-
const assignedPickingWorksheets: Worksheet[] = await getRepository(Worksheet).find({
|
|
29
|
-
where: {
|
|
30
|
-
type: In([WORKSHEET_TYPE.PICKING, WORKSHEET_TYPE.BATCH_PICKING]),
|
|
31
|
-
status: In([WORKSHEET_STATUS.DEACTIVATED, WORKSHEET_STATUS.EXECUTING]),
|
|
32
|
-
assignee: In(users.map((u: User) => u.id)),
|
|
33
|
-
domain
|
|
34
|
-
},
|
|
35
|
-
relations: ['assignee']
|
|
36
|
-
})
|
|
37
26
|
|
|
38
|
-
const
|
|
39
|
-
(assignmentMap: Map<string, AssignmentStatusByUserType>, worksheet: Worksheet) => {
|
|
40
|
-
const assignee: User = worksheet.assignee
|
|
41
|
-
const status: string = worksheet.status
|
|
27
|
+
const getUserInfoQb:SelectQueryBuilder<User> = await getRepository(User).createQueryBuilder('u')
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} else if (status === WORKSHEET_STATUS.EXECUTING) {
|
|
58
|
-
assignmentMap.set(assignee.id, {
|
|
59
|
-
user: assignee,
|
|
60
|
-
pending: [],
|
|
61
|
-
picking: [worksheet]
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
}
|
|
29
|
+
getUserInfoQb.select('u.id')
|
|
30
|
+
getUserInfoQb.addSelect('u.name')
|
|
31
|
+
getUserInfoQb.addSelect('u.email')
|
|
32
|
+
getUserInfoQb.addSelect("string_agg(r.name,', ') as roles")
|
|
33
|
+
getUserInfoQb.innerJoin('u.roles','r')
|
|
34
|
+
getUserInfoQb.where('r.domain_id = :domainId',{domainId:domain.id})
|
|
35
|
+
roleFilter? getUserInfoQb.andWhere('r.name ilike :userRole', { userRole: `%${roleFilter.value}%` }) :""
|
|
36
|
+
nameFilter? getUserInfoQb.andWhere('u.name ilike :userName', { userName: `%${nameFilter.value}%` }) :""
|
|
37
|
+
emailFilter? getUserInfoQb.andWhere('u.email ilike :userEmail', { userEmail: `%${emailFilter.value}%` }) :""
|
|
38
|
+
getUserInfoQb.andWhere('r.name not ilike :userR',{userR:`%CLIENT%`})
|
|
39
|
+
getUserInfoQb.andWhere('u.user_type = :userType',{userType:"user"})
|
|
40
|
+
getUserInfoQb.groupBy('u.id')
|
|
41
|
+
getUserInfoQb.addGroupBy('u.name')
|
|
42
|
+
getUserInfoQb.addGroupBy('u.email')
|
|
65
43
|
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
new Map()
|
|
69
|
-
)
|
|
44
|
+
const getAssignedWSQb = await getRepository(Worksheet).createQueryBuilder('ws')
|
|
70
45
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
46
|
+
getAssignedWSQb.select('ws.assignee_id')
|
|
47
|
+
getAssignedWSQb.addSelect('u.name')
|
|
48
|
+
getAssignedWSQb.addSelect("sum(case when ws.status='EXECUTING' then 1 else 0 end) as picking")
|
|
49
|
+
getAssignedWSQb.addSelect("sum(case when ws.status='DEACTIVATED' then 1 else 0 end) as pending")
|
|
50
|
+
getAssignedWSQb.innerJoin('ws.assignee','u')
|
|
51
|
+
getAssignedWSQb.where('ws.domain_id = :id',{id:domain.id})
|
|
52
|
+
getAssignedWSQb.andWhere('ws.type IN (:...type)', {type: [WORKSHEET_TYPE.PICKING, WORKSHEET_TYPE.BATCH_PICKING]})
|
|
53
|
+
getAssignedWSQb.andWhere('ws.status IN (:...status)', {status: [WORKSHEET_STATUS.DEACTIVATED, WORKSHEET_STATUS.EXECUTING]})
|
|
54
|
+
getAssignedWSQb.groupBy('ws.assignee_id')
|
|
55
|
+
getAssignedWSQb.addGroupBy('u.name')
|
|
56
|
+
pendingSorter?.desc ? getAssignedWSQb.orderBy('pending','DESC') : ''
|
|
57
|
+
pickingSorter?.desc ? getAssignedWSQb.orderBy('picking','DESC') : ''
|
|
58
|
+
pickingSorter && Object.keys(pickingSorter).length == 1 ?getAssignedWSQb.orderBy('picking','ASC') : ''
|
|
59
|
+
pendingSorter && Object.keys(pendingSorter).length == 1 ? getAssignedWSQb.orderBy('pending','ASC') : ''
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const parameter1= getUserInfoQb.getParameters()
|
|
63
|
+
const parameter2 = getAssignedWSQb.getParameters()
|
|
76
64
|
|
|
77
|
-
|
|
65
|
+
const combineParams = Object.assign(parameter1, parameter2)
|
|
66
|
+
|
|
67
|
+
const combineQb = getManager().createQueryBuilder()
|
|
68
|
+
|
|
69
|
+
combineQb.select('u.*')
|
|
70
|
+
combineQb.addSelect('coalesce(ws.picking, 0) as picking')
|
|
71
|
+
combineQb.addSelect('coalesce(ws.pending, 0) as pending')
|
|
72
|
+
combineQb.from("(" + getUserInfoQb.getQuery() + ")","u")
|
|
73
|
+
combineQb.leftJoin("(" + getAssignedWSQb.getQuery() + ")","ws",' ws.assignee_id = u.u_id')
|
|
74
|
+
combineQb.setParameters(combineParams)
|
|
75
|
+
|
|
76
|
+
const combineInfo = await combineQb.getRawMany()
|
|
77
|
+
|
|
78
|
+
return combineInfo.map(itm => {
|
|
79
|
+
return { user: { id:itm.u_id,email:itm.u_email,name:itm.u_name, description: itm.roles },pending:itm.pending,picking:itm.picking }
|
|
80
|
+
})
|
|
78
81
|
}
|
|
79
82
|
}
|
|
@@ -99,6 +99,7 @@ export const worksheetsResolver = {
|
|
|
99
99
|
const releaseGoodCrossDockingParam = params.filters.find(param => param.name === 'crossDocking')
|
|
100
100
|
const releaseGoodCourierOptionParam = params.filters.find(param => param.name === 'courierOption')
|
|
101
101
|
const releaseGoodPackingOptionParam = params.filters.find(param => param.name === 'packingOption')
|
|
102
|
+
const releaseGoodPickerOptionParam = params.filters.find(param => param.name === 'assignee')
|
|
102
103
|
if (
|
|
103
104
|
releaseGoodParam ||
|
|
104
105
|
releaseGoodRefNoParam ||
|
|
@@ -252,6 +253,31 @@ export const worksheetsResolver = {
|
|
|
252
253
|
}
|
|
253
254
|
}
|
|
254
255
|
|
|
256
|
+
//find assignee
|
|
257
|
+
|
|
258
|
+
const assigneeParam = params.filters.find(param => param.name === 'assignee')
|
|
259
|
+
let assigneeFilter = []
|
|
260
|
+
if (assigneeParam) {
|
|
261
|
+
params.filters.splice(
|
|
262
|
+
params.filters.findIndex(item => item.name == 'assignee'),
|
|
263
|
+
1
|
|
264
|
+
)
|
|
265
|
+
assigneeFilter.push({ ...assigneeParam, name: 'name' })
|
|
266
|
+
|
|
267
|
+
const foundAssignee: User[] = await getRepository(User).find({
|
|
268
|
+
...convertListParams({ filters: assigneeFilter })
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
if (foundAssignee) {
|
|
272
|
+
params.filters.push({
|
|
273
|
+
name: 'assigneeId',
|
|
274
|
+
operator: 'in',
|
|
275
|
+
value: foundAssignee.map((foundIC: User) => foundIC.id),
|
|
276
|
+
relation: false
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
255
281
|
////Set default bizplace filter
|
|
256
282
|
const bizplaceFilter = params.filters.find(param => param.name === 'bizplaceId')
|
|
257
283
|
if (!bizplaceFilter && typeParam.value[0] !== WORKSHEET_TYPE.BATCH_PICKING) {
|
|
@@ -681,8 +681,9 @@ export const Query = /* GraphQL */ `
|
|
|
681
681
|
): [Inventory] @privilege(category: "worksheet", privilege: "query")
|
|
682
682
|
|
|
683
683
|
pickingAssignmentStatusByUsers(
|
|
684
|
-
|
|
685
|
-
|
|
684
|
+
filters: [Filter],
|
|
685
|
+
pagination: Pagination,
|
|
686
|
+
sortings: [Sorting]
|
|
686
687
|
): [PickingAssignmentStatus] @privilege(category: "worksheet", privilege: "query")
|
|
687
688
|
|
|
688
689
|
myPickingAssignmentStatus: MyPickingAssignmentStatus @privilege(category: "worksheet", privilege: "query")
|
package/server/index.ts
CHANGED
|
@@ -10,3 +10,4 @@ export * from './graphql/resolvers/worksheet-detail/generate-release-good-worksh
|
|
|
10
10
|
export * from './graphql/resolvers/worksheet/unloading/activate-unloading'
|
|
11
11
|
export * from './graphql/resolvers/worksheet/picking/activate-picking'
|
|
12
12
|
export * from './migrations'
|
|
13
|
+
export * from './controllers'
|
package/server/routes.ts
CHANGED
|
@@ -8,7 +8,10 @@ import { renderOrientageDO } from './controllers/render-orientage-do'
|
|
|
8
8
|
import { renderOrientageGRN } from './controllers/render-orientage-grn'
|
|
9
9
|
import { renderRODO } from './controllers/render-ro-do'
|
|
10
10
|
import { renderSeebuuGRN } from './controllers/render-seebuu-grn'
|
|
11
|
+
import { renderFmGRN } from './controllers/render-fm-grn'
|
|
11
12
|
import { renderInvoices } from './controllers/render-invoices'
|
|
13
|
+
import { renderPO } from './controllers/render-po'
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
process.on('bootstrap-module-domain-private-route' as any, (app, routes) => {
|
|
14
17
|
routes.get('/view_document_ro_do/:doNo', async (context, next) => {
|
|
@@ -43,6 +46,10 @@ process.on('bootstrap-module-domain-private-route' as any, (app, routes) => {
|
|
|
43
46
|
context.body = await renderSeebuuGRN(context.params, context)
|
|
44
47
|
})
|
|
45
48
|
|
|
49
|
+
routes.get('/view_fm_grn/:grnNo/:timezoneOffSet', async (context, next) => {
|
|
50
|
+
context.body = await renderFmGRN(context.params, context)
|
|
51
|
+
})
|
|
52
|
+
|
|
46
53
|
routes.get('/view_job_sheet/:ganNo/:timezoneOffSet', async (context, next) => {
|
|
47
54
|
context.body = await renderJobSheet(context.params, context)
|
|
48
55
|
})
|
|
@@ -60,4 +67,14 @@ process.on('bootstrap-module-domain-private-route' as any, (app, routes) => {
|
|
|
60
67
|
context.type = 'application/json'
|
|
61
68
|
context.body = data
|
|
62
69
|
})
|
|
70
|
+
|
|
71
|
+
routes.post('/view_purchase_orders/:timezoneOffSet', async (context, next) => {
|
|
72
|
+
let req = context.request.body || {}
|
|
73
|
+
let timezoneOffSet = context.params.timezoneOffSet || 0
|
|
74
|
+
|
|
75
|
+
let data = await renderPO({ req, timezoneOffSet }, context)
|
|
76
|
+
|
|
77
|
+
context.type = 'application/json'
|
|
78
|
+
context.body = data
|
|
79
|
+
})
|
|
63
80
|
})
|