Opción C: Vinculación híbrida de inventario local con vehículos
- Nueva tabla inventory_vehicle_compat (v3.1) - Motor inventory_vehicle_compat.py: auto-match + gestión manual - catalog_service.get_parts_local() ahora incluye piezas locales vinculadas - inventory_bp: auto-match en create/update + endpoints REST /vehicles - Frontend catalog.js: badge 'Stock Local' para piezas nativas del tenant - Frontend inventory.js: panel de vehículos compatibles con auto-match - Tests: test_compatibility.py (9/9 pasan) Piezas locales aparecen en navegación por vehículo aunque no estén en TecDoc. Auto-match busca part_number en parts/aftermarket_parts y copia MYEs compatibles.
This commit is contained in:
@@ -653,6 +653,40 @@
|
||||
el.innerHTML = html2;
|
||||
}
|
||||
|
||||
// Vehicle compatibility section
|
||||
html += '<div style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-widest);margin-bottom:8px;">Vehiculos Compatibles</div>';
|
||||
html += '<div id="compatContent" style="margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid var(--color-border);">';
|
||||
html += '<p style="color:var(--color-text-muted);font-size:var(--text-caption);">Cargando compatibilidades...</p>';
|
||||
html += '</div>';
|
||||
|
||||
// Load vehicle compatibilities
|
||||
(function loadCompat() {
|
||||
fetch('/pos/api/inventory/items/' + itemId + '/vehicles', { headers: { 'Authorization': 'Bearer ' + token } })
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
var el = document.getElementById('compatContent');
|
||||
if (!el) return;
|
||||
var list = d.vehicles || [];
|
||||
var html2 = '';
|
||||
if (list.length > 0) {
|
||||
html2 += '<table class="data-table"><thead><tr><th>Marca</th><th>Modelo</th><th>Ano</th><th>Motor</th><th>Origen</th><th></th></tr></thead><tbody>';
|
||||
list.forEach(function(c) {
|
||||
html2 += '<tr><td>' + esc(c.brand || '') + '</td><td>' + esc(c.model || '') + '</td><td>' + esc(c.year || '') + '</td><td>' + esc(c.engine || '') + '</td><td>' + esc(c.source || '') + '</td>';
|
||||
html2 += '<td><button class="btn btn--ghost btn--sm" style="color:var(--color-error);" onclick="removeCompat(' + itemId + ',' + c.model_year_engine_id + ')">Quitar</button></td></tr>';
|
||||
});
|
||||
html2 += '</tbody></table>';
|
||||
} else {
|
||||
html2 += '<p style="color:var(--color-text-muted);font-size:var(--text-caption);">Sin vehiculos vinculados.</p>';
|
||||
}
|
||||
html2 += '<div style="margin-top:8px;"><button class="btn btn--primary btn--sm" onclick="autoMatchCompat(' + itemId + ')">Auto-Match por TecDoc</button> <span style="font-size:var(--text-caption);color:var(--color-text-muted);">Busca en catalogo central y vincula automaticamente</span></div>';
|
||||
el.innerHTML = html2;
|
||||
})
|
||||
.catch(function() {
|
||||
var el = document.getElementById('compatContent');
|
||||
if (el) el.innerHTML = '<p style="color:var(--color-text-muted);font-size:var(--text-caption);">Error al cargar compatibilidades.</p>';
|
||||
});
|
||||
})();
|
||||
|
||||
// Movement history
|
||||
html += '<div style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-widest);margin-bottom:8px;">Historial de Movimientos</div>';
|
||||
if (!history.length) {
|
||||
@@ -677,6 +711,29 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Vehicle compatibility actions
|
||||
function autoMatchCompat(itemId) {
|
||||
fetch('/pos/api/inventory/items/' + itemId + '/vehicles/auto-match', {
|
||||
method: 'POST',
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
}).then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
alert('Auto-match completado. Vehiculos vinculados: ' + (d.matched || 0));
|
||||
viewProductDetail(itemId);
|
||||
}).catch(function() { alert('Error en auto-match'); });
|
||||
}
|
||||
|
||||
function removeCompat(itemId, myeId) {
|
||||
if (!confirm('Quitar compatibilidad con este vehiculo?')) return;
|
||||
fetch('/pos/api/inventory/items/' + itemId + '/compatibility/' + myeId, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': 'Bearer ' + token }
|
||||
}).then(function(r) { return r.json(); })
|
||||
.then(function() {
|
||||
viewProductDetail(itemId);
|
||||
}).catch(function() { alert('Error al quitar compatibilidad'); });
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// EXPOSE GLOBALS (for onclick handlers in HTML)
|
||||
// =====================================================================
|
||||
|
||||
Reference in New Issue
Block a user