Files
MVE/views/solicitud_importacion/crear.php

374 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title> Nueva Solicitud de Importación</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar {
width: 220px;
height: 100vh;
background-color: #343a40;
position: fixed;
top: 0;
left: 0;
padding-top: 56px;
z-index: 1040;
}
.sidebar .nav-link {
font-weight: bold;
color: white;
transition: all 0.3s ease;
}
.sidebar .nav-link:hover, .sidebar .nav-link.active {
background-color: #495057;
color: #fff;
}
.content {
margin-top: 56px;
padding: 40px 20px;
position: relative;
z-index: 1;
background-color: #f4f6f9;
transition: margin-left 0.3s ease;
}
@media (min-width: 768px) { .content { margin-left: 250px; } }
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover, .sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
.hide { display: none !important; }
</style>
</head>
<body>
<div class="content">
<h4> Nueva Solicitud de Importación</h4>
<div class="card p-4 bg-white shadow-sm">
<form id="solicitudForm" action="/IMPORTADORES/solicitud_importacion/guardar" method="POST" enctype="multipart/form-data">
<!-- Sección principal -->
<div class="row">
<div class="col-md-3 mb-3">
<label for="numero_factura" class="form-label">Número de Factura</label>
<input id="numero_factura" name="numero_factura" type="text" class="form-control" required>
</div>
<div class="col-md-3 mb-3">
<label for="fecha_factura" class="form-label">Fecha de Factura</label>
<input id="fecha_factura" name="fecha_factura" type="date" class="form-control" required>
</div>
<div class="col-md-3 mb-3">
<label for="proveedor_id" class="form-label">Proveedor</label>
<select id="proveedor_id" name="proveedor_id" class="form-select searchable" required>
<option value="">Cargando proveedores…</option>
</select>
</div>
<div class="col-md-3 mb-3">
<label for="anexo22_apendice" class="form-label">Anexo 22 Apéndice</label>
<select id="anexo22_apendice" name="anexo22_apendice" class="form-select searchable" required>
<option value="">-- Selecciona Aduana --</option>
<?php foreach($aduanas as $a): ?>
<option value="<?= htmlspecialchars($a['aduana_seccion']) ?>">
<?= htmlspecialchars($a['aduana_seccion'].' '.$a['nombre']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<!-- Segunda fila: Incoterm, País, Moneda -->
<div class="row">
<div class="col-md-4 mb-3">
<label for="incoterm" class="form-label">INCOTERM</label>
<select id="incoterm" name="incoterm" class="form-select searchable" required>
<option value="">-- Selecciona Incoterm --</option>
<?php foreach($incoterms as $inc): ?>
<option value="<?= htmlspecialchars($inc['INCOTERM']) ?>">
<?= htmlspecialchars($inc['INCOTERM'].' - '.$inc['DESCESPANOL']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="pais_proveedor" class="form-label">País (Proveedor)</label>
<select id="pais_proveedor" name="pais_proveedor" class="form-select searchable" required>
<option value="">-- Selecciona País --</option>
<?php foreach($paises as $p): ?>
<option value="<?= htmlspecialchars($p['id_pais']) ?>"><?= htmlspecialchars($p['nombre']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="tipo_moneda" class="form-label">Moneda</label>
<select id="tipo_moneda" name="tipo_moneda" class="form-select searchable" required>
<?php foreach(['MXN'=>'Peso Mexicano','USD'=>'Dólar USD','EUR'=>'Euro','CNY'=>'Yuan','GBP'=>'Libra GBP','JPY'=>'Yen'] as $code=>$label): ?>
<option value="<?= $code ?>"><?= "$label ($code)" ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<!-- Valor y vinculación -->
<div class="row">
<div class="col-md-8 mb-3">
<label for="valor_factura" class="form-label">Valor Factura</label>
<input id="valor_factura" name="valor_factura" type="number" step="0.01" class="form-control" required>
</div>
<div class="col-md-4 mb-3">
<label for="vinculacion" class="form-label">Vinculación</label>
<select id="vinculacion" name="vinculacion" class="form-select searchable">
<option value="0">No existe</option>
<option value="1">Existe, no afecta</option>
<option value="2">Existe y afecta</option>
</select>
</div>
</div>
<!-- Transportista, Chofer, Foto Solicitud -->
<div class="row">
<div class="col-md-4 mb-3">
<label for="transportista_id" class="form-label">Transportista</label>
<select id="transportista_id" name="transportista_id" class="form-select searchable" required>
<option value="">-- Selecciona --</option>
<?php foreach($transportistas as $t): ?>
<option value="<?= htmlspecialchars($t['id_transportista']) ?>">
<?= htmlspecialchars($t['clave_identificador'] . ' - ' . $t['nombre']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="chofer_id" class="form-label">Chofer</label>
<select id="chofer_id" name="chofer_id" class="form-select searchable" required>
<option value="">-- Selecciona Chofer --</option>
<?php foreach($choferes as $c): ?>
<option value="<?= htmlspecialchars($c['id_chofer']) ?>">
<?= htmlspecialchars($c['nombre']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="foto_solicitud" class="form-label">Foto de la solicitud</label>
<input id="foto_solicitud" name="foto_solicitud" type="file" class="form-control" accept="image/*">
</div>
</div>
<!-- Partidas dinámicas -->
<hr>
<h5>📦 Partidas</h5>
<div class="table-responsive">
<table class="table table-sm" id="tabla-partidas">
<thead>
<tr>
<th>Descripción</th>
<th>Cantidad Comercial</th>
<th>Cantidad de Tarifa</th>
<th>Unidad Comercial</th>
<th>Valor Factura</th>
<th>Peso Bruto</th>
<th>Tasa Preferencial</th>
<th class="hide">Precio Unitario</th>
<th class="hide">OMA (Factura)</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="partidas[0][descripcion]" class="form-control w-100" required></td>
<td><input name="partidas[0][cantidad_comercial]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
<td><input name="partidas[0][cantidad_tarifa]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
<td>
<div class="mb-3">
<select name="partidas[0][unidad_comercial_id]" class="form-select searchable" required>
<option value="">-- Unidad --</option>
<?php foreach($unidades_medida as $um): ?>
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
<?php endforeach; ?>
</select>
</div>
</td>
<td><input name="partidas[0][valor_factura]" type="number" step="0.01" class="form-control valor-partida w-100" min="0" required></td>
<td><input name="partidas[0][peso_bruto]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
<td>
<div class="mb-3">
<select name="partidas[0][tasa_preferencial]" class="form-select searchable" required>
<option value="">-- Selecciona --</option>
<option>General</option>
<option>TLC</option>
<option>PROSEC</option>
<option>ALADI</option>
<option>COMERCIALIZADORA</option>
</select>
</div>
</td>
<td class="hide"><input name="partidas[0][precio_unitario]" type="number" class="form-control w-100"></td>
<td class="hide"><input name="partidas[0][oma_factura]" class="form-control w-100"></td>
<td><button type="button" class="btn btn-danger btn-sm remove-row">✖️</button></td>
</tr>
</tbody>
</table>
</div>
<button type="button" class="btn btn-secondary btn-sm" id="add-partida"> Agregar partida</button>
<!-- Activo -->
<div class="form-check mt-4">
<input id="status" name="status" type="checkbox" class="form-check-input" checked>
<label for="status" class="form-check-label">Activo</label>
</div>
<!-- Botones finales -->
<button type="submit" class="btn btn-success mt-3">Guardar</button>
<a href="/IMPORTADORES/solicitud_importacion/lista" class="btn btn-secondary mt-3 ms-2">Cancelar</a>
</form>
</div>
</div>
<!-- Choices.js JS -->
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0/dist/js/select2.min.js"></script>
<script>
// 1) Inicializar Choices para todos los selects excepto proveedor_id
document.querySelectorAll('.searchable:not(#proveedor_id)').forEach(el => {
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
});
// 2) Cargar proveedores dinámicamente
const proveedorEl = document.getElementById('proveedor_id');
let proveedorChoices = null;
fetch('/IMPORTADORES/solicitud_importacion/ajax_proveedores')
.then(res => res.ok ? res.json() : Promise.reject(res.status))
.then(json => {
proveedorEl.innerHTML = '<option value="">-- Selecciona Proveedor --</option>';
json.results.forEach(item => {
const opt = document.createElement('option');
opt.value = item.id;
opt.text = item.text;
proveedorEl.add(opt);
});
// destruir instancia previa si existe
if (proveedorChoices) proveedorChoices.destroy();
proveedorChoices = new Choices(proveedorEl, {
searchEnabled: true,
itemSelectText: '',
shouldSort: false
});
// seleccionar valor actual
const current = '<?= htmlspecialchars($factura['proveedor_id'], ENT_QUOTES) ?>';
if (current) {
proveedorChoices.setChoiceByValue(current);
}
})
.catch(err => {
console.error('Error cargando proveedores:', err);
proveedorEl.innerHTML = '<option value="">No fue posible cargar proveedores</option>';
});
// 3) Agregar partida dinámica
document.getElementById('add-partida').addEventListener('click', () => {
const tbody = document.querySelector('#tabla-partidas tbody');
const idx = tbody.querySelectorAll('tr').length;
const row = document.createElement('tr');
row.innerHTML = `
<td><input name="partidas[\${idx}][descripcion]" class="form-control"></td>
<td><input name="partidas[\${idx}][cantidad_comercial]" type="number" step="0.0001" class="form-control"></td>
<td><input name="partidas[\${idx}][cantidad_tarifa]" type="number" step="0.0001" class="form-control"></td>
<td>
<select name="partidas[\${idx}][unidad_comercial_id]" class="form-select searchable">
<option value="">-- Unidad --</option>
<?php foreach($unidades_medida as $um): ?>
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input name="partidas[\${idx}][valor_factura]" type="number" step="0.01" class="form-control valor-partida"></td>
<td><input name="partidas[\${idx}][peso_bruto]" type="number" step="0.0001" class="form-control"></td>
<td>
<select name="partidas[\${idx}][tasa_preferencial]" class="form-select searchable">
<option value="">-- Selecciona --</option>
<option>General</option><option>TLC</option><option>PROSEC</option><option>ALADI</option><option>COMERCIALIZADORA</option>
</select>
</td>
<td class="hide"><input name="partidas[\${idx}][precio_unitario]" type="number" class="form-control"></td>
<td class="hide"><input name="partidas[\${idx}][oma_factura]" class="form-control"></td>
<td><button type="button" class="btn btn-danger btn-sm remove-row">✖️</button></td>
`;
tbody.appendChild(row);
// Re-inicializar Choices.js en los nuevos selects
row.querySelectorAll('.searchable').forEach(el => {
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
});
});
// Manejador para controlar el overflow al abrir dropdowns
document.addEventListener('click', function(e) {
const tableContainer = document.querySelector('.table-responsive');
if (!tableContainer) return;
if (e.target.closest('.choices__inner')) {
tableContainer.style.overflow = 'visible';
} else {
tableContainer.style.overflow = 'auto';
}
});
document.querySelector('#tabla-partidas tbody').addEventListener('click', e => {
if (e.target.matches('.remove-row')) e.target.closest('tr').remove();
});
// validate suma partidas == valor_factura
$('#solicitudForm').submit(function(e){
const total = parseFloat($('#valor_factura').val())||0;
let sum = 0;
$('.valor-partida').each(function(){ sum += parseFloat($(this).val())||0; });
if(Math.abs(sum - total) > 0.001){
e.preventDefault();
Swal.fire({
icon:'error',
title:'Error de validación',
text:`La suma de partidas (${sum.toFixed(2)}) no coincide con Valor Factura (${total.toFixed(2)}).`
});
}
});
</script>
<script>
// proveedores script (no modificado)
document.querySelectorAll('.searchable').forEach(el => {
if (el.id !== 'proveedor_id') {
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
}
});
const proveedorEl = document.getElementById('proveedor_id');
fetch('/IMPORTADORES/solicitud_importacion/ajax_proveedores')
.then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); })
.then(json => {
proveedorEl.innerHTML = '<option value="">-- Selecciona Proveedor --</option>';
json.results.forEach(item => {
const opt = document.createElement('option');
opt.value = item.id; opt.text = item.text;
proveedorEl.add(opt);
});
if (proveedorEl._choice) proveedorEl._choice.destroy();
new Choices(proveedorEl, { searchEnabled: true, itemSelectText: '', shouldSort: false });
})
.catch(err => {
console.error('Error cargando proveedores:', err);
proveedorEl.innerHTML = '<option value="">No fue posible cargar proveedores</option>';
});
</script>
</body>
</html>