diff --git a/src/components/Menu.vue b/src/components/Menu.vue index fa41ce7e..68c2dce0 100644 --- a/src/components/Menu.vue +++ b/src/components/Menu.vue @@ -80,6 +80,7 @@ export default defineComponent({ url: "/open", iosIcon: mailUnreadOutline, mdIcon: mailUnreadOutline, + childRoutes: ["/open/"], meta: { permissionId: "APP_OPEN_ORDERS_VIEW" } @@ -89,6 +90,7 @@ export default defineComponent({ url: "/in-progress", iosIcon: mailOpenOutline, mdIcon: mailOpenOutline, + childRoutes: ["/in-progress/"], meta: { permissionId: "APP_IN_PROGRESS_ORDERS_VIEW" } @@ -98,6 +100,7 @@ export default defineComponent({ url: "/completed", iosIcon: checkmarkDoneOutline, mdIcon: checkmarkDoneOutline, + childRoutes: ["/completed/"], meta: { permissionId: "APP_COMPLETED_ORDERS_VIEW" } @@ -122,7 +125,7 @@ export default defineComponent({ const selectedIndex = computed(() => { const path = router.currentRoute.value.path - return appPages.findIndex((screen) => screen.url === path || screen.childRoutes?.includes(path)) + return appPages.findIndex((screen) => screen.url === path || screen.childRoutes?.includes(path) || screen.childRoutes?.some((route) => path.includes(route))) }) return { diff --git a/src/components/OrderActionsPopover.vue b/src/components/OrderActionsPopover.vue index bb2a764c..17048393 100644 --- a/src/components/OrderActionsPopover.vue +++ b/src/components/OrderActionsPopover.vue @@ -6,7 +6,7 @@ {{ translate("Copy ID") }} - + {{ translate("Pick order") }} @@ -70,7 +70,7 @@ export default defineComponent({ async viewOrder() { this.store.dispatch('order/updateCurrent', this.order).then(() => { this.closePopover(); - this.$router.push({ path: `/order-detail/${this.order.orderId}` }) + this.$router.push({ path: `${this.category}/order-detail/${this.order.orderId}/${this.order.shipGroupSeqId}` }) }) }, }, diff --git a/src/locales/en.json b/src/locales/en.json index 12425215..1ce4f6f5 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -259,6 +259,7 @@ "Shipping labels": "Shipping labels", "Some of the mapping fields are missing in the CSV: ": "Some of the mapping fields are missing in the CSV: {missingFields}", "Something went wrong": "Something went wrong", + "Something went wrong, could not fetch order details.": "Something went wrong, could not fetch order details.", "Something went wrong, could not edit picker(s)": "Something went wrong, could not edit picker(s)", "Something went wrong while login. Please contact administrator.": "Something went wrong while login. Please contact administrator.", "Sorry, your username or password is incorrect. Please try again.": "Sorry, your username or password is incorrect. Please try again.", @@ -289,6 +290,7 @@ "Turn on fulfillment": "Turn on fulfillment", "Turn on fulfillment for ": "Turn on fulfillment for { facilityName }", "Turn off fulfillment for ": "Turn off fulfillment for { facilityName }", + "Unable to fetch the order details. Either the order has been shipped or something went wrong. Please try again after some time.": "Unable to fetch the order details. Either the order has been shipped or something went wrong. Please try again after some time.", "Unlimited": "Unlimited", "Unlimited Capacity": "Unlimited Capacity", "Unlimited capacity removes the fulfillment capacity limit entirely. To add a fulfillment capacity to this facility, use the custom option.": "Unlimited capacity removes the fulfillment capacity limit entirely. To add a fulfillment capacity to this facility, use the custom option.", diff --git a/src/locales/es.json b/src/locales/es.json index a82a4a0b..fb8c34ac 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -261,6 +261,7 @@ "Shipping labels": "Etiquetas de Envío", "Some of the mapping fields are missing in the CSV: ": "Some of the mapping fields are missing in the CSV: {missingFields}", "Something went wrong": "Algo salió mal", + "Something went wrong, could not fetch order details.": "Something went wrong, could not fetch order details.", "Something went wrong, could not edit picker(s)": "Something went wrong, could not edit picker(s)", "Something went wrong while login. Please contact administrator.": "Something went wrong while login. Please contact administrator.", "Sorry, your username or password is incorrect. Please try again.": "Lo siento, tu nombre de usuario o contraseña es incorrecto. Por favor, inténtalo nuevamente.", @@ -291,6 +292,7 @@ "Turn on fulfillment": "Activar Cumplimiento", "Turn on fulfillment for ": "Activar cumplimiento para {facilityName}", "Turn off fulfillment for ": "Desactivar cumplimiento para {facilityName}", + "Unable to fetch the order details. Either the order has been shipped or something went wrong. Please try again after some time.": "Unable to fetch the order details. Either the order has been shipped or something went wrong. Please try again after some time.", "Unlimited": "Unlimited", "Unlimited Capacity": "Unlimited Capacity", "Unlimited fulfillment capacity": "Unlimited fulfillment capacity", diff --git a/src/router/index.ts b/src/router/index.ts index b2908370..463a059f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -77,10 +77,11 @@ const routes: Array = [ } }, { - path: '/order-detail/:orderId', + path: '/:category/order-detail/:orderId/:shipGroupSeqId', name: 'OrderDetail', component: OrderDetail, beforeEnter: authGuard, + props: true, meta: { permissionId: "APP_ORDER_DETAIL_VIEW" } diff --git a/src/store/index.ts b/src/store/index.ts index a8c47178..6a4ca665 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -22,7 +22,7 @@ const state: any = { } const persistState = createPersistedState({ - paths: ['user', 'order.current'], + paths: ['user'], fetchBeforeUse: true }) diff --git a/src/store/modules/order/actions.ts b/src/store/modules/order/actions.ts index f187d2af..46d6c6a7 100644 --- a/src/store/modules/order/actions.ts +++ b/src/store/modules/order/actions.ts @@ -266,6 +266,7 @@ const actions: ActionTree = { orders = orders.map((order: any) => { const orderItem = order.doclist.docs[0]; return { + category: 'in-progress', customerId: orderItem.customerId, customerName: orderItem.customerName, orderId: orderItem.orderId, @@ -275,6 +276,7 @@ const actions: ActionTree = { picklistBinId: orderItem.picklistBinId, picklistId: orderItem.picklistId, items: order.doclist.docs, + shipGroupSeqId: orderItem.shipGroupSeqId, shipmentMethodTypeId: orderItem.shipmentMethodTypeId, shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, shippingInstructions: orderItem.shippingInstructions @@ -359,6 +361,7 @@ const actions: ActionTree = { orders = orders.map((order: any) => { const orderItem = order.doclist.docs[0]; return { + category: 'open', customerId: orderItem.customerId, customerName: orderItem.customerName, orderId: orderItem.orderId, @@ -366,6 +369,7 @@ const actions: ActionTree = { orderName: orderItem.orderName, groupValue: order.groupValue, items: order.doclist.docs, + shipGroupSeqId: orderItem.shipGroupSeqId, shipmentMethodTypeId: orderItem.shipmentMethodTypeId, shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, shippingInstructions: orderItem.shippingInstructions, @@ -427,7 +431,6 @@ const actions: ActionTree = { total = resp.data.grouped.picklistBinId.ngroups orders = resp.data.grouped.picklistBinId.groups this.dispatch('product/getProductInformation', { orders }) - } else { throw resp.data } @@ -442,6 +445,7 @@ const actions: ActionTree = { const orderItem = order.doclist.docs[0]; // basic information for the order return { + category: 'completed', customerId: orderItem.customerId, customerName: orderItem.customerName, orderId: orderItem.orderId, @@ -452,6 +456,7 @@ const actions: ActionTree = { picklistBinId: orderItem.picklistBinId, picklistId: orderItem.picklistId, items: order.doclist.docs, + shipGroupSeqId: orderItem.shipGroupSeqId, shipmentId: orderItem.shipmentId, shipmentMethodTypeId: orderItem.shipmentMethodTypeId, shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, @@ -474,6 +479,7 @@ const actions: ActionTree = { emitter.emit('dismissLoader'); return resp; }, + async fetchPaymentDetail({ commit, state }) { try { const order = JSON.parse(JSON.stringify(state.current)); @@ -494,13 +500,14 @@ const actions: ActionTree = { } order.orderPaymentPreferences = orderPaymentPreferences; - commit(types.ORDER_CURRENT_UPDATED, { order }); + commit(types.ORDER_CURRENT_UPDATED, order); } } } catch (err) { logger.error("Error in fetching payment detail.", err); } }, + async fetchShippingAddress ({ commit, state }) { let resp; let order = JSON.parse(JSON.stringify(state.current)) @@ -519,15 +526,16 @@ const actions: ActionTree = { } } } catch (err: any) { - logger.error("Error in setting current order", err); + logger.error("Error in fetching shipping address information for current order", err); } - commit(types.ORDER_CURRENT_UPDATED, { order }) + commit(types.ORDER_CURRENT_UPDATED, order) }, async clearOrders ({ commit }) { commit(types.ORDER_INPROGRESS_CLEARED) commit(types.ORDER_OPEN_CLEARED) commit(types.ORDER_COMPLETED_CLEARED) + commit(types.ORDER_CURRENT_UPDATED, {}) }, async clearOpenOrders({ commit }) { @@ -571,6 +579,206 @@ const actions: ActionTree = { commit(types.ORDER_OPEN_QUERY_UPDATED, payload) }, + async getOpenOrder({ dispatch, state }, payload) { + const current = state.current as any + if (current.orderId === payload.orderId && current.category === 'open' && current.shipGroupSeqId === payload.shipGroupSeqId) { + return + } + + const orders = JSON.parse(JSON.stringify(state.open.list)) as Array + if (orders.length) { + const order = orders.find((order: any) => order.orderId === payload.orderId && current.category === 'open' && payload.shipGroupSeqId === order.shipGroupSeqId) + if (order) { + dispatch('updateCurrent', order) + return + } + } + + let resp, order = {} as any; + emitter.emit('presentLoader'); + + const params = { + viewSize: 1, + filters: { + orderId: { value: payload.orderId }, + quantityNotAvailable: { value: 0 }, + isPicked: { value: 'N' }, + shipGroupSeqId: { value: payload.shipGroupSeqId }, + '-shipmentMethodTypeId': { value: 'STOREPICKUP' }, + '-fulfillmentStatus': { value: 'Cancelled' }, + orderStatusId: { value: 'ORDER_APPROVED' }, + orderTypeId: { value: 'SALES_ORDER' }, + facilityId: { value: this.state.user.currentFacility.facilityId }, + productStoreId: { value: this.state.user.currentEComStore.productStoreId } + } + } + const orderQueryPayload = prepareOrderQuery(params) + try { + resp = await OrderService.findOpenOrders(orderQueryPayload); + if (!hasError(resp) && resp.data.grouped?.orderId.matches > 0) { + const orderItem = resp.data.grouped.orderId.groups[0].doclist.docs[0]; + order = { + category: 'open', + customerId: orderItem.customerId, + customerName: orderItem.customerName, + orderId: orderItem.orderId, + orderDate: orderItem.orderDate, + orderName: orderItem.orderName, + groupValue: resp.data.grouped.orderId.groups[0].groupValue, + items: resp.data.grouped.orderId.groups[0].doclist.docs, + shipGroupSeqId: orderItem.shipGroupSeqId, + shipmentMethodTypeId: orderItem.shipmentMethodTypeId, + shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, + reservedDatetime: orderItem.reservedDatetime + } + await this.dispatch('product/fetchProducts', { productIds: order.items.map((item: any) => item.productId) }) + } else { + throw resp.data + } + } catch (err) { + logger.error('Something went wrong, could not fetch order details.', err) + } + dispatch('updateCurrent', order) + emitter.emit('dismissLoader'); + return resp; + }, + + async getInProgressOrder ({ dispatch, state }, payload) { + // if order is modified, we refetch it instead of returning from the state + if (!payload.isModified) { + const current = state.current as any + if (current.orderId === payload.orderId && current.category === 'in-progress' && current.shipGroupSeqId === payload.shipGroupSeqId) { + return + } + + const orders = JSON.parse(JSON.stringify(state.inProgress.list)) as Array + if (orders.length) { + const order = orders.find((order: any) => order.orderId === payload.orderId && current.category === 'in-progress' && payload.shipGroupSeqId === order.shipGroupSeqId) + if (order) { + dispatch('updateCurrent', order) + return + } + } + } + emitter.emit('presentLoader'); + let resp, order = {} as any; + + try { + const params = { + viewSize: 1, + sort: 'orderDate asc', + groupBy: 'picklistBinId', + filters: { + orderId: { value: payload.orderId }, + picklistItemStatusId: { value: 'PICKITEM_PENDING' }, + shipGroupSeqId: { value: payload.shipGroupSeqId }, + '-fulfillmentStatus': { value: 'Rejected' }, + '-shipmentMethodTypeId': { value: 'STOREPICKUP' }, + facilityId: { value: this.state.user.currentFacility.facilityId }, + productStoreId: { value: this.state.user.currentEComStore.productStoreId } + } + } + + const orderQueryPayload = prepareOrderQuery(params) + + resp = await OrderService.findInProgressOrders(orderQueryPayload); + if (resp.status === 200 && !hasError(resp) && resp.data.grouped?.picklistBinId.matches > 0) { + const orderItem = resp.data.grouped.picklistBinId.groups[0].doclist.docs[0]; + order = { + category: 'in-progress', + customerId: orderItem.customerId, + customerName: orderItem.customerName, + orderId: orderItem.orderId, + orderDate: orderItem.orderDate, + orderName: orderItem.orderName, + groupValue: resp.data.grouped.picklistBinId.groups[0].groupValue, + picklistBinId: orderItem.picklistBinId, + items: resp.data.grouped.picklistBinId.groups[0].doclist.docs, + shipGroupSeqId: orderItem.shipGroupSeqId, + shipmentMethodTypeId: orderItem.shipmentMethodTypeId, + shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, + } + await this.dispatch('product/fetchProducts', { productIds: order.items.map((item: any) => item.productId) }) + } else { + throw resp.data + } + } catch (err) { + logger.error('Something went wrong', err) + } + + await dispatch('fetchInProgressOrderAdditionalInformation', order); + + emitter.emit('dismissLoader'); + }, + + async getCompletedOrder({ dispatch, state }, payload) { + const current = state.current as any + if (current.orderId === payload.orderId && current.category === 'completed' && current.shipGroupSeqId === payload.shipGroupSeqId) { + return + } + + const orders = JSON.parse(JSON.stringify(state.completed.list)) as Array + if (orders.length) { + const order = orders.find((order: any) => order.orderId === payload.orderId && current.category === 'completed' && payload.shipGroupSeqId === order.shipGroupSeqId) + if (order) { + dispatch('updateCurrent', order) + return + } + } + emitter.emit('presentLoader'); + let resp, order = {} as any; + + try { + const params = { + viewSize: 1, + groupBy: 'picklistBinId', + sort: 'orderDate asc', + filters: { + orderId: { value: payload.orderId }, + picklistItemStatusId: { value: '(PICKITEM_PICKED OR (PICKITEM_COMPLETED AND itemShippedDate: [NOW/DAY TO NOW/DAY+1DAY]))' }, + '-shipmentMethodTypeId': { value: 'STOREPICKUP' }, + shipGroupSeqId: { value: payload.shipGroupSeqId }, + facilityId: { value: this.state.user.currentFacility.facilityId }, + productStoreId: { value: this.state.user.currentEComStore.productStoreId } + } + } + + const orderQueryPayload = prepareOrderQuery(params) + + resp = await OrderService.findCompletedOrders(orderQueryPayload); + if (resp.status === 200 && !hasError(resp) && resp.data.grouped?.picklistBinId.matches > 0) { + const orderItem = resp.data.grouped.picklistBinId.groups[0].doclist.docs[0]; + order = { + category: 'completed', + customerId: orderItem.customerId, + customerName: orderItem.customerName, + orderId: orderItem.orderId, + orderDate: orderItem.orderDate, + orderName: orderItem.orderName, + reservedDatetime: orderItem.reservedDatetime, + groupValue: resp.data.grouped.picklistBinId.groups[0].groupValue, + picklistBinId: orderItem.picklistBinId, + items: resp.data.grouped.picklistBinId.groups[0].doclist.docs, + shipmentId: orderItem.shipmentId, + shipGroupSeqId: orderItem.shipGroupSeqId, + shipmentMethodTypeId: orderItem.shipmentMethodTypeId, + shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, + isGeneratingShippingLabel: false, + isGeneratingPackingSlip: false + } + + await this.dispatch('product/fetchProducts', { productIds: order.items.map((item: any) => item.productId) }) + } else { + throw resp.data + } + } catch (err) { + logger.error('No completed orders found', err) + } + + await dispatch('fetchCompletedOrderAdditionalInformation', order); + emitter.emit('dismissLoader'); + }, + async fetchShipGroupForOrder({ dispatch, state }) { const order = JSON.parse(JSON.stringify(state.current)) @@ -609,7 +817,7 @@ const actions: ActionTree = { } // return if shipGroups are not found for order - if(!shipGroups.length) { + if (!shipGroups.length) { return; } @@ -639,6 +847,159 @@ const actions: ActionTree = { await dispatch('fetchAdditionalShipGroupForOrder', { shipGroups }); }, + async fetchCompletedOrderAdditionalInformation({ dispatch }, order) { + let current = JSON.parse(JSON.stringify(order)) + + try { + // fetchShipments accepts Array parameters for picklistBinId and orderId + const shipmentBatches = await OrderService.fetchShipments([current.picklistBinId], [current.orderId], this.state.user.currentFacility.facilityId) + const shipments = shipmentBatches.flat(); + const shipmentIds = [...new Set(shipments.map((shipment: any) => shipment.shipmentId))] as Array + let shipmentPackages = [] as any; + + // Get packed shipmentIds + if (shipmentIds.length) { + try { + const shipmentPackagesBatches = await OrderService.fetchShipmentPackages(shipmentIds) + shipmentPackages = shipmentPackagesBatches.flat(); + } catch (err) { + current.hasMissingPackageInfo = true; + logger.error('Failed to fetch shipment packages for orders', err) + } + } + + const orderShipments = shipments.filter((shipment: any) => current.orderId === shipment.primaryOrderId && shipment.picklistBinId === current.picklistBinId); + if (!orderShipments || !orderShipments.length) { + dispatch('updateCurrent', current) + return + } + + const currentShipmentPackages = orderShipments.reduce((currentShipmentPackages: any, shipment: any) => { + currentShipmentPackages.push(...shipmentPackages.filter((shipmentPackage: any) => shipmentPackage.shipmentId === shipment.shipmentId)); + return currentShipmentPackages; + }, []); + + // If there is any shipment package with missing tracking code, retry shipping label + const missingLabelImage = currentShipmentPackages.length > 0; + current = { + ...current, + shipments: orderShipments, + missingLabelImage, + shipmentPackages: currentShipmentPackages // ShipmentPackages information is required when performing retryShippingLabel action + } + } catch(err) { + current.hasMissingPackageInfo = true; + logger.error('Something went wrong', err) + } + + dispatch('updateCurrent', current) + }, + + async fetchInProgressOrderAdditionalInformation({ dispatch }, order) { + let current = JSON.parse(JSON.stringify(order)) + + const picklistBinIds: Array = [current.picklistBinId]; + const orderIds: Array = [current.orderId]; + + try { + // maintaining an object containing information of shipmentIds for each order + const shipmentIdsForOrderAndPicklistBin = await UtilService.findShipmentIdsForOrders(picklistBinIds, orderIds); + + let shipmentPackagesByOrderAndPicklistBin = {} as any, itemInformationByOrder = {} as any, carrierPartyIdsByShipment = {} as any, carrierShipmentBoxType = {} as any + + // storing all the shipmentIds for all the orders in an array to use furthur + const orderShipmentIds = [...(new Set(Object.values(shipmentIdsForOrderAndPicklistBin).flat()))] as Array + + // TODO: handle case when shipmentIds is empty + // https://stackoverflow.com/questions/28066429/promise-all-order-of-resolved-values + const [shipmentPackagesByOrderInformationAndPicklistBin, itemInformationByOrderInformation, carrierPartyIdsByShipmentInformation] = await Promise.all([UtilService.findShipmentPackages(orderShipmentIds), UtilService.findShipmentItemInformation(orderShipmentIds), UtilService.findCarrierPartyIdsForShipment(orderShipmentIds)]) + + // TODO: try fetching the carrierPartyIds when fetching packages information, as ShipmentPackageRouteSegDetail entity contain carrierPartyIds as well + const carrierPartyIds = [...new Set(Object.values(carrierPartyIdsByShipmentInformation).map((carrierPartyIds: any) => carrierPartyIds.map((carrier: any) => carrier.carrierPartyId)).flat())] + + shipmentPackagesByOrderAndPicklistBin = { + ...shipmentPackagesByOrderAndPicklistBin, + ...shipmentPackagesByOrderInformationAndPicklistBin + } + + itemInformationByOrder = { + ...itemInformationByOrder, + ...itemInformationByOrderInformation + } + + carrierPartyIdsByShipment = { + ...carrierPartyIdsByShipment, + ...carrierPartyIdsByShipmentInformation + } + + carrierShipmentBoxType = { + ...carrierShipmentBoxType, + ...await UtilService.findCarrierShipmentBoxType(carrierPartyIds) + } + + // if for an order shipment information is not available then returning the same order information again + if (!shipmentIdsForOrderAndPicklistBin[`${current.orderId}_${current.picklistBinId}`]) { + // if there are no shipment for the order, there is some issue with the order + if (picklistBinIds.includes(current.picklistBinId) && orderIds.includes(current.orderId)) { + current = { + ...current, + hasMissingInfo: true, + } + return + } + return + } + + current.items.map((item: any) => { + // fetching shipmentItemInformation for the current order item and then assigning the shipmentItemSeqId to item + const shipment = itemInformationByOrder[item.orderId]?.find((shipmentItem: any) => shipmentItem.orderItemSeqId === item.orderItemSeqId) + + if (shipment) { + item.shipmentId = shipment.shipmentId + item.shipmentItemSeqId = shipment.shipmentItemSeqId + } + + item.selectedBox = shipmentPackagesByOrderAndPicklistBin[`${item.orderId}_${item.picklistBinId}`]?.find((shipmentPackage: any) => shipmentPackage.shipmentId === item.shipmentId)?.packageName + }) + + const orderItem = current.items[0]; + const carrierPartyIdsOnOrderShipment = [...new Set(orderShipmentIds.map((id: any) => carrierPartyIdsByShipment[id]?.map((carrierParty: any) => carrierParty.carrierPartyId)).flat())]; + + const shipmentBoxTypeByCarrierParty = carrierPartyIdsOnOrderShipment.reduce((shipmentBoxType: any, carrierPartyId: any) => { + if (shipmentBoxType[carrierPartyId]) { + shipmentBoxType[carrierPartyId].push(carrierShipmentBoxType[carrierPartyId]) + } else { + shipmentBoxType[carrierPartyId] = carrierShipmentBoxType[carrierPartyId] + } + + return shipmentBoxType + }, {}); + + const shipmentPackages = shipmentPackagesByOrderAndPicklistBin[`${orderItem.orderId}_${orderItem.picklistBinId}`].map((shipmentPackage: any) => { + return { + ...shipmentPackage, + shipmentBoxTypes: shipmentBoxTypeByCarrierParty[shipmentPackage.carrierPartyId] ? shipmentBoxTypeByCarrierParty[shipmentPackage.carrierPartyId] : [] + } + }); + + current = { + ...current, + shipmentIds: shipmentIdsForOrderAndPicklistBin[`${orderItem.orderId}_${orderItem.picklistBinId}`], + shipmentPackages: shipmentPackages, + carrierPartyIdsOnOrderShipment, + shipmentBoxTypeByCarrierParty: shipmentBoxTypeByCarrierParty + } + + this.dispatch('util/fetchShipmentBoxTypeDesc', [...new Set(Object.values(carrierShipmentBoxType).flat())]) + } catch (err) { + current.hasMissingPackageInfo = true; + logger.error('Something went wrong', err) + } + + // updating the state with the updated orders information + await dispatch('updateCurrent', current) + }, + async fetchAdditionalShipGroupForOrder({ commit, state }, payload) { const order = JSON.parse(JSON.stringify(state.current)) @@ -695,10 +1056,10 @@ const actions: ActionTree = { const carrierPartyIds: Array = []; const shipmentIds: Array = []; - if(total) { + if (total) { shipGroups.map((shipGroup: any) => { - if(shipGroup.shipmentId) shipmentIds.push(shipGroup.shipmentId) - if(shipGroup.carrierPartyId) carrierPartyIds.push(shipGroup.carrierPartyId) + if (shipGroup.shipmentId) shipmentIds.push(shipGroup.shipmentId) + if (shipGroup.carrierPartyId) carrierPartyIds.push(shipGroup.carrierPartyId) }) } @@ -712,20 +1073,20 @@ const actions: ActionTree = { // TODO: Remove default value check shipGroup.trackingCode = trackingCode ? trackingCode : 'TRACKING CODE'; }) - } catch(err) { + } catch (err) { logger.error('Failed to fetch information for ship groups', err) } order['shipGroups'] = shipGroups - commit(types.ORDER_CURRENT_UPDATED, { order }) + commit(types.ORDER_CURRENT_UPDATED, order) return shipGroups; }, // TODO clear current on logout - async updateCurrent ({ commit, dispatch }, payload) { - commit(types.ORDER_CURRENT_UPDATED, { order: payload }) + async updateCurrent({ commit, dispatch }, order) { + commit(types.ORDER_CURRENT_UPDATED, order) await dispatch('fetchShippingAddress'); await dispatch('fetchShipGroupForOrder'); await dispatch('fetchPaymentDetail'); diff --git a/src/store/modules/order/mutations.ts b/src/store/modules/order/mutations.ts index a021f7f8..2ffbe291 100644 --- a/src/store/modules/order/mutations.ts +++ b/src/store/modules/order/mutations.ts @@ -62,7 +62,7 @@ const mutations: MutationTree = { } }, [types.ORDER_CURRENT_UPDATED] (state, payload) { - state.current = payload.order + state.current = payload }, } export default mutations; \ No newline at end of file diff --git a/src/store/modules/product/actions.ts b/src/store/modules/product/actions.ts index 44305d65..7382c692 100644 --- a/src/store/modules/product/actions.ts +++ b/src/store/modules/product/actions.ts @@ -44,7 +44,7 @@ const actions: ActionTree = { return resp; }, - async getProductInformation ({ dispatch }, { orders }) { + async getProductInformation({ dispatch }, { orders }) { let productIds: any = new Set(); orders.forEach((list: any) => { list.doclist.docs.forEach((order: any) => { diff --git a/src/views/AssignPickerModal.vue b/src/views/AssignPickerModal.vue index 3ab3cb29..56cea499 100644 --- a/src/views/AssignPickerModal.vue +++ b/src/views/AssignPickerModal.vue @@ -2,7 +2,7 @@ - + @@ -113,8 +113,8 @@ export default defineComponent({ isPickerSelected(id) { return this.selectedPickers.some((picker) => picker.id == id) }, - closeModal() { - modalController.dismiss({ dismissed: true }); + closeModal(picklistId) { + modalController.dismiss({ dismissed: true, value: { picklistId } }); }, selectPicker(id) { const picker = this.selectedPickers.some((picker) => picker.id == id) @@ -163,7 +163,7 @@ export default defineComponent({ try { resp = await UtilService.createPicklist(formData); if (resp.status === 200 && !hasError(resp)) { - this.closeModal(); + this.closeModal(resp.data.picklistId); showToast(translate('Picklist created successfully')) // generating picklist after creating a new picklist diff --git a/src/views/OrderDetail.vue b/src/views/OrderDetail.vue index 6f2fecd9..cb2f7401 100644 --- a/src/views/OrderDetail.vue +++ b/src/views/OrderDetail.vue @@ -2,204 +2,209 @@ - - + {{ translate("Order details") }} -
-
-

{{ order.orderName }}

-
-
- - - {{ order.orderId }} - - - - {{ translate('Linked picklist') }}: {{ order.picklistId }} - - - - {{ getPaymentMethodDesc(order?.orderPaymentPreferences[0]?.paymentMethodTypeId)}} : {{ getStatusDesc(order?.orderPaymentPreferences[0]?.statusId) }} - -
- -
- - +
- - {{ order.customerName }} -

{{ translate("Ordered") }} {{ formatUtcDate(order.orderDate, 'dd MMMM yyyy t a ZZZZ') }}

-
+

{{ order.orderName }}

- - - -
-
- - + -
- {{ translate("Add Box") }} - - - {{ `Box ${shipmentPackage?.packageName}` }} {{ shipmentPackage.shipmentBoxTypes.length ? `| ${boxTypeDesc(getShipmentPackageType(shipmentPackage))}` : '' }} - - - -
-
-
- - - - + +
+
-

{{ item.productSku }}

- {{ item.virtualProductName }} -

{{ getFeature(getProduct(item.productId).featureHierarchy, '1/COLOR/')}} {{ getFeature(getProduct(item.productId).featureHierarchy, '1/SIZE/')}}

+ {{ order.customerName }} +

{{ translate("Ordered") }} {{ formatUtcDate(order.orderDate, 'dd MMMM yyyy t a ZZZZ') }}

- -
+
-
- - - {{ `Box ${item.selectedBox}` }} - - +
- - -
- - {{ translate("Pack using default packaging") }} - - - - -
+
+
+ + + + + +

{{ item.productSku }}

+ {{ item.virtualProductName }} +

{{ getFeature(getProduct(item.productId).featureHierarchy, '1/COLOR/')}} {{ getFeature(getProduct(item.productId).featureHierarchy, '1/SIZE/')}}

+
+
+
-
- - {{ translate("Ship Now") }} - - - - -
+
+ + + {{ `Box ${item.selectedBox}` }} + + +
-
- -
- - - {{ translate("Pack order") }} - - - - {{ translate("Pick order") }} - -
- - - {{ translate("Shipped") }} - - - - {{ translate("Ship order") }} - - - {{ translate("Regenerate Shipping Label") }} - + +
- -
- {{ translate("Unpack") }} +
+ + {{ translate("Pack using default packaging") }} + + + +
-
- - - -

{{ translate('Other shipments in this order') }}

-
- - -
- {{ getfacilityTypeDesc(shipGroup.facilityTypeId) }} - {{ shipGroup.facilityName }} -
- {{ shipGroup.category ? shipGroup.category : translate('Pending allocation') }} -
- - - {{ getPartyName(shipGroup.carrierPartyId) }} - {{ shipGroup.trackingCode }} - - - - - -

{{ translate("Handling Instructions") }}

-

{{ shipGroup.shippingInstructions }}

-
-
- - - - - - -

{{ getProduct(item.productId).sku }}

- {{ getProduct(item.productId).parentProductName }} -
- - + + + +

{{ translate('Other shipments in this order') }}

+
+ + +
+ {{ getfacilityTypeDesc(shipGroup.facilityTypeId) }} + {{ shipGroup.facilityName }} +
+ {{ shipGroup.category ? shipGroup.category : translate('Pending allocation') }} +
+ + + {{ getPartyName(shipGroup.carrierPartyId) }} + {{ shipGroup.trackingCode }} + + + + + +

{{ translate("Handling Instructions") }}

+

{{ shipGroup.shippingInstructions }}

+
+
+ + + + + + +

{{ getProduct(item.productId).sku }}

+ {{ getProduct(item.productId).parentProductName }} +
+ + +
+
+
+
+
+

{{ translate("Unable to fetch the order details. Either the order has been shipped or something went wrong. Please try again after some time.")}}

+
@@ -249,12 +254,10 @@ import { pricetagOutline, trashBinOutline } from 'ionicons/icons'; -import { ShopifyImg } from '@hotwax/dxp-components'; +import { translate, ShopifyImg } from '@hotwax/dxp-components'; import { formatUtcDate, getFeature, showToast } from '@/utils' -import { translate } from '@hotwax/dxp-components'; import { Actions, hasPermission } from '@/authorization' import OrderActionsPopover from '@/components/OrderActionsPopover.vue' -import { getOrderCategory } from '@/utils/order' import emitter from '@/event-bus'; import { OrderService } from "@/services/OrderService"; import { hasError } from "@/adapter"; @@ -272,7 +275,7 @@ import ShippingDetails from '@/views/ShippingDetails.vue'; export default defineComponent({ name: "OrderDetail", - props: ['orderId'], + props: ['category', 'orderId', 'shipGroupSeqId'], components: { IonBackButton, IonBadge, @@ -317,7 +320,6 @@ export default defineComponent({ }, data() { return { - orderCategory: '', carrierPartyIds: [] as Array, shipmentMethods: [] as Array, picklists: [] as any, @@ -327,7 +329,11 @@ export default defineComponent({ } }, async ionViewDidEnter() { - this.orderCategory = getOrderCategory(this.order.items[0]) + this.category === 'open' + ? await this.store.dispatch('order/getOpenOrder', { orderId: this.orderId, shipGroupSeqId: this.shipGroupSeqId }) + : this.category === 'in-progress' + ? await this.store.dispatch('order/getInProgressOrder', { orderId: this.orderId, shipGroupSeqId: this.shipGroupSeqId }) + : await this.store.dispatch('order/getCompletedOrder', { orderId: this.orderId, shipGroupSeqId: this.shipGroupSeqId }) }, methods: { async printPicklist (order: any) { @@ -347,7 +353,7 @@ export default defineComponent({ const result = await popover.onDidDismiss(); - if(result.data && item.selectedBox !== result.data) { + if (result.data && item.selectedBox !== result.data) { this.confirmUpdateBox(item, order, result.data) } }, @@ -362,9 +368,10 @@ export default defineComponent({ }, { text: translate("Confirm"), - handler: () => { + handler: async () => { item.selectedBox = selectedBox; - this.updateOrder(order, 'box-selection'); + await this.updateOrder(order, 'box-selection'); + await this.store.dispatch('order/getInProgressOrder', { orderId: this.orderId, isModified: true }) } } ], @@ -440,8 +447,7 @@ export default defineComponent({ } else { showToast(translate('Order packed successfully')); } - this.store.dispatch('order/updateCurrent', {}) - this.router.replace('/in-progress') + this.router.replace(`/completed/order-detail/${this.orderId}/${this.shipGroupSeqId}`) } catch (err) { // in case of error, if loader and toast are not dismissed above if (toast) toast.dismiss() @@ -578,9 +584,6 @@ export default defineComponent({ this.reportIssue(order, itemsToReject) } }, - closePopover() { - popoverController.dismiss(); - }, async assignPickers() { const assignPickerModal = await modalController.create({ component: AssignPickerModal, @@ -588,10 +591,12 @@ export default defineComponent({ }); // dismissing the popover once the picker modal is closed - assignPickerModal.onDidDismiss().finally(() => { - this.closePopover(); - this.store.dispatch('order/updateCurrent', {}) - this.router.replace('/open') + assignPickerModal.onDidDismiss().then((result: any) => { + popoverController.dismiss(); + // redirect to in-progress page only when we have picklist created successfully for the order + if(result?.data?.value?.picklistId) { + this.router.replace(`/in-progress/order-detail/${this.orderId}/${this.shipGroupSeqId}`) + } }); return assignPickerModal.present(); @@ -676,8 +681,7 @@ export default defineComponent({ if(!hasError(resp)) { showToast(translate('Box added successfully')) - // TODO: only update the order in which the box is added instead of fetching all the inProgress orders - await Promise.all([this.fetchPickersInformation(), this.findInProgressOrders()]) + await this.store.dispatch('order/getInProgressOrder', { orderId: this.orderId, isModified: true }) } else { throw resp.data } @@ -879,6 +883,7 @@ export default defineComponent({ role: 'confirm', handler: async() => { await this.updateOrder(order, 'report'); + await this.store.dispatch('order/getInProgressOrder', { orderId: this.orderId, isModified: true }) } }] }); @@ -890,7 +895,6 @@ export default defineComponent({ return order.shipments ? Object.values(order.shipments).some((shipment: any) => shipment.statusId === 'SHIPMENT_PACKED') : {} }, async shipOrder(order: any) { - const packedShipments = order.shipments.filter((shipment: any) => shipment.statusId === "SHIPMENT_PACKED"); if (packedShipments.length === 0) { @@ -918,8 +922,6 @@ export default defineComponent({ if (!hasError(resp)) { showToast(translate('Order shipped successfully')) - this.store.dispatch('order/updateCurrent', {}) - this.router.replace('/completed') } else { throw resp.data } @@ -1043,9 +1045,7 @@ export default defineComponent({ if(resp.status == 200 && !hasError(resp)) { showToast(translate('Order unpacked successfully')) - // TODO: handle the case of data not updated correctly - this.store.dispatch('order/updateCurrent', {}) - this.router.replace('/completed') + this.router.replace(`/in-progress/order-detail/${this.orderId}/${this.shipGroupSeqId}`) } else { throw resp.data }