296 lines
12 KiB
JavaScript
296 lines
12 KiB
JavaScript
// Configuración global
|
|
const CONFIG = {
|
|
apis: {
|
|
brasil: {
|
|
endpoint: '/api/brasil.php',
|
|
currency: 'BRL',
|
|
currencySymbol: 'R$',
|
|
label: 'Precio Reales'
|
|
},
|
|
chile: {
|
|
endpoint: '/api/chile.php',
|
|
currency: 'CLP',
|
|
currencySymbol: '$',
|
|
label: 'Precio Pesos Chilenos'
|
|
}
|
|
},
|
|
exchangeRateAPI: 'https://api.exchangerate-api.com/v4/latest/'
|
|
};
|
|
|
|
// Estado de la aplicación
|
|
let productos = [];
|
|
let cotizacion = 0;
|
|
let cotizacionUsd = 0;
|
|
let paisActual = '';
|
|
|
|
// Inicializar aplicación
|
|
function inicializarApp(pais) {
|
|
paisActual = pais;
|
|
obtenerCotizacion();
|
|
configurarEventos();
|
|
}
|
|
|
|
// Cargar productos desde la API
|
|
async function cargarDesdeArchivo() {
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.showLoading();
|
|
}
|
|
|
|
const endpoint = CONFIG.apis[paisActual].endpoint;
|
|
|
|
try {
|
|
const response = await fetch(endpoint);
|
|
productos = await response.json();
|
|
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.updateLastUpdate();
|
|
}
|
|
|
|
cargarListado();
|
|
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.hideLoading();
|
|
}
|
|
} catch (error) {
|
|
console.error('No se pudo cargar productos desde ' + endpoint, error);
|
|
productos = [];
|
|
cargarListado();
|
|
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.hideLoading();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Obtener cotización de la moneda
|
|
async function obtenerCotizacion() {
|
|
const currency = CONFIG.apis[paisActual].currency;
|
|
const apiUrl = CONFIG.exchangeRateAPI + currency;
|
|
|
|
try {
|
|
const response = await fetch(apiUrl);
|
|
const data = await response.json();
|
|
|
|
if (data.rates && data.rates.ARS) {
|
|
cotizacion = data.rates.ARS;
|
|
cotizacionUsd = 1 / data.rates.USD;
|
|
document.getElementById('cotizacionMoneda').textContent = cotizacion.toFixed(2);
|
|
document.getElementById('cotizacionUsd').textContent = cotizacionUsd.toFixed(2);
|
|
await cargarDesdeArchivo();
|
|
} else {
|
|
document.getElementById('cotizacionMoneda').textContent = 'No disponible';
|
|
}
|
|
} catch (error) {
|
|
console.error('Error al obtener cotización:', error);
|
|
document.getElementById('cotizacionMoneda').textContent = 'Error al obtener cotización';
|
|
await cargarDesdeArchivo();
|
|
}
|
|
}
|
|
|
|
// Renderizar la tabla de productos
|
|
function cargarListado() {
|
|
let html = '';
|
|
let totalDiferenciaGlobal = 0;
|
|
|
|
// Agrupar productos por responsable
|
|
const responsables = {};
|
|
productos.forEach(producto => {
|
|
if (!responsables[producto.responsable]) {
|
|
responsables[producto.responsable] = [];
|
|
}
|
|
responsables[producto.responsable].push(producto);
|
|
});
|
|
|
|
// Renderizar por responsable
|
|
for (const responsable in responsables) {
|
|
let totalDiferenciaResponsable = 0;
|
|
let totalPrecioExtranjeroResponsable = 0;
|
|
|
|
html += `
|
|
<tr class="bg-gray-100">
|
|
<td colspan="6" class="px-6 py-3 text-center font-bold text-gray-700">${responsable}</td>
|
|
</tr>`;
|
|
|
|
responsables[responsable].forEach(producto => {
|
|
const diferencia = ((producto.precioBra * cotizacion) - producto.precioAr);
|
|
|
|
totalDiferenciaResponsable += diferencia;
|
|
totalDiferenciaGlobal += diferencia;
|
|
totalPrecioExtranjeroResponsable += producto.precioBra;
|
|
|
|
const colorClass = diferencia < 0 ? 'text-green-600' : 'text-red-600';
|
|
|
|
html += `
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4">
|
|
<input type="text" class="w-full px-2 sm:px-3 py-1 text-xs sm:text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 articuloInput" data-id="${producto.id}" value="${producto.articulo}">
|
|
</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4">
|
|
<input type="number" class="w-full px-2 sm:px-3 py-1 text-xs sm:text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 precioArInput" data-id="${producto.id}" step="0.1" value="${producto.precioAr}">
|
|
</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4">
|
|
<input type="number" class="w-full px-2 sm:px-3 py-1 text-xs sm:text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 precioExtranjeroInput" data-id="${producto.id}" step="0.1" value="${producto.precioBra}">
|
|
</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4">
|
|
<span class="diferencia font-bold text-xs sm:text-sm ${colorClass}" data-id="${producto.id}">${diferencia.toLocaleString('es-AR')}</span>
|
|
</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4 hidden lg:table-cell">${producto.responsable}</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-3 sm:py-4">
|
|
<button class="bg-red-500 hover:bg-red-600 text-white px-2 sm:px-3 py-1 rounded text-xs sm:text-sm font-medium transition eliminarBtn" data-id="${producto.id}">
|
|
<span class="hidden sm:inline">Eliminar</span>
|
|
<span class="sm:hidden">✕</span>
|
|
</button>
|
|
</td>
|
|
</tr>`;
|
|
});
|
|
|
|
// Total por responsable
|
|
html += `
|
|
<tr class="bg-gray-100">
|
|
<td colspan="2" class="px-3 sm:px-4 lg:px-6 py-2 sm:py-3 text-right font-bold text-xs sm:text-sm text-gray-700">Total ${responsable}</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-2 sm:py-3 text-right font-bold text-xs sm:text-sm text-gray-700">${(totalPrecioExtranjeroResponsable * cotizacion).toLocaleString('es-AR')}</td>
|
|
<td class="px-3 sm:px-4 lg:px-6 py-2 sm:py-3 text-right font-bold text-xs sm:text-sm text-gray-700">${totalDiferenciaResponsable.toLocaleString('es-AR')}</td>
|
|
<td colspan="2"></td>
|
|
</tr>`;
|
|
}
|
|
|
|
document.getElementById('priceList').innerHTML = html;
|
|
|
|
const totalElement = document.getElementById('totalDiferencia');
|
|
totalElement.textContent = totalDiferenciaGlobal.toLocaleString('es-AR');
|
|
totalElement.className = `px-3 sm:px-4 lg:px-6 py-3 sm:py-4 font-bold text-sm sm:text-base lg:text-lg ${totalDiferenciaGlobal < 0 ? 'text-green-600' : 'text-red-600'}`;
|
|
|
|
// Reconfigurar eventos después de renderizar
|
|
configurarEventosTabla();
|
|
}
|
|
|
|
// Guardar productos en la API
|
|
async function guardarProductos() {
|
|
const endpoint = CONFIG.apis[paisActual].endpoint;
|
|
|
|
try {
|
|
const response = await fetch(endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(productos)
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.error) {
|
|
console.error('Error del servidor:', data.error);
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.showToast('Error al guardar: ' + data.error, 'error');
|
|
} else {
|
|
alert('Error al guardar: ' + data.error);
|
|
}
|
|
} else {
|
|
console.log('✓ Guardado exitoso:', data.mensaje);
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.showToast('Productos guardados correctamente', 'success');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error al guardar los datos:', error);
|
|
if (typeof LayoutManager !== 'undefined') {
|
|
LayoutManager.showToast('Error de conexión al guardar', 'error');
|
|
} else {
|
|
alert('Error al guardar los productos. Verifica la consola.');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Agregar nuevo artículo
|
|
function agregarArticulo(nombre, precioAr, precioExtranjero, responsable) {
|
|
const nuevoId = productos.length ? Math.max(...productos.map(p => p.id)) + 1 : 1;
|
|
|
|
productos.push({
|
|
id: nuevoId,
|
|
articulo: nombre,
|
|
precioAr: parseFloat(precioAr),
|
|
precioBra: parseFloat(precioExtranjero),
|
|
responsable: responsable
|
|
});
|
|
|
|
cargarListado();
|
|
guardarProductos();
|
|
}
|
|
|
|
// Eliminar artículo
|
|
function eliminarArticulo(id) {
|
|
productos = productos.filter(producto => producto.id !== id);
|
|
cargarListado();
|
|
guardarProductos();
|
|
}
|
|
|
|
// Configurar eventos de la tabla
|
|
function configurarEventosTabla() {
|
|
// Actualizar precios al editar
|
|
const inputs = document.querySelectorAll('.articuloInput, .precioArInput, .precioExtranjeroInput');
|
|
inputs.forEach(input => {
|
|
input.addEventListener('input', function() {
|
|
const id = parseInt(this.dataset.id);
|
|
const producto = productos.find(p => p.id === id);
|
|
|
|
const articulo = document.querySelector(`.articuloInput[data-id="${id}"]`).value;
|
|
const precioAr = parseFloat(document.querySelector(`.precioArInput[data-id="${id}"]`).value);
|
|
const precioExtranjero = parseFloat(document.querySelector(`.precioExtranjeroInput[data-id="${id}"]`).value);
|
|
|
|
if (!isNaN(precioAr) && !isNaN(precioExtranjero)) {
|
|
producto.articulo = articulo;
|
|
producto.precioAr = precioAr;
|
|
producto.precioBra = precioExtranjero;
|
|
|
|
const diferencia = ((precioExtranjero * cotizacion) - precioAr);
|
|
const diferenciaElement = document.querySelector(`.diferencia[data-id="${id}"]`);
|
|
diferenciaElement.textContent = diferencia.toLocaleString('es-AR');
|
|
diferenciaElement.className = `diferencia font-bold ${diferencia < 0 ? 'text-green-600' : 'text-red-600'}`;
|
|
|
|
guardarProductos();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Botones de eliminar
|
|
const deleteButtons = document.querySelectorAll('.eliminarBtn');
|
|
deleteButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const id = parseInt(this.dataset.id);
|
|
if (confirm('¿Estás seguro de que deseas eliminar este artículo?')) {
|
|
eliminarArticulo(id);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Configurar eventos principales
|
|
function configurarEventos() {
|
|
const form = document.getElementById('formAgregarArticulo');
|
|
if (form) {
|
|
form.addEventListener('submit', function(event) {
|
|
event.preventDefault();
|
|
|
|
const nombre = document.getElementById('articulo').value;
|
|
const precioAr = document.getElementById('precioAr').value;
|
|
const precioExtranjero = document.getElementById('precioExtranjero').value;
|
|
const responsable = document.getElementById('responsable').value;
|
|
|
|
if (nombre && precioAr && precioExtranjero && responsable) {
|
|
agregarArticulo(nombre, precioAr, precioExtranjero, responsable);
|
|
document.getElementById('articulo').value = '';
|
|
document.getElementById('precioAr').value = '';
|
|
document.getElementById('precioExtranjero').value = '';
|
|
document.getElementById('responsable').value = '';
|
|
} else {
|
|
alert('Por favor ingrese todos los campos.');
|
|
}
|
|
});
|
|
}
|
|
}
|