diff --git a/src/components/POS/SerialSelector.vue b/src/components/POS/SerialSelector.vue index 5a13cb4..d647703 100644 --- a/src/components/POS/SerialSelector.vue +++ b/src/components/POS/SerialSelector.vue @@ -14,10 +14,6 @@ const props = defineProps({ type: Object, required: true }, - quantity: { - type: Number, - required: true - }, excludeSerials: { type: Array, default: () => [] @@ -31,7 +27,6 @@ const emit = defineEmits(['close', 'confirm']); const loading = ref(false); const availableSerials = ref([]); const selectedSerials = ref([]); -const selectionMode = ref('auto'); // 'auto' | 'manual' const searchQuery = ref(''); /** Computados */ @@ -47,22 +42,12 @@ const filteredSerials = computed(() => { const selectedCount = computed(() => selectedSerials.value.length); -const isComplete = computed(() => { - if (selectionMode.value === 'auto') { - return availableSerials.value.length >= props.quantity; - } - return selectedSerials.value.length === props.quantity; +const hasEnoughStock = computed(() => { + return availableSerials.value.length > 0; }); const canConfirm = computed(() => { - if (selectionMode.value === 'auto') { - return availableSerials.value.length >= props.quantity; - } - return selectedSerials.value.length === props.quantity; -}); - -const hasEnoughStock = computed(() => { - return availableSerials.value.length >= props.quantity; + return selectedSerials.value.length > 0; }); /** Métodos */ @@ -87,11 +72,7 @@ const toggleSerial = (serial) => { if (index > -1) { selectedSerials.value.splice(index, 1); } else { - if (selectedSerials.value.length < props.quantity) { - selectedSerials.value.push(serial); - } else { - Notify.warning(`Solo puedes seleccionar ${props.quantity} serial(es)`); - } + selectedSerials.value.push(serial); } }; @@ -100,7 +81,7 @@ const isSelected = (serial) => { }; const selectAll = () => { - selectedSerials.value = availableSerials.value.slice(0, props.quantity); + selectedSerials.value = [...availableSerials.value]; }; const clearSelection = () => { @@ -108,19 +89,9 @@ const clearSelection = () => { }; const handleConfirm = () => { - let serialNumbers = []; - - if (selectionMode.value === 'auto') { - // En modo automático, el backend asignará los seriales - serialNumbers = null; - } else { - // En modo manual, enviamos los seriales seleccionados - serialNumbers = selectedSerials.value.map(s => s.serial_number); - } - emit('confirm', { - selectionMode: selectionMode.value, - serialNumbers: serialNumbers + serialNumbers: selectedSerials.value.map(s => s.serial_number), + quantity: selectedSerials.value.length }); }; @@ -131,7 +102,6 @@ const handleClose = () => { const resetState = () => { selectedSerials.value = []; searchQuery.value = ''; - selectionMode.value = 'auto'; }; /** Watchers */ @@ -140,13 +110,7 @@ watch(() => props.show, (isShown) => { resetState(); loadSerials(); } -}); - -watch(selectionMode, (newMode) => { - if (newMode === 'auto') { - selectedSerials.value = []; - } -}); +},{ immediate: true }); diff --git a/src/pages/POS/Point.vue b/src/pages/POS/Point.vue index 5d113e2..5d4ae0f 100644 --- a/src/pages/POS/Point.vue +++ b/src/pages/POS/Point.vue @@ -34,7 +34,6 @@ const lastSaleData = ref(null); // Estado para selector de seriales const showSerialSelector = ref(false); const serialSelectorProduct = ref(null); -const serialSelectorQuantity = ref(1); /** Buscador de productos */ const searcher = useSearcher({ @@ -69,7 +68,6 @@ const addToCart = (product) => { // Si el producto tiene seriales, mostrar selector if (product.has_serials) { serialSelectorProduct.value = product; - serialSelectorQuantity.value = 1; showSerialSelector.value = true; return; } @@ -84,7 +82,6 @@ const addToCart = (product) => { const closeSerialSelector = () => { showSerialSelector.value = false; serialSelectorProduct.value = null; - serialSelectorQuantity.value = 1; }; const handleSerialConfirm = (serialConfig) => { @@ -92,7 +89,7 @@ const handleSerialConfirm = (serialConfig) => { cart.addProductWithSerials( serialSelectorProduct.value, - serialSelectorQuantity.value, + serialConfig.quantity, serialConfig ); @@ -468,7 +465,6 @@ onMounted(() => { :show="showClientModal" :sale-data="lastSaleData" @close="closeClientModal" - @save="handleClientSave" /> @@ -476,7 +472,6 @@ onMounted(() => { v-if="serialSelectorProduct" :show="showSerialSelector" :product="serialSelectorProduct" - :quantity="serialSelectorQuantity" :exclude-serials="cart.getSelectedSerials()" @close="closeSerialSelector" @confirm="handleSerialConfirm" diff --git a/src/pages/POS/Sales/DetailModal.vue b/src/pages/POS/Sales/DetailModal.vue index 20a680b..25ef154 100644 --- a/src/pages/POS/Sales/DetailModal.vue +++ b/src/pages/POS/Sales/DetailModal.vue @@ -229,8 +229,9 @@ watch(() => props.show, () => {

{{ item.product_name }}

-

- SKU: {{ item.inventory.sku }} + +

+ {{ item.serials.map(s => s.serial_number).join(', ') }}

diff --git a/src/stores/cart.js b/src/stores/cart.js index 4d9c46e..26626f3 100644 --- a/src/stores/cart.js +++ b/src/stores/cart.js @@ -74,22 +74,28 @@ const useCart = defineStore('cart', { // Agregar producto con seriales ya configurados addProductWithSerials(product, quantity, serialConfig) { - // Eliminar item existente si hay - this.removeProduct(product.id); + const existingItem = this.items.find(item => item.inventory_id === product.id); + const newSerials = serialConfig.serialNumbers || []; - // Agregar nuevo item con seriales - this.items.push({ - inventory_id: product.id, - product_name: product.name, - sku: product.sku, - quantity: quantity, - unit_price: parseFloat(product.price?.retail_price || 0), - tax_rate: parseFloat(product.price?.tax || 16), - max_stock: product.stock, - has_serials: true, - serial_numbers: serialConfig.serialNumbers || [], - serial_selection_mode: serialConfig.selectionMode - }); + if (existingItem) { + // Combinar seriales existentes con los nuevos + const combinedSerials = [...existingItem.serial_numbers, ...newSerials]; + existingItem.serial_numbers = combinedSerials; + existingItem.quantity = combinedSerials.length; + } else { + // Agregar nuevo item con seriales + this.items.push({ + inventory_id: product.id, + product_name: product.name, + sku: product.sku, + quantity: quantity, + unit_price: parseFloat(product.price?.retail_price || 0), + tax_rate: parseFloat(product.price?.tax || 16), + max_stock: product.stock, + has_serials: true, + serial_numbers: newSerials + }); + } }, // Actualizar seriales de un item diff --git a/src/utils/formatters.js b/src/utils/formatters.js index 5040859..4505eb3 100644 --- a/src/utils/formatters.js +++ b/src/utils/formatters.js @@ -29,7 +29,10 @@ export const formatCurrency = (amount) => { * formatMoney(null) // "0.00" */ export const formatMoney = (amount) => { - return parseFloat(amount || 0).toFixed(2); + return new Intl.NumberFormat('es-MX', { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).format(amount || 0); }; /**