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 });
@@ -163,7 +127,7 @@ watch(selectionMode, (newMode) => {
Seleccionar Números de Serie
- {{ product.name }} - Cantidad: {{ quantity }}
+ {{ product.name }}
@@ -199,66 +163,9 @@ watch(selectionMode, (newMode) => {
-
-
-
- Modo de asignación
-
-
-
-
-
-
-
-
+
@@ -274,11 +181,11 @@ watch(selectionMode, (newMode) => {
/>
@@ -349,21 +255,6 @@ watch(selectionMode, (newMode) => {
-
-
-
-
-
-
-
- Asignación automática
-
-
- Se asignarán automáticamente los primeros {{ quantity }} número(s) de serie disponible(s) al confirmar la venta.
-
-
-
-
diff --git a/src/pages/POS/Inventory/Serials.vue b/src/pages/POS/Inventory/Serials.vue
index 79d1d6a..9a59336 100644
--- a/src/pages/POS/Inventory/Serials.vue
+++ b/src/pages/POS/Inventory/Serials.vue
@@ -154,51 +154,6 @@ const confirmDelete = async () => {
}
};
-// Importación masiva
-const openBulkModal = () => {
- bulkSerials.value = '';
- showBulkModal.value = true;
-};
-
-const closeBulkModal = () => {
- showBulkModal.value = false;
- bulkSerials.value = '';
-};
-
-const bulkImport = async () => {
- const lines = bulkSerials.value
- .split('\n')
- .map(line => line.trim())
- .filter(line => line.length > 0);
-
- if (lines.length === 0) {
- Notify.warning('Ingresa al menos un número de serie');
- return;
- }
-
- bulkProcessing.value = true;
- try {
- const response = await serialService.bulkImport(inventoryId.value, lines);
- Notify.success(`${response.count || lines.length} números de serie importados`);
- if (response.inventory) {
- inventory.value = response.inventory;
- }
- closeBulkModal();
- loadSerials();
- } catch (error) {
- Notify.error('Error al importar números de serie');
- } finally {
- bulkProcessing.value = false;
- }
-};
-
-const bulkCount = computed(() => {
- return bulkSerials.value
- .split('\n')
- .map(line => line.trim())
- .filter(line => line.length > 0).length;
-});
-
// Navegación
const goBack = () => {
router.push({ name: 'pos.inventory.index' });
@@ -276,15 +231,6 @@ onMounted(() => {
-
-
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);
};
/**
|