diff --git a/.gitignore b/.gitignore index 8ef7218..a55a2de 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ notes.md *.njsproj *.sln *.sw? +CLAUDE.md \ No newline at end of file diff --git a/src/components/POS/CartItem.vue b/src/components/POS/CartItem.vue index ca8cce0..115ad0a 100644 --- a/src/components/POS/CartItem.vue +++ b/src/components/POS/CartItem.vue @@ -11,7 +11,7 @@ const props = defineProps({ }); /** Emits */ -const emit = defineEmits(['update-quantity', 'remove']); +const emit = defineEmits(['update-quantity', 'remove', 'select-serials']); /** Computados */ const formattedUnitPrice = computed(() => { @@ -29,7 +29,20 @@ const formattedSubtotal = computed(() => { }).format(subtotal); }); -const canIncrement = computed(() => props.item.quantity < props.item.max_stock); +const canIncrement = computed(() => { + // Si tiene seriales, no permitir incremento directo + if (props.item.track_serials) return false; + return props.item.quantity < props.item.max_stock; +}); + +const hasSerials = computed(() => props.item.track_serials); +const serialsSelected = computed(() => { + return props.item.serial_numbers && props.item.serial_numbers.length > 0; +}); + +const needsSerialSelection = computed(() => { + return hasSerials.value && (!serialsSelected.value || props.item.serial_numbers.length !== props.item.quantity); +}); /** Métodos */ const increment = () => { diff --git a/src/lang/es.js b/src/lang/es.js index 797a491..6724b63 100644 --- a/src/lang/es.js +++ b/src/lang/es.js @@ -458,6 +458,7 @@ export default { cashRegister: 'Caja', point: 'Punto de Venta', sales: 'Ventas', + returns: 'Devoluciones', clients: 'Clientes', billingRequests: 'Solicitudes de Facturación' }, diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue index eee004e..7073b8b 100644 --- a/src/layouts/AppLayout.vue +++ b/src/layouts/AppLayout.vue @@ -57,6 +57,11 @@ onMounted(() => { name="pos.sales" to="pos.sales.index" /> + parseFloat(props.cashRegister?.cash_sales || 0) const cardSales = computed(() => parseFloat(props.cashRegister?.card_sales || 0)); const transactionCount = computed(() => parseInt(props.cashRegister?.transaction_count || 0)); -const expectedCash = computed(() => initialCash.value + cashSales.value); +// Devoluciones +const totalReturns = computed(() => parseFloat(props.cashRegister?.total_returns || 0)); +const cashReturns = computed(() => parseFloat(props.cashRegister?.cash_returns || 0)); +const cardReturns = computed(() => parseFloat(props.cashRegister?.card_returns || 0)); +const hasReturns = computed(() => totalReturns.value > 0); + +// Ventas netas (ventas - devoluciones) +const netSales = computed(() => totalSales.value - totalReturns.value); +const netCashSales = computed(() => cashSales.value - cashReturns.value); + +const expectedCash = computed(() => initialCash.value + netCashSales.value); const difference = computed(() => finalCash.value - expectedCash.value); const hasDifference = computed(() => Math.abs(difference.value) > 0.01); @@ -128,6 +138,44 @@ const handleClose = () => { + +
+
+ +

+ Devoluciones +

+
+
+
+

Total Devoluciones

+

+ -${{ (totalReturns || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} +

+
+
+

Efectivo

+

+ -${{ (cashReturns || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} +

+
+
+

Tarjeta

+

+ -${{ (cardReturns || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} +

+
+
+
+
+ Ventas Netas: + + ${{ (netSales || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} + +
+
+
+

@@ -159,11 +207,27 @@ const handleClose = () => {

- Ventas en Efectivo (Neto): + Ventas en Efectivo: = ${{ (cashSales || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }}
+ + +
+ Devoluciones en Efectivo: + + - ${{ (cashReturns || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} + +
+ + +
+ Ventas Netas en Efectivo: + + = ${{ (netCashSales || 0).toLocaleString('es-MX', { minimumFractionDigits: 2 }) }} + +
diff --git a/src/pages/POS/Point.vue b/src/pages/POS/Point.vue index 5d4ae0f..b2d7326 100644 --- a/src/pages/POS/Point.vue +++ b/src/pages/POS/Point.vue @@ -1,5 +1,5 @@ diff --git a/src/pages/POS/Returns/CreateReturn.vue b/src/pages/POS/Returns/CreateReturn.vue new file mode 100644 index 0000000..42f668d --- /dev/null +++ b/src/pages/POS/Returns/CreateReturn.vue @@ -0,0 +1,496 @@ + + + \ No newline at end of file diff --git a/src/pages/POS/Returns/Index.vue b/src/pages/POS/Returns/Index.vue new file mode 100644 index 0000000..af5062f --- /dev/null +++ b/src/pages/POS/Returns/Index.vue @@ -0,0 +1,211 @@ + + + \ No newline at end of file diff --git a/src/pages/POS/Returns/ReturnDetail.vue b/src/pages/POS/Returns/ReturnDetail.vue new file mode 100644 index 0000000..be6e80c --- /dev/null +++ b/src/pages/POS/Returns/ReturnDetail.vue @@ -0,0 +1,316 @@ + + + \ No newline at end of file diff --git a/src/pages/POS/Returns/SelectSale.vue b/src/pages/POS/Returns/SelectSale.vue new file mode 100644 index 0000000..8dad87b --- /dev/null +++ b/src/pages/POS/Returns/SelectSale.vue @@ -0,0 +1,255 @@ + + + \ No newline at end of file diff --git a/src/pages/POS/Sales/DetailModal.vue b/src/pages/POS/Sales/DetailModal.vue index 25ef154..833695f 100644 --- a/src/pages/POS/Sales/DetailModal.vue +++ b/src/pages/POS/Sales/DetailModal.vue @@ -1,8 +1,9 @@