diff --git a/src/components/Controls/AutoComplete.vue b/src/components/Controls/AutoComplete.vue
index 948bf38e..361b746e 100644
--- a/src/components/Controls/AutoComplete.vue
+++ b/src/components/Controls/AutoComplete.vue
@@ -300,6 +300,7 @@ export default {
return;
}
+ this.triggerChange(e.target.value);
this.toggleDropdown(true);
this.updateSuggestions(e.target.value);
},
diff --git a/src/components/Controls/MultiLabelLink.vue b/src/components/Controls/MultiLabelLink.vue
index 0d702542..cfb4a524 100644
--- a/src/components/Controls/MultiLabelLink.vue
+++ b/src/components/Controls/MultiLabelLink.vue
@@ -22,6 +22,11 @@ export default {
},
},
props: {
+ thirdLink: String,
+ showSecondaryLink: {
+ type: Boolean,
+ default: false,
+ },
secondaryLink: String,
},
mounted() {
@@ -80,9 +85,10 @@ export default {
return (this.results = results
.map((r) => {
const option = {
- label: r[this.secondaryLink]
- ? `${r[schema.titleField]} ` + ` ${r[this.secondaryLink]}`
- : r[schema.titleField],
+ label:
+ r[this.secondaryLink] && this.showSecondaryLink
+ ? `${r[schema.titleField]} ` + ` ${r[this.secondaryLink]}`
+ : r[schema.titleField],
value: r.name,
value2: r[this.secondaryLink],
};
diff --git a/src/components/POS/types.ts b/src/components/POS/types.ts
index 0e5321ae..3825c798 100644
--- a/src/components/POS/types.ts
+++ b/src/components/POS/types.ts
@@ -30,6 +30,7 @@ export type PosEmits =
| 'setPaymentMethod'
| 'setCouponsCount'
| 'routeToSinvList'
+ | 'handleItemSearch'
| 'applyPricingRule'
| 'setTransferRefNo'
| 'setLoyaltyPoints'
diff --git a/src/pages/POS/ClassicPOS.vue b/src/pages/POS/ClassicPOS.vue
index c85c94fd..313d31e7 100644
--- a/src/pages/POS/ClassicPOS.vue
+++ b/src/pages/POS/ClassicPOS.vue
@@ -85,47 +85,23 @@
- emitEvent('addItem', await getItem(itemSearchTerm) as Item)
- "
- @change="(item: string) =>itemSearchTerm= item"
- />
-
- {
- emitEvent('addItem', await getItem(name) as Item);
- }
- "
- />
-
- {
- emitEvent('addItem', await getItem(name) as Item,qty as number);
- }
+ @keyup.enter="(item) =>
+ emitEvent('handleItemSearch', item.target.value as string, true)
"
+ @change="(item: string) => emitEvent('handleItemSearch', item)"
/>
@@ -369,14 +345,12 @@ import Button from 'src/components/Button.vue';
import { defineComponent, PropType } from 'vue';
import PriceListModal from './PriceListModal.vue';
import { Item } from 'models/baseModels/Item/Item';
-import Link from 'src/components/Controls/Link.vue';
import CouponCodeModal from './CouponCodeModal.vue';
import POSQuickActions from './POSQuickActions.vue';
import { PosEmits } from 'src/components/POS/types';
import SavedInvoiceModal from './SavedInvoiceModal.vue';
import OpenPOSShiftModal from './OpenPOSShiftModal.vue';
import ClosePOSShiftModal from './ClosePOSShiftModal.vue';
-import Barcode from 'src/components/Controls/Barcode.vue';
import LoyaltyProgramModal from './LoyaltyProgramModal.vue';
import { POSItem, ItemQtyMap } from 'src/components/POS/types';
import ItemsGrid from 'src/components/POS/Classic/ItemsGrid.vue';
@@ -385,7 +359,6 @@ import ReturnSalesInvoiceModal from './ReturnSalesInvoiceModal.vue';
import MultiLabelLink from 'src/components/Controls/MultiLabelLink.vue';
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
import SelectedItemTable from 'src/components/POS/Classic/SelectedItemTable.vue';
-import WeightEnabledBarcode from 'src/components/Controls/WeightEnabledBarcode.vue';
import FloatingLabelFloatInput from 'src/components/POS/FloatingLabelFloatInput.vue';
import FloatingLabelCurrencyInput from 'src/components/POS/FloatingLabelCurrencyInput.vue';
import { AppliedCouponCodes } from 'models/baseModels/AppliedCouponCodes/AppliedCouponCodes';
@@ -393,9 +366,7 @@ import { AppliedCouponCodes } from 'models/baseModels/AppliedCouponCodes/Applied
export default defineComponent({
name: 'ClassicPOS',
components: {
- Link,
Button,
- Barcode,
ItemsGrid,
AlertModal,
ItemsTable,
@@ -409,7 +380,6 @@ export default defineComponent({
SavedInvoiceModal,
ClosePOSShiftModal,
LoyaltyProgramModal,
- WeightEnabledBarcode,
FloatingLabelFloatInput,
ReturnSalesInvoiceModal,
FloatingLabelCurrencyInput,
@@ -437,6 +407,10 @@ export default defineComponent({
type: Number,
default: 0,
},
+ itemSearchTerm: {
+ type: String,
+ default: '',
+ },
loyaltyProgram: {
type: String,
default: '',
@@ -471,6 +445,7 @@ export default defineComponent({
'setPaidAmount',
'setCouponsCount',
'routeToSinvList',
+ 'handleItemSearch',
'setPaymentMethod',
'setTransferRefNo',
'setLoyaltyPoints',
@@ -486,7 +461,6 @@ export default defineComponent({
data() {
return {
additionalDiscounts: fyo.pesa(0),
- itemSearchTerm: '',
};
},
computed: {
diff --git a/src/pages/POS/POS.vue b/src/pages/POS/POS.vue
index a3978995..e8da11e8 100644
--- a/src/pages/POS/POS.vue
+++ b/src/pages/POS/POS.vue
@@ -18,6 +18,7 @@
:loyalty-points="loyaltyPoints"
:open-alert-modal="openAlertModal"
:default-customer="defaultCustomer"
+ :item-search-term="itemSearchTerm"
:is-pos-shift-open="isPosShiftOpen"
:items="(items as [] as POSItem[])"
:sinv-doc="(sinvDoc as SalesInvoice)"
@@ -39,6 +40,7 @@
@clear-values="clearValues"
@set-customer="setCustomer"
@toggle-modal="toggleModal"
+ @handle-item-search="handleItemSearch"
@set-paid-amount="setPaidAmount"
@set-payment-method="setPaymentMethod"
@set-coupons-count="setCouponsCount"
@@ -287,6 +289,87 @@ export default defineComponent({
this.loyaltyProgram = party[0]?.loyaltyProgram as string;
this.loyaltyPoints = party[0]?.loyaltyPoints as number;
},
+
+ async handleItemSearch(searchTerm: string, addItem?: boolean) {
+ this.itemSearchTerm = searchTerm;
+ if (!addItem) return;
+
+ let quantity = 1;
+ const posSettings = fyo.singles.POSSettings;
+ const isWeightEnabledBarcode = posSettings?.weightEnabledBarcode;
+
+ const checkDigits = posSettings?.checkDigits || '';
+ const itemCodeDigits = posSettings?.itemCodeDigits || 0;
+ const weightDigits = posSettings?.itemWeightDigits || 0;
+
+ const expectedWeightBarcodeLength =
+ String(checkDigits).length +
+ Number(itemCodeDigits) +
+ Number(weightDigits);
+
+ let isWeightBarcode = false;
+ let itemCode = searchTerm;
+ let weightPart = '';
+
+ if (
+ isWeightEnabledBarcode &&
+ searchTerm.length === expectedWeightBarcodeLength
+ ) {
+ const extractedItemCode = searchTerm.slice(
+ checkDigits.toString().length,
+ checkDigits.toString().length + itemCodeDigits
+ );
+ const weightData = searchTerm.slice(
+ checkDigits.toString().length + itemCodeDigits
+ );
+
+ if (!isNaN(Number(weightData))) {
+ isWeightBarcode = true;
+ itemCode = extractedItemCode;
+ weightPart = weightData;
+ }
+ }
+
+ const allItems = await this.fyo.db.getAll(ModelNameEnum.Item, {
+ fields: ['name', 'barcode', 'itemCode', 'unit'],
+ });
+
+ let matchedItem = null;
+
+ if (isWeightBarcode) {
+ matchedItem = allItems.find(
+ (item) => item.itemCode === itemCode || item.barcode === itemCode
+ );
+ } else if (searchTerm.length === 12) {
+ matchedItem = allItems.find((item) => item.barcode === searchTerm);
+ }
+
+ if (!matchedItem) {
+ matchedItem = allItems.find((item) => item.name === searchTerm);
+ }
+
+ if (!matchedItem) return;
+
+ if (isWeightBarcode && weightPart) {
+ const weightValue = parseInt(weightPart, 10);
+ if ((matchedItem.unit as string)?.toLowerCase() === 'kg') {
+ quantity = weightValue / 1000;
+ } else {
+ quantity = weightValue;
+ }
+ }
+
+ const itemDoc = this.getItem(matchedItem.name as string);
+ if (itemDoc && addItem) {
+ await this.addItem(itemDoc as POSItem, quantity);
+ this.itemSearchTerm = '';
+ }
+ },
+
+ getItem(name: string) {
+ return this.items.find((item) => item.name === name);
+ },
+
isModalOpen() {
for (const modal of modalNames) {
if (modal && this[`open${modal}Modal`]) {
diff --git a/src/pages/POS/POSQuickActions.vue b/src/pages/POS/POSQuickActions.vue
index a265d259..9d50dfbf 100644
--- a/src/pages/POS/POSQuickActions.vue
+++ b/src/pages/POS/POSQuickActions.vue
@@ -337,7 +337,6 @@ export default defineComponent({
paymentDoc: {} as Payment,
itemSerialNumbers: {} as ItemSerialNumbers,
- itemSearchTerm: '',
transferRefNo: undefined as string | undefined,
transferClearanceDate: undefined as Date | undefined,
};