Skip to content

Commit

Permalink
Merge pull request #541 from amansinghbais/#528-hard-count-view
Browse files Browse the repository at this point in the history
Implemented: store view screen for the counting in Hard count (#528)
  • Loading branch information
ymaheshwari1 authored Dec 23, 2024
2 parents 1acf71b + d70bc08 commit cba4d6c
Show file tree
Hide file tree
Showing 10 changed files with 943 additions and 35 deletions.
114 changes: 114 additions & 0 deletions src/components/MatchProductModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="closeOutline" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Match product") }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-searchbar v-model="queryString" :placeholder="translate('Search product')" @keyup.enter="handleSearch" />

<template v-if="products.length">
<ion-radio-group v-model="selectedProductId">
<ion-item v-for="product in products" :key="product.productId">
<ion-thumbnail slot="start">
<Image :src="product.mainImageUrl" />
</ion-thumbnail>

<ion-radio :value="product.productId" :disabled="isProductAvailableInCycleCount(product.productId)">
<ion-label>
<h2>{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].primaryId, product) || getProduct(product.productId).productName }}</h2>
<p>{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].secondaryId, product) }}</p>
</ion-label>
</ion-radio>
</ion-item>
</ion-radio-group>
</template>

<div v-else-if="queryString && isSearching && !products.length" class="empty-state">
<p>{{ translate("No product found") }}</p>
</div>
<div v-else class="empty-state">
<img src="../assets/images/empty-state-add-product-modal.png" alt="empty-state" />
<p>{{ translate("Enter a SKU, or product name to search a product") }}</p>
</div>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button :disabled="!selectedProductId" @click="save()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
</ion-content>
</template>

<script setup lang="ts">
import {
IonButton,
IonButtons,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonRadio,
IonRadioGroup,
IonSearchbar,
IonThumbnail,
IonTitle,
IonToolbar,
modalController,
} from "@ionic/vue";
import { computed, defineProps, Ref, ref } from "vue";
import { closeOutline, saveOutline } from "ionicons/icons";
import store from "@/store";
import { translate } from "@hotwax/dxp-components";
import { getProductIdentificationValue, hasError } from "@/utils"
import Image from "@/components/Image.vue"
import { ProductService } from "@/services/ProductService";
import logger from "@/logger";
const props = defineProps(["items"])
const productStoreSettings = computed(() => store.getters["user/getProductStoreSettings"])
const getProduct = computed(() => (id: any) => store.getters["product/getProduct"](id))
const products = ref([]) as any;
let queryString = ref('');
const isSearching = ref(false);
const selectedProductId = ref("") as Ref<string>;
async function handleSearch() {
if(!queryString.value.trim()) {
isSearching.value = false;
return;
}
await getProducts();
isSearching.value = true;
}
async function getProducts() {
let productsList = [] as any;
try {
const resp = await ProductService.fetchProducts({
"keyword": queryString.value.trim(),
"viewSize": 100
})
if(!hasError(resp)) {
productsList = resp.data.response.docs;
}
} catch(err) {
logger.error("Failed to fetch products", err)
}
products.value = productsList
}
function closeModal(payload = {}) {
modalController.dismiss({ dismissed: true, ...payload });
}
function save() {
closeModal({ selectedProduct: products.value.find((product: any) => product.productId === selectedProductId) })
}
function isProductAvailableInCycleCount(id: string) {
return props.items.some((item: any) => item.productId === id && item.itemStatusId !== "INV_COUNT_REJECTED")
}
</script>
3 changes: 3 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
"Make sure you've reviewed the products and their counts before uploading them for review": "Make sure you've reviewed the products and their counts before uploading them for review",
"Map all required fields": "Map all required fields",
"Mapping name": "Mapping name",
"Match product": "Match product",
"Name - A to Z": "Name - A to Z",
"Name - Z to A": "Name - Z to A",
"New Count": "New Count",
Expand Down Expand Up @@ -240,6 +241,7 @@
"Scan a count before saving changes": "Scan a count before saving changes",
"Scan items": "Scan items",
"Scanned item does not match current product": "Scanned item does not match current product",
"Scanned item is not present in the count. To add new product move to All Segment.": "Scanned item is not present in the count. To add new product move to All Segment.",
"Scan or search products": "Scan or search products",
"Scanned quantity": "Scanned quantity",
"selected": "selected",
Expand All @@ -249,6 +251,7 @@
"Select store": "Select store",
"Select the following columns from the uploaded CSV": "Select the following columns from the uploaded CSV",
"Search": "Search",
"Search product": "Search product",
"Search result": "Search result",
"Search SKU or product name": "Search SKU or product name",
"Search time zones": "Search time zones",
Expand Down
10 changes: 10 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import StorePermissions from "@/views/StorePermissions.vue";
import Settings from "@/views/Settings.vue";
import BulkUpload from "@/views/BulkUpload.vue"
import HardCount from "@/views/HardCount.vue"
import HardCountDetail from "@/views/HardCountDetail.vue"

