Uncategorized
#calc-cotizacion-wrapper * { margin: 0; padding: 0; box-sizing: border-box; } #calc-cotizacion-wrapper { font-family: Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 15px; } .calc-container { max-width: 1400px; margin: 0 auto; background: white; border-radius: 15px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); } .calc-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 15px 15px 0 0; } .calc-header h1 { font-size: 2em; margin-bottom: 10px; } .calc-sku { background: rgba(255,255,255,0.2); padding: 15px; border-radius: 10px; margin-top: 15px; font-family: monospace; font-size: 1.2em; } .calc-content { padding: 30px; } .calc-block { margin-bottom: 20px; border: 2px solid #e0e0e0; border-radius: 10px; overflow: hidden; } .calc-block-header { background: #667eea; color: white; padding: 15px 20px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; user-select: none; } .calc-block-header:hover { background: #5568d3; } .calc-toggle { font-size: 1.5em; transition: transform 0.3s; } .calc-collapsed .calc-toggle { transform: rotate(-90deg); } .calc-block-content { padding: 20px; background: #fafafa; } .calc-hidden { display: none; } .calc-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 15px; } .calc-form-group label { display: block; font-weight: 600; margin-bottom: 5px; color: #333; font-size: 0.9em; } .calc-form-group input, .calc-form-group select { width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 5px; font-size: 1em; } .calc-form-group input:focus, .calc-form-group select:focus { outline: none; border-color: #667eea; } .calc-subtotal { background: #667eea; color: white; padding: 15px; border-radius: 8px; margin-top: 15px; text-align: right; font-size: 1.2em; font-weight: bold; } .calc-btn { background: #667eea; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-weight: 600; margin: 5px 5px 15px 0; transition: background 0.3s; font-size: 0.9em; } .calc-btn:hover { background: #5568d3; } .calc-btn-danger { background: #dc3545; padding: 5px 10px; font-size: 0.85em; } .calc-btn-danger:hover { background: #c82333; } .calc-conditional { display: none; margin-top: 10px; padding: 15px; background: #f8f9fa; border-left: 3px solid #667eea; border-radius: 3px; } .calc-conditional.calc-show { display: block; } .calc-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 0.9em; } .calc-table th { background: #667eea; color: white; padding: 8px; text-align: left; font-weight: 600; font-size: 0.85em; } .calc-table td { padding: 6px; border-bottom: 1px solid #ddd; background: white; } .calc-table td input, .calc-table td select { padding: 5px; border: 1px solid #ddd; border-radius: 3px; width: 100%; font-size: 0.85em; } .calc-nested { background: #f9f9f9; margin: 5px 0; padding: 10px; border-left: 3px solid #764ba2; } .calc-nested-table { font-size: 0.85em; } .calc-summary { background: white; padding: 15px; border-radius: 8px; border: 2px solid #e0e0e0; } .calc-summary-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.95em; } .calc-summary-item:last-child { border-bottom: none; font-weight: bold; color: #667eea; margin-top: 10px; padding-top: 10px; border-top: 2px solid #667eea; font-size: 1.1em; } .calc-result-box { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 10px; margin-top: 20px; } .calc-result-item { display: flex; justify-content: space-between; padding: 15px; background: rgba(255,255,255,0.15); border-radius: 8px; margin-bottom: 10px; font-size: 1.05em; } .calc-result-item.calc-big { background: rgba(255,255,255,0.3); font-size: 1.4em; font-weight: bold; } .calc-precio-objetivo { background: #764ba2; color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; text-align: center; } .calc-precio-objetivo input { width: 300px; max-width: 100%; padding: 15px; font-size: 1.3em; text-align: center; border: 2px solid white; border-radius: 8px; } .calc-area-buttons { display: flex; gap: 15px; justify-content: center; margin-bottom: 20px; flex-wrap: wrap; } .calc-area-btn { background: white; color: #667eea; border: 3px solid #667eea; padding: 15px 30px; border-radius: 10px; cursor: pointer; font-weight: bold; font-size: 1.1em; transition: all 0.3s; min-width: 150px; } .calc-area-btn:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0,0,0,0.2); } .calc-area-btn.calc-active { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-color: white; }

Calculadora de Cotización Industrial

Sistema Completo de Cotización para Manufactura

