Skip to content

Commit 874ddf6

Browse files
author
Ahmed Osama
committed
refactor: clean up console statements
- Remove debugging console.log statements from ItemsSelector and POSSale - Add console.error to all error handlers for proper error tracking - Keep error logging while removing unnecessary flow-tracking logs
1 parent 37af929 commit 874ddf6

2 files changed

Lines changed: 222 additions & 30 deletions

File tree

POS/src/components/sale/ItemsSelector.vue

Lines changed: 169 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,19 @@
6262
@input="handleSearchInput"
6363
@keydown="handleKeyDown"
6464
type="text"
65-
:placeholder="scannerEnabled ? 'Scanner Ready - Scan barcode now' : 'Search by item code, name or scan barcode'"
65+
:placeholder="searchPlaceholder"
6666
:class="[
67-
'w-full text-sm border rounded-md px-3 py-2 pl-10 pr-10 focus:outline-none transition-all',
68-
scannerEnabled
67+
'w-full text-sm border rounded-md px-3 py-2 pl-10 pr-28 focus:outline-none transition-all',
68+
autoAddEnabled
69+
? 'border-blue-400 bg-blue-50 focus:ring-2 focus:ring-blue-500 focus:border-transparent'
70+
: scannerEnabled
6971
? 'border-green-400 bg-green-50 focus:ring-2 focus:ring-green-500 focus:border-transparent'
7072
: 'border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-transparent'
7173
]"
7274
aria-label="Search items"
7375
/>
74-
<!-- Barcode Scan Icon -->
75-
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
76+
<!-- Barcode Scan Icon and Auto-Add Toggle -->
77+
<div class="absolute inset-y-0 right-0 pr-3 flex items-center gap-1">
7678
<button
7779
@click="toggleBarcodeScanner"
7880
:class="[
@@ -87,6 +89,21 @@
8789
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"/>
8890
</svg>
8991
</button>
92+
<button
93+
@click="toggleAutoAdd"
94+
:class="[
95+
'p-1 rounded transition-all flex items-center gap-1 text-xs font-medium px-2',
96+
autoAddEnabled
97+
? 'bg-blue-100 hover:bg-blue-200 text-blue-700'
98+
: 'hover:bg-gray-100 text-gray-600'
99+
]"
100+
:title="autoAddEnabled ? 'Auto-Add: ON - Press Enter to add items to cart' : 'Auto-Add: OFF - Click to enable automatic cart addition on Enter'"
101+
>
102+
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
103+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
104+
</svg>
105+
<span>Auto</span>
106+
</button>
90107
</div>
91108
</div>
92109
<div class="flex items-center space-x-0.5 bg-gray-100 rounded-md p-0.5">
@@ -392,8 +409,11 @@ const lastKeyTime = ref(0)
392409
const barcodeBuffer = ref("")
393410
const searchInputRef = ref(null)
394411
const scannerEnabled = ref(false)
412+
const autoAddEnabled = ref(false)
395413
const itemThreshold = ref(50) // Threshold for auto-switching to list view
396414
const userManuallySetView = ref(false) // Track if user manually changed view mode
415+
const scannerInputDetected = ref(false) // Track if current input is from scanner
416+
const autoSearchTimer = ref(null) // Timer for auto-search when typing stops
397417
398418
// Pagination state
399419
const currentPage = ref(1)
@@ -413,6 +433,26 @@ const totalPages = computed(() => {
413433
return Math.ceil(filteredItems.value.length / itemsPerPage.value)
414434
})
415435
436+
const SEARCH_PLACEHOLDERS = Object.freeze({
437+
auto: "Auto-Add ON - Type or scan barcode",
438+
scanner: "Scanner ON - Enable Auto for automatic addition",
439+
default: "Search by item code, name or scan barcode",
440+
})
441+
442+
const searchMode = computed(() => {
443+
if (autoAddEnabled.value) {
444+
return "auto"
445+
}
446+
447+
if (scannerEnabled.value) {
448+
return "scanner"
449+
}
450+
451+
return "default"
452+
})
453+
454+
const searchPlaceholder = computed(() => SEARCH_PLACEHOLDERS[searchMode.value])
455+
416456
// Watch for cart items and pos profile changes
417457
watch(
418458
() => props.cartItems,
@@ -475,21 +515,43 @@ function handleKeyDown(event) {
475515
const currentTime = Date.now()
476516
const timeDiff = currentTime - lastKeyTime.value
477517
478-
// If Enter is pressed, always trigger search
518+
// If Enter/newline is pressed, trigger barcode search
479519
if (event.key === "Enter") {
480520
event.preventDefault()
481-
handleBarcodeSearch()
521+
522+
const isFromScanner = scannerInputDetected.value
523+
524+
// Auto-add if Auto-Add mode is enabled (regardless of manual typing vs scanner)
525+
if (autoAddEnabled.value) {
526+
// Auto-add enabled - add item directly to cart
527+
handleBarcodeSearch(true) // Pass true to indicate auto-add
528+
} else {
529+
// Auto-add disabled - normal search behavior
530+
handleBarcodeSearch(false)
531+
}
532+
533+
// Reset detection
482534
barcodeBuffer.value = ""
535+
scannerInputDetected.value = false
536+
537+
// Clear auto-search timer since Enter was pressed
538+
if (autoSearchTimer.value) {
539+
clearTimeout(autoSearchTimer.value)
540+
autoSearchTimer.value = null
541+
}
542+
483543
return
484544
}
485545
486546
// Barcode scanners typically input very fast (< 50ms between characters)
487547
// If time between keystrokes is very short, it's likely a barcode scanner
488-
if (timeDiff < 50 && event.key.length === 1) {
548+
if (timeDiff < 50 && event.key.length === 1 && barcodeBuffer.value.length > 0) {
489549
barcodeBuffer.value += event.key
490-
} else {
550+
scannerInputDetected.value = true // Mark as scanner input
551+
} else if (event.key.length === 1) {
491552
// Manual typing - reset buffer
492-
barcodeBuffer.value = event.key.length === 1 ? event.key : ""
553+
barcodeBuffer.value = event.key
554+
scannerInputDetected.value = false // Mark as manual input
493555
}
494556
495557
lastKeyTime.value = currentTime
@@ -499,36 +561,61 @@ function handleKeyDown(event) {
499561
function handleSearchInput(event) {
500562
const value = event.target.value
501563
itemStore.setSearchTerm(value)
564+
565+
// Clear any existing timer
566+
if (autoSearchTimer.value) {
567+
clearTimeout(autoSearchTimer.value)
568+
autoSearchTimer.value = null
569+
}
570+
571+
// If Auto-Add is enabled and user is typing, automatically trigger search after they stop
572+
if (autoAddEnabled.value && value.trim().length > 0) {
573+
// Wait 500ms after user stops typing, then auto-search and add
574+
autoSearchTimer.value = setTimeout(() => {
575+
handleBarcodeSearch(true) // Auto-add mode
576+
}, 500) // 500ms delay after typing stops
577+
}
502578
}
503579
504580
function handleItemClick(item) {
505581
emit("item-selected", item)
506582
}
507583
508-
async function handleBarcodeSearch() {
584+
async function handleBarcodeSearch(forceAutoAdd = false) {
509585
const barcode = searchTerm.value.trim()
510586
511587
if (!barcode) {
512588
return
513589
}
514590
515-
// If scanner is enabled, always try to add to cart automatically
516-
const shouldAutoAdd = scannerEnabled.value
591+
// Auto-add if explicitly requested (from scanner newline detection)
592+
// OR if both scanner and auto-add modes are enabled
593+
const shouldAutoAdd = forceAutoAdd || (scannerEnabled.value && autoAddEnabled.value)
517594
518595
try {
519596
// First try exact barcode lookup via API
520597
const item = await itemStore.searchByBarcode(barcode)
521598
522599
if (item) {
523-
// Item found by barcode - add to cart immediately
524-
emit("item-selected", item)
600+
// Item found by barcode - add to cart immediately with auto-add flag
601+
emit("item-selected", item, shouldAutoAdd)
525602
itemStore.clearSearch()
526-
toast.create({
527-
title: "Item Added",
528-
text: `${item.item_name} added to cart`,
529-
icon: "check",
530-
iconClasses: "text-green-600",
531-
})
603+
604+
if (shouldAutoAdd) {
605+
toast.create({
606+
title: "✓ Auto-Added",
607+
text: `${item.item_name} added to cart`,
608+
icon: "check",
609+
iconClasses: "text-blue-600",
610+
})
611+
} else {
612+
toast.create({
613+
title: "Item Added",
614+
text: `${item.item_name} added to cart`,
615+
icon: "check",
616+
iconClasses: "text-green-600",
617+
})
618+
}
532619
return
533620
}
534621
} catch (error) {
@@ -537,14 +624,24 @@ async function handleBarcodeSearch() {
537624
538625
// Fallback: If only one item matches in filtered results, auto-select it
539626
if (filteredItems.value.length === 1) {
540-
emit("item-selected", filteredItems.value[0])
627+
emit("item-selected", filteredItems.value[0], shouldAutoAdd)
541628
itemStore.clearSearch()
542-
toast.create({
543-
title: "Item Added",
544-
text: `${filteredItems.value[0].item_name} added to cart`,
545-
icon: "check",
546-
iconClasses: "text-green-600",
547-
})
629+
630+
if (shouldAutoAdd) {
631+
toast.create({
632+
title: "✓ Auto-Added",
633+
text: `${filteredItems.value[0].item_name} added to cart`,
634+
icon: "check",
635+
iconClasses: "text-blue-600",
636+
})
637+
} else {
638+
toast.create({
639+
title: "Item Added",
640+
text: `${filteredItems.value[0].item_name} added to cart`,
641+
icon: "check",
642+
iconClasses: "text-green-600",
643+
})
644+
}
548645
} else if (filteredItems.value.length === 0) {
549646
toast.create({
550647
title: "Item Not Found",
@@ -580,6 +677,11 @@ async function handleBarcodeSearch() {
580677
function toggleBarcodeScanner() {
581678
scannerEnabled.value = !scannerEnabled.value
582679
680+
// Disable auto-add when scanner is disabled
681+
if (!scannerEnabled.value) {
682+
autoAddEnabled.value = false
683+
}
684+
583685
// Focus on search input when enabling scanner
584686
if (scannerEnabled.value) {
585687
const input = searchInputRef.value || document.getElementById("item-search")
@@ -589,7 +691,7 @@ function toggleBarcodeScanner() {
589691
590692
toast.create({
591693
title: "Barcode Scanner Enabled",
592-
text: "Scan barcode to automatically add items to cart",
694+
text: "Click 'Auto' button to automatically add items when you press Enter",
593695
icon: "check",
594696
iconClasses: "text-green-600",
595697
})
@@ -603,6 +705,44 @@ function toggleBarcodeScanner() {
603705
}
604706
}
605707
708+
function toggleAutoAdd() {
709+
// Auto-add works independently - no need for scanner mode
710+
autoAddEnabled.value = !autoAddEnabled.value
711+
712+
// Auto-enable scanner mode when auto-add is enabled
713+
if (autoAddEnabled.value && !scannerEnabled.value) {
714+
scannerEnabled.value = true
715+
}
716+
717+
// Clear any pending timer when toggling off
718+
if (!autoAddEnabled.value && autoSearchTimer.value) {
719+
clearTimeout(autoSearchTimer.value)
720+
autoSearchTimer.value = null
721+
}
722+
723+
if (autoAddEnabled.value) {
724+
toast.create({
725+
title: "Auto-Add Enabled",
726+
text: "Type or scan barcode - items will be added automatically after 0.5s",
727+
icon: "check",
728+
iconClasses: "text-blue-600",
729+
})
730+
731+
// Focus on search input
732+
const input = searchInputRef.value || document.getElementById("item-search")
733+
if (input) {
734+
input.focus()
735+
}
736+
} else {
737+
toast.create({
738+
title: "Auto-Add Disabled",
739+
text: "Items will require manual selection",
740+
icon: "alert-circle",
741+
iconClasses: "text-gray-600",
742+
})
743+
}
744+
}
745+
606746
function formatCurrency(amount) {
607747
return formatCurrencyUtil(parseFloat(amount || 0), props.currency)
608748
}

POS/src/pages/POSSale.vue

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,59 @@ function handleShiftClosed() {
782782
}, 500)
783783
}
784784
785-
function handleItemSelected(item) {
785+
function handleItemSelected(item, autoAdd = false) {
786+
// When auto-add mode is active, skip all dialogs and add with defaults
787+
if (autoAdd) {
788+
// Check stock availability before adding to cart
789+
const warehouse = item.warehouse || currentProfile.value?.warehouse
790+
const actualQty = item.actual_qty !== undefined ? item.actual_qty : (item.stock_qty || 0)
791+
792+
// Check if item has stock information and validate
793+
if (warehouse && actualQty !== undefined && actualQty !== null) {
794+
const stockCheck = checkStockAvailability({
795+
itemCode: item.item_code,
796+
qty: 1,
797+
warehouse: warehouse,
798+
actualQty: actualQty
799+
})
800+
801+
if (!stockCheck.available) {
802+
const errorMsg = formatStockError(
803+
item.item_name,
804+
1,
805+
stockCheck.actualQty,
806+
warehouse
807+
)
808+
809+
// Show error but don't block in auto-add mode
810+
toast.create({
811+
title: "Insufficient Stock",
812+
text: errorMsg,
813+
icon: "alert-circle",
814+
iconClasses: "text-red-600",
815+
})
816+
817+
return
818+
}
819+
}
820+
821+
// Add to cart directly with default UOM (stock UOM)
822+
addItem(item)
823+
824+
// Show toast AFTER successful add
825+
setTimeout(() => {
826+
toast.create({
827+
title: "✓ Auto-Added to Cart",
828+
text: `${item.item_name} added to cart`,
829+
icon: "check",
830+
iconClasses: "text-blue-600",
831+
})
832+
}, 100)
833+
834+
return
835+
}
836+
837+
// Normal mode: Show dialogs as needed
786838
// Priority 1: Check if item is a template with variants
787839
if (item.has_variants) {
788840
pendingItem.value = item

0 commit comments

Comments
 (0)