From ec4f45dcbcad8d07a4c13960ec391cdbc2ce3ce4 Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Fri, 11 Oct 2024 16:08:30 +0530 Subject: [PATCH 1/4] Improved: Used MDM(Uploading json file) to receive items. --- src/services/UploadService.ts | 33 ++++++++++++ src/store/modules/shipment/actions.ts | 75 +++++++++++++++++++++++++++ src/types/index.ts | 5 ++ src/views/ShipmentDetails.vue | 2 +- 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/services/UploadService.ts create mode 100644 src/types/index.ts diff --git a/src/services/UploadService.ts b/src/services/UploadService.ts new file mode 100644 index 00000000..c6198277 --- /dev/null +++ b/src/services/UploadService.ts @@ -0,0 +1,33 @@ +import { api } from '@/adapter'; +import { UploadRequest } from '@/types' + +const uploadJsonFile = async (payload: any): Promise => { + return api({ + url: "uploadAndImportFile", + method: "post", + ...payload + }); +} + +const prepareUploadJsonPayload = (request: UploadRequest) => { + const blob = new Blob([JSON.stringify(request.uploadData)], { type: 'application/json'}); + const formData = new FormData(); + const fileName = request.fileName ? request.fileName : Date.now() + ".json" ; + formData.append("uploadedFile", blob, fileName); + if (request.params) { + for (const key in request.params) { + formData.append(key, request.params[key]); + } + } + return { + data: formData, + headers: { + 'Content-Type': 'multipart/form-data;' + } + } +} + +export const UploadService = { + prepareUploadJsonPayload, + uploadJsonFile +} \ No newline at end of file diff --git a/src/store/modules/shipment/actions.ts b/src/store/modules/shipment/actions.ts index 5b761523..0209b92d 100644 --- a/src/store/modules/shipment/actions.ts +++ b/src/store/modules/shipment/actions.ts @@ -7,6 +7,9 @@ import { hasError, showToast } from '@/utils' import { getProductIdentificationValue, translate } from '@hotwax/dxp-components' import emitter from '@/event-bus' import store from "@/store"; +import { DateTime } from 'luxon'; +import { UploadService } from "@/services/UploadService"; +import { toHandlerKey } from "vue"; const actions: ActionTree = { async findShipment ({ commit, state }, payload) { @@ -123,6 +126,78 @@ const actions: ActionTree = { } })) }, + async receiveShipmentJson ({ dispatch }, payload) { + emitter.emit("presentLoader"); + const fileName = `ReceiveShipment_${payload.shipmentId}_${DateTime.now().toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS)}.json`; + const params = { + "configId": "RECEIVE_SHIP_ITEMS" + } + const uploadData = payload.items.map((item: any) => { + return { + shipmentId: payload.shipmentId, + facilityId: this.state.user.currentFacility.facilityId, + shipmentItemSeqId: item.itemSeqId, + productId: item.productId, + quantityAccepted: item.quantityAccepted, + orderId: item.orderId, + orderItemSeqId: item.orderItemSeqId, + unitCost: 0.00, + locationSeqId: item.locationSeqId + }; + }) + + try { + const uploadPayload = UploadService.prepareUploadJsonPayload({ + uploadData, + fileName, + params + }); + let resp = await UploadService.uploadJsonFile(uploadPayload); + if (resp.status == 200 && !hasError(resp)) { + resp = await ShipmentService.receiveShipment({ + "shipmentId": payload.shipmentId, + "statusId": "PURCH_SHIP_RECEIVED" + }) + if (resp.status == 200 && !hasError(resp)) { + showToast(translate("Shipment received successfully", { shipmentId: payload.shipmentId })) + } else { + throw resp.data; + } + return resp; + } else { + throw resp.data; + } + } catch (err) { + showToast(translate("Something went wrong, please try again")); + } + emitter.emit("dismissLoader"); + + + + /* UploadService.uploadJsonFile(UploadService.prepareUploadJsonPayload({ + uploadData, + fileName, + params + })).then(async (resp: any) => { + if (!hasError(resp)) { + resp = await ShipmentService.receiveShipment({ + "shipmentId": payload.shipmentId, + "statusId": "PURCH_SHIP_RECEIVED" + }) + console.log("=======resp==", resp); + if (resp.status == 200 && !hasError(resp)) { + showToast(translate("Shipment received successfully", { shipmentId: payload.shipmentId })) + } + emitter.emit("dismissLoader"); + return resp; + } else { + throw resp.data; + } + }).catch(() => { + showToast(translate("Something went wrong, please try again")); + })*/ + }, + async receiveShipment ({ dispatch }, payload) { emitter.emit("presentLoader"); return await dispatch("receiveShipmentItem", payload).then(async () => { diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 00000000..980465b0 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,5 @@ +export interface UploadRequest { + params?: any; + fileName?: string; + uploadData: any; +} \ No newline at end of file diff --git a/src/views/ShipmentDetails.vue b/src/views/ShipmentDetails.vue index 2497d3ba..180553b9 100644 --- a/src/views/ShipmentDetails.vue +++ b/src/views/ShipmentDetails.vue @@ -225,7 +225,7 @@ export default defineComponent({ async receiveShipment() { const eligibleItems = this.current.items.filter((item: any) => item.quantityAccepted > 0) const shipmentId = this.current.shipment ? this.current.shipment.shipmentId : this.current.shipmentId - const resp = await this.store.dispatch('shipment/receiveShipment', { items: eligibleItems, shipmentId }) + const resp = await this.store.dispatch('shipment/receiveShipmentJson', { items: eligibleItems, shipmentId }) if (resp.status === 200 && !hasError(resp)) { this.router.push('/shipments'); } else { From c38915f3e849c5f63f3ef4ca3a563a8e7605c0db Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Fri, 11 Oct 2024 16:10:15 +0530 Subject: [PATCH 2/4] Removed: unused code. --- src/store/modules/shipment/actions.ts | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/store/modules/shipment/actions.ts b/src/store/modules/shipment/actions.ts index 0209b92d..1625b321 100644 --- a/src/store/modules/shipment/actions.ts +++ b/src/store/modules/shipment/actions.ts @@ -171,31 +171,6 @@ const actions: ActionTree = { showToast(translate("Something went wrong, please try again")); } emitter.emit("dismissLoader"); - - - - /* UploadService.uploadJsonFile(UploadService.prepareUploadJsonPayload({ - uploadData, - fileName, - params - })).then(async (resp: any) => { - if (!hasError(resp)) { - resp = await ShipmentService.receiveShipment({ - "shipmentId": payload.shipmentId, - "statusId": "PURCH_SHIP_RECEIVED" - }) - console.log("=======resp==", resp); - if (resp.status == 200 && !hasError(resp)) { - showToast(translate("Shipment received successfully", { shipmentId: payload.shipmentId })) - } - emitter.emit("dismissLoader"); - return resp; - } else { - throw resp.data; - } - }).catch(() => { - showToast(translate("Something went wrong, please try again")); - })*/ }, async receiveShipment ({ dispatch }, payload) { From 63d344b335ea698a9e4603776b34913434f35de7 Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Wed, 16 Oct 2024 15:19:39 +0530 Subject: [PATCH 3/4] Improved: Added checks to allow receiving of items if it was not received earlier. This is helpful when some of the items got failed and allowed to receive the remaining items. --- src/store/modules/shipment/actions.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/store/modules/shipment/actions.ts b/src/store/modules/shipment/actions.ts index b1d454e0..12a50d5f 100644 --- a/src/store/modules/shipment/actions.ts +++ b/src/store/modules/shipment/actions.ts @@ -147,6 +147,9 @@ const actions: ActionTree = { const params = { "configId": "RECEIVE_SHIP_ITEMS" } + if(!payload.isMultiReceivingEnabled) { + payload.items = payload.items.filter((item: any) => item.quantityReceived === 0) + } const uploadData = payload.items.map((item: any) => { return { shipmentId: payload.shipmentId, @@ -171,7 +174,6 @@ const actions: ActionTree = { if (resp.status == 200 && !hasError(resp)) { const uploadFileContentId = resp.data.uploadFileContentId; if (uploadFileContentId) { - console.log("=========uploadFileContentId==", uploadFileContentId) resp = await UploadService.fetchDataManagerLog({ "inputFields": { "configId": "RECEIVE_SHIP_ITEMS", @@ -183,7 +185,6 @@ const actions: ActionTree = { "entityName": "DataManagerLog", "viewSize": 1 }); - console.log("=========resp==", resp) if (!hasError(resp) && resp.data.docs.length) { //If there is no error and file is processed then mark the shipment as received resp = await ShipmentService.receiveShipment({ From b201629aa516a61d14bbaa0dd228d9a26c11d7b6 Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Tue, 22 Oct 2024 11:36:16 +0530 Subject: [PATCH 4/4] Improved: Used createIncomingShipment service to create shipment with items instead of doing multiple calls for creating/adding shipment and items. Also used the common flow for shipment, return and po to import the json file and processing the item receiving at backend. (#402) --- src/locales/en.json | 1 + src/services/OrderService.ts | 9 +++++ src/store/modules/order/actions.ts | 47 ++++++++++++++++++++++++++- src/store/modules/return/actions.ts | 1 + src/store/modules/shipment/actions.ts | 2 -- src/views/PurchaseOrderDetail.vue | 9 +++-- src/views/ReturnDetails.vue | 14 +++++--- src/views/ShipmentDetails.vue | 1 + 8 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 8d36c657..967f66d7 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -79,6 +79,7 @@ "Purchase Order": "Purchase Order", "Purchase Order Details": "Purchase Order Details", "Purchase Orders": "Purchase Orders", + "Purchase order received successfully" : "Purchase order received successfully {orderId}", "Qty": "Qty", "Receive": "Receive", "Receive All": "Receive All", diff --git a/src/services/OrderService.ts b/src/services/OrderService.ts index a10e0bc1..988e9495 100644 --- a/src/services/OrderService.ts +++ b/src/services/OrderService.ts @@ -24,6 +24,14 @@ const createPurchaseShipment = async (payload: any): Promise => { }) } +const createIncomingShipment = async (payload: any): Promise => { + return api({ + url: "/service/createIncomingShipment", + method: "POST", + data: payload + }) +} + const fetchPOHistory = async (payload: any): Promise => { return api({ url: "/performFind", @@ -43,6 +51,7 @@ const updatePOItemStatus = async (payload: any): Promise => { export const OrderService = { fetchPurchaseOrders, fetchPODetail, + createIncomingShipment, createPurchaseShipment, fetchPOHistory, updatePOItemStatus diff --git a/src/store/modules/order/actions.ts b/src/store/modules/order/actions.ts index 9d56b736..55258b2e 100644 --- a/src/store/modules/order/actions.ts +++ b/src/store/modules/order/actions.ts @@ -164,6 +164,50 @@ const actions: ActionTree = { return resp; }, + async createAndReceiveIncomingShipment({ commit }, payload) { + let resp; + try { + payload.items.map((item: any, index: number) => { + item.itemSeqId = `1000${index+1}` + item.quantity = item.quantityAccepted + }) + + const params = { + orderId: payload.orderId, + destinationFacilityId: this.state.user.currentFacility.facilityId, + "type": "PURCHASE_SHIPMENT", + "status": "PURCH_SHIP_CREATED", + "items": payload.items + } + resp = await OrderService.createIncomingShipment({"payload": params}) + + if (resp.status === 200 && !hasError(resp) && resp.data.shipmentId) { + const facilityLocations = await this.dispatch('user/getFacilityLocations', this.state.user.currentFacility.facilityId); + if (facilityLocations.length){ + const locationSeqId = facilityLocations[0].locationSeqId + payload.items.map((item: any) => { + item.locationSeqId = locationSeqId + item.quantityReceived = item.quantityAccepted ? Number(item.quantityAccepted) : 0 + }) + } else { + showToast(translate("Facility locations were not found corresponding to destination facility of PO. Please add facility locations to avoid receive PO failure.")) + } + const poShipment = { + shipmentId : resp.data.shipmentId, + items: payload.items, + isMultiReceivingEnabled: true + } + return await this.dispatch('shipment/receiveShipmentJson', poShipment).catch((err) => console.error(err)) + } else { + showToast(translate("Something went wrong")); + } + } catch(error){ + console.error(error) + showToast(translate("Something went wrong")); + } + return false; + }, + async getPOHistory({ commit, state }, payload) { let resp; const current = state.current as any; @@ -175,7 +219,8 @@ const actions: ActionTree = { }, "entityName": "ShipmentReceiptAndItem", "fieldList": ["datetimeReceived", "productId", "quantityAccepted", "quantityRejected", "receivedByUserLoginId", "shipmentId", 'locationSeqId'], - "orderBy": 'datetimeReceived DESC' + "orderBy": 'datetimeReceived DESC', + "viewSize": "250" } const facilityLocations = await this.dispatch('user/getFacilityLocations', this.state.user.currentFacility.facilityId); const locationSeqId = facilityLocations.length > 0 ? facilityLocations[0].locationSeqId : ""; diff --git a/src/store/modules/return/actions.ts b/src/store/modules/return/actions.ts index 4bd19b35..7deb5c05 100644 --- a/src/store/modules/return/actions.ts +++ b/src/store/modules/return/actions.ts @@ -90,6 +90,7 @@ const actions: ActionTree = { const locationSeqId = facilityLocations[0].locationSeqId resp.data.items.map((item: any) => { item.locationSeqId = locationSeqId; + item.quantityReceived = item.quantityAccepted ? Number(item.quantityAccepted) : 0 }); } else { showToast(translate("Facility locations were not found corresponding to destination facility of return shipment. Please add facility locations to avoid receive return shipment failure.")) diff --git a/src/store/modules/shipment/actions.ts b/src/store/modules/shipment/actions.ts index 12a50d5f..ac9fe0e5 100644 --- a/src/store/modules/shipment/actions.ts +++ b/src/store/modules/shipment/actions.ts @@ -192,7 +192,6 @@ const actions: ActionTree = { "statusId": "PURCH_SHIP_RECEIVED" }) if (resp.status == 200 && !hasError(resp)) { - showToast(translate("Shipment received successfully", { shipmentId: payload.shipmentId })) return true; } else { throw resp.data; @@ -205,7 +204,6 @@ const actions: ActionTree = { throw resp.data; } } catch (err) { - await dispatch('setCurrent', { shipmentId: payload.shipmentId }) showToast(translate("Something went wrong, please try again")); } emitter.emit("dismissLoader"); diff --git a/src/views/PurchaseOrderDetail.vue b/src/views/PurchaseOrderDetail.vue index c55fc3cf..ec989379 100644 --- a/src/views/PurchaseOrderDetail.vue +++ b/src/views/PurchaseOrderDetail.vue @@ -361,9 +361,14 @@ export default defineComponent({ }, async createShipment() { const eligibleItems = this.order.items.filter((item: any) => item.quantityAccepted > 0) - const resp = await this.store.dispatch('order/createPurchaseShipment', { items: eligibleItems, orderId: this.order.orderId }) - if (resp.status === 200 && !hasError(resp)) { + const isShipmentReceived = await this.store.dispatch('order/createAndReceiveIncomingShipment', { items: eligibleItems, orderId: this.order.orderId }) + if (isShipmentReceived) { + showToast(translate("Purchase order received successfully", { orderId: this.order.orderId })) this.router.push('/purchase-orders') + } else { + this.store.dispatch("order/getOrderDetail", { orderId: this.$route.params.slug }).then(() => { + this.store.dispatch('order/getPOHistory', { orderId: this.order.orderId }) + }) } }, isEligibileForCreatingShipment() { diff --git a/src/views/ReturnDetails.vue b/src/views/ReturnDetails.vue index 52508f0e..cfeb9790 100644 --- a/src/views/ReturnDetails.vue +++ b/src/views/ReturnDetails.vue @@ -55,17 +55,17 @@
- + - + {{ item.quantityAccepted }} {{ translate("received") }}
- + {{ translate("Receive All") }} @@ -228,9 +228,13 @@ export default defineComponent({ async receiveReturn() { const eligibleItems = this.current.items.filter((item: any) => item.quantityAccepted > 0) const shipmentId = this.current.shipment ? this.current.shipment.shipmentId : this.current.shipmentId - let resp = await this.store.dispatch('return/receiveReturn', { items: eligibleItems, shipmentId }); - if(resp.status === 200 && !hasError(resp)) { + let isReturnReceived = await this.store.dispatch('shipment/receiveShipmentJson', { items: eligibleItems, shipmentId }); + if (isReturnReceived) { + showToast(translate("Return received successfully", { shipmentId: shipmentId })) this.router.push('/returns'); + } else { + showToast(translate('Something went wrong')); + await this.store.dispatch('return/setCurrent', { shipmentId: this.$route.params.id }) } }, isEligibleForReceivingReturns() { diff --git a/src/views/ShipmentDetails.vue b/src/views/ShipmentDetails.vue index eb540e6c..4a71f370 100644 --- a/src/views/ShipmentDetails.vue +++ b/src/views/ShipmentDetails.vue @@ -227,6 +227,7 @@ export default defineComponent({ const shipmentId = this.current.shipment ? this.current.shipment.shipmentId : this.current.shipmentId const isShipmentReceived = await this.store.dispatch('shipment/receiveShipmentJson', { items: eligibleItems, shipmentId }) if (isShipmentReceived) { + showToast(translate("Shipment received successfully", { shipmentId: shipmentId })) this.router.push('/shipments'); } else { showToast(translate("Failed to receive shipment"))