From 35bebc1f056e9a6e045d1a79e102ccd1f3a320de Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Tue, 17 Sep 2024 14:50:38 +0530 Subject: [PATCH 1/7] Implemented: Added rejections page (#715). --- src/authorization/Actions.ts | 3 +- src/authorization/Rules.ts | 3 +- src/components/Menu.vue | 12 +- src/router/index.ts | 10 + src/services/RejectionService.ts | 22 ++ src/store/RootState.ts | 4 +- src/store/index.ts | 4 +- src/store/modules/rejection/RejectionState.ts | 13 + src/store/modules/rejection/actions.ts | 220 ++++++++++++ src/store/modules/rejection/getters.ts | 16 + src/store/modules/rejection/index.ts | 28 ++ src/store/modules/rejection/mutation-types.ts | 4 + src/store/modules/rejection/mutations.ts | 16 + src/views/Rejections.vue | 325 ++++++++++++++++++ 14 files changed, 675 insertions(+), 5 deletions(-) create mode 100644 src/services/RejectionService.ts create mode 100644 src/store/modules/rejection/RejectionState.ts create mode 100644 src/store/modules/rejection/actions.ts create mode 100644 src/store/modules/rejection/getters.ts create mode 100644 src/store/modules/rejection/index.ts create mode 100644 src/store/modules/rejection/mutation-types.ts create mode 100644 src/store/modules/rejection/mutations.ts create mode 100644 src/views/Rejections.vue diff --git a/src/authorization/Actions.ts b/src/authorization/Actions.ts index 505ac678..eefcc5f8 100644 --- a/src/authorization/Actions.ts +++ b/src/authorization/Actions.ts @@ -14,5 +14,6 @@ export default { "APP_PARTIAL_ORDER_REJECTION_CONFIG_UPDATE": "APP_PARTIAL_ORDER_REJECTION_CONFIG_UPDATE", "APP_COLLATERAL_REJECTION_CONFIG_UPDATE": "APP_COLLATERAL_REJECTION_CONFIG_UPDATE", "APP_UPDT_FULFILL_FORCE_SCAN_CONFIG": "APP_UPDT_FULFILL_FORCE_SCAN_CONFIG", - "APP_ORGANIZATION_HEADER_VIEW": "APP_ORGANIZATION_HEADER_VIEW" + "APP_ORGANIZATION_HEADER_VIEW": "APP_ORGANIZATION_HEADER_VIEW", + "APP_REJECTIONS_VIEW": "APP_REJECTIONS_VIEW" } \ No newline at end of file diff --git a/src/authorization/Rules.ts b/src/authorization/Rules.ts index 314d60d4..7bbb8272 100644 --- a/src/authorization/Rules.ts +++ b/src/authorization/Rules.ts @@ -23,5 +23,6 @@ export default { "APP_PARTIAL_ORDER_REJECTION_CONFIG_UPDATE": "COMMON_ADMIN", "APP_COLLATERAL_REJECTION_CONFIG_UPDATE": "COMMON_ADMIN", "APP_UPDT_FULFILL_FORCE_SCAN_CONFIG": "COMMON_ADMIN", - "APP_ORGANIZATION_HEADER_VIEW": "SFA_ADMIN OR CARRIER_SETUP_VIEW OR FF_ORDER_LOOKUP_VIEW" + "APP_ORGANIZATION_HEADER_VIEW": "SFA_ADMIN OR CARRIER_SETUP_VIEW OR FF_ORDER_LOOKUP_VIEW", + "APP_REJECTIONS_VIEW": "SFA_ADMIN" } as any \ No newline at end of file diff --git a/src/components/Menu.vue b/src/components/Menu.vue index 78f8d032..e6475670 100644 --- a/src/components/Menu.vue +++ b/src/components/Menu.vue @@ -46,7 +46,7 @@ import { } from "@ionic/vue"; import { computed, defineComponent } from "vue"; import { mapGetters } from "vuex"; -import { arrowBackOutline, mailUnreadOutline, mailOpenOutline, checkmarkDoneOutline, settingsOutline, swapVerticalOutline } from "ionicons/icons"; +import { arrowBackOutline, backspaceOutline, mailUnreadOutline, mailOpenOutline, checkmarkDoneOutline, settingsOutline, swapVerticalOutline } from "ionicons/icons"; import { useStore } from "@/store"; import { useRouter } from "vue-router"; import { hasPermission } from "@/authorization"; @@ -113,6 +113,15 @@ export default defineComponent({ permissionId: "APP_COMPLETED_ORDERS_VIEW" } }, + { + title: "Rejections", + url: "/rejections", + iosIcon: backspaceOutline, + mdIcon: backspaceOutline, + meta: { + permissionId: "APP_REJECTIONS_VIEW" + } + }, { title: "Transfer Orders", url: "/transfer-orders", @@ -178,6 +187,7 @@ export default defineComponent({ return { appPages, + backspaceOutline, checkmarkDoneOutline, hasPermission, arrowBackOutline, diff --git a/src/router/index.ts b/src/router/index.ts index edc99c51..532b72e6 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -34,6 +34,7 @@ import { useAuthStore, DxpLogin } from '@hotwax/dxp-components' import { loader } from '@/utils/user'; import OrderLookup from '@/views/OrderLookup.vue'; import OrderLookupDetail from '@/views/OrderLookupDetail.vue'; +import Rejections from '@/views/Rejections.vue'; const authGuard = async (to: any, from: any, next: any) => { const authStore = useAuthStore() @@ -242,6 +243,15 @@ const routes: Array = [ name: "Notifications", component: Notifications, beforeEnter: authGuard, + }, + { + path: "/rejections", + name: "Rejections", + component: Rejections, + beforeEnter: authGuard, + meta: { + permissionId: "APP_REJECTIONS_VIEW" + } } ] diff --git a/src/services/RejectionService.ts b/src/services/RejectionService.ts new file mode 100644 index 00000000..d7bf5468 --- /dev/null +++ b/src/services/RejectionService.ts @@ -0,0 +1,22 @@ +import { api} from '@/adapter'; + +const fetchRejectionStats = async (query: any): Promise => { + return api({ + url: "solr-query", + method: "post", + data: query + }); +} + +const fetchRejctedOrders = async (query: any): Promise => { + return api({ + url: "solr-query", + method: "post", + data: query + }); +} + + export const RejectionService = { + fetchRejctedOrders, + fetchRejectionStats + } \ No newline at end of file diff --git a/src/store/RootState.ts b/src/store/RootState.ts index 590d41f3..23f7190e 100644 --- a/src/store/RootState.ts +++ b/src/store/RootState.ts @@ -2,6 +2,7 @@ import OrderState from "./modules/order/OrderState"; import UtilState from "./modules/util/UtilState"; import TransferOrderState from "./modules/transferorder/TransferOrderState"; import CarrierState from "./modules/carrier/CarrierState" +import RejectionState from "./modules/rejection/RejectionState" export default interface RootState { @@ -10,5 +11,6 @@ export default interface RootState { util: UtilState; order: OrderState; transferOrder: TransferOrderState, - carrier: CarrierState + carrier: CarrierState, + rejectionState: RejectionState } \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index d0ced25b..83a81246 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -13,6 +13,7 @@ import stockModule from "./modules/stock" import carrierModule from "./modules/carrier" import { setPermissions } from '@/authorization' import orderLookupModule from "./modules/orderLookup" +import rejectionModule from "./modules/rejection" // TODO check how to register it from the components only @@ -44,7 +45,8 @@ const store = createStore({ 'util': utilModule, 'stock': stockModule, 'transferorder': transferOrderModule, - 'carrier': carrierModule + 'carrier': carrierModule, + 'rejection': rejectionModule }, }) diff --git a/src/store/modules/rejection/RejectionState.ts b/src/store/modules/rejection/RejectionState.ts new file mode 100644 index 00000000..7144fb8f --- /dev/null +++ b/src/store/modules/rejection/RejectionState.ts @@ -0,0 +1,13 @@ +export default interface OrderState { + rejectedItems: any, + usedReasons: any, + rejectedOrders: { + list: any, + total: number, + query: { + viewIndex: number, + viewSize: any, + queryString: string + } + } + } \ No newline at end of file diff --git a/src/store/modules/rejection/actions.ts b/src/store/modules/rejection/actions.ts new file mode 100644 index 00000000..ae208420 --- /dev/null +++ b/src/store/modules/rejection/actions.ts @@ -0,0 +1,220 @@ +import { ActionTree } from 'vuex' +import RootState from '@/store/RootState' +import RejectionState from './RejectionState' +import { RejectionService } from '@/services/RejectionService' +import { hasError } from '@/adapter' +import * as types from './mutation-types' +import { escapeSolrSpecialChars, prepareOrderQuery } from '@/utils/solrHelper' +import { UtilService } from '@/services/UtilService' +import logger from '@/logger' + +const actions: ActionTree = { + async fetchRejectionStats({ commit, dispatch, state }, payload) { + let rejectionReasons = [] as any, rejectedItems= [] as any + + let rejectionPeriodFilter = "[NOW-24HOURS TO NOW]" + if (payload.rejectionPeriodId && payload.rejectionPeriodId === 'LAST_SEVEN_DAYS') { + rejectionPeriodFilter = "[NOW-7DAYS TO NOW]" + } + const query = prepareOrderQuery({ + docType: "FULFILLMENT_REJECTION", + queryFields: 'orderId_s', + viewSize: '0', // passed viewSize as 0 to not fetch any data + sort: 'rejectedAt_dt desc', + groupBy: 'orderId_s', + filters: { + rejectedAt_dt: {value: rejectionPeriodFilter}, + rejectedFrom_txt_en: { value: escapeSolrSpecialChars(this.state.user.currentFacility.facilityId) }, + }, + facet: { + "rejectionReasonIdFacet":{ + "field":"rejectionReasonId_txt_en", + "mincount":1, + "limit":-1, + "sort":"index", + "type":"terms", + }, + "prodductIdFacet":{ + "field":"productId_s", + "mincount":1, + "limit":-1, + "sort":"index", + "type":"terms", + } + } + }) + query.coreName = "logInsights" + + + try { + const resp = await RejectionService.fetchRejectionStats(query); + if (!hasError(resp)) { + const usedReasons = resp.data.facets.rejectionReasonIdFacet.buckets + rejectedItems = resp.data.facets.prodductIdFacet.buckets + if (rejectedItems) { + const productIds = rejectedItems.map((rejectedItem: any) => rejectedItem.val) + await this.dispatch('product/fetchProducts', { productIds }) + } + + if (usedReasons) { + const reasonIds = usedReasons.map((usedReason: any) => usedReason.val) + const payload = { + "inputFields": { + "enumId": reasonIds, + "enumId_op": "in" + }, + "fieldList": ["description", "enumId", "enumName", "enumTypeId", "sequenceNum"], + "distinct": "Y", + "entityName": "EnumTypeChildAndEnum", + "viewSize": reasonIds.length, //There won't we rejection reasons more than 20, hence fetching detail for all the reasons at once + "orderBy": "sequenceNum" + } + const resp = await UtilService.fetchRejectReasons(payload) + + if (!hasError(resp) && resp.data.count > 0) { + const reasonCountDetail = usedReasons.reduce((reasonDetail: any, reason: any) => { + reasonDetail[reason.val.trim().toUpperCase()] = reason; + return reasonDetail; + }, {}); + rejectionReasons = resp.data.docs + rejectionReasons.map((rejectionReason: any) => { + rejectionReason.count = reasonCountDetail[rejectionReason.enumId]?.count + }) + } else { + throw resp.data + } + } + } else { + throw resp.data; + } + } catch(err) { + logger.error('Failed to fetch rejection stats.', err) + } + commit(types.REJECTION_REJECTED_ITEMS_UPDATED, rejectedItems) + commit(types.REJECTION_USED_REASONS_UPDATED, rejectionReasons) + }, + + async fetchRejectedOrders({ commit, dispatch, state }, payload) { + let orders = [] as any, total = 0 + + let rejectionPeriodFilter = "[NOW-24HOURS TO NOW]" + if (payload.rejectionPeriodId && payload.rejectionPeriodId === 'LAST_SEVEN_DAYS') { + rejectionPeriodFilter = "[NOW-7DAYS TO NOW]" + } + const rejectedOrderQuery = JSON.parse(JSON.stringify(state.rejectedOrders.query)) + const query = prepareOrderQuery({ + docType: "FULFILLMENT_REJECTION", + queryString: rejectedOrderQuery.queryString, + queryFields: 'orderId_s', + viewIndex: rejectedOrderQuery.viewIndex, + viewSize: rejectedOrderQuery.viewSize, + sort: 'rejectedAt_dt desc', + groupBy: 'orderId_s', + filters: { + rejectedAt_dt: {value: rejectionPeriodFilter}, + rejectedFrom_txt_en: { value: escapeSolrSpecialChars(this.state.user.currentFacility.facilityId) }, + } + }) + query.coreName = "logInsights" + + + try { + const resp = await RejectionService.fetchRejctedOrders(query); + if (!hasError(resp)) { + total = resp.data.grouped.picklistBinId.ngroups + orders = resp.data.grouped.picklistBinId.groups + + orders = orders.map((order: any) => { + const orderItem = order.doclist.docs[0]; + return { + customerId: orderItem.customerId, + customerName: orderItem.customerName, + orderId: orderItem.orderId, + orderDate: orderItem.orderDate, + orderName: orderItem.orderName, + groupValue: order.groupValue, + items: order.doclist.docs, + shipmentMethodTypeId: orderItem.shipmentMethodTypeId, + shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, + } + }) + } else { + throw resp.data; + } + } catch(err) { + logger.error('Failed to fetch rejected orders.', err) + } + rejectedOrderQuery.viewSize = orders.length + commit(types.ORDER_REJECTED_QUERY_UPDATED, { ...rejectedOrderQuery }) + commit(types.ORDER_REJECTED_UPDATED, {orders, total}) + }, + + async fetchRejectedOrdersDetail ({ commit, dispatch, state }, payload = {}) { + let resp; + let orders = JSON.parse(JSON.stringify(state.rejectedOrders.list)); + + try { + const params = { + ...payload, + viewSize: , + sort: 'orderDate asc', + groupBy: 'orderId', + filters: { + productStoreId: { value: productIds } + } + } + + const orderQueryPayload = prepareOrderQuery(params) + + resp = await OrderService.findInProgressOrders(orderQueryPayload); + if (resp.status === 200 && !hasError(resp) && resp.data.grouped?.picklistBinId.matches > 0) { + total = resp.data.grouped.picklistBinId.ngroups + orders = resp.data.grouped.picklistBinId.groups + + // TODO get only product visible + await this.dispatch('product/getProductInformation', { orders }) + + orders = orders.map((order: any) => { + const orderItem = order.doclist.docs[0]; + return { + category: 'in-progress', + customerId: orderItem.customerId, + customerName: orderItem.customerName, + orderId: orderItem.orderId, + orderDate: orderItem.orderDate, + orderName: orderItem.orderName, + groupValue: order.groupValue, + picklistBinId: orderItem.picklistBinId, + picklistId: orderItem.picklistId, + items: removeKitComponents({items: order.doclist.docs}), + shipGroupSeqId: orderItem.shipGroupSeqId, + shipmentMethodTypeId: orderItem.shipmentMethodTypeId, + shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, + shippingInstructions: orderItem.shippingInstructions + } + }) + } else { + throw resp.data + } + } catch (err) { + logger.error('No inProgress orders found', err) + } + + inProgressQuery.viewSize = orders.length + + commit(types.ORDER_INPROGRESS_QUERY_UPDATED, { ...inProgressQuery }) + commit(types.ORDER_INPROGRESS_UPDATED, {orders, total}) + + // fetching the additional information like shipmentRoute, carrierParty information + // If no orders then no need to fetch any additional information + if(orders.length){ + dispatch('fetchInProgressOrdersAdditionalInformation'); + } + + emitter.emit('dismissLoader'); + return resp; + }, + +} + +export default actions; \ No newline at end of file diff --git a/src/store/modules/rejection/getters.ts b/src/store/modules/rejection/getters.ts new file mode 100644 index 00000000..defe364f --- /dev/null +++ b/src/store/modules/rejection/getters.ts @@ -0,0 +1,16 @@ +import { GetterTree } from "vuex"; +import RejectionState from "./RejectionState"; +import RootState from "../../RootState"; + +const getters: GetterTree = { + getRejectedItems (state) { + return state.rejectedItems; + }, + getUsedReasons (state) { + return state.usedReasons; + }, + getRejectedOrders (state) { + return state.rejectedOrders; + } +}; +export default getters; \ No newline at end of file diff --git a/src/store/modules/rejection/index.ts b/src/store/modules/rejection/index.ts new file mode 100644 index 00000000..aa44ff62 --- /dev/null +++ b/src/store/modules/rejection/index.ts @@ -0,0 +1,28 @@ +import actions from './actions' +import getters from './getters' +import mutations from './mutations' +import { Module } from 'vuex' +import RejectionState from './RejectionState' +import RootState from '../../RootState' + +const orderModule: Module = { + namespaced: true, + state: { + rejectedItems: [], + usedReasons: [], + rejectedOrders: { + list: [], + total: 0, + query: { + viewIndex: 0, + viewSize: process.env.VUE_APP_VIEW_SIZE, + queryString: '' + } + } + }, + getters, + actions, + mutations +} + +export default orderModule; \ No newline at end of file diff --git a/src/store/modules/rejection/mutation-types.ts b/src/store/modules/rejection/mutation-types.ts new file mode 100644 index 00000000..556d6d9c --- /dev/null +++ b/src/store/modules/rejection/mutation-types.ts @@ -0,0 +1,4 @@ +export const SN_REJECTION = 'rejection' +export const REJECTION_REJECTED_ITEMS_UPDATED = SN_REJECTION + '/REJECTED_ITEMS_UPDATED' +export const REJECTION_USED_REASONS_UPDATED = SN_REJECTION + '/USED_REASONS_UPDATED' +export const REJECTION_REJECTED_ORDERS_UPDATED = SN_REJECTION + '/REJECTION_REJECTED_ORDERS_UPDATED' diff --git a/src/store/modules/rejection/mutations.ts b/src/store/modules/rejection/mutations.ts new file mode 100644 index 00000000..01d0320a --- /dev/null +++ b/src/store/modules/rejection/mutations.ts @@ -0,0 +1,16 @@ +import { MutationTree } from 'vuex' +import RejectionState from './RejectionState' +import * as types from './mutation-types' + +const mutations: MutationTree = { + [types.REJECTION_REJECTED_ITEMS_UPDATED] (state, payload) { + state.rejectedItems = payload; + }, + [types.REJECTION_USED_REASONS_UPDATED] (state, payload) { + state.usedReasons = payload; + }, + [types.REJECTION_REJECTED_ORDERS_UPDATED] (state, payload) { + state.rejectedOrders = payload; + }, +} +export default mutations; \ No newline at end of file diff --git a/src/views/Rejections.vue b/src/views/Rejections.vue new file mode 100644 index 00000000..a0986397 --- /dev/null +++ b/src/views/Rejections.vue @@ -0,0 +1,325 @@ + + + + + \ No newline at end of file From 230b5676c609a13fdd3c8282b74afebfba7286f0 Mon Sep 17 00:00:00 2001 From: Ravi Lodhi Date: Fri, 20 Sep 2024 19:11:35 +0530 Subject: [PATCH 2/7] Improved: Rejections page rendering logic and UI (#715). --- src/services/RejectionService.ts | 11 +- src/store/modules/rejection/RejectionState.ts | 3 +- src/store/modules/rejection/actions.ts | 174 +++++++++--------- src/store/modules/rejection/index.ts | 7 +- src/store/modules/rejection/mutation-types.ts | 3 +- src/store/modules/rejection/mutations.ts | 8 +- src/utils/solrHelper.ts | 6 +- src/views/Rejections.vue | 126 ++++++++----- 8 files changed, 195 insertions(+), 143 deletions(-) diff --git a/src/services/RejectionService.ts b/src/services/RejectionService.ts index d7bf5468..edb16f61 100644 --- a/src/services/RejectionService.ts +++ b/src/services/RejectionService.ts @@ -16,7 +16,16 @@ const fetchRejctedOrders = async (query: any): Promise => { }); } +const findRejectedOrdersDetail = async (query: any): Promise => { + return api({ + url: "solr-query", + method: "post", + data: query + }); +} + export const RejectionService = { fetchRejctedOrders, - fetchRejectionStats + findRejectedOrdersDetail, + fetchRejectionStats, } \ No newline at end of file diff --git a/src/store/modules/rejection/RejectionState.ts b/src/store/modules/rejection/RejectionState.ts index 7144fb8f..1c674ba8 100644 --- a/src/store/modules/rejection/RejectionState.ts +++ b/src/store/modules/rejection/RejectionState.ts @@ -7,7 +7,8 @@ export default interface OrderState { query: { viewIndex: number, viewSize: any, - queryString: string + queryString: string, + rejectionPeriodId: string } } } \ No newline at end of file diff --git a/src/store/modules/rejection/actions.ts b/src/store/modules/rejection/actions.ts index ae208420..e753f5a2 100644 --- a/src/store/modules/rejection/actions.ts +++ b/src/store/modules/rejection/actions.ts @@ -4,7 +4,7 @@ import RejectionState from './RejectionState' import { RejectionService } from '@/services/RejectionService' import { hasError } from '@/adapter' import * as types from './mutation-types' -import { escapeSolrSpecialChars, prepareOrderQuery } from '@/utils/solrHelper' +import { escapeSolrSpecialChars, prepareSolrQuery } from '@/utils/solrHelper' import { UtilService } from '@/services/UtilService' import logger from '@/logger' @@ -16,12 +16,11 @@ const actions: ActionTree = { if (payload.rejectionPeriodId && payload.rejectionPeriodId === 'LAST_SEVEN_DAYS') { rejectionPeriodFilter = "[NOW-7DAYS TO NOW]" } - const query = prepareOrderQuery({ + const query = prepareSolrQuery({ + coreName: "logInsights", docType: "FULFILLMENT_REJECTION", - queryFields: 'orderId_s', + sort: "orderId_s desc", viewSize: '0', // passed viewSize as 0 to not fetch any data - sort: 'rejectedAt_dt desc', - groupBy: 'orderId_s', filters: { rejectedAt_dt: {value: rejectionPeriodFilter}, rejectedFrom_txt_en: { value: escapeSolrSpecialChars(this.state.user.currentFacility.facilityId) }, @@ -43,8 +42,6 @@ const actions: ActionTree = { } } }) - query.coreName = "logInsights" - try { const resp = await RejectionService.fetchRejectionStats(query); @@ -95,126 +92,133 @@ const actions: ActionTree = { }, async fetchRejectedOrders({ commit, dispatch, state }, payload) { - let orders = [] as any, total = 0 - + let orders = [] as any, orderList = [] as any, total = 0 + const rejectedOrderQuery = JSON.parse(JSON.stringify(state.rejectedOrders.query)) + let rejectionPeriodFilter = "[NOW-24HOURS TO NOW]" - if (payload.rejectionPeriodId && payload.rejectionPeriodId === 'LAST_SEVEN_DAYS') { + if (rejectedOrderQuery.rejectionPeriodId === 'LAST_SEVEN_DAYS') { rejectionPeriodFilter = "[NOW-7DAYS TO NOW]" } - const rejectedOrderQuery = JSON.parse(JSON.stringify(state.rejectedOrders.query)) - const query = prepareOrderQuery({ + + const query = prepareSolrQuery({ + coreName: "logInsights", docType: "FULFILLMENT_REJECTION", queryString: rejectedOrderQuery.queryString, - queryFields: 'orderId_s', + queryFields: 'orderId_s itemDescription_txt_en productId_s rejectedFrom_txt_en rejectedBy_txt_en rejectionReasonId_txt_en rejectionReasonDesc_txt_en', viewIndex: rejectedOrderQuery.viewIndex, viewSize: rejectedOrderQuery.viewSize, sort: 'rejectedAt_dt desc', + isGroupingRequired: true, groupBy: 'orderId_s', filters: { rejectedAt_dt: {value: rejectionPeriodFilter}, rejectedFrom_txt_en: { value: escapeSolrSpecialChars(this.state.user.currentFacility.facilityId) }, } }) - query.coreName = "logInsights" - try { const resp = await RejectionService.fetchRejctedOrders(query); if (!hasError(resp)) { - total = resp.data.grouped.picklistBinId.ngroups - orders = resp.data.grouped.picklistBinId.groups + total = resp.data.grouped.orderId_s.ngroups + orders = resp.data.grouped.orderId_s.groups orders = orders.map((order: any) => { - const orderItem = order.doclist.docs[0]; + const orderItemDocs = order.doclist.docs.map((doc: any) => { + return { + orderId: doc.orderId_s, + orderItemSeqId: doc.orderItemSeqId_s, + itemDescription: doc.itemDescription_txt_en, + productId: doc.productId_s, + availableToPromise: doc.availableToPromise_d, + rejectedFrom: order.rejectedFrom_txt_en, + rejectedBy: doc.rejectedBy_txt_en, + rejectedAt: doc.rejectedAt_dt, + rejectionReasonId: doc.rejectionReasonId_txt_en, + rejectionReasonDesc: doc.rejectionReasonDesc_txt_en, + brokeredAt: doc.brokeredAt_dt, + brokeredBy: doc.brokeredBy_txt_en, + }; + }); + + const orderItem = orderItemDocs[0]; return { - customerId: orderItem.customerId, - customerName: orderItem.customerName, orderId: orderItem.orderId, - orderDate: orderItem.orderDate, - orderName: orderItem.orderName, - groupValue: order.groupValue, - items: order.doclist.docs, - shipmentMethodTypeId: orderItem.shipmentMethodTypeId, - shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, - } - }) - } else { - throw resp.data; - } - } catch(err) { - logger.error('Failed to fetch rejected orders.', err) + items: orderItemDocs, + }; + }); + + if (rejectedOrderQuery.viewIndex && rejectedOrderQuery.viewIndex > 0) orderList = JSON.parse(JSON.stringify(state.rejectedOrders.list)).concat(orders) + } else { + throw resp.data; + } + } catch(err) { + logger.error('Failed to fetch rejected orders.', err) + } + commit(types.REJECTION_ORDERS_UPDATED, { list: orderList.length > 0 ? orderList : orders, total}) + dispatch("fetchRejectedOrdersDetail", { orderIds: orders.map((order:any) => order.orderId)}) +}, + + async fetchRejectedOrdersDetail ({ commit, dispatch, state }, payload) { + let resp, orders = []; + const rejectedOrders = JSON.parse(JSON.stringify(state.rejectedOrders.list)); + const total = JSON.parse(JSON.stringify(state.rejectedOrders.total)); + const orderIds = payload.orderIds + if (!orderIds.length) { + return } - rejectedOrderQuery.viewSize = orders.length - commit(types.ORDER_REJECTED_QUERY_UPDATED, { ...rejectedOrderQuery }) - commit(types.ORDER_REJECTED_UPDATED, {orders, total}) - }, - - async fetchRejectedOrdersDetail ({ commit, dispatch, state }, payload = {}) { - let resp; - let orders = JSON.parse(JSON.stringify(state.rejectedOrders.list)); try { const params = { - ...payload, - viewSize: , + docType: "ORDER", + viewIndex: 0, + viewSize: orderIds.length, sort: 'orderDate asc', + fieldsToSelect: "orderId customerId customerName orderDate orderName reservedDatetime shipmentMethodTypeId shipmentMethodTypeDesc", + isGroupingRequired: true, groupBy: 'orderId', + groupLimit: 1, filters: { - productStoreId: { value: productIds } + orderId: { value: orderIds} } } - const orderQueryPayload = prepareOrderQuery(params) - - resp = await OrderService.findInProgressOrders(orderQueryPayload); - if (resp.status === 200 && !hasError(resp) && resp.data.grouped?.picklistBinId.matches > 0) { - total = resp.data.grouped.picklistBinId.ngroups - orders = resp.data.grouped.picklistBinId.groups - - // TODO get only product visible - await this.dispatch('product/getProductInformation', { orders }) - - orders = orders.map((order: any) => { - const orderItem = order.doclist.docs[0]; - return { - category: 'in-progress', - customerId: orderItem.customerId, - customerName: orderItem.customerName, - orderId: orderItem.orderId, - orderDate: orderItem.orderDate, - orderName: orderItem.orderName, - groupValue: order.groupValue, - picklistBinId: orderItem.picklistBinId, - picklistId: orderItem.picklistId, - items: removeKitComponents({items: order.doclist.docs}), - shipGroupSeqId: orderItem.shipGroupSeqId, - shipmentMethodTypeId: orderItem.shipmentMethodTypeId, - shipmentMethodTypeDesc: orderItem.shipmentMethodTypeDesc, - shippingInstructions: orderItem.shippingInstructions + const orderQueryPayload = prepareSolrQuery(params) + + resp = await RejectionService.findRejectedOrdersDetail(orderQueryPayload); + if (resp.status === 200 && !hasError(resp) && resp.data.grouped?.orderId.matches > 0) { + orders = resp.data.grouped.orderId.groups + const orderDetails = orders.reduce((orderDetail: any, order: any) => { + orderDetail[order.doclist.docs[0].orderId] = order.doclist.docs[0]; //we are fetching only one item for order detail + return orderDetail; + }, {}); + + rejectedOrders.map((rejectedOrder: any) => { + if (orderIds.includes(rejectedOrder.orderId)) { + const detail = orderDetails[rejectedOrder.orderId] + rejectedOrder.customerId = detail.customerId + rejectedOrder.customerName = detail.customerName + rejectedOrder.orderDate = detail.orderDate + rejectedOrder.orderName = detail.orderName + rejectedOrder.reservedDatetime = detail.reservedDatetime + rejectedOrder.shipmentMethodTypeId = detail.shipmentMethodTypeId + rejectedOrder.shipmentMethodTypeDesc = detail.shipmentMethodTypeDesc } }) + } else { throw resp.data } } catch (err) { - logger.error('No inProgress orders found', err) + logger.error('No rejected orders found', err) } - - inProgressQuery.viewSize = orders.length - - commit(types.ORDER_INPROGRESS_QUERY_UPDATED, { ...inProgressQuery }) - commit(types.ORDER_INPROGRESS_UPDATED, {orders, total}) - - // fetching the additional information like shipmentRoute, carrierParty information - // If no orders then no need to fetch any additional information - if(orders.length){ - dispatch('fetchInProgressOrdersAdditionalInformation'); - } - - emitter.emit('dismissLoader'); + commit(types.REJECTION_ORDERS_UPDATED, { list: rejectedOrders, total}) return resp; }, + async updateRejectedOrderQuery({ commit, dispatch }, payload) { + commit(types.REJECTION_ORDER_QUERY_UPDATED, payload) + await dispatch('fetchRejectedOrders'); + }, } export default actions; \ No newline at end of file diff --git a/src/store/modules/rejection/index.ts b/src/store/modules/rejection/index.ts index aa44ff62..d37f5907 100644 --- a/src/store/modules/rejection/index.ts +++ b/src/store/modules/rejection/index.ts @@ -5,7 +5,7 @@ import { Module } from 'vuex' import RejectionState from './RejectionState' import RootState from '../../RootState' -const orderModule: Module = { +const rejectionModule: Module = { namespaced: true, state: { rejectedItems: [], @@ -16,7 +16,8 @@ const orderModule: Module = { query: { viewIndex: 0, viewSize: process.env.VUE_APP_VIEW_SIZE, - queryString: '' + queryString: '', + rejectionPeriodId: 'LAST_TWENTY_FOUR_HOURS' } } }, @@ -25,4 +26,4 @@ const orderModule: Module = { mutations } -export default orderModule; \ No newline at end of file +export default rejectionModule; \ No newline at end of file diff --git a/src/store/modules/rejection/mutation-types.ts b/src/store/modules/rejection/mutation-types.ts index 556d6d9c..62809251 100644 --- a/src/store/modules/rejection/mutation-types.ts +++ b/src/store/modules/rejection/mutation-types.ts @@ -1,4 +1,5 @@ export const SN_REJECTION = 'rejection' export const REJECTION_REJECTED_ITEMS_UPDATED = SN_REJECTION + '/REJECTED_ITEMS_UPDATED' export const REJECTION_USED_REASONS_UPDATED = SN_REJECTION + '/USED_REASONS_UPDATED' -export const REJECTION_REJECTED_ORDERS_UPDATED = SN_REJECTION + '/REJECTION_REJECTED_ORDERS_UPDATED' +export const REJECTION_ORDERS_UPDATED = SN_REJECTION + '/ORDERS_UPDATED' +export const REJECTION_ORDER_QUERY_UPDATED = SN_REJECTION + '/ORDER_QUERY_UPDATED' diff --git a/src/store/modules/rejection/mutations.ts b/src/store/modules/rejection/mutations.ts index 01d0320a..1f3937d7 100644 --- a/src/store/modules/rejection/mutations.ts +++ b/src/store/modules/rejection/mutations.ts @@ -9,8 +9,12 @@ const mutations: MutationTree = { [types.REJECTION_USED_REASONS_UPDATED] (state, payload) { state.usedReasons = payload; }, - [types.REJECTION_REJECTED_ORDERS_UPDATED] (state, payload) { - state.rejectedOrders = payload; + [types.REJECTION_ORDERS_UPDATED] (state, payload) { + state.rejectedOrders.list = payload.list; + state.rejectedOrders.total = payload.total; }, + [types.REJECTION_ORDER_QUERY_UPDATED](state, payload) { + state.rejectedOrders.query = payload + } } export default mutations; \ No newline at end of file diff --git a/src/utils/solrHelper.ts b/src/utils/solrHelper.ts index f33470ff..8106f22f 100644 --- a/src/utils/solrHelper.ts +++ b/src/utils/solrHelper.ts @@ -57,7 +57,7 @@ const prepareSolrQuery = (params: any) => { groupParams = { "group": true, "group.field": params.groupBy ? params.groupBy : "orderId", - "group.limit": 1000, + "group.limit": params.groupLimit ? params.groupLimit : 1000, "group.ngroups": true, } } @@ -85,6 +85,10 @@ const prepareSolrQuery = (params: any) => { payload.json.params['defType'] = "edismax" } + if (params.fieldsToSelect) { + payload.json.params['fl'] = params.fieldsToSelect + } + // checking that if the params has filters, and then adding the filter values in the payload filter // for each key present in the params filters if (params.filters) { diff --git a/src/views/Rejections.vue b/src/views/Rejections.vue index a0986397..fe189bc7 100644 --- a/src/views/Rejections.vue +++ b/src/views/Rejections.vue @@ -11,11 +11,11 @@ - {{ "4" }} + {{ rejectedOrders.total }} - + {{ rejectionPeriod.description }} @@ -24,51 +24,61 @@ {{ translate('Most rejected items') }} - + {{ translate('View All') }} - - - - - -

{{ getProductIdentificationValue(productIdentificationPref.secondaryId, getProduct(item.val)) }}

- {{ getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.val)) ? getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.val)) : item.val }} -
- {{ item.count }} -
+ +
+

{{ translate("No items found.") }}

+
{{ translate('Most used reasons') }} - + {{ translate('View All') }} - - - {{ reason.description }} -

{{ reason.enumTypeId }}

-
- {{ reason.count }} -
+ +
+

{{ translate("No reasons found.") }}

+
-