SKU: SJ-0000-FA-NA-MA-RE-AC-
(function() { const MAQUINAS_MAQUINADO = [ ‘DMG MORI HNTX 1000’, ‘Torno CNC Haas HSSP-10’, ‘Fresadora CNC Haas PM-2P’, ‘Fresadora CNC Haas M-3P’, ‘Fresadora CNC Haas VF-4’, ‘Fresadora CNC Neway NW-AN’, ‘Ilusionadora’, ‘Barrenadora’, ‘Torno convencional’, ‘Fresadora convencional’, ‘Rectificadora plana’, ‘Rectificadora cilíndrica’ ]; const MAQUINAS_CARBURO = [ ‘MAQUINA DE CORTE’, ‘RECTIFICADORA ROLLOMATIC’, ‘RECTIFICADORA STUDER’, ‘AFILADO EN ANCA’, ‘ANCA CNC GRINDING MACHINE’, ‘ANCA TX7’, ‘ANCA MX7’, ‘Rectificadora de carburo’, ‘Horno de sinterizado’, ‘Prensa hidráulica’, ‘Máquina de mezcla’ ]; const MAQUINAS_PCD = [ ‘Máquina de corte láser’, ‘Rectificadora PCD’, ‘Máquina EDM’, ‘Torno CNC para PCD’, ‘Centro de mecanizado PCD’ ]; const MAQUINAS_DISTRIBUCION = [ ‘Empaquetadora’, ‘Etiquetadora’, ‘Clasificadora’, ‘Control de calidad’ ]; function obtenerMaquinasPorArea(area) { switch(area) { case ‘MA’: return MAQUINAS_MAQUINADO; case ‘CA’: return MAQUINAS_CARBURO; case ‘PC’: return MAQUINAS_PCD; case ‘DI’: return MAQUINAS_DISTRIBUCION; default: return MAQUINAS_MAQUINADO; } } function convertirMoneda(valor) { // La calculadora trabaja en USD internamente // Si está en MXN, convertir multiplicando por tasa de cambio return state.moneda === ‘MXN’ ? valor * state.tasaCambio : valor; } function convertirAUSD(valor) { // Convierte de la moneda actual a USD // Si está en MXN, dividir por tasa de cambio para obtener USD return state.moneda === ‘MXN’ ? valor / state.tasaCambio : valor; } function obtenerSimboloMoneda() { return state.moneda === ‘USD’ ? ‘USD $’ : ‘MXN $’; } function formatearPrecio(valor) { const convertido = convertirMoneda(valor); const simbolo = obtenerSimboloMoneda(); return `${simbolo}${convertido.toFixed(2)}`; } function calcularPiezasYSobrante() { if (state.tipoCorte === ‘TOCHO’) { return { piezas: 1, sobrante: 0 }; } else { // BARRA // Si es Carburo y hay datos en la tabla, calcular desde ahí if (state.area === ‘CA’ && state.procesosAdicionales.length > 0) { let totalPiezas = 0; let totalSobrante = 0; state.procesosAdicionales.forEach(item => { if (item.espesor > 0 && item.longitudBarra > 0) { totalPiezas += Math.floor(item.longitudBarra / item.espesor); totalSobrante += item.longitudBarra % item.espesor; } }); return { piezas: totalPiezas, sobrante: totalSobrante }; } else { // Cálculo tradicional con campos individuales if (state.espesor === 0 || state.longitudBarra === 0) { return { piezas: 0, sobrante: 0 }; } const piezas = Math.floor(state.longitudBarra / state.espesor); const sobrante = state.longitudBarra % state.espesor; return { piezas, sobrante }; } } } const CONSUMIBLES = [ { nombre: ‘MANO DE OBRA DIRECTA’, precio: 0.60 }, { nombre: ‘RUEDAS’, precio: 0.20 }, { nombre: ‘ACEITE COMBUSTIBLE’, precio: 0.05 }, { nombre: ‘CONSUMIBLES’, precio: 0.01 }, { nombre: ‘DEPRECIACIÓN MAQUINARIA’, precio: 0.50 }, { nombre: ‘MANTENIMIENTO’, precio: 0.10 }, { nombre: ‘MAQUINAS CNC AFILADO Y FABRICACION’, precio: 0.00 }, { nombre: ‘LUZ’, precio: 0.00 }, { nombre: ‘AGUA’, precio: 0.00 }, { nombre: ‘HERRAMIENTAS’, precio: 0.00 }, { nombre: ‘ANCA CNC GRINDING MACHINE’, precio: 0.50 }, { nombre: ‘ANCA’, precio: 0.50 }, { nombre: ‘MANTENIMIENTO CONSUMIBLES’, precio: 0.10 } ]; const CONCEPTOS_CONSUMIBLES_DEFAULT = [ { concepto: ‘Ruedas’, marca: ‘NO’, valorUSD: 0.2, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Aceite’, marca: ‘NO’, valorUSD: 0.05, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Energía eléctrica’, marca: ‘NO’, valorUSD: 0.15, minutos: 20, unidad: ‘NO’ }, { concepto: ‘MAQUINAS CNC AFILADO Y FABRICACION’, marca: ‘NO’, valorUSD: 0, minutos: 0, unidad: ‘NO’ }, { concepto: ‘Mano de obra directa’, marca: ‘NO’, valorUSD: 0.6, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Depreciación de maquinaria’, marca: ‘NO’, valorUSD: 0, minutos: 0, unidad: ‘NO’ }, { concepto: ‘ANCA CNC GRINDING MACHINE’, marca: ‘FX5 LINEAL’, valorUSD: 0.5, minutos: 20, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA CNC GRINDING MACHINE’, marca: ‘MX7 LINEAR’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA’, marca: ‘MX7 LINEAR’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA’, marca: ‘FX5 MACHINE’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘Mantenimiento’, marca: ‘NO’, valorUSD: 0.1, minutos: 20, unidad: ‘MINUTOS’ } ]; const RECUBRIMIENTOS = [ { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘4.85-9.5’, longitud: ‘0-100’, precio: 3.90 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘4.85-9.5’, longitud: ‘100.1-200.0’, precio: 4.37 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘4.85-9.5’, longitud: ‘200.1-300.0’, precio: 4.80 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘9.51-12.7’, longitud: ‘0-100’, precio: 5.08 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘9.51-12.7’, longitud: ‘100.1-200.0’, precio: 5.59 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘9.51-12.7’, longitud: ‘200.1-300.0’, precio: 6.13 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘12.71-15.9’, longitud: ‘0-100’, precio: 7.31 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘12.71-15.9’, longitud: ‘100.1-200.0’, precio: 8.05 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘12.71-15.9’, longitud: ‘200.1-300.0’, precio: 8.56 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘16.0-19.19’, longitud: ‘0-100’, precio: 9.20 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘16.0-19.19’, longitud: ‘100.1-200.0’, precio: 10.12 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘16.0-19.19’, longitud: ‘200.1-300.0’, precio: 11.13 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘19.20-22.39’, longitud: ‘0-100’, precio: 11.05 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘19.20-22.39’, longitud: ‘100.1-200.0’, precio: 12.15 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘19.20-22.39’, longitud: ‘200.1-300.0’, precio: 13.36 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘22.4-25.4’, longitud: ‘0-100’, precio: 12.55 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘22.4-25.4’, longitud: ‘100.1-200.0’, precio: 13.47 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘22.4-25.4’, longitud: ‘200.1-300.0’, precio: 14.62 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘25.5-28.4’, longitud: ‘0-100’, precio: 13.95 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘25.5-28.4’, longitud: ‘100.1-200.0’, precio: 14.81 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘25.5-28.4’, longitud: ‘200.1-300.0’, precio: 15.31 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘28.5-31.4’, longitud: ‘0-100’, precio: 15.21 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘28.5-31.4’, longitud: ‘100.1-200.0’, precio: 16.08 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘28.5-31.4’, longitud: ‘200.1-300.0’, precio: 17.02 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘31.5-32’, longitud: ‘0-100’, precio: 16.88 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘31.5-32’, longitud: ‘100.1-200.0’, precio: 17.21 }, { nombre: ‘Shark CROSSCUT AICrN’, diametro: ‘31.5-32’, longitud: ‘200.1-300.0’, precio: 17.81 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘4.85-9.5’, longitud: ‘0-100’, precio: 4.41 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘4.85-9.5’, longitud: ‘100.1-200.0’, precio: 4.85 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘4.85-9.5’, longitud: ‘200.1-300.0’, precio: 5.34 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘9.51-12.7’, longitud: ‘0-100’, precio: 5.65 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘9.51-12.7’, longitud: ‘100.1-200.0’, precio: 6.21 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘9.51-12.7’, longitud: ‘200.1-300.0’, precio: 6.84 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘12.71-15.9’, longitud: ‘0-100’, precio: 8.13 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘12.71-15.9’, longitud: ‘100.1-200.0’, precio: 8.94 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘12.71-15.9’, longitud: ‘200.1-300.0’, precio: 9.83 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘16.0-19.19’, longitud: ‘0-100’, precio: 10.83 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘16.0-19.19’, longitud: ‘100.1-200.0’, precio: 11.25 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘16.0-19.19’, longitud: ‘200.1-300.0’, precio: 12.37 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘19.20-22.39’, longitud: ‘0-100’, precio: 12.27 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘19.20-22.39’, longitud: ‘100.1-200.0’, precio: 13.50 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘19.20-22.39’, longitud: ‘200.1-300.0’, precio: 14.85 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘22.4-25.4’, longitud: ‘0-100’, precio: 13.31 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘22.4-25.4’, longitud: ‘100.1-200.0’, precio: 14.57 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘22.4-25.4’, longitud: ‘200.1-300.0’, precio: 15.04 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘25.5-28.4’, longitud: ‘0-100’, precio: 14.87 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘25.5-28.4’, longitud: ‘100.1-200.0’, precio: 15.22 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘25.5-28.4’, longitud: ‘200.1-300.0’, precio: 16.09 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘28.5-31.4’, longitud: ‘0-100’, precio: 15.82 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘28.5-31.4’, longitud: ‘100.1-200.0’, precio: 16.76 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘28.5-31.4’, longitud: ‘200.1-300.0’, precio: 17.02 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘31.5-32’, longitud: ‘0-100’, precio: 16.99 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘31.5-32’, longitud: ‘100.1-200.0’, precio: 18.05 }, { nombre: ‘Rhino HARDCUT TISIN’, diametro: ‘31.5-32’, longitud: ‘200.1-300.0’, precio: 18.57 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘4.85-9.5’, longitud: ‘0-100’, precio: 3.31 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘4.85-9.5’, longitud: ‘100.1-200.0’, precio: 3.78 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘4.85-9.5’, longitud: ‘200.1-300.0’, precio: 4.21 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘9.51-12.7’, longitud: ‘0-100’, precio: 4.67 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘9.51-12.7’, longitud: ‘100.1-200.0’, precio: 5.21 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘9.51-12.7’, longitud: ‘200.1-300.0’, precio: 5.89 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘12.71-15.9’, longitud: ‘0-100’, precio: 6.11 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘12.71-15.9’, longitud: ‘100.1-200.0’, precio: 7.21 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘12.71-15.9’, longitud: ‘200.1-300.0’, precio: 7.89 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘16.0-19.19’, longitud: ‘0-100’, precio: 9.31 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘16.0-19.19’, longitud: ‘100.1-200.0’, precio: 8.86 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘16.0-19.19’, longitud: ‘200.1-300.0’, precio: 9.12 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘19.20-22.39’, longitud: ‘0-100’, precio: 9.68 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘19.20-22.39’, longitud: ‘100.1-200.0’, precio: 10.31 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘19.20-22.39’, longitud: ‘200.1-300.0’, precio: 10.68 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘22.4-25.4’, longitud: ‘0-100’, precio: 11.31 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘22.4-25.4’, longitud: ‘100.1-200.0’, precio: 11.89 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘22.4-25.4’, longitud: ‘200.1-300.0’, precio: 12.07 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘25.5-28.4’, longitud: ‘0-100’, precio: 12.46 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘25.5-28.4’, longitud: ‘100.1-200.0’, precio: 12.98 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘25.5-28.4’, longitud: ‘200.1-300.0’, precio: 13.21 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘28.5-31.4’, longitud: ‘0-100’, precio: 13.76 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘28.5-31.4’, longitud: ‘100.1-200.0’, precio: 14.23 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘28.5-31.4’, longitud: ‘200.1-300.0’, precio: 14.87 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘31.5-32’, longitud: ‘0-100’, precio: 15.24 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘31.5-32’, longitud: ‘100.1-200.0’, precio: 15.67 }, { nombre: ‘Panther MAXIMIZER TiAIN’, diametro: ‘31.5-32’, longitud: ‘200.1-300.0’, precio: 16.21 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘4.85-9.5’, longitud: ‘0-100’, precio: 5.20 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘4.85-9.5’, longitud: ‘100.1-200.0’, precio: 5.55 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘4.85-9.5’, longitud: ‘200.1-300.0’, precio: 5.90 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘9.51-12.7’, longitud: ‘0-100’, precio: 6.30 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘9.51-12.7’, longitud: ‘100.1-200.0’, precio: 6.89 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘9.51-12.7’, longitud: ‘200.1-300.0’, precio: 7.21 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘12.71-15.9’, longitud: ‘0-100’, precio: 7.78 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘12.71-15.9’, longitud: ‘100.1-200.0’, precio: 8.31 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘12.71-15.9’, longitud: ‘200.1-300.0’, precio: 9.02 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘16.0-19.19’, longitud: ‘0-100’, precio: 9.56 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘16.0-19.19’, longitud: ‘100.1-200.0’, precio: 9.78 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘16.0-19.19’, longitud: ‘200.1-300.0’, precio: 10.31 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘19.20-22.39’, longitud: ‘0-100’, precio: 10.52 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘19.20-22.39’, longitud: ‘100.1-200.0’, precio: 11.00 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘19.20-22.39’, longitud: ‘200.1-300.0’, precio: 11.31 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘22.4-25.4’, longitud: ‘0-100’, precio: 11.87 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘22.4-25.4’, longitud: ‘100.1-200.0’, precio: 12.31 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘22.4-25.4’, longitud: ‘200.1-300.0’, precio: 13.21 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘25.5-28.4’, longitud: ‘0-100’, precio: 13.95 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘25.5-28.4’, longitud: ‘100.1-200.0’, precio: 14.81 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘25.5-28.4’, longitud: ‘200.1-300.0’, precio: 15.31 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘28.5-31.4’, longitud: ‘0-100’, precio: 15.21 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘28.5-31.4’, longitud: ‘100.1-200.0’, precio: 16.08 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘28.5-31.4’, longitud: ‘200.1-300.0’, precio: 17.02 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘31.5-32’, longitud: ‘0-100’, precio: 16.88 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘31.5-32’, longitud: ‘100.1-200.0’, precio: 17.21 }, { nombre: ‘Snake AURORA X PLUS’, diametro: ‘31.5-32’, longitud: ‘200.1-300.0’, precio: 17.81 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘4.85-9.5’, longitud: ‘0-100’, precio: 2.22 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘4.85-9.5’, longitud: ‘100.1-200.0’, precio: 2.56 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘4.85-9.5’, longitud: ‘200.1-300.0’, precio: 2.89 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘9.51-12.7’, longitud: ‘0-100’, precio: 2.99 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘9.51-12.7’, longitud: ‘100.1-200.0’, precio: 3.14 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘9.51-12.7’, longitud: ‘200.1-300.0’, precio: 3.25 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘12.71-15.9’, longitud: ‘0-100’, precio: 3.33 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘12.71-15.9’, longitud: ‘100.1-200.0’, precio: 3.58 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘12.71-15.9’, longitud: ‘200.1-300.0’, precio: 3.99 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘16.0-19.19’, longitud: ‘0-100’, precio: 4.21 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘16.0-19.19’, longitud: ‘100.1-200.0’, precio: 4.44 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘16.0-19.19’, longitud: ‘200.1-300.0’, precio: 4.67 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘19.20-22.39’, longitud: ‘0-100’, precio: 5.11 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘19.20-22.39’, longitud: ‘100.1-200.0’, precio: 5.31 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘19.20-22.39’, longitud: ‘200.1-300.0’, precio: 5.77 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘22.4-25.4’, longitud: ‘0-100’, precio: 5.89 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘22.4-25.4’, longitud: ‘100.1-200.0’, precio: 6.12 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘22.4-25.4’, longitud: ‘200.1-300.0’, precio: 6.35 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘25.5-28.4’, longitud: ‘0-100’, precio: 6.58 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘25.5-28.4’, longitud: ‘100.1-200.0’, precio: 6.78 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘25.5-28.4’, longitud: ‘200.1-300.0’, precio: 7.21 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘28.5-31.4’, longitud: ‘0-100’, precio: 7.33 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘28.5-31.4’, longitud: ‘100.1-200.0’, precio: 7.79 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘28.5-31.4’, longitud: ‘200.1-300.0’, precio: 8.14 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘31.5-32’, longitud: ‘0-100’, precio: 8.31 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘31.5-32’, longitud: ‘100.1-200.0’, precio: 8.51 }, { nombre: ‘Lion Ionbond 01 TiN’, diametro: ‘31.5-32’, longitud: ‘200.1-300.0’, precio: 8.77 } ]; // Catálogo de barras de carburo const BARRAS_CARBURO = [ // BARRA CARBURO SOLIDA (13 variantes) { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 4*330 SOLIDA’, diametro: 4, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 5*330 SOLIDA’, diametro: 5, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 6*330 SOLIDA’, diametro: 6, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 7 * 330 SOLIDA’, diametro: 7, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 8*330 SOLIDA’, diametro: 8, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 11*330 SOLIDA’, diametro: 11, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 10*330 SOLIDA’, diametro: 10, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 12*330 SOLIDA’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 14*330 SOLIDA’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 16*330 SOLIDA’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 20*330 SOLIDA’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 25*330 SOLIDA’, diametro: 25, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO SOLIDA’, descripcion: ‘CARBURO 25.4*330 SOLIDA’, diametro: 25.4, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, // BARRA CARBURO 1 VENA CENTRAL (7 variantes) { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 12*330 1 VENA CENTRAL DIA ø2.00’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 14*330 1 VENA CENTRAL DIA ø2.00’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 16*330 1 VENA CENTRAL DIAø 2.00’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 14*102 1 VENA CENTRALø 2.00’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 102, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 20*330 1 VENA CENTRAL ø2.00’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 3/4*330 1 VENA CENTRAL ø2.00’, diametro: 0.75, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 1 VENA CENTRAL’, descripcion: ‘CARBURO 5/8″ *330 1 VENA CENTRAL DIA ø2.00’, diametro: 0.625, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, // BARRA CARBURO 2 VENAS RECTAS (21 variantes) { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 6*330 2VR-REDUCIDA TK1.5/d0.8’, diametro: 6, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 8*330 2VR-REDUCIDA TK2.6/d1.0’, diametro: 8, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 10*330 2VR-REDUCIDA TK2.6/d1.0’, diametro: 10, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 12*330 2VR-REDUCIDA TK3.5/d1.2’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 14*330 2VR-REDUCIDA TK5.0/d1.5’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 16*330 2VR-REDUCIDA TK5.0/d1.5’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 18*330 2VR-REDUCIDA TK6.2/d2.0’, diametro: 18, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 20*330 2VR-REDUCIDA TK6.2/d2.0’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 25*330 2VR- REDUCE TK7.50 d2’, diametro: 25, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 4*330 2VR-STANDAR’, diametro: 4, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 6*330 2VR-STANDAR TK3.0/d1.0’, diametro: 6, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 8*330 2VR-STANDAR TL4.0/d1.0’, diametro: 8, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 10*330 2VR-STANDAR’, diametro: 10, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 12*330 2VR-STANDAR TK6.0/d1.75’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 14*330 2VR-STANDAR’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 16*330 2VR-STANDAR TK8.0/d2.0’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 18*330 2VR-STANDAR TK9.0/d2.0’, diametro: 18, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 20*330 2VR-STANDAR TK10/d2.5’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, descripcion: ‘CARBURO 25*330 2VR-STANDAR TK8’, diametro: 25, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, // BARRA CARBURO 2 VENAS HELICOIDALES (16 variantes) { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 6 * 330 2VH-REDUCIDA TK2/d0.5’, diametro: 6, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 8 * 330 2VH-REDUCIDA TK2.4/d0.65’, diametro: 8, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 10*330 2VH-REDUCIDA TK3.1/d0.8’, diametro: 10, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 12*330 2VH-REDUCIDA TK3.8/d0.9’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 14*330 2 VH-REDUCIDA TK4.3/CAR-14*330 d1.0’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 16*330 2VH-REDUCIDA TK5.1/d1.2’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 18*330 2VH-REDUCIDA TK5.9/d1.4’, diametro: 18, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 20*330 2VH-REDUCIDA TK6.2/d2.0’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 4*330 2VH-STANDAR TK2.1/d0.6’, diametro: 4, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 6*330 2VH-STANDAR TK2.4/d0.7’, diametro: 6, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 8*330 2VH-STANDAR TL3.8/d1.0’, diametro: 8, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 10*330 2VH-STANDAR TK4.5/d1.4’, diametro: 10, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 12*330 2VH-STANDAR TK5.85/d1.4’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 14*330 2VH-STANDAR TK6.7/d1.8’, diametro: 14, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 16*330 2VH-STANDAR TK8.0/d2.0’, diametro: 16, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 18 * 330 2VH-STANDAR TK9.0/d2.3’, diametro: 18, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS HELICOIDALES’, descripcion: ‘CARBURO 20*330 2VH ESTÁNDAR TK10/d2.5’, diametro: 20, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precio: 0 }, // BARRA CARBURO 3 VENAS RECTAS (1 ejemplo) { tipo: ‘BARRA CARBURO 3 VENAS RECTAS’, descripcion: ‘CARBURO ejemplo’, diametro: 0, longitudHerramienta: 0, espesor: 0, longitudBarra: 0, precio: 0 } ]; // Función para filtrar barras por tipo function obtenerBarrasPorTipo(tipoBarra) { return BARRAS_CARBURO.filter(barra => barra.tipo === tipoBarra); } // Función dinámica para tipos de procesos según área function obtenerTiposProcesosExternos() { if (state.area === ‘CA’) { return [‘Recubrimiento’, ‘Decapado’]; } else if (state.area === ‘MA’) { return [‘Tratamiento Térmico’, ‘Ionizado’, ‘Limpieza Ultrasónica’]; } else { // Para PCD y DI, usar array original return [‘Recubrimiento’, ‘Tratamiento térmico’, ‘Ionizado’, ‘Limpieza Ultrasónica’, ‘Otro’]; } } // Función específica para tipos de barra en Área y Material (Carburo) function obtenerTiposDeBarra() { return [ ‘BARRA CARBURO SOLIDA’, ‘BARRA CARBURO 1 VENA CENTRAL’, ‘BARRA CARBURO 2 VENAS RECTAS’, ‘BARRA CARBURO 2 VENAS HELICOIDALES’, ‘BARRA CARBURO 3 VENAS RECTAS’ ]; } const SUBTIPOS_MATERIAL = { AC: [‘4140 AISI 4140’, ‘4140 tratado’, ‘E18 AISI 1018’, ‘E2 AISI 1020’, ‘D2 AISI D2’, ‘Otro’], LA: [‘Amarillo (70% Cu / 30% Zn)’, ‘Rojo (85% Cu)’, ‘Naval (Cu-Zn + Sn)’, ‘De maquinado (Cu-Zn + Pb)’, ‘Forjado’, ‘Eléctrico’, ‘Otro’], NA: [‘Nailami 6 (PA6)’, ‘Nailami 6/6 (PA66)’, ‘Con fibra de vidrio’, ‘Lubricado’, ‘Grado automotriz’, ‘Alimenticio’, ‘Otro’], AL: [‘1050/1100 (Serie 1xxx)’, ‘3003/3004 (Serie 3xxx)’, ‘5052, 5083, 5754 (Serie 5xxx)’, ‘6061, 6063, 6082 (Serie 6xxx)’, ‘A356/A357, 319, 380 (Fundición)’, ‘Otro’], CA: [‘Tungsteno estándar’, ‘Tungsteno con cobalto’, ‘Grado submicron’, ‘Otro’], OB: [‘Oblea PCD’, ‘Oblea PCBN’, ‘Oblea CVD’, ‘Otro’], NA_MAT: [‘N/A’] }; const TIPOS_MATERIAL_POR_AREA = { CA: [{ codigo: ‘CA’, nombre: ‘Carburo’ }], MA: [ { codigo: ‘AC’, nombre: ‘Acero’ }, { codigo: ‘LA’, nombre: ‘Latón’ }, { codigo: ‘NA’, nombre: ‘Nailami’ }, { codigo: ‘AL’, nombre: ‘Aluminio’ } ], PC: [{ codigo: ‘OB’, nombre: ‘Obleas’ }], DI: [{ codigo: ‘NA_MAT’, nombre: ‘N/A’ }] }; function obtenerTiposMaterialPorArea(area) { return TIPOS_MATERIAL_POR_AREA[area] || TIPOS_MATERIAL_POR_AREA[‘MA’]; } const state = { precioObjetivo: 0, moneda: ‘USD’, tasaCambio: 18.50, nuevoCliente: ‘NO’, nombreEmpresa: ”, rfc: ”, direccion: ”, telefono: ”, email: ”, contacto: ”, numeroCliente: ”, nombreCliente: ”, tipoHerramienta: ‘Broca’, trabajo: ‘FA’, ventas: ‘NA’, credito: ‘NO’, creditoDias: 1, rebate: ‘NO’, rebatePorcentaje: 1, area: ‘CA’, unidad: ‘MM’, forma: ‘RE’, tipoMaterial: ‘CA’, subtipoMaterial: ‘Tungsteno estándar’, tipoCorte: ‘BARRA’, // Campos para BARRA diametro: 0, longitudHerramienta: 0, espesor: 0, longitudBarra: 6000, precioUnitarioBarra: 5000, // Campos para TOCHO diametroTocho: 0, longitudTocho: 0, precioTocho: 0, maquinas: [ { nombre: ‘MAQUINA DE CORTE’, tiempo: 0, costo: 0, consumibles: [ { concepto: ‘Ruedas’, marca: ‘NO’, valorUSD: 0.2, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Aceite’, marca: ‘NO’, valorUSD: 0.05, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Energía eléctrica’, marca: ‘NO’, valorUSD: 0.15, minutos: 20, unidad: ‘NO’ }, { concepto: ‘MAQUINAS CNC AFILADO Y FABRICACION’, marca: ‘NO’, valorUSD: 0, minutos: 0, unidad: ‘NO’ }, { concepto: ‘Mano de obra directa’, marca: ‘NO’, valorUSD: 0.6, minutos: 20, unidad: ‘NO’ }, { concepto: ‘Depreciación de maquinaria’, marca: ‘NO’, valorUSD: 0, minutos: 0, unidad: ‘NO’ }, { concepto: ‘ANCA CNC GRINDING MACHINE’, marca: ‘FX5 LINEAL’, valorUSD: 0.5, minutos: 20, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA CNC GRINDING MACHINE’, marca: ‘MX7 LINEAR’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA’, marca: ‘MX7 LINEAR’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘ANCA’, marca: ‘FX5 MACHINE’, valorUSD: 0.5, minutos: 0, unidad: ‘MINUTOS’ }, { concepto: ‘Mantenimiento’, marca: ‘NO’, valorUSD: 0.1, minutos: 20, unidad: ‘MINUTOS’ } ] } ], calidad: [ { concepto: ‘MANO DE OBRA’, marca: ”, valorUSD: 0.44, minutos: 10, unidad: ‘minutos’ }, { concepto: ‘MANTENIMIENTO’, marca: ”, valorUSD: 0.1, minutos: 10, unidad: ‘minutos’ }, { concepto: ‘GENIUS PILOT 4.0’, marca: ”, valorUSD: 0.1, minutos: 10, unidad: ‘minutos’ }, { concepto: ‘MY FOCUS’, marca: ”, valorUSD: 0.054, minutos: 0, unidad: ‘minutos’ }, { concepto: ‘KEYENCE’, marca: ”, valorUSD: 0.043, minutos: 0, unidad: ‘minutos’ } ], honeo: [ { concepto: ‘Depreciación de maquinaria OTEC’, marca: ‘NO’, valorUSD: 0.07, minutos: 28, unidad: ‘minutos’ }, { concepto: ‘Mantenimiento’, marca: ‘NO’, valorUSD: 0.009, minutos: 28, unidad: ‘minutos’ }, { concepto: ‘Consumibles’, marca: ‘NO’, valorUSD: 0.012, minutos: 28, unidad: ‘minutos’ }, { concepto: ‘operador’, marca: ‘NO’, valorUSD: 0.05, minutos: 0, unidad: ‘minutos’ }, { concepto: ‘PLANOS’, marca: ‘NO’, valorUSD: 0.05, minutos: 0, unidad: ‘minutos’ }, { concepto: ‘RANURAS’, marca: ‘NO’, valorUSD: 0.05, minutos: 0, unidad: ‘minutos’ } ], procesosExternos: [], procesosAdicionales: [ { tipo: ‘BARRA CARBURO SOLIDA’, subtipo: ‘CARBURO 12*330 SOLIDA’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precioUnitarioBarra: 0 }, { tipo: ‘BARRA CARBURO 2 VENAS RECTAS’, subtipo: ‘CARBURO 12*330 2VR-REDUCIDA TK3.5/d1.2’, diametro: 12, longitudHerramienta: 0, espesor: 0, longitudBarra: 330, precioUnitarioBarra: 0 } ], rectificado: [ { concepto: ‘ROLLOMATIC’, marca: ”, valorUSD: 0.3, minutos: 25, unidad: ” }, { concepto: ‘studer’, marca: ”, valorUSD: 0.3, minutos: 25, unidad: ” }, { concepto: ‘Mano de obra directa’, marca: ”, valorUSD: 0.25, minutos: 25, unidad: ” }, { concepto: ‘Mantenimiento’, marca: ”, valorUSD: 0.02, minutos: 25, unidad: ” }, { concepto: ‘aceite’, marca: ”, valorUSD: 0.05, minutos: 25, unidad: ” }, { concepto: ‘Energía eléctrica’, marca: ”, valorUSD: 0.1, minutos: 25, unidad: ” } ], almacen: [ { concepto: ‘COSTO OPERATIVO’, marca: ‘NO’, valorUSD: 0.28, minutos: 10, unidad: ‘no’ }, { concepto: ‘DEPRECIACION MAQUINA ETIQUETAS’, marca: ‘NO’, valorUSD: 0.13, minutos: 1, unidad: ‘no’ }, { concepto: ‘ETIQUeTAS’, marca: ‘NO’, valorUSD: 0.013, minutos: 1, unidad: ‘no’ }, { concepto: ‘EMBALAJE’, marca: ‘NO’, valorUSD: 1, minutos: 1, unidad: ‘no’ } ], gastos: [ { concepto: ‘Gastos administrativos y ventas’, marca: ‘NO’, valorUSD: 1.2, minutos: 20, unidad: ‘minutos’ } ], utilidad: 30, vendedor1: 3, vendedor2: 3, compensacion: 5, compensacionRebate: 5, margen: 0, descuento: 0, impuestos: 16, collapsed: {} }; // Variable para rastrear la moneda anterior (para conversión automática de precio objetivo) let monedaAnterior = state.moneda; function calcularMaterial() { if (state.tipoCorte === ‘BARRA’) { // Si es Carburo y hay datos en la tabla, calcular desde ahí if (state.area === ‘CA’ && state.procesosAdicionales.length > 0) { let costoTotal = 0; state.procesosAdicionales.forEach(item => { if (item.longitudBarra > 0 && item.espesor > 0) { const piezasPorFila = item.longitudBarra / item.espesor; costoTotal += item.precioUnitarioBarra / piezasPorFila; } }); return costoTotal; } else { // Cálculo tradicional con campos individuales if (state.longitudBarra === 0 || state.espesor === 0) return 0; return state.precioUnitarioBarra / (state.longitudBarra / state.espesor); } } else { // TOCHO return state.precioTocho; } } function calcularMaquinas() { return state.maquinas.reduce((sum, maq) => { const costoMaquina = maq.tiempo * maq.costo; const costoConsumibles = (maq.consumibles || []).reduce((s, c) => s + (c.minutos * c.valorUSD), 0); return sum + costoMaquina + costoConsumibles; }, 0); } function calcularTabla(tipo) { if (tipo === ‘procesosExternos’) { return state[tipo].reduce((sum, item) => { if (item.tipo === ‘Recubrimiento’) { return sum + (item.precio || 0); } else { return sum + ((item.cant || 0) * (item.precio || 0)); } }, 0); } return state[tipo].reduce((sum, item) => sum + ((item.minutos || 0) * (item.valorUSD || 0)), 0); } function calcularTodo() { const costoMaterial = calcularMaterial(); const costoMaquinas = calcularMaquinas(); const costoCalidad = calcularTabla(‘calidad’); const costoHoneo = calcularTabla(‘honeo’); const costoProcesosExternos = calcularTabla(‘procesosExternos’); const costoRectificado = calcularTabla(‘rectificado’); const costoAlmacen = calcularTabla(‘almacen’); const costoGastos = calcularTabla(‘gastos’); const costoBase = costoMaterial + costoMaquinas + costoCalidad + costoHoneo + costoProcesosExternos + costoRectificado + costoAlmacen + costoGastos; const costoCredito = state.credito === ‘SI’ ? costoBase * (state.creditoDias / 100) : 0; const costoRebate = state.rebate === ‘SI’ ? costoBase * (state.rebatePorcentaje / 100) : 0; const subtotalUtilidades = costoBase + costoCredito – costoRebate; const costoUtilidad = subtotalUtilidades * (state.utilidad / 100); const costoVendedor1 = subtotalUtilidades * (state.vendedor1 / 100); const costoVendedor2 = subtotalUtilidades * (state.vendedor2 / 100); const costoCompensacion = subtotalUtilidades * (state.compensacion / 100); const costoCompRebate = subtotalUtilidades * (state.compensacionRebate / 100); const costoConAjustes = subtotalUtilidades + costoUtilidad + costoVendedor1 + costoVendedor2 + costoCompensacion + costoCompRebate; const costoMargen = costoConAjustes * (state.margen / 100); const subtotalConMargen = costoConAjustes + costoMargen; const costoDescuento = subtotalConMargen * (state.descuento / 100); const subtotalSinDescuento = subtotalConMargen – costoDescuento; const costoImpuestos = subtotalSinDescuento * (state.impuestos / 100); const precioFinalMXN = subtotalSinDescuento + costoImpuestos; // Todos los valores están en USD internamente // La conversión se hace en las funciones de visualización return { costoMaterial, costoMaquinas, costoCalidad, costoHoneo, costoProcesosExternos, costoRectificado, costoAlmacen, costoGastos, costoBase, costoCredito, costoRebate, subtotalUtilidades, costoUtilidad, costoVendedor1, costoVendedor2, costoCompensacion, costoCompRebate, costoConAjustes, costoMargen, costoDescuento, costoImpuestos, precioFinalMXN }; } function actualizarSKU() { // Tomar hasta 4 caracteres del número de cliente y rellenar con ceros a la izquierda si es menor let num = (state.numeroCliente || ”).substring(0, 4); num = num.padStart(4, ‘0’); const maq = state.maquinas.length > 0 ? state.maquinas[0].nombre.substring(0, 2).toUpperCase() : ”; const sku = `SJ-${num}-${state.trabajo}-${state.ventas}-${state.area}-${state.forma}-${state.tipoMaterial}-${maq}`; document.getElementById(‘calc-sku’).textContent = sku; } function render() { const app = document.getElementById(‘calc-app’); app.innerHTML = ”; // BOTONES DE ÁREA const areaButtons = document.createElement(‘div’); areaButtons.className = ‘calc-area-buttons’; areaButtons.innerHTML = ` `; app.appendChild(areaButtons); // BLOQUE 0: Precio Objetivo const precioObjetivo = document.createElement(‘div’); precioObjetivo.className = ‘calc-precio-objetivo’; precioObjetivo.innerHTML = ` `; app.appendChild(precioObjetivo); // BLOQUE 1: Información General app.appendChild(crearBloque({ id: ‘info’, titulo: ‘Información General’, campos: [ { id: ‘moneda’, label: ‘Moneda’, tipo: ‘select’, opciones: [ { valor: ‘USD’, texto: ‘USD – Dólares’ }, { valor: ‘MXN’, texto: ‘MXN – Pesos Mexicanos’ } ]}, { id: ‘tasaCambio’, label: ‘Tipo de Cambio USD→MXN’, tipo: ‘number’, step: ‘0.01’ }, { id: ‘nuevoCliente’, label: ‘¿Es Nuevo Cliente?’, tipo: ‘select’, opciones: [ { valor: ‘NO’, texto: ‘No’ }, { valor: ‘SI’, texto: ‘Sí’ } ], condicional: { id: ‘datosNuevoCliente’, campos: [ { id: ‘nombreEmpresa’, label: ‘Nombre de Empresa’, tipo: ‘text’ }, { id: ‘rfc’, label: ‘RFC’, tipo: ‘text’ }, { id: ‘direccion’, label: ‘Dirección’, tipo: ‘text’ }, { id: ‘telefono’, label: ‘Teléfono’, tipo: ‘text’ }, { id: ’email’, label: ‘Email’, tipo: ‘text’ }, { id: ‘contacto’, label: ‘Contacto’, tipo: ‘text’ } ] }}, { id: ‘numeroCliente’, label: ‘Número de Cliente’, tipo: ‘text’ }, { id: ‘nombreCliente’, label: ‘Nombre del Cliente’, tipo: ‘text’ }, { id: ‘tipoHerramienta’, label: ‘Tipo de Herramienta’, tipo: ‘select’, opciones: [ { valor: ‘Broca’, texto: ‘Broca’ }, { valor: ‘Fresa / End Mill’, texto: ‘Fresa / End Mill’ }, { valor: ‘Rimador / Escariador’, texto: ‘Rimador / Escariador’ }, { valor: ‘Machuelo / Macho de roscar’, texto: ‘Machuelo / Macho de roscar’ }, { valor: ‘Buril / Herramienta de torneado’, texto: ‘Buril / Herramienta de torneado’ } ]}, { id: ‘trabajo’, label: ‘Trabajo’, tipo: ‘select’, opciones: [ { valor: ‘FA’, texto: ‘FA – Fabricación’ }, { valor: ‘MO’, texto: ‘MO – Modificación’ }, { valor: ‘RE’, texto: ‘RE – Retrabajo’ }, { valor: ‘AF’, texto: ‘AF – Afilado’ } ]}, { id: ‘ventas’, label: ‘Ventas’, tipo: ‘select’, opciones: [ { valor: ‘NA’, texto: ‘NA – Nacional’ }, { valor: ‘IN’, texto: ‘IN – Internacional’ }, { valor: ‘LO’, texto: ‘LO – Local’ } ]}, { id: ‘credito’, label: ‘Crédito’, tipo: ‘select’, opciones: [ { valor: ‘NO’, texto: ‘No’ }, { valor: ‘SI’, texto: ‘Sí’ } ], condicional: { id: ‘creditoDias’, label: ‘Días’, tipo: ‘select’, opciones: [ { valor: 1, texto: ’30 (+1%)’ }, { valor: 2, texto: ’60 (+2%)’ }, { valor: 3, texto: ’90 (+3%)’ }, { valor: 5, texto: ‘120 (+5%)’ } ] }}, { id: ‘rebate’, label: ‘Rebate’, tipo: ‘select’, opciones: [ { valor: ‘NO’, texto: ‘No’ }, { valor: ‘SI’, texto: ‘Sí’ } ], condicional: { id: ‘rebatePorcentaje’, label: ‘%’, tipo: ‘select’, opciones: [1,2,3,5,10,15,20,25].map(v => ({ valor: v, texto: v+’%’ })) }} ] })); // BLOQUE 2: Área y Material app.appendChild(crearBloqueAreaMaterial()); // BLOQUE 3: Máquinas app.appendChild(crearBloqueMaquinas()); // BLOQUES 4-5: Tablas simples [‘calidad’, ‘honeo’].forEach(tipo => { app.appendChild(crearTablaSimple({ id: tipo, titulo: tipo.charAt(0).toUpperCase() + tipo.slice(1) })); }); // BLOQUE 6: PROCESOS EXTERNOS (único bloque con tipos seleccionables) app.appendChild(crearBloqueProcesosExternos()); // BLOQUE 7: RECTIFICADO – Solo para área CARBURO if (state.area === ‘CA’) { app.appendChild(crearTablaSimple({ id: ‘rectificado’, titulo: ‘RECTIFICADO’ })); } // BLOQUES 8-9: Continuar con resto de tablas [‘almacen’, ‘gastos’].forEach(tipo => { app.appendChild(crearTablaSimple({ id: tipo, titulo: tipo.charAt(0).toUpperCase() + tipo.slice(1) })); }); // BLOQUE 10: Costo Base Total app.appendChild(crearResumenCostoBase()); // BLOQUE 11: Utilidades y Ajustes app.appendChild(crearBloqueUtilidadesAjustes()); // BLOQUE 12: Precio Final app.appendChild(crearBloquePrecioFinal()); actualizarSKU(); } function crearBloque(config) { const block = document.createElement(‘div’); block.className = ‘calc-block’; const header = document.createElement(‘div’); header.className = ‘calc-block-header’; if (state.collapsed[config.id]) header.classList.add(‘calc-collapsed’); header.innerHTML = `

${config.titulo}

`; header.onclick = () => { state.collapsed[config.id] = !state.collapsed[config.id]; render(); }; const content = document.createElement(‘div’); content.className = ‘calc-block-content’; if (state.collapsed[config.id]) content.classList.add(‘calc-hidden’); const row = document.createElement(‘div’); row.className = ‘calc-form-row’; config.campos.forEach(campo => { const group = document.createElement(‘div’); group.className = ‘calc-form-group’; const label = document.createElement(‘label’); label.textContent = campo.label; group.appendChild(label); let input; if (campo.tipo === ‘select’) { input = document.createElement(‘select’); campo.opciones.forEach(opt => { const option = document.createElement(‘option’); option.value = opt.valor; option.textContent = opt.texto; input.appendChild(option); }); input.value = state[campo.id]; input.onchange = (e) => { // Caso especial para el campo moneda: usar función de conversión if (campo.id === ‘moneda’) { window.calcCambiarMoneda(e.target.value); } else { state[campo.id] = e.target.value; actualizarSKU(); render(); } }; } else { input = document.createElement(‘input’); input.type = campo.tipo; input.value = state[campo.id] || ”; if (campo.step) input.step = campo.step; // Para campos de texto, usar ‘blur’ para actualizar solo al salir // Para campos numéricos, usar ‘change’ para actualizar al terminar const evento = campo.tipo === ‘text’ ? ‘blur’ : ‘change’; input.addEventListener(evento, (e) => { state[campo.id] = campo.tipo === ‘number’ ? parseFloat(e.target.value)||0 : e.target.value; actualizarSKU(); render(); }); } group.appendChild(input); if (campo.condicional) { const cond = document.createElement(‘div’); cond.className = ‘calc-conditional’; if (state[campo.id] === ‘SI’) cond.classList.add(‘calc-show’); // Si el condicional tiene múltiples campos (como nuevo cliente) if (campo.condicional.campos) { // Primera fila: Nombre de Empresa, RFC, Dirección const condRow1 = document.createElement(‘div’); condRow1.className = ‘calc-form-row’; condRow1.style.marginBottom = ’10px’; for (let i = 0; i { state[condCampo.id] = e.target.value; render(); }); condGroup.appendChild(condInput); condRow1.appendChild(condGroup); } cond.appendChild(condRow1); // Segunda fila: Teléfono, Email, Contacto const condRow2 = document.createElement(‘div’); condRow2.className = ‘calc-form-row’; condRow2.style.marginBottom = ’15px’; for (let i = 3; i { state[condCampo.id] = e.target.value; render(); }); condGroup.appendChild(condInput); condRow2.appendChild(condGroup); } cond.appendChild(condRow2); // Botón guardar (solo visual) const btnContainer = document.createElement(‘div’); btnContainer.style.textAlign = ‘center’; btnContainer.style.marginTop = ’10px’; const btnGuardar = document.createElement(‘button’); btnGuardar.className = ‘calc-btn’; btnGuardar.textContent = ‘💾 Guardar Cliente’; btnGuardar.onclick = (e) => { e.preventDefault(); alert(‘Cliente guardado correctamente ✓’); }; btnContainer.appendChild(btnGuardar); cond.appendChild(btnContainer); } else { // Condicional simple (como crédito días o rebate %) const condLabel = document.createElement(‘label’); condLabel.textContent = campo.condicional.label; cond.appendChild(condLabel); const condSelect = document.createElement(‘select’); campo.condicional.opciones.forEach(opt => { const option = document.createElement(‘option’); option.value = opt.valor; option.textContent = opt.texto; condSelect.appendChild(option); }); condSelect.value = state[campo.condicional.id]; condSelect.onchange = (e) => { state[campo.condicional.id] = parseFloat(e.target.value); render(); }; cond.appendChild(condSelect); } group.appendChild(cond); } row.appendChild(group); }); content.appendChild(row); block.appendChild(header); block.appendChild(content); return block; } function crearBloqueAreaMaterial() { const block = document.createElement(‘div’); block.className = ‘calc-block’; const piezasInfo = calcularPiezasYSobrante(); let camposHTML = ”; if (state.tipoCorte === ‘BARRA’) { // Si NO es Carburo, mostrar campos individuales if (state.area !== ‘CA’) { camposHTML = `
`; } camposHTML += state.area === ‘CA’ ? `
${state.procesosAdicionales.length > 0 ? ` ${state.procesosAdicionales.map((item, idx) => { return ``; }).join(”)}
Tipo de Barra Descripción/Subtipo Diámetro (mm) Longitud Herramienta (mm) Espesor (mm) Longitud Barra (mm) Precio Unitario Barra ($)
${obtenerTiposDeBarra().map(tipo => `${tipo}` ).join(”)} ${obtenerBarrasPorTipo(item.tipo).map(barra => `${barra.descripcion}` ).join(”)}
` : ”}
` : ”; camposHTML += `
PIEZAS QUE SALEN
${piezasInfo.piezas}
SOBRANTE
${piezasInfo.sobrante.toFixed(2)} mm
`; } else { // TOCHO camposHTML = `
`; } block.innerHTML = `

Área y Material

CA – Carburo MA – Maquinado PC – PCD DI – Distribución
MM – Milímetros PU – Pulgadas
RE – Redondo CU – Cuadrado BA – Barra BH – Barra Hueca OT – Otro
${obtenerTiposMaterialPorArea(state.area).map(tm => `${tm.codigo} – ${tm.nombre}` ).join(”)}
${SUBTIPOS_MATERIAL[state.tipoMaterial].map(s => `${s}` ).join(”)}
Barra Completa Tocho
${camposHTML}
Subtotal Material: ${formatearPrecio(calcularMaterial())}
`; return block; } function crearBloqueMaquinas() { const block = document.createElement(‘div’); block.className = ‘calc-block’; const MAQUINAS_LIST = obtenerMaquinasPorArea(state.area); let html = `

Máquinas

`; if (state.maquinas.length > 0) { state.maquinas.forEach((maq, idx) => { const totalMaq = maq.tiempo * maq.costo; const totalCons = (maq.consumibles||[]).reduce((s,c) => s+(c.minutos*c.valorUSD), 0); html += `
MáquinaTiempo (min)Costo/min Total
${MAQUINAS_LIST.map(m => `${m}` ).join(”)} ${formatearPrecio(totalMaq)}
${(maq.consumibles||[]).map((cons, cidx) => ` `).join(”)}
ConceptoMarcaValor USD/min MinutosTotalUnidad
${formatearPrecio(cons.minutos*cons.valorUSD)}
Total Máquina + Consumibles: ${formatearPrecio(totalMaq+totalCons)}
`; }); } html += `
Subtotal Máquinas: ${formatearPrecio(calcularMaquinas())}
`; block.innerHTML = html; return block; } function crearTablaSimple(config) { const titulosMapa = { calidad: ‘Calidad’, honeo: ‘HONEO’, rectificado: ‘RECTIFICADO’, almacen: ‘ALMACÉN’, gastos: ‘GASTOS VENTAS Y ADMÓN’ }; const titulo = titulosMapa[config.id] || config.titulo; const block = document.createElement(‘div’); block.className = ‘calc-block’; let html = `

${titulo}

`; if (state[config.id].length > 0) { html += ``; state[config.id].forEach((item, idx) => { const total = (item.minutos || 0) * (item.valorUSD || 0); html += ``; }); html += `
ConceptoMarcaValor USD/minMinutosTotalUnidad de medida
${formatearPrecio(total)}
`; } html += `
Subtotal ${titulo}: ${formatearPrecio(calcularTabla(config.id))}
`; block.innerHTML = html; return block; } function crearBloqueProcesosExternos() { const block = document.createElement(‘div’); block.className = ‘calc-block’; let html = `

PROCESOS EXTERNOS

`; if (state.procesosExternos.length > 0) { html += ``; state.procesosExternos.forEach((item, idx) => { const total = item.tipo === ‘Recubrimiento’ ? (item.precio || 0) : (item.cant * item.precio); html += ``; // Columna Diámetro/Cantidad (condicional) if (item.tipo === ‘Recubrimiento’) { html += ``; } else { html += ``; } // Columna Longitud/Unidad (condicional) if (item.tipo === ‘Recubrimiento’) { html += ``; } else { html += ``; } html += ``; }); html += `
Tipo de ProcesoDescripción/SubtipoDiámetro/Cantidad Longitud/UnidadPrecioTotal
${obtenerTiposProcesosExternos().map(tipo => `${tipo}` ).join(”)} `; // Columna descripción/subtipo condicional según el tipo if (item.tipo === ‘Recubrimiento’) { html += ` ${RECUBRIMIENTOS.map(r => { const opcionCompleta = `${r.nombre} | ${r.diametro} | ${r.longitud}`; return `${r.nombre} | Ø${r.diametro} | L${r.longitud} | $${r.precio.toFixed(2)}` }).join(”)} `; } else if (item.tipo === ‘Tratamiento térmico’) { html += “; } else { html += “; } html += ` ${formatearPrecio(total)}
`; } html += `
Subtotal Procesos Externos: ${formatearPrecio(calcularTabla(‘procesosExternos’))}
`; block.innerHTML = html; return block; } function crearResumenCostoBase() { const r = calcularTodo(); const block = document.createElement(‘div’); block.className = ‘calc-block’; block.innerHTML = `

Costo Base Total

Material:${formatearPrecio(r.costoMaterial)}
Máquinas:${formatearPrecio(r.costoMaquinas)}
Calidad:${formatearPrecio(r.costoCalidad)}
Honeo:${formatearPrecio(r.costoHoneo)}
Procesos Externos:${formatearPrecio(r.costoProcesosExternos)}
Rectificado:${formatearPrecio(r.costoRectificado)}
Almacén:${formatearPrecio(r.costoAlmacen)}
Gastos:${formatearPrecio(r.costoGastos)}
COSTO BASE TOTAL:${formatearPrecio(r.costoBase)}
`; return block; } function crearBloqueUtilidadesAjustes() { const r = calcularTodo(); const block = document.createElement(‘div’); block.className = ‘calc-block’; block.innerHTML = `

Utilidades y Ajustes

GASTOS FINANCIEROS CREDITO

Estado: ${state.credito} ${state.credito === ‘SI’ ? `| Días: ${state.creditoDias === 1 ? ’30 días (1%)’ : state.creditoDias === 2 ? ’60 días (2%)’ : state.creditoDias === 3 ? ’90 días (3%)’ : ‘120 días (5%)’} | Costo: ${formatearPrecio(r.costoCredito)}` : ”}
Para cambiar, edite en la sección “Información General”
Costo Base:${formatearPrecio(r.costoBase)}
+ Crédito (${state.creditoDias}%):${formatearPrecio(r.costoCredito)}
Subtotal (Base + Crédito):${formatearPrecio(r.costoBase + r.costoCredito)}
+ Utilidad (${state.utilidad}%):${formatearPrecio(r.costoUtilidad)}
+ Vendedor 1 (${state.vendedor1}%):${formatearPrecio(r.costoVendedor1)}
+ Vendedor 2 (${state.vendedor2}%):${formatearPrecio(r.costoVendedor2)}
+ Compensación 1 (${state.compensacion}%):${formatearPrecio(r.costoCompensacion)}
– Rebate (${state.rebatePorcentaje}%):${formatearPrecio(r.costoRebate)}
+ Compensación Rebate (${state.compensacionRebate}%):${formatearPrecio(r.costoCompRebate)}
COSTO CON AJUSTES:${formatearPrecio(r.costoConAjustes)}
`; return block; } function crearBloquePrecioFinal() { const r = calcularTodo(); const simbolo = obtenerSimboloMoneda(); const precioFinalConvertido = convertirMoneda(r.precioFinalMXN); const diferencia = state.precioObjetivo – precioFinalConvertido; // Helper para obtener color según porcentaje de margen const getColorMargen = (pct) => pct >= 5 ? ‘#4caf50’ : pct >= 0 ? ‘#ffa726’ : ‘#f44336’; const getIconoMargen = (pct) => pct >= 5 ? ‘🟢’ : pct >= 0 ? ‘🟡’ : ‘🔴’; let analisisHTML = ”; const precioObj = state.precioObjetivo || 0; if (precioObj > 0) { const precioObjUSD = convertirAUSD(precioObj); const precioSinImpuestos = precioObjUSD / (1 + state.impuestos / 100); const margenSinImpuestos = precioSinImpuestos – r.costoConAjustes; const margenSinImpuestosPct = r.costoConAjustes > 0 ? (margenSinImpuestos / r.costoConAjustes) * 100 : 0; const margenConImpuestos = precioObjUSD – r.precioFinalMXN; const margenConImpuestosPct = r.costoConAjustes > 0 ? (margenConImpuestos / r.costoConAjustes) * 100 : 0; // Configuración del semáforo const semaforos = [ { min: 15, icono: ‘🟢’, color: ‘#4caf50’, texto: ‘VIABLE – Excelente margen’, msg: ‘Precio objetivo alcanzable con buen margen de ganancia.’ }, { min: 5, icono: ‘🟡’, color: ‘#ffa726’, texto: ‘VIABLE PERO RIESGOSO’, msg: ‘Margen bajo. Cualquier imprevisto podría afectar rentabilidad.’ }, { min: 0, icono: ‘🟠’, color: ‘#ff6f00’, texto: ‘POCO VIABLE – Ganas muy poco’, msg: ‘Margen muy bajo. Alto riesgo de pérdidas ante imprevistos.’ }, { min: -Infinity, icono: ‘🔴’, color: ‘#f44336’, texto: ‘NO VIABLE – Pierdes dinero’, msg: ‘El precio objetivo está por debajo de tus costos totales.’ } ]; const semaforo = semaforos.find(s => margenConImpuestosPct >= s.min); analisisHTML = `

🎯 Análisis vs Precio Objetivo

Tu Precio Final (${state.moneda})
${formatearPrecio(r.precioFinalMXN)}
Precio Objetivo (${state.moneda})
${simbolo}${precioObj.toFixed(2)}
${semaforo.icono}
${semaforo.texto}
${semaforo.msg}
Diferencia: =0?’#4caf50′:’#f44336′}”>${diferencia>=0?’+’:”}${simbolo.split(‘ ‘)[1]}${Math.abs(diferencia).toFixed(2)}
Margen sin impuestos:
${margenSinImpuestosPct.toFixed(2)}% ${getIconoMargen(margenSinImpuestosPct)}
Margen con impuestos:
${margenConImpuestosPct.toFixed(2)}% ${getIconoMargen(margenConImpuestosPct)}
${diferencia < 0 ? `
💡 Opciones para alcanzar ${simbolo}${precioObj.toFixed(2)}:
  • Reducir costos en: ${formatearPrecio(Math.abs(diferencia))}
  • Vender sin IVA: ${formatearPrecio(precioSinImpuestos)}
  • Negociar precio a: ${formatearPrecio(r.precioFinalMXN)}
  • ${margenSinImpuestosPct >= 0 ? `
  • Aceptar margen de ${margenSinImpuestosPct.toFixed(2)}% (sin IVA)
  • ` : ”}
` : ”}
`; } const block = document.createElement(‘div’); block.className = ‘calc-block’; block.innerHTML = `

Precio Final (Por Margen de Ganancia)

Resultados Finales

+ Margen (${state.margen}%):${formatearPrecio(r.costoMargen)}
– Descuento (${state.descuento}%):${formatearPrecio(r.costoDescuento)}
+ Impuestos (${state.impuestos}%):${formatearPrecio(r.costoImpuestos)}
PRECIO FINAL:${formatearPrecio(r.precioFinalMXN)}
${analisisHTML}
¡Copiado! Ahora pégalo en Excel
`; return block; } // Funciones globales window.calcState = state; window.calcRender = render; window.calcSKU = actualizarSKU; window.calcCambiarMoneda = function(nuevaMoneda) { // Convertir precio objetivo si la moneda cambió y hay valor if (nuevaMoneda !== monedaAnterior && state.precioObjetivo > 0) { if (nuevaMoneda === ‘MXN’ && monedaAnterior === ‘USD’) { state.precioObjetivo *= state.tasaCambio; } else if (nuevaMoneda === ‘USD’ && monedaAnterior === ‘MXN’) { state.precioObjetivo /= state.tasaCambio; } } state.moneda = nuevaMoneda; monedaAnterior = nuevaMoneda; actualizarSKU(); render(); }; window.calcUpdateSubtipos = function() { state.subtipoMaterial = SUBTIPOS_MATERIAL[state.tipoMaterial][0]; }; window.calcAgregarMaquina = function() { const MAQUINAS_LIST = obtenerMaquinasPorArea(state.area); // Crear consumibles por defecto con concepto, marca, valorUSD, minutos y unidad const consumiblesDefault = CONCEPTOS_CONSUMIBLES_DEFAULT.map(item => ({ concepto: item.concepto, marca: item.marca, valorUSD: item.valorUSD, minutos: item.minutos, unidad: item.unidad })); state.maquinas.push({ nombre: MAQUINAS_LIST[0], tiempo: 0, costo: 0, consumibles: consumiblesDefault }); render(); }; window.calcEliminarMaquina = function(idx) { state.maquinas.splice(idx, 1); render(); }; window.calcAgregarFilaConsumible = function(maqIdx) { if (!state.maquinas[maqIdx].consumibles) state.maquinas[maqIdx].consumibles = []; state.maquinas[maqIdx].consumibles.push({ concepto: ”, marca: ”, valorUSD: 0, minutos: 0, unidad: ‘MINUTOS’ }); render(); }; window.calcEliminarFilaConsumible = function(maqIdx, consIdx) { state.maquinas[maqIdx].consumibles.splice(consIdx, 1); render(); }; window.calcAgregar = function(tipo) { state[tipo].push({ concepto: ”, marca: ”, valorUSD: 0, minutos: 0, unidad: ‘c/u’ }); render(); }; window.calcEliminar = function(tipo, idx) { state[tipo].splice(idx, 1); render(); }; window.calcAgregarProcesoExterno = function() { state.procesosExternos.push({ tipo: ‘Recubrimiento’, subtipo: `${RECUBRIMIENTOS[0].nombre} | ${RECUBRIMIENTOS[0].diametro} | ${RECUBRIMIENTOS[0].longitud}`, cant: 0, precio: RECUBRIMIENTOS[0].precio, diametro: RECUBRIMIENTOS[0].diametro, longitud: RECUBRIMIENTOS[0].longitud }); render(); }; window.calcActualizarTipoProceso = function(idx, tipo) { state.procesosExternos[idx].tipo = tipo; // Actualizar subtipo y precio según el tipo if (tipo === ‘Recubrimiento’) { state.procesosExternos[idx].subtipo = `${RECUBRIMIENTOS[0].nombre} | ${RECUBRIMIENTOS[0].diametro} | ${RECUBRIMIENTOS[0].longitud}`; state.procesosExternos[idx].precio = RECUBRIMIENTOS[0].precio; state.procesosExternos[idx].diametro = RECUBRIMIENTOS[0].diametro; state.procesosExternos[idx].longitud = RECUBRIMIENTOS[0].longitud; } else { state.procesosExternos[idx].subtipo = ”; state.procesosExternos[idx].precio = 0; } render(); }; window.calcActualizarSubtipoProceso = function(idx, subtipoCompleto) { state.procesosExternos[idx].subtipo = subtipoCompleto; // Buscar el recubrimiento correspondiente const rec = RECUBRIMIENTOS.find(r => `${r.nombre} | ${r.diametro} | ${r.longitud}` === subtipoCompleto); if (rec) { state.procesosExternos[idx].diametro = rec.diametro; state.procesosExternos[idx].longitud = rec.longitud; state.procesosExternos[idx].precio = rec.precio; } render(); }; window.calcAgregarProcesoAdicional = function() { // Obtener la primera barra del tipo SOLIDA por defecto const tipoDefault = ‘BARRA CARBURO SOLIDA’; const barrasDelTipo = obtenerBarrasPorTipo(tipoDefault); const primeraBarra = barrasDelTipo.length > 0 ? barrasDelTipo[0] : null; if (primeraBarra) { state.procesosAdicionales.push({ tipo: tipoDefault, subtipo: primeraBarra.descripcion, diametro: primeraBarra.diametro, longitudHerramienta: primeraBarra.longitudHerramienta, espesor: primeraBarra.espesor, longitudBarra: primeraBarra.longitudBarra, precioUnitarioBarra: primeraBarra.precio }); } else { // Fallback si no hay barras en el catálogo state.procesosAdicionales.push({ tipo: tipoDefault, subtipo: ”, diametro: 0, longitudHerramienta: 0, espesor: 0, longitudBarra: 0, precioUnitarioBarra: 0 }); } render(); }; window.calcActualizarTipoProcesoAdicional = function(idx, tipo) { state.procesosAdicionales[idx].tipo = tipo; // Al cambiar tipo, seleccionar automáticamente la primera barra de ese tipo const barrasDelTipo = obtenerBarrasPorTipo(tipo); if (barrasDelTipo.length > 0) { const primeraBarra = barrasDelTipo[0]; state.procesosAdicionales[idx].subtipo = primeraBarra.descripcion; state.procesosAdicionales[idx].diametro = primeraBarra.diametro; state.procesosAdicionales[idx].longitudHerramienta = primeraBarra.longitudHerramienta; state.procesosAdicionales[idx].espesor = primeraBarra.espesor; state.procesosAdicionales[idx].longitudBarra = primeraBarra.longitudBarra; state.procesosAdicionales[idx].precioUnitarioBarra = primeraBarra.precio; } render(); }; window.calcActualizarDescripcionBarra = function(idx, descripcion) { // Buscar la barra seleccionada en el catálogo const barraSeleccionada = BARRAS_CARBURO.find(barra => barra.descripcion === descripcion); if (barraSeleccionada) { state.procesosAdicionales[idx].subtipo = barraSeleccionada.descripcion; state.procesosAdicionales[idx].diametro = barraSeleccionada.diametro; state.procesosAdicionales[idx].longitudHerramienta = barraSeleccionada.longitudHerramienta; state.procesosAdicionales[idx].espesor = barraSeleccionada.espesor; state.procesosAdicionales[idx].longitudBarra = barraSeleccionada.longitudBarra; state.procesosAdicionales[idx].precioUnitarioBarra = barraSeleccionada.precio; } render(); }; window.calcActualizarSubtipoProcesoAdicional = function(idx, subtipo) { state.procesosAdicionales[idx].subtipo = subtipo; render(); }; window.calcCopiarExcel = function() { const r = calcularTodo(); const fecha = new Date().toLocaleDateString(‘es-MX’); const hora = new Date().toLocaleTimeString(‘es-MX’); const timestamp = Date.now().toString().slice(-6); const codigo = `COT-${fecha.replace(/\//g,”)}-${timestamp}-${state.numeroCliente||’XXXX’}`; // Función helper para formatear precios con conversión const fp = (valor) => `$${convertirMoneda(valor).toFixed(2)}`; let txt = `COTIZACIÓN INDUSTRIAL\t\t\t\t\n`; txt += `Código:\t${codigo}\t\t\t\n`; txt += `Fecha:\t${fecha}\tHora:\t${hora}\t\n`; txt += `Moneda:\t${state.moneda}\tTipo de Cambio:\t${state.tasaCambio.toFixed(2)}\t\n`; txt += `\n`; // INFORMACIÓN GENERAL txt += `INFORMACIÓN GENERAL\t\t\t\t\n`; txt += `Nuevo Cliente:\t${state.nuevoCliente}\t\t\t\n`; if (state.nuevoCliente === ‘SI’) { txt += `Nombre de Empresa:\t${state.nombreEmpresa}\t\t\t\n`; txt += `RFC:\t${state.rfc}\t\t\t\n`; txt += `Dirección:\t${state.direccion}\t\t\t\n`; txt += `Teléfono:\t${state.telefono}\t\t\t\n`; txt += `Email:\t${state.email}\t\t\t\n`; txt += `Contacto:\t${state.contacto}\t\t\t\n`; } txt += `Número de Cliente:\t${state.numeroCliente}\t\t\t\n`; txt += `Nombre del Cliente:\t${state.nombreCliente}\t\t\t\n`; txt += `Tipo de Herramienta:\t${state.tipoHerramienta}\t\t\t\n`; txt += `SKU:\t${document.getElementById(‘calc-sku’).textContent}\t\t\t\n`; txt += `\n`; txt += `Trabajo:\t${state.trabajo}\tVentas:\t${state.ventas}\n`; txt += `Crédito:\t${state.credito}\t${state.credito===’SI’?’Días: ‘+state.creditoDias+’%’:”}\t\n`; txt += `Rebate:\t${state.rebate}\t${state.rebate===’SI’?state.rebatePorcentaje+’%’:”}\t\n`; txt += `\n`; // ÁREA Y MATERIAL txt += `ÁREA Y MATERIAL\t\t\t\t\n`; txt += `Área:\t${state.area}\tUnidad:\t${state.unidad}\n`; txt += `Forma:\t${state.forma}\tTipo Material:\t${state.tipoMaterial}\n`; txt += `Subtipo:\t${state.subtipoMaterial}\t\t\n`; txt += `Tipo de Corte:\t${state.tipoCorte}\t\t\n`; if (state.tipoCorte === ‘BARRA’) { txt += `Diámetro:\t${state.diametro}\tLong. Herramienta:\t${state.longitudHerramienta}\n`; txt += `Espesor:\t${state.espesor}\tLong. Barra:\t${state.longitudBarra}\n`; txt += `Precio Barra:\t${fp(state.precioUnitarioBarra)}\t\t\n`; const piezasInfo = calcularPiezasYSobrante(); txt += `Piezas que salen:\t${piezasInfo.piezas}\tSobrante:\t${piezasInfo.sobrante.toFixed(2)} mm\n`; } else { // TOCHO txt += `Diámetro del Tocho:\t${state.diametroTocho}\tLong. del Tocho:\t${state.longitudTocho}\n`; txt += `Precio del Tocho:\t${fp(state.precioTocho)}\t\t\n`; } txt += `\t\t\t\n`; txt += `Costo Material:\t${fp(r.costoMaterial)}\t\t\n`; txt += `\n`; // MÁQUINAS if (state.maquinas.length > 0) { txt += `MÁQUINAS\t\t\t\t\t\n`; txt += `Máquina\tTiempo (min)\tCosto/min\tTotal\t\n`; state.maquinas.forEach(maq => { const totalMaq = maq.tiempo * maq.costo; txt += `${maq.nombre}\t${maq.tiempo}\t${fp(maq.costo)}\t${fp(totalMaq)}\t\n`; if (maq.consumibles && maq.consumibles.length > 0) { txt += `\tCONSUMIBLES\t\t\t\t\t\n`; txt += `\tConcepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad\n`; maq.consumibles.forEach(cons => { txt += `\t${cons.concepto||”}\t${cons.marca||”}\t${fp(cons.valorUSD)}\t${cons.minutos}\t${fp(cons.minutos*cons.valorUSD)}\t${cons.unidad||’c/u’}\n`; }); } }); txt += `\t\t\t\n`; txt += `Subtotal Máquinas:\t${fp(r.costoMaquinas)}\t\t\n`; txt += `\n`; } // CALIDAD if (state.calidad.length > 0) { txt += `CALIDAD\t\t\t\t\t\t\n`; txt += `Concepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad de medida\n`; state.calidad.forEach(item => { txt += `${item.concepto||”}\t${item.marca||”}\t${fp(item.valorUSD||0)}\t${item.minutos||0}\t${fp((item.minutos||0)*(item.valorUSD||0))}\t${item.unidad||’c/u’}\n`; }); txt += `\t\t\t\n`; txt += `Subtotal Calidad:\t${fp(r.costoCalidad)}\t\t\n`; txt += `\n`; } // HONEO if (state.honeo.length > 0) { txt += `HONEO\t\t\t\t\t\t\n`; txt += `Concepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad de medida\n`; state.honeo.forEach(item => { txt += `${item.concepto||”}\t${item.marca||”}\t${fp(item.valorUSD||0)}\t${item.minutos||0}\t${fp((item.minutos||0)*(item.valorUSD||0))}\t${item.unidad||’c/u’}\n`; }); txt += `\t\t\t\n`; txt += `Subtotal Honeo:\t${fp(r.costoHoneo)}\t\t\n`; txt += `\n`; } // PROCESOS EXTERNOS if (state.procesosExternos.length > 0) { const recubrimientos = state.procesosExternos.filter(item => item.tipo === ‘Recubrimiento’); const otros = state.procesosExternos.filter(item => item.tipo !== ‘Recubrimiento’); if (recubrimientos.length > 0) { txt += `PROCESOS EXTERNOS – RECUBRIMIENTOS\t\t\t\t\n`; txt += `Descripción/Subtipo\tDiámetro\tLongitud\tPrecio\tTotal\n`; recubrimientos.forEach(item => { txt += `${item.subtipo||”}\t${item.diametro||0}\t${item.longitud||0}\t${fp(item.precio||0)}\t${fp(item.precio||0)}\n`; }); txt += `\t\t\t\n`; } if (otros.length > 0) { txt += `PROCESOS EXTERNOS – OTROS\t\t\t\t\t\n`; txt += `Tipo\tDescripción/Subtipo\tCantidad\tUnidad\tPrecio\tTotal\n`; otros.forEach(item => { txt += `${item.tipo}\t${item.subtipo||”}\t${item.cant}\tc/u\t${fp(item.precio)}\t${fp(item.cant*item.precio)}\n`; }); txt += `\t\t\t\t\n`; } txt += `Subtotal Procesos Externos:\t${fp(r.costoProcesosExternos)}\t\t\t\n`; txt += `\n`; } // RECTIFICADO if (state.rectificado.length > 0) { txt += `RECTIFICADO\t\t\t\t\t\t\n`; txt += `Concepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad de medida\n`; state.rectificado.forEach(item => { txt += `${item.concepto||”}\t${item.marca||”}\t${fp(item.valorUSD||0)}\t${item.minutos||0}\t${fp((item.minutos||0)*(item.valorUSD||0))}\t${item.unidad||’c/u’}\n`; }); txt += `\t\t\t\n`; txt += `Subtotal Rectificado:\t${fp(r.costoRectificado)}\t\t\n`; txt += `\n`; } // ALMACÉN if (state.almacen.length > 0) { txt += `ALMACÉN\t\t\t\t\t\t\n`; txt += `Concepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad de medida\n`; state.almacen.forEach(item => { txt += `${item.concepto||”}\t${item.marca||”}\t${fp(item.valorUSD||0)}\t${item.minutos||0}\t${fp((item.minutos||0)*(item.valorUSD||0))}\t${item.unidad||’c/u’}\n`; }); txt += `\t\t\t\n`; txt += `Subtotal Almacén:\t${fp(r.costoAlmacen)}\t\t\n`; txt += `\n`; } // GASTOS if (state.gastos.length > 0) { txt += `GASTOS VENTAS Y ADMÓN\t\t\t\t\t\t\n`; txt += `Concepto\tMarca\tValor USD/min\tMinutos\tTotal\tUnidad de medida\n`; state.gastos.forEach(item => { txt += `${item.concepto||”}\t${item.marca||”}\t${fp(item.valorUSD||0)}\t${item.minutos||0}\t${fp((item.minutos||0)*(item.valorUSD||0))}\t${item.unidad||’c/u’}\n`; }); txt += `\t\t\t\n`; txt += `Subtotal Gastos:\t${fp(r.costoGastos)}\t\t\n`; txt += `\n`; } // RESUMEN COSTO BASE txt += `COSTO BASE TOTAL\t\t\t\n`; txt += `Material:\t${fp(r.costoMaterial)}\t\t\n`; txt += `Máquinas:\t${fp(r.costoMaquinas)}\t\t\n`; txt += `Calidad:\t${fp(r.costoCalidad)}\t\t\n`; txt += `Honeo:\t${fp(r.costoHoneo)}\t\t\n`; txt += `Procesos Externos:\t${fp(r.costoProcesosExternos)}\t\t\n`; txt += `Rectificado:\t${fp(r.costoRectificado)}\t\t\n`; txt += `Almacén:\t${fp(r.costoAlmacen)}\t\t\n`; txt += `Gastos:\t${fp(r.costoGastos)}\t\t\n`; txt += `\t\t\t\n`; txt += `COSTO BASE TOTAL:\t${fp(r.costoBase)}\t\t\n`; txt += `\n`; // UTILIDADES Y AJUSTES txt += `UTILIDADES Y AJUSTES\t\t\t\n`; txt += `Costo Base:\t${fp(r.costoBase)}\t\t\n`; txt += `+ Crédito (${state.creditoDias}%):\t${fp(r.costoCredito)}\t\t\n`; txt += `Subtotal (Base + Crédito):\t${fp(r.costoBase + r.costoCredito)}\t\t\n`; txt += `+ Utilidad (${state.utilidad}%):\t${fp(r.costoUtilidad)}\t\t\n`; txt += `+ Vendedor 1 (${state.vendedor1}%):\t${fp(r.costoVendedor1)}\t\t\n`; txt += `+ Vendedor 2 (${state.vendedor2}%):\t${fp(r.costoVendedor2)}\t\t\n`; txt += `+ Compensación 1 (${state.compensacion}%):\t${fp(r.costoCompensacion)}\t\t\n`; txt += `- Rebate (${state.rebatePorcentaje}%):\t${fp(r.costoRebate)}\t\t\n`; txt += `+ Compensación Rebate (${state.compensacionRebate}%):\t${fp(r.costoCompRebate)}\t\t\n`; txt += `\t\t\t\n`; txt += `COSTO CON AJUSTES:\t${fp(r.costoConAjustes)}\t\t\n`; txt += `\n`; // PRECIO FINAL txt += `PRECIO FINAL\t\t\t\n`; txt += `Costo con Ajustes:\t${fp(r.costoConAjustes)}\t\t\n`; txt += `+ Margen (${state.margen}%):\t${fp(r.costoMargen)}\t\t\n`; txt += `- Descuento (${state.descuento}%):\t${fp(r.costoDescuento)}\t\t\n`; txt += `+ Impuestos (${state.impuestos}%):\t${fp(r.costoImpuestos)}\t\t\n`; txt += `\t\t\t\n`; txt += `PRECIO FINAL (${state.moneda}):\t${fp(r.precioFinalMXN)}\t\t\n`; txt += `\n`; txt += `Precio Objetivo (${state.moneda}):\t${fp(state.precioObjetivo)}\t\t\n`; const diferencia = convertirMoneda(state.precioObjetivo) – convertirMoneda(r.precioFinalMXN); txt += `Diferencia:\t$${diferencia.toFixed(2)}\t${diferencia>=0?’✓ DENTRO DEL OBJETIVO’:’✗ FUERA DEL OBJETIVO’}\t\n`; navigator.clipboard.writeText(txt).then(() => { const m = document.getElementById(‘calc-mensaje’); m.style.display = ‘block’; setTimeout(() => m.style.display = ‘none’, 3000); }).catch(() => alert(‘Error al copiar’)); }; window.calcCambiarArea = function(area) { state.area = area; // Cambiar tipo de material según área const tiposMaterial = obtenerTiposMaterialPorArea(area); state.tipoMaterial = tiposMaterial[0].codigo; state.subtipoMaterial = SUBTIPOS_MATERIAL[state.tipoMaterial][0]; actualizarSKU(); render(); }; render(); })();
E