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

Implemented: support for barcode identification for scanning (#494) #498

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"Assigned to": "Assigned to",
"Authenticating": "Authenticating",
"Back to Launchpad": "Back to Launchpad",
"Barcode Identifier": "Barcode Identifier",
"Before": "Before",
"Browser TimeZone": "Browser TimeZone",
"Browser time zone": "Browser time zone",
Expand Down Expand Up @@ -200,6 +201,7 @@
"REJECTED": "REJECTED",
"Rejected": "Rejected",
"rejected": "rejected",
"Require inventory to be scanned when counting instead of manually entering values. If the identifier is not found, the scan will default to using the internal name.": "Require inventory to be scanned when counting instead of manually entering values.{space} If the identifier is not found, the scan will default to using the internal name.",
"Required": "Required",
"Recount requested": "Recount requested",
"Rename": "Rename",
Expand All @@ -209,7 +211,6 @@
"Review count": "Review count",
"rejected counts": "rejected counts",
"Require barcode scanning": "Require barcode scanning",
"Require inventory to be scanned when counting instead of manually entering values.": "Require inventory to be scanned when counting instead of manually entering values.",
"Save": "Save",
"Save count": "Save count",
"Save re-count": "Save re-count",
Expand All @@ -222,7 +223,7 @@
"Scan items": "Scan items",
"Scanned item does not match current product": "Scanned item does not match current product",
"Scan or search products": "Scan or search products",
"Scan a valid product sku": "Scan a valid product sku",
"Scan a valid product barcode identifier": "Scan a valid product barcode identifier",
"Scanned quantity": "Scanned quantity",
"selected": "selected",
"Select": "Select",
Expand Down
2 changes: 1 addition & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createStore, useStore as useVuexStore, Store } from "vuex";

Check warning on line 1 in src/store/index.ts

View workflow job for this annotation

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

'Store' is defined but never used

Check warning on line 1 in src/store/index.ts

View workflow job for this annotation

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

'Store' is defined but never used
import createPersistedState from "vuex-persistedstate";
import RootState from "./RootState"; // Ensure this is correctly imported
import mutations from "./mutations";
Expand All @@ -17,7 +17,7 @@
const state: any = {}

const persistState = createPersistedState({
paths: ["user"],
paths: ["user", "product.cached"],
fetchBeforeUse: true
})

Expand Down
4 changes: 4 additions & 0 deletions src/store/modules/product/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import ProductState from './ProductState'
import * as types from './mutation-types'
import { ProductService } from "@/services/ProductService"
import { hasError, showToast } from '@/utils';

Check warning on line 6 in src/store/modules/product/actions.ts

View workflow job for this annotation

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

'showToast' is defined but never used

Check warning on line 6 in src/store/modules/product/actions.ts

View workflow job for this annotation

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

'showToast' is defined but never used
import emitter from '@/event-bus';
import { translate } from '@/i18n';

Check warning on line 8 in src/store/modules/product/actions.ts

View workflow job for this annotation

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

'translate' is defined but never used

Check warning on line 8 in src/store/modules/product/actions.ts

View workflow job for this annotation

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

'translate' is defined but never used
import logger from '@/logger'

