203 lines
9.1 KiB
PHP
203 lines
9.1 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', 'Crear Cotización')
|
|
|
|
@section('content')
|
|
<div class="content-header">
|
|
<div class="container-fluid">
|
|
<div class="row mb-2">
|
|
<div class="col-sm-6">
|
|
<h1 class="m-0">Crear Cotización</h1>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<a href="{{ route('cotizaciones.index') }}" class="btn btn-secondary float-right">
|
|
<i class="fas fa-arrow-left"></i> Volver
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<div class="container-fluid">
|
|
<form action="{{ route('cotizaciones.store') }}" method="POST" id="quotationForm">
|
|
@csrf
|
|
|
|
<div class="row">
|
|
<!-- IZQUIERDA: Tabla de productos -->
|
|
<div class="col-md-7">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Productos Disponibles</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-bordered" id="products-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Imagen</th>
|
|
<th>Producto</th>
|
|
<th>Precio</th>
|
|
<th>Cantidad</th>
|
|
<th>Agregar</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($productos as $product)
|
|
<tr data-id="{{ $product->id }}" data-price="{{ $product->precio }}">
|
|
<td>
|
|
@if($product->foto)
|
|
<img src="{{ asset('storage/' . $product->foto) }}" alt="Imagen" style="width:50px;">
|
|
@else
|
|
<img src="https://via.placeholder.com/50" alt="Imagen">
|
|
@endif
|
|
</td>
|
|
<td>{{ $product->nombre }}</td>
|
|
<td>${{ number_format($product->precio,2) }}</td>
|
|
<td>
|
|
<input type="number" class="form-control quantity" value="1" min="1" style="width:70px;">
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-success btn-sm add-product">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DERECHA: Items seleccionados y resumen -->
|
|
<div class="col-md-5">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Productos Seleccionados</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-bordered" id="items-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Producto</th>
|
|
<th>Cantidad</th>
|
|
<th>Precio</th>
|
|
<th>Total</th>
|
|
<th>Eliminar</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Items se agregan dinámicamente -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card mt-2">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Resumen</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Subtotal:</span>
|
|
<span id="subtotal">$0.00</span>
|
|
</div>
|
|
<div class="d-flex justify-content-between">
|
|
<span>IVA (16%):</span>
|
|
<span id="tax">$0.00</span>
|
|
</div>
|
|
<hr>
|
|
<div class="d-flex justify-content-between">
|
|
<strong>Total:</strong>
|
|
<strong id="total">$0.00</strong>
|
|
</div>
|
|
|
|
<input type="hidden" name="subtotal" id="input_subtotal" value="0">
|
|
<input type="hidden" name="tax" id="input_tax" value="0">
|
|
<input type="hidden" name="total" id="input_total" value="0">
|
|
</div>
|
|
<div class="card-footer">
|
|
<div class="form-group">
|
|
<label for="cliente_id">Cliente *</label>
|
|
<select name="cliente_id" id="cliente_id" class="form-control" required>
|
|
<option value="">Seleccionar Cliente</option>
|
|
@foreach($clientes as $cliente)
|
|
<option value="{{ $cliente->id }}">{{ $cliente->nombre }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary btn-block">
|
|
<i class="fas fa-save"></i> Guardar Cotización
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
function recalcTotals() {
|
|
let subtotal = 0;
|
|
document.querySelectorAll('#items-table tbody tr').forEach(row => {
|
|
let qty = parseInt(row.querySelector('.item-quantity').value) || 0;
|
|
let price = parseFloat(row.querySelector('.item-price').dataset.price) || 0;
|
|
let total = qty * price;
|
|
row.querySelector('.item-total').textContent = '$' + total.toFixed(2);
|
|
subtotal += total;
|
|
});
|
|
let tax = subtotal * 0.16;
|
|
let total = subtotal + tax;
|
|
|
|
document.getElementById('subtotal').textContent = '$' + subtotal.toFixed(2);
|
|
document.getElementById('tax').textContent = '$' + tax.toFixed(2);
|
|
document.getElementById('total').textContent = '$' + total.toFixed(2);
|
|
|
|
document.getElementById('input_subtotal').value = subtotal;
|
|
document.getElementById('input_tax').value = tax;
|
|
document.getElementById('input_total').value = total;
|
|
}
|
|
|
|
// Agregar producto a items
|
|
document.querySelectorAll('.add-product').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const tr = this.closest('tr');
|
|
const id = tr.dataset.id;
|
|
const name = tr.children[1].textContent;
|
|
const price = parseFloat(tr.dataset.price);
|
|
const quantity = parseInt(tr.querySelector('.quantity').value);
|
|
|
|
// Evitar duplicados
|
|
if(document.querySelector(`#items-table tbody tr[data-id="${id}"]`)) return;
|
|
|
|
const row = document.createElement('tr');
|
|
row.dataset.id = id;
|
|
row.innerHTML = `
|
|
<td>${name}<input type="hidden" name="items[][product_id]" value="${id}"></td>
|
|
<td><input type="number" name="items[][quantity]" class="form-control item-quantity" value="${quantity}" min="1"></td>
|
|
<td data-price="${price}" class="item-price">$${price.toFixed(2)}</td>
|
|
<td class="item-total">$${(price*quantity).toFixed(2)}</td>
|
|
<td><button type="button" class="btn btn-danger btn-sm remove-item"><i class="fas fa-times"></i></button></td>
|
|
`;
|
|
document.querySelector('#items-table tbody').appendChild(row);
|
|
|
|
row.querySelector('.item-quantity').addEventListener('change', recalcTotals);
|
|
row.querySelector('.remove-item').addEventListener('click', function(){
|
|
row.remove();
|
|
recalcTotals();
|
|
});
|
|
|
|
recalcTotals();
|
|
});
|
|
});
|
|
|
|
});
|
|
</script>
|
|
@endpush
|
|
|
|
@endsection
|