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: added logic to save count of item already counted after product fetching (#528) #543

Merged
merged 6 commits into from
Dec 23, 2024
27 changes: 3 additions & 24 deletions src/views/CountDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@
<ion-label>{{ `${currentItemIndex + 1}/${itemsList.length}` }}</ion-label>
</ion-item>

<ion-button @click="changeProduct('previous')" :disabled="isFirstItem" fill="outline" shape="round" color="medium" class="ion-no-padding">
<ion-button @click="changeProduct('previous')" :disabled="currentItemIndex === 0" fill="outline" shape="round" color="medium" class="ion-no-padding">
<ion-icon slot="icon-only" :icon="chevronUpOutline"></ion-icon>
</ion-button>

<ion-button @click="changeProduct('next')" :disabled="isLastItem" fill="outline" shape="round" color="medium" class="ion-no-padding">
<ion-button @click="changeProduct('next')" :disabled="currentItemIndex === itemsList.length - 1" fill="outline" shape="round" color="medium" class="ion-no-padding">
<ion-icon slot="icon-only" :icon="chevronDownOutline"></ion-icon>
</ion-button>
</ion-item>
Expand Down Expand Up @@ -288,22 +288,18 @@ let cycleCount = ref([]);
const queryString = ref('');

const inputCount = ref('');
const isFirstItem = ref(true);
const isLastItem = ref(false);
const isScrolling = ref(false);
let previousItem = {};
let hasUnsavedChanges = ref(false);
const barcodeInput = ref();
let isScanningInProgress = ref(false);

onIonViewDidEnter(async() => {
await fetchCycleCount();
await fetchCycleCountItems();
await Promise.allSettled([await fetchCycleCount(), store.dispatch("count/fetchCycleCountItems", { inventoryCountImportId : props?.id })])
selectedSegment.value = 'all';
queryString.value = '';
previousItem = itemsList.value[0]
await store.dispatch("product/currentProduct", itemsList.value[0])
updateNavigationState(0);
barcodeInput.value?.$el?.setFocus();
})

Expand Down Expand Up @@ -351,10 +347,6 @@ function inputCountValidation(event) {
if(/[`!@#$%^&*()_+\-=\\|,.<>?~e]/.test(event.key) && event.key !== 'Backspace') event.preventDefault();
}

async function fetchCycleCountItems() {
await store.dispatch("count/fetchCycleCountItems", { inventoryCountImportId : props?.id });
}

async function fetchCycleCount() {
emitter.emit("presentLoader");
let payload = props?.id
Expand Down Expand Up @@ -439,15 +431,11 @@ function updateFilteredItems() {
const updatedProduct = Object.keys(product.value)?.length ? itemsList.value.find((item) => item.productId === product.value.productId && item.importItemSeqId === product.value.importItemSeqId) : itemsList.value[0]
if (updatedProduct) {
store.dispatch("product/currentProduct", updatedProduct);
updateNavigationState(itemsList.value.indexOf(updatedProduct));
} else {
store.dispatch("product/currentProduct", itemsList.value[0]);
updateNavigationState(0);
}
} else {
store.dispatch("product/currentProduct", {});
isFirstItem.value = true
isLastItem.value = false
}
}

Expand All @@ -470,9 +458,7 @@ const onScroll = (event) => {
previousItem = currentProduct // Update the previousItem variable with the current item

if (currentProduct) {
const currentIndex = itemsList.value?.indexOf(currentProduct);
store.dispatch("product/currentProduct", currentProduct);
updateNavigationState(currentIndex);
product.value.isRecounting = false;
}
}
Expand All @@ -487,12 +473,6 @@ const onScroll = (event) => {
});
};

// Add this function to update the navigation state
const updateNavigationState = (currentIndex) => {
isFirstItem.value = currentIndex === 0;
isLastItem.value = currentIndex === itemsList.value.length - 1;
};

async function changeProduct(direction) {
if (isScrolling.value) return;
isScrolling.value = true;
Expand All @@ -506,7 +486,6 @@ async function changeProduct(direction) {
if (productEl) productEl.scrollIntoView({ behavior: 'smooth' });
await new Promise(resolve => setTimeout(resolve, 500));
await store.dispatch("product/currentProduct", product);
updateNavigationState(index);
}
isScrolling.value = false;
}
Expand Down
91 changes: 56 additions & 35 deletions src/views/HardCountDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@

<ion-radio-group v-model="selectedCountUpdateType">
<ion-item>
<ion-radio justify="start" label-placement="end" value="new">
<ion-radio justify="start" label-placement="end" value="add">
<ion-label>
{{ translate("Add to existing count") }}
</ion-label>
Expand All @@ -119,8 +119,8 @@
</ion-item>
</ion-radio-group>

<ion-button v-if="!['INV_COUNT_REJECTED', 'INV_COUNT_COMPLETED'].includes(currentProduct.itemStatusId)" class="ion-margin" expand="block" @click="saveCount(currentProduct)">
{{ translate("Save count") }}
<ion-button v-if="!['INV_COUNT_REJECTED', 'INV_COUNT_COMPLETED'].includes(currentProduct.itemStatusId)" class="ion-margin" expand="block" :disabled="currentProduct.isMatching" @click="currentProduct.isMatchNotFound ? matchProduct(currentProduct) : saveCount(currentProduct)">
{{ translate((currentProduct.isMatchNotFound || currentProduct.isMatching) ? "Match product" : "Save count") }}
</ion-button>
</ion-list>

Expand All @@ -143,8 +143,8 @@
<ion-label slot="end">{{ isItemAlreadyAdded(currentProduct) ? getVariance(currentProduct, true) : "-" }}</ion-label>
</ion-item>
</template>
<ion-button v-if="!['INV_COUNT_REJECTED', 'INV_COUNT_COMPLETED'].includes(currentProduct.itemStatusId)" class="ion-margin" expand="block" @click="currentProduct.isMatchNotFound ? matchProduct(currentProduct) : saveCount(currentProduct)">
{{ translate(currentProduct.isMatchNotFound ? "Match product" : "Save count") }}
<ion-button v-if="!['INV_COUNT_REJECTED', 'INV_COUNT_COMPLETED'].includes(currentProduct.itemStatusId)" class="ion-margin" expand="block" :disabled="currentProduct.isMatching" @click="currentProduct.isMatchNotFound ? matchProduct(currentProduct) : saveCount(currentProduct)">
{{ translate((currentProduct.isMatchNotFound || currentProduct.isMatching) ? "Match product" : "Save count") }}
</ion-button>
</ion-list>
</div>
Expand Down Expand Up @@ -234,7 +234,7 @@ const selectedSegment = ref("all");
let previousItem = {} as any;
const barcodeInputRef = ref();
const inputCount = ref("") as any;
const selectedCountUpdateType = ref("new");
const selectedCountUpdateType = ref("add");
const isScrolling = ref(false);
let isScanningInProgress = ref(false);

Expand Down Expand Up @@ -321,13 +321,7 @@ async function changeProduct(direction: string) {

if(index >= 0 && index < itemsList.value.length) {
const product = itemsList.value[index];
let productEl = {} as any;
if(isItemAlreadyAdded(product)) {
productEl = document.querySelector(`[data-seq="${product.importItemSeqId}"]`);
} else {
productEl = document.getElementById(product.scannedId);
}
if(productEl) productEl.scrollIntoView({ behavior: 'smooth' });
scrollToProduct(product);
await new Promise(resolve => setTimeout(resolve, 500));
await store.dispatch("product/currentProduct", product);
}
Expand Down Expand Up @@ -373,13 +367,7 @@ async function scanProduct() {

const isAlreadySelected = isItemAlreadyAdded(selectedItem) ? (currentProduct.value.productId === selectedItem.productId && currentProduct.value.importItemSeqId === selectedItem.importItemSeqId) : (currentProduct.value.scannedId === selectedItem.scannedId);
if(!isAlreadySelected) {
router.replace({ hash: isItemAlreadyAdded(selectedItem) ? `#${selectedItem.productId}-${selectedItem.importItemSeqId}` : `#${selectedItem.scannedId}` });
setTimeout(() => {
const element = document.getElementById(isItemAlreadyAdded(selectedItem) ? `${selectedItem.productId}-${selectedItem.importItemSeqId}` : selectedItem.scannedId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}, 0);
scrollToProduct(selectedItem);
} else if(selectedItem.itemStatusId === "INV_COUNT_CREATED" && !isNewlyAdded) {
inputCount.value++;
}
Expand All @@ -390,6 +378,16 @@ async function scanProduct() {
queryString.value = ""
}

function scrollToProduct(product: any) {
router.replace({ hash: isItemAlreadyAdded(product) ? `#${product.productId}-${product.importItemSeqId}` : `#${product.scannedId}` });
setTimeout(() => {
const element = document.getElementById(isItemAlreadyAdded(product) ? `${product.productId}-${product.importItemSeqId}` : product.scannedId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}, 0);
}

async function addProductToItemsList() {
const newItem = {
scannedId: queryString.value,
Expand Down Expand Up @@ -434,9 +432,42 @@ async function addProductToCount(productId: any) {
return 0;
}

function updateCurrentItemInList(importItemSeqId: any, product: any, scannedValue: string) {
async function updateCurrentItemInList(importItemSeqId: any, product: any, scannedValue: string) {
const items = JSON.parse(JSON.stringify(cycleCountItems.value.itemList));
const updatedProduct = JSON.parse(JSON.stringify(currentProduct.value))
let prevItem = {} as any, hasErrorSavingCount = false;

if(updatedProduct.scannedId === scannedValue) {
if(importItemSeqId) {
updatedProduct["importItemSeqId"] = importItemSeqId
updatedProduct["productId"] = product.productId
updatedProduct["isMatchNotFound"] = false
} else {
updatedProduct["isMatchNotFound"] = true
}
updatedProduct["isMatching"] = false;
store.dispatch("product/currentProduct", updatedProduct);
} else if(importItemSeqId) {
prevItem = items.find((item: any) => item.scannedId === scannedValue);

if(prevItem && prevItem?.scannedCount >= 0) {
try {
const resp = await CountService.updateCount({
inventoryCountImportId: cycleCount.value.inventoryCountImportId,
importItemSeqId,
productId: product.productId,
quantity: prevItem.scannedCount,
countedByUserLoginId: userProfile.value.username
})

if(hasError(resp)) {
hasErrorSavingCount = true;
}
} catch(error) {
logger.error(error)
}
}
}

items.map((item: any) => {
if(item.scannedId === scannedValue) {
Expand All @@ -447,22 +478,12 @@ function updateCurrentItemInList(importItemSeqId: any, product: any, scannedValu
} else {
item["isMatchNotFound"] = true
}
item.isMatching = false;
item["isMatching"] = false;
if(prevItem && Object.keys(prevItem)?.length && !hasErrorSavingCount) delete item["scannedCount"]
}
})

store.dispatch('count/updateCycleCountItems', items);
if(updatedProduct.scannedId === scannedValue) {
if(importItemSeqId) {
updatedProduct["importItemSeqId"] = importItemSeqId
updatedProduct["productId"] = product.oroductId
updatedProduct["isMatchNotFound"] = false
} else {
updatedProduct["isMatchNotFound"] = true
}
updatedProduct.isMatching = false;
store.dispatch("product/currentProduct", updatedProduct);
}
}

async function readyForReview() {
Expand Down Expand Up @@ -542,7 +563,7 @@ async function saveCount(currentProduct: any, isScrollEvent = false) {
const prevCount = currentProduct.scannedCount ? currentProduct.scannedCount : 0

item.countedByUserLoginId = userProfile.value.username
if(selectedCountUpdateType.value === "new") item.scannedCount = inputCount.value
if(selectedCountUpdateType.value === "replace") item.scannedCount = inputCount.value
else item.scannedCount = inputCount.value + prevCount
currentItem = item;
}
Expand Down Expand Up @@ -620,7 +641,7 @@ function getVariance(item: any , isRecounting: boolean) {
}

function hasUnsavedChanges() {
return inputCount.value >= 0 || cycleCountItems.value.itemList.find((item: any) => item.scannedCount && !item.isMatchNotFound);
return (inputCount.value && inputCount.value >= 0) || cycleCountItems.value.itemList.find((item: any) => item.scannedCount && !item.isMatchNotFound);
}

function isItemAlreadyAdded(product: any) {
Expand Down
Loading