const actions: ActionTree<ProductState, RootState> = {
Expand Down Expand Up @@ -72,6 +72,10 @@

async clearProducts({ commit }) {
commit(types.PRODUCT_LIST_UPDATED, { products: [], total: 0 });
},

async clearCachedProducts({ commit }) {
commit(types.PRODUCT_CACHED_CLEARED);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/store/modules/product/mutation-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export const PRODUCT_ADD_TO_CACHED = SN_PRODUCT + '/ADD_TO_CACHED'
export const PRODUCT_CURRENT_UPDATED = SN_PRODUCT + '/CURRENT_UPDATED'
export const PRODUCT_ADD_TO_CACHED_MULTIPLE = SN_PRODUCT + '/ADD_TO_CACHED_MULTIPLE'
export const PRODUCT_LIST_UPDATED = SN_PRODUCT + '/LIST_UPDATED'
export const PRODUCT_CACHED_CLEARED = SN_PRODUCT + '/CACHED_CLEARED'
5 changes: 4 additions & 1 deletion src/store/modules/product/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const mutations: MutationTree <ProductState> = {
[types.PRODUCT_LIST_UPDATED](state, payload) {
state.list.items = payload.products
state.list.total = payload.total
}
},
[types.PRODUCT_CACHED_CLEARED] (state) {
state.cached = {}
},
}
export default mutations;
3 changes: 2 additions & 1 deletion src/store/modules/user/UserState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export default interface UserState {
productIdentificationPref: {
primaryId: string,
secondaryId: string
}
},
barcodeIdentificationPref: string;
},
goodIdentificationTypes: Array<string>;
}
33 changes: 26 additions & 7 deletions src/store/modules/user/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const actions: ActionTree<UserState, RootState> = {
commit(types.USER_FACILITIES_UPDATED, [])
commit(types.USER_CURRENT_FACILITY_UPDATED, {})
commit(types.USER_PRODUCT_STORES_UPDATED, [])
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { showQoh: false, forceScan: false, productIdentificationPref: {
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { showQoh: false, forceScan: false, barcodeIdentificationPref: "internalName", productIdentificationPref: {
primaryId: 'productId',
secondaryId: ''
}})
Expand Down Expand Up @@ -264,14 +264,17 @@ const actions: ActionTree<UserState, RootState> = {

async updateCurrentProductStore({ commit, dispatch }, productStore) {
commit(types.USER_CURRENT_PRODUCT_STORE_UPDATED, productStore)
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { showQoh: false, forceScan: false })
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { showQoh: false, forceScan: false, barcodeIdentificationPref: "internalName", productIdentificationPref: {
primaryId: 'productId',
secondaryId: ''
} })
dispatch("getProductStoreSetting")
},

async getProductStoreSetting({ commit, state }, productStoreId?: string) {
const payload = {
"productStoreId": productStoreId ? productStoreId : state.currentProductStore.productStoreId,
"settingTypeEnumId": "INV_CNT_VIEW_QOH,INV_FORCE_SCAN,PRDT_IDEN_PREF",
"settingTypeEnumId": "INV_CNT_VIEW_QOH,INV_FORCE_SCAN,PRDT_IDEN_PREF,BARCODE_IDEN_PREF",
"settingTypeEnumId_op": "in",
"pageSize": 10
}
Expand All @@ -291,10 +294,15 @@ const actions: ActionTree<UserState, RootState> = {
if(setting.settingTypeEnumId === "PRDT_IDEN_PREF" && setting.settingValue) {
settings["productIdentificationPref"] = JSON.parse(setting.settingValue)
}

if(setting.settingTypeEnumId === "BARCODE_IDEN_PREF" && setting.settingValue) {
settings["barcodeIdentificationPref"] = setting.settingValue
}
return settings
}, {
showQoh: false,
forceScan: false
forceScan: false,
barcodeIdentificationPref: "internalName"
})
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, settings)
}
Expand All @@ -307,11 +315,18 @@ const actions: ActionTree<UserState, RootState> = {
const eComStoreId = state.currentProductStore.productStoreId;
const fromDate = Date.now()

let settingValue = false as any;
if(payload.enumId === "BARCODE_IDEN_PREF") settingValue = "internalName"
if(payload.enumId === "PRDT_IDEN_PREF") settingValue = JSON.stringify({
primaryId: 'productId',
secondaryId: ''
})

const params = {
fromDate,
"productStoreId": eComStoreId,
"settingTypeEnumId": payload.enumId,
"settingValue": false
settingValue
}

try {
Expand All @@ -322,7 +337,7 @@ const actions: ActionTree<UserState, RootState> = {

// not checking for resp success and fail case as every time we need to update the state with the
// default value when creating a scan setting
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { [payload.key]: false })
commit(types.USER_PRODUCT_STORE_SETTING_UPDATED, { [payload.key]: settingValue })
return fromDate;
},

Expand All @@ -344,6 +359,10 @@ const actions: ActionTree<UserState, RootState> = {
enumId = "PRDT_IDEN_PREF"
}

if(payload.key === "barcodeIdentificationPref") {
enumId = "BARCODE_IDEN_PREF"
}

let fromDate;

try {
Expand All @@ -366,7 +385,7 @@ const actions: ActionTree<UserState, RootState> = {
"fromDate": fromDate,
"productStoreId": eComStoreId,
"settingTypeEnumId": enumId,
"settingValue": JSON.stringify(payload.value)
"settingValue": payload.key !== "barcodeIdentificationPref" ? JSON.stringify(payload.value) : payload.value
}

try {
Expand Down
1 change: 1 addition & 0 deletions src/store/modules/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const userModule: Module<UserState, RootState> = {
primaryId: 'productId',
secondaryId: ''
},
barcodeIdentificationPref: ""
},
goodIdentificationTypes: []
},
Expand Down
28 changes: 10 additions & 18 deletions src/views/CountDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -354,28 +354,20 @@ function handleBlur() {
async function handleInput(event) {
if (!isInputFocused.value) return;

let sku = event.target.value;
if(!sku) {
showToast(translate("Scan a valid product sku"));
let scannedValue = event.target.value;
if(!scannedValue) {
showToast(translate("Scan a valid product barcode identifier"));
return;
}

const cachedProducts = getCachedProducts.value;
let scannedItemId = Object.keys(cachedProducts).find(productId => cachedProducts[productId].sku === sku);
if (!scannedItemId) {
const product = await findProduct(sku);
if(product) {
scannedItemId = product.data.response?.docs[0]?.productId
}
}
if (scannedItemId) {
if (scannedItemId === product.value.productId) {
inputCount.value++;
} else {
showToast(translate('Scanned item does not match current product'));
}
} else {
showToast(translate('Product not found'));
const barcodeIdentifer = productStoreSettings.value["barcodeIdentificationPref"];

const itemVal = getProductIdentificationValue(barcodeIdentifer, cachedProducts[product.value.productId]) ? getProductIdentificationValue(barcodeIdentifer, cachedProducts[product.value.productId]) : cachedProducts[product.value.productId]?.internalName
if(itemVal && itemVal === scannedValue) {
inputCount.value++;
} else {
showToast(translate('Scanned item does not match current product'));
}
scannedCount.value = ''
}
Expand Down
17 changes: 14 additions & 3 deletions src/views/StorePermissions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@
{{ translate('Force scan') }}
</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>{{ translate("Require inventory to be scanned when counting instead of manually entering values.") }}</p>
</ion-card-content>
<ion-card-content v-html="barcodeContentMessage"></ion-card-content>
<ion-item lines="none">
<ion-toggle :checked="productStoreSettings['forceScan']" @click.prevent="updateProductStoreSetting($event, 'forceScan')">
{{ translate("Require barcode scanning") }}
</ion-toggle>
</ion-item>
<ion-item lines="none">
<ion-select :label="translate('Barcode Identifier')" interface="popover" :placeholder="translate('Select')" :value="productStoreSettings['barcodeIdentificationPref']" @ionChange="setBarcodeIdentificationPref($event.detail.value)">
<ion-select-option v-for="identification in productIdentifications" :key="identification" :value="identification" >{{ identification }}</ion-select-option>
</ion-select>
</ion-item>
</ion-card>
</div>
</ion-content>
Expand All @@ -53,6 +56,8 @@ import {
IonHeader,
IonItem,
IonPage,
IonSelect,
IonSelectOption,
IonTitle,
IonToggle,
IonToolbar,
Expand All @@ -62,7 +67,9 @@ import { translate } from '@/i18n'
import store from "@/store";
import { computed } from "vue";

const barcodeContentMessage = translate("Require inventory to be scanned when counting instead of manually entering values. If the identifier is not found, the scan will default to using the internal name.", { space: '<br /><br />' })
const productStoreSettings = computed(() => store.getters["user/getProductStoreSettings"])
const productIdentifications = computed(() => store.getters["user/getGoodIdentificationTypes"])

onIonViewWillEnter(async () => {
await store.dispatch("user/getProductStoreSetting")
Expand All @@ -72,6 +79,10 @@ function updateProductStoreSetting(event: any, key: string) {
event.stopImmediatePropagation();
store.dispatch("user/setProductStoreSetting", { key, value: !productStoreSettings.value[key] })
}

function setBarcodeIdentificationPref(value: any) {
store.dispatch("user/setProductStoreSetting", { key: "barcodeIdentificationPref", value })
}
</script>

<style scoped>
Expand Down
Loading