Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved: Receive shipment enhancement (#402). #391

Merged
merged 8 commits into from
Nov 18, 2024
1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,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",
Expand Down
9 changes: 9 additions & 0 deletions src/services/OrderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ const createPurchaseShipment = async (payload: any): Promise<any> => {
})
}

const createIncomingShipment = async (payload: any): Promise<any> => {
return api({
url: "/service/createIncomingShipment",
method: "POST",
data: payload
})
}

const fetchPOHistory = async (payload: any): Promise<any> => {
return api({
url: "/performFind",
Expand All @@ -43,6 +51,7 @@ const updatePOItemStatus = async (payload: any): Promise<any> => {
export const OrderService = {
fetchPurchaseOrders,
fetchPODetail,
createIncomingShipment,
createPurchaseShipment,
fetchPOHistory,
updatePOItemStatus
Expand Down
42 changes: 42 additions & 0 deletions src/services/UploadService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { api } from '@/adapter';
import { UploadRequest } from '@/types'

const uploadJsonFile = async (payload: any): Promise <any> => {
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;'
}
}
}

const fetchDataManagerLog = async (payload: any): Promise<any> => {
return api({
url: "/performFind",
method: "POST",
data: payload
})
}

export const UploadService = {
fetchDataManagerLog,
prepareUploadJsonPayload,
uploadJsonFile
}
47 changes: 46 additions & 1 deletion src/store/modules/order/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
}
commit(types.ORDER_CURRENT_PRODUCT_ADDED, product)
},
async getOrderDetail({ commit, state }, { orderId }) {

Check warning on line 71 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'state' is defined but never used

Check warning on line 71 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'state' is defined but never used
let resp;

try {
Expand Down Expand Up @@ -106,7 +106,7 @@
}
return resp;
},
async createPurchaseShipment({ commit }, payload) {

Check warning on line 109 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'commit' is defined but never used

Check warning on line 109 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'commit' is defined but never used
let resp;
try {
const params = {
Expand Down Expand Up @@ -150,6 +150,50 @@
return resp;
},

async createAndReceiveIncomingShipment({ commit }, payload) {

Check warning on line 153 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'commit' is defined but never used

Check warning on line 153 in src/store/modules/order/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'commit' is defined but never used
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;
Expand All @@ -161,7 +205,8 @@
},
"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 : "";
Expand Down
1 change: 1 addition & 0 deletions src/store/modules/return/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const actions: ActionTree<ReturnState, RootState> = {
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."))
Expand Down
72 changes: 72 additions & 0 deletions src/store/modules/shipment/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
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";

Check warning on line 12 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'toHandlerKey' is defined but never used

Check warning on line 12 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'toHandlerKey' is defined but never used

const actions: ActionTree<ShipmentState, RootState> = {
async findShipment ({ commit, state }, payload) {
Expand Down Expand Up @@ -102,7 +105,7 @@
return Promise.reject(new Error(err))
}
},
async receiveShipmentItem ({ commit }, payload) {

Check warning on line 108 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'commit' is defined but never used

Check warning on line 108 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'commit' is defined but never used
let areAllSuccess = true;

for (const item of payload.items) {
Expand Down Expand Up @@ -138,6 +141,75 @@

return areAllSuccess;
},
async receiveShipmentJson ({ dispatch }, payload) {

Check warning on line 144 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'dispatch' is defined but never used

Check warning on line 144 in src/store/modules/shipment/actions.ts

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'dispatch' is defined but never used
emitter.emit("presentLoader");
const fileName = `ReceiveShipment_${payload.shipmentId}_${DateTime.now().toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS)}.json`;
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,
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)) {
const uploadFileContentId = resp.data.uploadFileContentId;
if (uploadFileContentId) {
resp = await UploadService.fetchDataManagerLog({
"inputFields": {
"configId": "RECEIVE_SHIP_ITEMS",
"uploadFileContentId": uploadFileContentId,
"errorRecordContentId_op": "empty",
"statusI": "SERVICE_FINISHED",
},
"fieldList": ["logId", "configId", "uploadFileContentId", "errorRecordContentId", "statusId"],
"entityName": "DataManagerLog",
"viewSize": 1
});
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({
"shipmentId": payload.shipmentId,
"statusId": "PURCH_SHIP_RECEIVED"
})
if (resp.status == 200 && !hasError(resp)) {
return true;
} else {
throw resp.data;
}
} else {
throw resp.data;
}
}
} else {
throw resp.data;
}
} catch (err) {
showToast(translate("Something went wrong, please try again"));
}
emitter.emit("dismissLoader");
return false;
},

async receiveShipment ({ dispatch }, payload) {
emitter.emit("presentLoader", {message: 'Receiving in-progress.', backdropDismiss: false});
const areAllSuccess = await dispatch("receiveShipmentItem", payload);
Expand Down
5 changes: 5 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface UploadRequest {
params?: any;
fileName?: string;
uploadData: any;
}
9 changes: 7 additions & 2 deletions src/views/PurchaseOrderDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
import ClosePurchaseOrderModal from '@/components/ClosePurchaseOrderModal.vue'
import LocationPopover from '@/components/LocationPopover.vue'
import ImageModal from '@/components/ImageModal.vue';
import { copyToClipboard, hasError, showToast } from '@/utils';

Check warning on line 193 in src/views/PurchaseOrderDetail.vue

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'hasError' is defined but never used

Check warning on line 193 in src/views/PurchaseOrderDetail.vue

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'hasError' is defined but never used
import { Actions, hasPermission } from '@/authorization'

export default defineComponent({
Expand Down Expand Up @@ -382,9 +382,14 @@
},
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() {
Expand Down
14 changes: 9 additions & 5 deletions src/views/ReturnDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@
</div>

<div class="product-count">
<ion-item v-if="isReturnReceivable(current.statusId)">
<ion-item v-if="isReturnReceivable(current.statusId) && item.quantityReceived === 0">
<ion-input :label="translate('Qty')" :disabled="isForceScanEnabled" label-placement="floating" type="number" min="0" v-model="item.quantityAccepted" />
</ion-item>
<ion-item v-if="!isReturnReceivable(current.statusId)" lines="none">
<ion-item v-else lines="none">
<ion-label>{{ item.quantityAccepted }} {{ translate("received") }}</ion-label>
</ion-item>
</div>
</div>

<ion-item lines="none" class="border-top" v-if="item.quantityOrdered > 0">
<ion-button v-if="isReturnReceivable(current.statusId)" :disabled="isForceScanEnabled" @click="receiveAll(item)" slot="start" fill="outline">
<ion-button v-if="isReturnReceivable(current.statusId) && item.quantityReceived === 0" :disabled="isForceScanEnabled" @click="receiveAll(item)" slot="start" fill="outline">
{{ translate("Receive All") }}
</ion-button>
<ion-progress-bar :color="getRcvdToOrdrdFraction(item) === 1 ? 'success' : getRcvdToOrdrdFraction(item) > 1 ? 'danger' : 'primary'" :value="getRcvdToOrdrdFraction(item)" />
Expand Down Expand Up @@ -117,7 +117,7 @@
import { useRouter } from 'vue-router';
import Scanner from "@/components/Scanner.vue";
import ImageModal from '@/components/ImageModal.vue';
import { hasError } from '@/utils';

Check warning on line 120 in src/views/ReturnDetails.vue

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (18.x)

'hasError' is defined but never used

Check warning on line 120 in src/views/ReturnDetails.vue

View workflow job for this annotation

GitHub Actions / call-workflow-in-another-repo / reusable_workflow_job (20.x)

'hasError' is defined but never used
import { showToast } from '@/utils'
import { Actions, hasPermission } from '@/authorization'
import { ProductService } from '@/services/ProductService';
Expand Down Expand Up @@ -255,9 +255,13 @@
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() {
Expand Down
5 changes: 3 additions & 2 deletions src/views/ShipmentDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ 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 isShipmentReceived = await this.store.dispatch('shipment/receiveShipment', { items: eligibleItems, shipmentId })
if(isShipmentReceived) {
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"))
Expand Down
Loading