@things-factory/worksheet-base 4.0.37 → 4.0.41
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 +32 -1
- package/dist-server/controllers/ecommerce/sellercraft-controller.js.map +1 -1
- package/dist-server/controllers/inbound/unloading-returning-worksheet-controller.js +1 -1
- package/dist-server/controllers/inbound/unloading-returning-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js +16 -12
- package/dist-server/controllers/inbound/unloading-worksheet-controller.js.map +1 -1
- package/dist-server/controllers/render-grn.js +1 -0
- package/dist-server/controllers/render-grn.js.map +1 -1
- package/dist-server/controllers/render-invoices.js +138 -0
- package/dist-server/controllers/render-invoices.js.map +1 -0
- package/dist-server/controllers/render-ro-do.js +5 -1
- package/dist-server/controllers/render-ro-do.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js +5 -4
- package/dist-server/graphql/resolvers/worksheet/find-release-orders-by-task-no.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js +10 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-batch-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js +90 -76
- package/dist-server/graphql/resolvers/worksheet/picking/complete-picking.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/complete-unloading-partially.js.map +1 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/complete-unloading.js +2 -1
- package/dist-server/graphql/resolvers/worksheet/unloading/complete-unloading.js.map +1 -1
- package/dist-server/routes.js +8 -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 +37 -1
- package/server/controllers/inbound/unloading-returning-worksheet-controller.ts +1 -1
- package/server/controllers/inbound/unloading-worksheet-controller.ts +21 -14
- package/server/controllers/render-grn.ts +1 -0
- package/server/controllers/render-invoices.ts +154 -0
- package/server/controllers/render-ro-do.ts +6 -1
- package/server/graphql/resolvers/worksheet/find-release-orders-by-task-no.ts +11 -7
- package/server/graphql/resolvers/worksheet/picking/complete-batch-picking.ts +12 -1
- package/server/graphql/resolvers/worksheet/picking/complete-picking.ts +96 -79
- package/server/graphql/resolvers/worksheet/unloading/complete-unloading-partially.ts +1 -1
- package/server/graphql/resolvers/worksheet/unloading/complete-unloading.ts +2 -2
- package/server/routes.ts +11 -0
|
@@ -578,7 +578,8 @@ export class UnloadingWorksheetController extends VasWorksheetController {
|
|
|
578
578
|
oi =>
|
|
579
579
|
oi.batchId == inventory.batchId &&
|
|
580
580
|
oi.packingType == inventory.packingType &&
|
|
581
|
-
oi.product.id == inventory.product.id
|
|
581
|
+
oi.product.id == inventory.product.id &&
|
|
582
|
+
oi.packingSize === inventory.packingSize
|
|
582
583
|
)
|
|
583
584
|
if (inventory.status == INVENTORY_STATUS.UNLOADED) {
|
|
584
585
|
targetInventory.actualPackQty -= qty
|
|
@@ -621,6 +622,9 @@ export class UnloadingWorksheetController extends VasWorksheetController {
|
|
|
621
622
|
inventory.qty = 0
|
|
622
623
|
inventory.uomValue = 0
|
|
623
624
|
inventory.updater = this.user
|
|
625
|
+
targetProduct.actualPalletQty--
|
|
626
|
+
|
|
627
|
+
await this.updateOrderTargets([targetProduct])
|
|
624
628
|
|
|
625
629
|
await this.trxMgr.getRepository(InventoryHistory).update({ inventory }, { inventory: null })
|
|
626
630
|
|
|
@@ -822,7 +826,7 @@ export class UnloadingWorksheetController extends VasWorksheetController {
|
|
|
822
826
|
|
|
823
827
|
async completeUnloadingPartially(
|
|
824
828
|
arrivalNoticeNo: string,
|
|
825
|
-
unloadingWorksheetDetail: Partial<WorksheetDetail>
|
|
829
|
+
unloadingWorksheetDetail: Partial<WorksheetDetail>[]
|
|
826
830
|
): Promise<Worksheet> {
|
|
827
831
|
const arrivalNotice: ArrivalNotice = await this.findRefOrder(ArrivalNotice, {
|
|
828
832
|
name: arrivalNoticeNo,
|
|
@@ -835,25 +839,28 @@ export class UnloadingWorksheetController extends VasWorksheetController {
|
|
|
835
839
|
])
|
|
836
840
|
this.checkRecordValidity(worksheet, { status: WORKSHEET_STATUS.EXECUTING })
|
|
837
841
|
|
|
838
|
-
let
|
|
839
|
-
(
|
|
842
|
+
let worksheetDetails = worksheet.worksheetDetails.filter(({ name: itm1 }) =>
|
|
843
|
+
unloadingWorksheetDetail.some(({ name: itm2 }) => itm2 === itm1)
|
|
840
844
|
)
|
|
841
|
-
worksheetDetail.status = WORKSHEET_STATUS.PARTIALLY_UNLOADED
|
|
842
|
-
worksheetDetail.issue = unloadingWorksheetDetail.issue || worksheetDetail.issue
|
|
843
|
-
worksheetDetail.updater = this.user
|
|
844
|
-
worksheetDetail = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetail)
|
|
845
845
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
846
|
+
worksheetDetails.forEach((wsds: WorksheetDetail) => {
|
|
847
|
+
wsds.status = WORKSHEET_STATUS.PARTIALLY_UNLOADED
|
|
848
|
+
wsds.updater = this.user
|
|
849
|
+
})
|
|
850
|
+
|
|
851
|
+
worksheetDetails = await this.trxMgr.getRepository(WorksheetDetail).save(worksheetDetails)
|
|
852
|
+
|
|
853
|
+
for (let i = 0; i < worksheetDetails.length; i++) {
|
|
854
|
+
worksheetDetails[i].targetProduct.status = ORDER_PRODUCT_STATUS.PARTIALLY_UNLOADED
|
|
855
|
+
worksheetDetails[i].targetProduct.remark = worksheetDetails[i].issue || worksheetDetails[i].targetProduct.remark
|
|
856
|
+
await this.updateOrderTargets([worksheetDetails[i].targetProduct])
|
|
857
|
+
}
|
|
850
858
|
|
|
851
859
|
let inventories: Inventory[] = await this.trxMgr.getRepository(Inventory).find({
|
|
852
860
|
where: {
|
|
853
861
|
domain: this.domain,
|
|
854
862
|
refOrderId: arrivalNotice.id,
|
|
855
|
-
|
|
856
|
-
status: INVENTORY_STATUS.UNLOADED
|
|
863
|
+
status: In([INVENTORY_STATUS.UNLOADED, INVENTORY_STATUS.CHECKED])
|
|
857
864
|
}
|
|
858
865
|
})
|
|
859
866
|
|
|
@@ -194,6 +194,7 @@ export async function renderGRN({ grnNo, timezoneOffSet }, context: any) {
|
|
|
194
194
|
product_type: item.packingType,
|
|
195
195
|
product_size: item.packingSize,
|
|
196
196
|
product_batch: item.batchId,
|
|
197
|
+
batch_id_ref: item?.batchIdRef ? item.batchIdRef : '',
|
|
197
198
|
pallet_qty: item.actualPalletQty,
|
|
198
199
|
product_qty: unloadInvHistory.qty || item.actualPackQty,
|
|
199
200
|
product_unit_uom_value: `${Math.round(item.uomValue * 100) / 100}`,
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import FormData from 'form-data'
|
|
2
|
+
import fetch from 'node-fetch'
|
|
3
|
+
import { getRepository } 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 { Invoice, ReleaseGood } from '@things-factory/sales-base'
|
|
9
|
+
import { Domain } from '@things-factory/shell'
|
|
10
|
+
|
|
11
|
+
import { TEMPLATE_TYPE } from '../constants'
|
|
12
|
+
import { DateTimeConverter } from '../utils/datetime-util'
|
|
13
|
+
|
|
14
|
+
const REPORT_API_URL = config.get('reportApiUrl', 'http://localhost:8888/rest/report/show_html')
|
|
15
|
+
|
|
16
|
+
export async function renderInvoices({ req, timezoneOffSet }, context: any) {
|
|
17
|
+
try {
|
|
18
|
+
const domain: Domain = await getRepository(Domain).findOne({
|
|
19
|
+
where: { id: context.state.domain.id }
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
let result = await Promise.all(
|
|
23
|
+
req.roIds.map(async roId => {
|
|
24
|
+
try {
|
|
25
|
+
const foundReleaseGoods: ReleaseGood = await getRepository(ReleaseGood).findOne({
|
|
26
|
+
where: { domain, id: roId },
|
|
27
|
+
relations: ['domain', 'bizplace', 'bizplace.domain', 'bizplace.company', 'bizplace.company.domain']
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
if (foundReleaseGoods) {
|
|
31
|
+
const foundInvoice: Invoice = await getRepository(Invoice).findOne({
|
|
32
|
+
where: { releaseGood: foundReleaseGoods },
|
|
33
|
+
relations: ['invoiceProducts', 'invoiceProducts.product', 'domain', 'creator', 'updater']
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const partnerBiz: Bizplace = foundReleaseGoods.bizplace
|
|
37
|
+
|
|
38
|
+
const partnerCompanyDomain: Domain = foundReleaseGoods.bizplace.company.domain
|
|
39
|
+
|
|
40
|
+
const foundTemplate: Attachment = await getRepository(Attachment).findOne({
|
|
41
|
+
where: { domain: partnerCompanyDomain, category: TEMPLATE_TYPE.INVOICE_TEMPLATE }
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const template = await STORAGE.readFile(foundTemplate.path, 'utf-8')
|
|
45
|
+
|
|
46
|
+
let fullBillingAddress = [
|
|
47
|
+
foundInvoice.billingAddress1,
|
|
48
|
+
foundInvoice.billingAddress2,
|
|
49
|
+
foundInvoice.billingAddress3,
|
|
50
|
+
foundInvoice.billingAddress4,
|
|
51
|
+
foundInvoice.billingAddress5
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
let fullDeliveryAddress = [
|
|
55
|
+
foundInvoice.deliveryAddress1,
|
|
56
|
+
foundInvoice.deliveryAddress2,
|
|
57
|
+
foundInvoice.deliveryAddress3,
|
|
58
|
+
foundInvoice.deliveryAddress4,
|
|
59
|
+
foundInvoice.deliveryAddress5
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
let date = DateTimeConverter.date(
|
|
63
|
+
new Date((foundInvoice.issuedOn || foundInvoice.createdAt) - timezoneOffSet)
|
|
64
|
+
)
|
|
65
|
+
const data = {
|
|
66
|
+
order_no: foundReleaseGoods.name,
|
|
67
|
+
ref_no: foundReleaseGoods.refNo,
|
|
68
|
+
deliver_to: foundInvoice.deliverTo,
|
|
69
|
+
deliver_to_phone: foundInvoice.deliverToPhone || '',
|
|
70
|
+
bill_to: foundInvoice.billTo,
|
|
71
|
+
bill_to_phone: foundInvoice.billToPhone || '',
|
|
72
|
+
customer_address: partnerBiz.address,
|
|
73
|
+
delivery_date: date,
|
|
74
|
+
store_name: foundInvoice.from,
|
|
75
|
+
billing_address_1: foundInvoice.billingAddress1,
|
|
76
|
+
billing_address_2: foundInvoice.billingAddress2,
|
|
77
|
+
billing_address_3: foundInvoice.billingAddress3,
|
|
78
|
+
billing_address_4: foundInvoice.billingAddress4,
|
|
79
|
+
billing_address_5: foundInvoice.billingAddress5,
|
|
80
|
+
billing_postcode: foundInvoice.billingPostcode,
|
|
81
|
+
billing_city: foundInvoice.billingCity,
|
|
82
|
+
billing_state: foundInvoice.billingState,
|
|
83
|
+
billing_country: foundInvoice.billingCountry,
|
|
84
|
+
full_billing_address: fullBillingAddress
|
|
85
|
+
.reduce((acc, itm) => {
|
|
86
|
+
if (itm && itm.trim() != '') {
|
|
87
|
+
acc.push(itm)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return acc
|
|
91
|
+
}, [])
|
|
92
|
+
.join(' '),
|
|
93
|
+
delivery_address_1: foundInvoice.deliveryAddress1,
|
|
94
|
+
delivery_address_2: foundInvoice.deliveryAddress2,
|
|
95
|
+
delivery_address_3: foundInvoice.deliveryAddress3,
|
|
96
|
+
delivery_address_4: foundInvoice.deliveryAddress4,
|
|
97
|
+
delivery_address_5: foundInvoice.deliveryAddress5,
|
|
98
|
+
delivery_postcode: foundInvoice.deliveryPostcode,
|
|
99
|
+
delivery_city: foundInvoice.deliveryCity,
|
|
100
|
+
delivery_state: foundInvoice.deliveryState,
|
|
101
|
+
delivery_country: foundInvoice.deliveryCountry,
|
|
102
|
+
full_delivery_address: fullDeliveryAddress
|
|
103
|
+
.reduce((acc, itm) => {
|
|
104
|
+
if (itm && itm.trim() != '') {
|
|
105
|
+
acc.push(itm)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return acc
|
|
109
|
+
}, [])
|
|
110
|
+
.join(' '),
|
|
111
|
+
product_list: foundInvoice.invoiceProducts.map((item, idx) => {
|
|
112
|
+
return {
|
|
113
|
+
list_no: idx + 1,
|
|
114
|
+
product_sku: item.sku,
|
|
115
|
+
product_name: item.name,
|
|
116
|
+
product_desc: item.description,
|
|
117
|
+
product_qty: item.qty,
|
|
118
|
+
product_other_charges: item.otherCharges,
|
|
119
|
+
product_paid_price: parseFloat(item.paidPrice || item.unitPrice).toFixed(2),
|
|
120
|
+
product_unit_price: parseFloat(item.unitPrice).toFixed(2),
|
|
121
|
+
product_total_paid_price: (
|
|
122
|
+
parseFloat(item.paidPrice || item.unitPrice) * parseFloat(item.qty)
|
|
123
|
+
).toFixed(2),
|
|
124
|
+
product_total_unit_price: (parseFloat(item.unitPrice) * parseFloat(item.qty)).toFixed(2)
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const formData = new FormData()
|
|
130
|
+
formData.append('template', template)
|
|
131
|
+
formData.append('jsonString', JSON.stringify(data))
|
|
132
|
+
|
|
133
|
+
const response = await fetch(REPORT_API_URL, {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
body: formData
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return await response.text()
|
|
139
|
+
}
|
|
140
|
+
return ''
|
|
141
|
+
} catch (ex) {
|
|
142
|
+
return ''
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if (result.length <= 0) {
|
|
148
|
+
throw Error('No invoice found!')
|
|
149
|
+
}
|
|
150
|
+
return result.join()
|
|
151
|
+
} catch (ex) {
|
|
152
|
+
throw ex
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -143,6 +143,7 @@ export async function renderRODO({ doNo }, context: any) {
|
|
|
143
143
|
product_type: inventory.packingType,
|
|
144
144
|
product_size: matchedProductDetail ? matchedProductDetail.packingSize : inventory.packingSize,
|
|
145
145
|
product_batch: inventory.batchId,
|
|
146
|
+
product_batch_ref: inventory.batchIdRef,
|
|
146
147
|
product_qty: targetInventory.releaseQty,
|
|
147
148
|
product_weight: targetInventory.releaseWeight,
|
|
148
149
|
product_gross_weight: inventory.product.grossWeight,
|
|
@@ -159,6 +160,7 @@ export async function renderRODO({ doNo }, context: any) {
|
|
|
159
160
|
newItem =>
|
|
160
161
|
newItem.product_name === item.product_name &&
|
|
161
162
|
newItem.product_batch === item.product_batch &&
|
|
163
|
+
newItem.product_batch_ref === item.product_batch_ref &&
|
|
162
164
|
newItem.cross_docking === item.cross_docking &&
|
|
163
165
|
newItem.pallet === item.pallet
|
|
164
166
|
)
|
|
@@ -169,6 +171,7 @@ export async function renderRODO({ doNo }, context: any) {
|
|
|
169
171
|
product_type: item.product_type,
|
|
170
172
|
product_size: item.product_size,
|
|
171
173
|
product_batch: item.product_batch,
|
|
174
|
+
product_batch_ref: item.product_batch_ref,
|
|
172
175
|
product_qty: item.product_qty,
|
|
173
176
|
product_weight: item.product_weight,
|
|
174
177
|
product_gross_weight: item.product_gross_weight,
|
|
@@ -190,6 +193,7 @@ export async function renderRODO({ doNo }, context: any) {
|
|
|
190
193
|
if (
|
|
191
194
|
ni.product_name === item.product_name &&
|
|
192
195
|
ni.product_batch === item.product_batch &&
|
|
196
|
+
ni.product_batch_ref === item.product_batch_ref &&
|
|
193
197
|
ni.cross_docking === item.cross_docking &&
|
|
194
198
|
ni.pallet === item.pallet
|
|
195
199
|
) {
|
|
@@ -268,7 +272,8 @@ export async function renderRODO({ doNo }, context: any) {
|
|
|
268
272
|
: prod.pallet === ''
|
|
269
273
|
? `${prod.palletQty} PALLET(S)`
|
|
270
274
|
: `${prod.palletQty} PALLET(S) (${prod.pallet})`,
|
|
271
|
-
inventory_remark: prod?.inventory_remark ? prod.inventory_remark : ''
|
|
275
|
+
inventory_remark: prod?.inventory_remark ? prod.inventory_remark : '',
|
|
276
|
+
batch_id_ref: prod.product_batch_ref
|
|
272
277
|
}
|
|
273
278
|
})
|
|
274
279
|
} //.. make data from do
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import { Domain } from '@things-factory/shell'
|
|
2
|
-
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
3
1
|
import { EntityManager, SelectQueryBuilder } from 'typeorm'
|
|
4
|
-
|
|
2
|
+
|
|
5
3
|
import {
|
|
6
|
-
|
|
4
|
+
ORDER_STATUS,
|
|
7
5
|
OrderInventory as OrderInventoryEntity,
|
|
8
|
-
|
|
6
|
+
ReleaseGood as ReleaseGoodEntity
|
|
9
7
|
} from '@things-factory/sales-base'
|
|
8
|
+
import { Domain } from '@things-factory/shell'
|
|
9
|
+
|
|
10
|
+
import { WORKSHEET_STATUS, WORKSHEET_TYPE } from '../../../constants'
|
|
11
|
+
import { Worksheet as WorksheetEntity, WorksheetDetail as WorksheetDetailEntity } from '../../../entities'
|
|
10
12
|
|
|
11
13
|
export const findReleaseOrdersByTaskNoResolver = {
|
|
12
14
|
async findReleaseOrdersByTaskNo(_: any, { taskNo }, context: any) {
|
|
13
15
|
const { domain, tx }: { domain: Domain; tx: EntityManager } = context.state
|
|
14
|
-
|
|
16
|
+
let task = await tx.getRepository(WorksheetEntity).findOne({
|
|
17
|
+
where: { taskNo, status: WORKSHEET_STATUS.EXECUTING, type: WORKSHEET_TYPE.SORTING }
|
|
18
|
+
})
|
|
19
|
+
if (!task) throw new Error('Unable to find task no.')
|
|
15
20
|
|
|
16
21
|
const qb: SelectQueryBuilder<WorksheetEntity> = tx
|
|
17
22
|
.getRepository(WorksheetEntity)
|
|
@@ -33,7 +38,6 @@ export const findReleaseOrdersByTaskNoResolver = {
|
|
|
33
38
|
.addGroupBy('rg.status')
|
|
34
39
|
|
|
35
40
|
const releaseGoods: ReleaseGoodEntity[] = await qb.getRawMany()
|
|
36
|
-
if (releaseGoods.length === 0) throw new Error('Unable to find task no.')
|
|
37
41
|
return releaseGoods
|
|
38
42
|
}
|
|
39
43
|
}
|
|
@@ -64,7 +64,18 @@ export async function completeBatchPicking(
|
|
|
64
64
|
await Promise.all(
|
|
65
65
|
uniqueReleaseGoods.map(async releaseGood => {
|
|
66
66
|
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
67
|
-
|
|
67
|
+
|
|
68
|
+
let foundReleaseGood: ReleaseGood = await tx.getRepository(ReleaseGood).findOne({
|
|
69
|
+
where: { id: releaseGood.id },
|
|
70
|
+
relations: ['orderProducts', 'orderProducts.product', 'orderProducts.product.productDetails']
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
if (!foundReleaseGood?.packageId) {
|
|
74
|
+
foundReleaseGood = await sellercraftCtrl.packOrder(sellercraft, foundReleaseGood)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
foundReleaseGood = await sellercraftCtrl.initiateOrderShipment(sellercraft, foundReleaseGood)
|
|
78
|
+
await sellercraftCtrl.initiateOrderDocument(sellercraft, foundReleaseGood)
|
|
68
79
|
})
|
|
69
80
|
)
|
|
70
81
|
}
|
|
@@ -55,7 +55,10 @@ export async function completePicking(
|
|
|
55
55
|
'bizplace.company.domain',
|
|
56
56
|
'orderInventories',
|
|
57
57
|
'orderInventories.inventory',
|
|
58
|
-
'orderInventories.product'
|
|
58
|
+
'orderInventories.product',
|
|
59
|
+
'orderProducts',
|
|
60
|
+
'orderProducts.product',
|
|
61
|
+
'orderProducts.product.productDetails'
|
|
59
62
|
]
|
|
60
63
|
})
|
|
61
64
|
|
|
@@ -86,6 +89,11 @@ export async function completePicking(
|
|
|
86
89
|
|
|
87
90
|
if (sellercraft) {
|
|
88
91
|
const sellercraftCtrl: SellercraftController = new SellercraftController(tx, domain, user)
|
|
92
|
+
|
|
93
|
+
if (!releaseGood?.packageId) {
|
|
94
|
+
releaseGood = await sellercraftCtrl.packOrder(sellercraft, releaseGood)
|
|
95
|
+
}
|
|
96
|
+
|
|
89
97
|
releaseGood = await sellercraftCtrl.initiateOrderShipment(sellercraft, releaseGood)
|
|
90
98
|
await sellercraftCtrl.initiateOrderDocument(sellercraft, releaseGood)
|
|
91
99
|
} else {
|
|
@@ -94,91 +102,100 @@ export async function completePicking(
|
|
|
94
102
|
where: { orderNo: releaseGood.refNo, domain: companyDomain },
|
|
95
103
|
relations: ['marketplaceStore', 'marketplaceOrderItems', 'marketplaceOrderItems.marketplaceOrderShipping']
|
|
96
104
|
})
|
|
97
|
-
const marketplaceStore: MarketplaceStore = marketplaceOrder.marketplaceStore
|
|
98
|
-
let eTraxOption: boolean
|
|
99
105
|
|
|
100
|
-
if (
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
}
|
|
106
|
+
if (marketplaceOrder) {
|
|
107
|
+
const marketplaceStore: MarketplaceStore = marketplaceOrder.marketplaceStore
|
|
108
|
+
let eTraxOption: boolean
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// if eTrax option is true
|
|
110
|
-
if (eTraxOption) {
|
|
111
|
-
const marketplaceOrderItems: MarketplaceOrderItem[] = marketplaceOrder.marketplaceOrderItems
|
|
112
|
-
|
|
113
|
-
// access every marketplaceOrderItems for shipping information you need
|
|
114
|
-
// trigger the controller from integration-lmd that trigger the API, build the parameters needed
|
|
115
|
-
// for etrax didn't support multi awb per order
|
|
116
|
-
const marketplaceOrderShipping: MarketplaceOrderShipping = marketplaceOrderItems[0].marketplaceOrderShipping
|
|
117
|
-
const lmd: LastMileDelivery = await tx.getRepository(LastMileDelivery).findOne({
|
|
118
|
-
where: {
|
|
119
|
-
domain,
|
|
120
|
-
platform: 'eTrax'
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
//Get which transporter to use
|
|
125
|
-
const marketplaceTransporter: MarketplaceTransporter = await tx.getRepository(MarketplaceTransporter).findOne({
|
|
126
|
-
where: { marketplaceStore: marketplaceOrder.marketplaceStore },
|
|
127
|
-
relations: ['pickupTransporter', 'deliveryTransporter']
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
const resp = await LastMileAPI.createShipmentRequest(lmd, {
|
|
131
|
-
orderNo: marketplaceOrder.orderNo,
|
|
132
|
-
clientId: lmd.clientId,
|
|
133
|
-
clientType: lmd.clientType,
|
|
134
|
-
clientName: lmd.clientName,
|
|
135
|
-
transporterId: marketplaceTransporter.pickupTransporter.transporterId,
|
|
136
|
-
pickupName: warehouseContactPoint.name,
|
|
137
|
-
pickupAddress1: warehouseContactPoint.address,
|
|
138
|
-
pickupAddress2: warehouseContactPoint.address2,
|
|
139
|
-
pickupPostcode: warehouseContactPoint.postCode,
|
|
140
|
-
pickupState: warehouseContactPoint.state,
|
|
141
|
-
pickupCity: warehouseContactPoint.city,
|
|
142
|
-
pickupPhone: warehouseContactPoint.phone,
|
|
143
|
-
pickupEmail: warehouseContactPoint.email,
|
|
144
|
-
name: marketplaceOrderShipping?.attentionTo ? marketplaceOrderShipping.attentionTo.trim() : '',
|
|
145
|
-
address1: marketplaceOrderShipping?.address1 ? marketplaceOrderShipping?.address1.trim() : '-',
|
|
146
|
-
address2: marketplaceOrderShipping?.address2 ? marketplaceOrderShipping?.address2.trim() : '-',
|
|
147
|
-
postCode: marketplaceOrderShipping?.postCode ? marketplaceOrderShipping?.postCode.trim() : '',
|
|
148
|
-
city: marketplaceOrderShipping?.city ? marketplaceOrderShipping?.city.trim() : '',
|
|
149
|
-
state: marketplaceOrderShipping?.state ? marketplaceOrderShipping?.state.trim() : '',
|
|
150
|
-
phone: marketplaceOrderShipping.phone1 || '',
|
|
151
|
-
email: marketplaceOrderShipping.email || '',
|
|
152
|
-
attentionTo: marketplaceOrderShipping.attentionTo,
|
|
153
|
-
quantity: marketplaceOrderItems.length
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
const delay = (ms: number) => {
|
|
157
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
110
|
+
if (marketplaceStore.isAutoUpdateShipment) {
|
|
111
|
+
const ecommerceCtrl: EcommerceController = new EcommerceController(tx, domain, user)
|
|
112
|
+
await ecommerceCtrl.createOrderComment(marketplaceStore, marketplaceOrder, ORDER_STATUS.PACKING)
|
|
158
113
|
}
|
|
159
114
|
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
115
|
+
if (!marketplaceOrder)
|
|
116
|
+
throw new Error('Failed to find ecommerce order, kindly contact our support team regarding this issue')
|
|
117
|
+
eTraxOption = marketplaceOrder?.marketplaceStore.eTrax
|
|
118
|
+
|
|
119
|
+
// if eTrax option is true
|
|
120
|
+
if (eTraxOption) {
|
|
121
|
+
const marketplaceOrderItems: MarketplaceOrderItem[] = marketplaceOrder.marketplaceOrderItems
|
|
122
|
+
|
|
123
|
+
// access every marketplaceOrderItems for shipping information you need
|
|
124
|
+
// trigger the controller from integration-lmd that trigger the API, build the parameters needed
|
|
125
|
+
// for etrax didn't support multi awb per order
|
|
126
|
+
const marketplaceOrderShipping: MarketplaceOrderShipping = marketplaceOrderItems[0].marketplaceOrderShipping
|
|
127
|
+
const lmd: LastMileDelivery = await tx.getRepository(LastMileDelivery).findOne({
|
|
128
|
+
where: {
|
|
129
|
+
domain,
|
|
130
|
+
platform: 'eTrax'
|
|
172
131
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
//Get which transporter to use
|
|
135
|
+
const marketplaceTransporter: MarketplaceTransporter = await tx
|
|
136
|
+
.getRepository(MarketplaceTransporter)
|
|
137
|
+
.findOne({
|
|
138
|
+
where: { marketplaceStore: marketplaceOrder.marketplaceStore },
|
|
139
|
+
relations: ['pickupTransporter', 'deliveryTransporter']
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const resp = await LastMileAPI.createShipmentRequest(lmd, {
|
|
143
|
+
orderNo: marketplaceOrder.orderNo,
|
|
144
|
+
clientId: lmd.clientId,
|
|
145
|
+
clientType: lmd.clientType,
|
|
146
|
+
clientName: lmd.clientName,
|
|
147
|
+
transporterId: marketplaceTransporter.pickupTransporter.transporterId,
|
|
148
|
+
pickupName: warehouseContactPoint.name,
|
|
149
|
+
pickupAddress1: warehouseContactPoint.address,
|
|
150
|
+
pickupAddress2: warehouseContactPoint.address2,
|
|
151
|
+
pickupPostcode: warehouseContactPoint.postCode,
|
|
152
|
+
pickupState: warehouseContactPoint.state,
|
|
153
|
+
pickupCity: warehouseContactPoint.city,
|
|
154
|
+
pickupPhone: warehouseContactPoint.phone,
|
|
155
|
+
pickupEmail: warehouseContactPoint.email,
|
|
156
|
+
name: marketplaceOrderShipping?.attentionTo ? marketplaceOrderShipping.attentionTo.trim() : '',
|
|
157
|
+
address1: marketplaceOrderShipping?.address1 ? marketplaceOrderShipping?.address1.trim() : '-',
|
|
158
|
+
address2: marketplaceOrderShipping?.address2 ? marketplaceOrderShipping?.address2.trim() : '-',
|
|
159
|
+
postCode: marketplaceOrderShipping?.postCode ? marketplaceOrderShipping?.postCode.trim() : '',
|
|
160
|
+
city: marketplaceOrderShipping?.city ? marketplaceOrderShipping?.city.trim() : '',
|
|
161
|
+
state: marketplaceOrderShipping?.state ? marketplaceOrderShipping?.state.trim() : '',
|
|
162
|
+
phone: marketplaceOrderShipping.phone1 || '',
|
|
163
|
+
email: marketplaceOrderShipping.email || '',
|
|
164
|
+
attentionTo: marketplaceOrderShipping.attentionTo,
|
|
165
|
+
quantity: marketplaceOrderItems.length
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const delay = (ms: number) => {
|
|
169
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (resp.Status === 'SUCCESS') {
|
|
173
|
+
//Success
|
|
174
|
+
let awbObtained = false
|
|
175
|
+
let retry = 0
|
|
176
|
+
while (!awbObtained) {
|
|
177
|
+
const marketplaceOrder2: MarketplaceOrder = await tx.getRepository(MarketplaceOrder).findOne({
|
|
178
|
+
where: { releaseOrderId: releaseGood.id },
|
|
179
|
+
relations: [
|
|
180
|
+
'marketplaceStore',
|
|
181
|
+
'marketplaceOrderItems',
|
|
182
|
+
'marketplaceOrderItems.marketplaceOrderShipping'
|
|
183
|
+
]
|
|
184
|
+
})
|
|
185
|
+
const orderShipping = marketplaceOrder2.marketplaceOrderItems[0].marketplaceOrderShipping
|
|
186
|
+
if (orderShipping?.airwayBill) {
|
|
187
|
+
awbObtained = true
|
|
188
|
+
}
|
|
189
|
+
await delay(5000)
|
|
190
|
+
//Timeout after 15sec
|
|
191
|
+
if (++retry > 3) {
|
|
192
|
+
break
|
|
193
|
+
}
|
|
177
194
|
}
|
|
195
|
+
} else {
|
|
196
|
+
throw resp
|
|
197
|
+
//Failed
|
|
178
198
|
}
|
|
179
|
-
} else {
|
|
180
|
-
throw resp
|
|
181
|
-
//Failed
|
|
182
199
|
}
|
|
183
200
|
}
|
|
184
201
|
}
|
|
@@ -16,7 +16,7 @@ export async function completeUnloadingPartially(
|
|
|
16
16
|
domain: Domain,
|
|
17
17
|
user: User,
|
|
18
18
|
arrivalNoticeNo: string,
|
|
19
|
-
unloadingWorksheetDetail: Partial<WorksheetDetail>
|
|
19
|
+
unloadingWorksheetDetail: Partial<WorksheetDetail>[]
|
|
20
20
|
): Promise<void> {
|
|
21
21
|
const worksheetController: UnloadingWorksheetController = new UnloadingWorksheetController(tx, domain, user)
|
|
22
22
|
await worksheetController.completeUnloadingPartially(arrivalNoticeNo, unloadingWorksheetDetail)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityManager } from 'typeorm'
|
|
1
|
+
import { EntityManager, In } from 'typeorm'
|
|
2
2
|
|
|
3
3
|
import { User } from '@things-factory/auth-base'
|
|
4
4
|
import { Bizplace } from '@things-factory/biz-base'
|
|
@@ -37,7 +37,7 @@ export const completeUnloadingResolver = {
|
|
|
37
37
|
let putawayWorksheet: Worksheet
|
|
38
38
|
|
|
39
39
|
const inventories: Inventory[] = await tx.getRepository(Inventory).find({
|
|
40
|
-
where: { domain, refOrderId: arrivalNotice.id, status: INVENTORY_STATUS.UNLOADED }
|
|
40
|
+
where: { domain, refOrderId: arrivalNotice.id, status: In([INVENTORY_STATUS.UNLOADED, INVENTORY_STATUS.CHECKED]) }
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
// search for any active marketplace connection
|
package/server/routes.ts
CHANGED
|
@@ -8,6 +8,7 @@ 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 { renderInvoices } from './controllers/render-invoices'
|
|
11
12
|
|
|
12
13
|
process.on('bootstrap-module-domain-private-route' as any, (app, routes) => {
|
|
13
14
|
routes.get('/view_document_ro_do/:doNo', async (context, next) => {
|
|
@@ -49,4 +50,14 @@ process.on('bootstrap-module-domain-private-route' as any, (app, routes) => {
|
|
|
49
50
|
routes.get('/view_manifest/:manifestNo', async (context, next) => {
|
|
50
51
|
context.body = await renderManifest(context.params, context)
|
|
51
52
|
})
|
|
53
|
+
|
|
54
|
+
routes.post('/view_invoices/:timezoneOffSet', async (context, next) => {
|
|
55
|
+
let req = context.request.body || {}
|
|
56
|
+
let timezoneOffSet = context.params.timezoneOffSet || 0
|
|
57
|
+
|
|
58
|
+
let data = await renderInvoices({ req, timezoneOffSet }, context)
|
|
59
|
+
|
|
60
|
+
context.type = 'application/json'
|
|
61
|
+
context.body = data
|
|
62
|
+
})
|
|
52
63
|
})
|