// Defining types for the meta values
declare module 'vue-router' {
Expand Down Expand Up @@ -82,6 +83,15 @@ const routes: Array<RouteRecordRaw> = [
permissionId: "APP_COUNT_VIEW"
}
},
{
path: 'hard-count-detail/:id',
name: 'HardCountDetail',
component: HardCountDetail,
props: true,
meta: {
permissionId: "APP_COUNT_VIEW"
}
},
{
path: 'settings',
component: () => import('@/views/Settings.vue')
Expand Down
25 changes: 14 additions & 11 deletions src/store/modules/count/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,23 @@ const actions: ActionTree<CountState, RootState> = {
},

async fetchCycleCountItems({commit} ,payload) {
let items;
try {
const resp = await CountService.fetchCycleCountItems(payload)
if(!hasError(resp)) {
items = resp.data
let items = [] as any, resp, pageIndex = 0;

this.dispatch("product/fetchProducts", { productIds: [...new Set(resp.data.itemList.map((item: any) => item.productId))] })
} else {
throw resp.data;
}
} catch (err: any) {
try {
do {
resp = await CountService.fetchCycleCountItems({ ...payload, pageSize: 100, pageIndex })
if(!hasError(resp) && resp.data?.itemList?.length) {
items = items.concat(resp.data.itemList)
} else {
throw resp.data;
}
pageIndex++;
} while(resp.data.itemList?.length >= 100)
} catch(err: any) {
logger.error(err)
}
commit(types.COUNT_ITEMS_UPDATED, items)
this.dispatch("product/fetchProducts", { productIds: [...new Set(items.map((item: any) => item.productId))] })
commit(types.COUNT_ITEMS_UPDATED, { itemList: items })
},

async updateCycleCountItems ({ commit }, payload) {
Expand Down
28 changes: 26 additions & 2 deletions src/store/modules/product/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import RootState from '@/store/RootState'
import ProductState from './ProductState'
import * as types from './mutation-types'
import { ProductService } from "@/services/ProductService"
import { hasError, showToast } from '@/utils';
import { hasError } from '@/utils';
import emitter from '@/event-bus';
import { translate } from '@/i18n';
import logger from '@/logger'
import store from '@/store'

const actions: ActionTree<ProductState, RootState> = {

Expand Down Expand Up @@ -70,6 +70,30 @@ const actions: ActionTree<ProductState, RootState> = {
return resp;
},

async fetchProductByIdentification ( { commit, state }, payload) {
const cachedProductIds = Object.keys(state.cached);
if(cachedProductIds.includes(payload.scannedValue)) return;

const productStoreSettings = store.getters["user/getProductStoreSettings"];
let resp;

try {
resp = await ProductService.fetchProducts({
"filters": [`goodIdentifications: ${productStoreSettings["barcodeIdentificationPref"]}/${payload.scannedValue}`],
"viewSize": 1
})
if(resp.status === 200 && !hasError(resp)) {
const products = resp.data.response.docs;
// Handled empty response in case of failed query
if (resp.data) commit(types.PRODUCT_ADD_TO_CACHED_MULTIPLE, { products });
return resp.data.response.docs[0]
}
} catch(err) {
logger.error("Failed to fetch products", err)
}
return {};
},

async clearProducts({ commit }) {
commit(types.PRODUCT_LIST_UPDATED, { products: [], total: 0 });
},
Expand Down
4 changes: 2 additions & 2 deletions src/views/Count.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
</template>
</main>

<ion-infinite-scroll ref="infiniteScrollRef" v-show="isScrollable" threshold="100px" @ionInfinite="loadMoreCycleCounts($event)">
<ion-infinite-scroll ref="infiniteScrollRef" v-show="isScrollable" threshold="100px" @ionInfinite="loadMoreCycleCount($event)">
<ion-infinite-scroll-content loading-spinner="crescent" :loading-text="translate('Loading')" />
</ion-infinite-scroll>
</ion-content>
Expand Down Expand Up @@ -229,7 +229,7 @@ async function segmentChanged(value) {
}
function navigateToStoreView(count) {
router.push((count.countTypeEnumId === "HARD_COUNT") ? `/tabs/hard-count-detail/${count.inventoryCountImportId}` : `/tabs/count-detail/${count.inventoryCountImportId}`);
router.push((count.countTypeEnumId === "HARD_COUNT" && count.statusId === "INV_COUNT_ASSIGNED") ? `/tabs/hard-count-detail/${count.inventoryCountImportId}` : `/tabs/count-detail/${count.inventoryCountImportId}`);
}
function getStatusIdForCountsToBeFetched() {
Expand Down
7 changes: 2 additions & 5 deletions src/views/CountDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<div class="detail" v-if="Object.keys(product)?.length">
<ion-item lines="none">
<ion-label class="ion-text-wrap">
<p class="overline" v-if="product.countTypeEnumId === 'HARD_COUNT'" color="warning">{{ translate("HARD COUNT") }}</p>
<h1>{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].primaryId, getProduct(product.productId)) || getProduct(product.productId).productName }}</h1>
<p>{{ getProductIdentificationValue(productStoreSettings["productIdentificationPref"].secondaryId, getProduct(product.productId)) }}</p>
</ion-label>
Expand Down Expand Up @@ -351,11 +352,7 @@ function inputCountValidation(event) {
}
async function fetchCycleCountItems() {
let payload = {
inventoryCountImportId : props?.id,
pageSize: 100
}
await store.dispatch("count/fetchCycleCountItems", payload);
await store.dispatch("count/fetchCycleCountItems", { inventoryCountImportId : props?.id });
}
async function fetchCycleCount() {
Expand Down
19 changes: 10 additions & 9 deletions src/views/HardCount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@
</ion-checkbox>
</ion-item>
</ion-list>

<ion-infinite-scroll
@ionInfinite="loadMoreFacilities($event)"
threshold="100px"
v-show="selectedSegment === 'individual' && isScrollable"
ref="infiniteScrollRef"
>
<ion-infinite-scroll-content loading-spinner="crescent" :loading-text="translate('Loading')" />
</ion-infinite-scroll>
</div>
</div>
</div>

<ion-infinite-scroll
@ionInfinite="loadMoreFacilities($event)"
threshold="100px"
v-show="selectedSegment === 'individual' && isScrollable"
ref="infiniteScrollRef"
>
<ion-infinite-scroll-content loading-spinner="crescent" :loading-text="translate('Loading')" />
</ion-infinite-scroll>
</ion-content>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
Expand Down Expand Up @@ -271,6 +271,7 @@ async function toggleCountNameUpdation() {
function handleSegmentChange() {
selectedFacilityIds.value = [];
selectedFacilityGroupId.value = "";
queryString.value = "";
}
function enableScrolling() {
Expand Down
Loading

0 comments on commit cba4d6c

Please sign in to comment.