216 lines
11 KiB
PHP
216 lines
11 KiB
PHP
<x-filament-panels::page>
|
|
<div class="mb-4" x-data x-init="$nextTick(() => $refs.barcodeInput.focus())">
|
|
<input x-ref="barcodeInput" tabindex="1" type="text" wire:model.lazy="barcodeBusqueda"
|
|
wire:keydown.enter="buscarProductoPorBarcode" class="w-full p-2 border rounded-lg"
|
|
placeholder="Escanea o escribe el código de barras..." />
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex gap-4 justify-between w-full">
|
|
<div class="w-3/5 min-w-0">
|
|
<h2 class="text-xl font-bold">Selecciona un producto</h2>
|
|
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 w-full text-center">
|
|
@foreach ($productos as $producto)
|
|
<div class="p-4 border rounded-lg hover:bg-gray-100">
|
|
<img src="{{ $producto->imagen ? asset('/storage/' . $producto->imagen) : asset('/img/generico1.png') }}" class="w-32 text-center mx-auto">
|
|
<h3 class="font-semibold">{{ $producto->nombre }}</h3>
|
|
<p>${{ number_format($producto->precio_venta, 2) }}</p>
|
|
@php $bodegas = $producto->bodegas; @endphp
|
|
@if($bodegas->count())
|
|
<div class="text-xs text-gray-600 mt-1">
|
|
Disponible en:
|
|
@foreach($bodegas as $bodega)
|
|
{{ $bodega->nombre }} ({{ $bodega->pivot->stock }})@if(!$loop->last), @endif
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
|
|
@php
|
|
$variantes = $producto->variants ?? [];
|
|
@endphp
|
|
|
|
@if (!count($variantes))
|
|
<x-filament::button wire:click="agregarAlCarrito({{ $producto->id }}, 'p')" color="primary"
|
|
size="sm" class="mt-2">
|
|
Agregar al Carrito
|
|
</x-filament::button>
|
|
@endif
|
|
|
|
@if (count($variantes))
|
|
<div class="mt-2">
|
|
<h4 class="text-sm font-bold">Variantes disponibles:</h4>
|
|
<div class="flex flex-col gap-2 mt-2">
|
|
@foreach ($variantes as $variante)
|
|
<x-filament::button wire:click="agregarAlCarrito({{ $variante->id }}, 'v')"
|
|
color="gray" size="sm" class="justify-start">
|
|
Color: {{ $variante->color->name ?? '-' }}, Talla:
|
|
{{ $variante->size->name ?? '-' }}
|
|
</x-filament::button>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full max-w-md bg-white shadow-xl p-6 rounded-2xl space-y-6">
|
|
<h2 class="text-2xl font-bold text-gray-800">Carrito de Compras</h2>
|
|
|
|
<div class="space-y-3">
|
|
@foreach ($carrito as $key => $item)
|
|
<div class="p-3 border border-gray-200 rounded-lg bg-gray-50 hover:bg-gray-100 transition">
|
|
{{-- Nombre del producto --}}
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div class="flex-1">
|
|
<div class="font-semibold text-gray-700">{{ $item['nombre'] }}</div>
|
|
@if (isset($item['variante']))
|
|
<div class="text-xs text-gray-500 mt-1">{{ $item['variante'] }}</div>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Botón eliminar --}}
|
|
<x-filament::button wire:click="eliminarDelCarrito('{{ $key }}')" color="danger"
|
|
size="xs" icon="heroicon-o-x-mark" />
|
|
</div>
|
|
|
|
{{-- Precio editable --}}
|
|
<div class="mb-2">
|
|
<div class="flex items-center gap-2 flex-wrap">
|
|
<label class="text-xs text-gray-600 font-medium">Precio:</label>
|
|
|
|
{{-- Mostrar precio original tachado si fue modificado --}}
|
|
@if ($item['precio_modificado'] != $item['precio_original'])
|
|
<span class="text-xs text-gray-400 line-through">
|
|
${{ number_format($item['precio_original'], 2) }}
|
|
</span>
|
|
@endif
|
|
|
|
{{-- Campo editable de precio --}}
|
|
<input
|
|
type="number"
|
|
step="0.01"
|
|
min="0"
|
|
wire:model.lazy="carrito.{{ $key }}.precio_modificado"
|
|
wire:change="actualizarPrecio('{{ $key }}', $event.target.value)"
|
|
class="w-28 px-2 py-1 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
value="{{ $item['precio_modificado'] }}"
|
|
/>
|
|
|
|
{{-- Mostrar porcentaje de descuento/aumento --}}
|
|
@if ($item['precio_modificado'] < $item['precio_original'])
|
|
<span class="text-xs text-green-600 font-semibold">
|
|
-{{ number_format((($item['precio_original'] - $item['precio_modificado']) / $item['precio_original']) * 100, 1) }}%
|
|
</span>
|
|
@elseif ($item['precio_modificado'] > $item['precio_original'])
|
|
<span class="text-xs text-red-600 font-semibold">
|
|
+{{ number_format((($item['precio_modificado'] - $item['precio_original']) / $item['precio_original']) * 100, 1) }}%
|
|
</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Cantidad y Subtotal --}}
|
|
<div class="flex justify-between items-center">
|
|
{{-- Controles de cantidad --}}
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-xs text-gray-600">Cantidad:</span>
|
|
<div class="flex items-center border border-gray-300 rounded bg-white">
|
|
<x-filament::button wire:click="decrementarCantidad('{{ $key }}')"
|
|
color="warning" size="xs" icon="heroicon-o-minus" />
|
|
|
|
<div class="text-sm font-semibold w-8 text-center">
|
|
{{ $item['cantidad'] }}
|
|
</div>
|
|
|
|
<x-filament::button wire:click="incrementarCantidad('{{ $key }}')"
|
|
color="primary" size="xs" icon="heroicon-o-plus" />
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Subtotal --}}
|
|
<div class="text-sm font-semibold text-gray-700">
|
|
Subtotal: ${{ number_format($item['precio_modificado'] * $item['cantidad'], 2) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
|
|
<div class="text-lg font-bold text-right text-gray-800">
|
|
Total: ${{ number_format($total, 2) }}
|
|
</div>
|
|
|
|
|
|
|
|
<div class="space-y-3">
|
|
<input type="text" tabindex="2" wire:model.defer="numeroDocumentoCliente"
|
|
placeholder="Número de documento"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
|
<x-filament::button wire:click="buscarClientePorDocumento" color="primary" size="sm" class="w-full"
|
|
tabindex="3">
|
|
Buscar Cliente
|
|
</x-filament::button>
|
|
|
|
@if (!$cliente_id && $numeroDocumentoCliente)
|
|
<div class="grid grid-cols-1 gap-2">
|
|
<input type="text" wire:model.defer="datosCliente.nombre" placeholder="Nombre"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg" />
|
|
<input type="text" wire:model.defer="datosCliente.correo" placeholder="Correo"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg" />
|
|
<input type="text" wire:model.defer="datosCliente.telefono" placeholder="Teléfono"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg" />
|
|
</div>
|
|
@endif
|
|
{{-- Campo tipo de pago --}}
|
|
<select wire:model.defer="tipo_pago"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
tabindex="4">
|
|
<option value="" disabled selected>Selecciona tipo de pago</option>
|
|
<option value="Transferencia">Transferencia</option>
|
|
<option value="Efectivo">Efectivo</option>
|
|
</select>
|
|
</div>
|
|
|
|
<x-filament::button wire:click="procesarVenta" color="success" size="lg" class="w-full" tabindex="4">
|
|
Finalizar Venta
|
|
</x-filament::button>
|
|
|
|
<div class="pt-4 border-t border-gray-200 space-y-3">
|
|
<input type="email" wire:model.lazy="correoCotizacion" tabindex="5"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg"
|
|
placeholder="Correo electrónico para enviar cotización" />
|
|
<x-filament::button wire:click="enviarCotizacion" color="gray" size="lg" class="w-full"
|
|
tabindex="6">
|
|
Enviar Cotización
|
|
</x-filament::button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@if (session()->has('error'))
|
|
<div class="text-red-500 font-semibold mb-2">
|
|
{{ session('error') }}
|
|
</div>
|
|
@endif
|
|
|
|
@if (session()->has('message'))
|
|
<div class="text-primary-500 font-semibold mb-2">
|
|
{{ session('message') }}
|
|
</div>
|
|
@endif
|
|
|
|
<script>
|
|
window.addEventListener('imprimir-recibo', event => {
|
|
const ventaId = event.detail.venta_id;
|
|
const printWindow = window.open(`/imprimir-recibo/${ventaId}`, '_blank', 'width=300,height=600');
|
|
printWindow.focus();
|
|
});
|
|
</script>
|
|
|
|
</x-filament-panels::page>
|