273 lines
11 KiB
JavaScript
273 lines
11 KiB
JavaScript
/**
|
|
* Material Relationships - Cross-reference system
|
|
* Links steel grades with welding consumables and painting systems
|
|
*/
|
|
|
|
import { loadCSV } from './csv-manager.js';
|
|
|
|
// Cache for relationship data
|
|
let weldingRelations = [];
|
|
let paintingRelations = [];
|
|
let isLoaded = false;
|
|
|
|
/**
|
|
* Load all relationship data
|
|
* @returns {Promise<boolean>} Success status
|
|
*/
|
|
export async function loadRelationships() {
|
|
if (isLoaded) return true;
|
|
|
|
try {
|
|
console.log('📊 Carregando relacionamentos...');
|
|
|
|
// Load both CSV files
|
|
[weldingRelations, paintingRelations] = await Promise.all([
|
|
loadCSV('Tabela_Acos_Soldagem_Consumiveis.csv'),
|
|
loadCSV('Tabela_Acos_Pintura_Tintas.csv')
|
|
]);
|
|
|
|
isLoaded = true;
|
|
console.log(`✅ Relacionamentos carregados: ${weldingRelations.length} soldagem, ${paintingRelations.length} pintura`);
|
|
return true;
|
|
|
|
} catch (error) {
|
|
console.error('❌ Erro ao carregar relacionamentos:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get welding recommendations for a steel grade
|
|
* @param {string} steelGrade - Steel grade (e.g., "ASTM A36")
|
|
* @returns {Array<object>} Welding recommendations
|
|
*/
|
|
export function getWeldingRecommendations(steelGrade) {
|
|
if (!isLoaded) {
|
|
console.warn('⚠️ Relacionamentos não carregados');
|
|
return [];
|
|
}
|
|
|
|
// Normalize steel grade for comparison
|
|
const normalized = steelGrade.toUpperCase().trim();
|
|
|
|
return weldingRelations.filter(rel => {
|
|
const relSteel = rel.Aço?.toUpperCase().trim() || '';
|
|
return relSteel.includes(normalized) || normalized.includes(relSteel);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get painting recommendations for a steel grade and environment
|
|
* @param {string} steelGrade - Steel grade
|
|
* @param {string} environment - Corrosive environment (optional)
|
|
* @returns {Array<object>} Painting recommendations
|
|
*/
|
|
export function getPaintingRecommendations(steelGrade, environment = null) {
|
|
if (!isLoaded) {
|
|
console.warn('⚠️ Relacionamentos não carregados');
|
|
return [];
|
|
}
|
|
|
|
const normalized = steelGrade.toUpperCase().trim();
|
|
|
|
let results = paintingRelations.filter(rel => {
|
|
const relSteel = rel.Aço?.toUpperCase().trim() || '';
|
|
return relSteel.includes(normalized) || normalized.includes(relSteel);
|
|
});
|
|
|
|
// Filter by environment if specified
|
|
if (environment) {
|
|
const envNorm = environment.toUpperCase();
|
|
results = results.filter(rel => {
|
|
const relEnv = rel.Ambiente_Corrosivo?.toUpperCase() || '';
|
|
return relEnv.includes(envNorm);
|
|
});
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Get complete recommendation (steel + welding + painting)
|
|
* @param {string} steelGrade - Steel grade
|
|
* @param {string} environment - Corrosive environment
|
|
* @returns {object} Complete recommendation
|
|
*/
|
|
export function getCompleteRecommendation(steelGrade, environment = 'C3') {
|
|
const welding = getWeldingRecommendations(steelGrade);
|
|
const painting = getPaintingRecommendations(steelGrade, environment);
|
|
|
|
return {
|
|
steel: steelGrade,
|
|
environment,
|
|
welding: welding[0] || null,
|
|
painting: painting[0] || null,
|
|
hasWelding: welding.length > 0,
|
|
hasPainting: painting.length > 0,
|
|
isComplete: welding.length > 0 && painting.length > 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get all available steel grades
|
|
* @returns {Array<string>} Unique steel grades
|
|
*/
|
|
export function getAvailableSteelGrades() {
|
|
if (!isLoaded) return [];
|
|
|
|
const grades = new Set();
|
|
|
|
weldingRelations.forEach(rel => {
|
|
if (rel.Aço) grades.add(rel.Aço);
|
|
});
|
|
|
|
return Array.from(grades).sort();
|
|
}
|
|
|
|
/**
|
|
* Get available environments for a steel grade
|
|
* @param {string} steelGrade - Steel grade
|
|
* @returns {Array<string>} Available environments
|
|
*/
|
|
export function getAvailableEnvironments(steelGrade) {
|
|
if (!isLoaded) return [];
|
|
|
|
const painting = getPaintingRecommendations(steelGrade);
|
|
const environments = new Set();
|
|
|
|
painting.forEach(rel => {
|
|
if (rel.Ambiente_Corrosivo) {
|
|
environments.add(rel.Ambiente_Corrosivo);
|
|
}
|
|
});
|
|
|
|
return Array.from(environments).sort();
|
|
}
|
|
|
|
/**
|
|
* Format welding recommendation as HTML
|
|
* @param {object} welding - Welding data
|
|
* @returns {string} HTML
|
|
*/
|
|
export function formatWeldingRecommendation(welding) {
|
|
if (!welding) {
|
|
return '<p style="color: var(--color-text-secondary);">Nenhuma recomendação de soldagem disponível</p>';
|
|
}
|
|
|
|
return `
|
|
<div class="recommendation-card" style="background: var(--color-bg-1); padding: 16px; border-radius: 8px; margin-bottom: 16px;">
|
|
<h4 style="margin: 0 0 12px 0; color: var(--color-primary);">🔥 Soldagem Recomendada</h4>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 12px;">
|
|
<div>
|
|
<strong>Processo 1:</strong> ${welding.Processo_Soldagem_1 || '-'}<br>
|
|
<small>Eletrodo: ${welding.Eletrodo_1 || '-'}</small>
|
|
</div>
|
|
<div>
|
|
<strong>Processo 2:</strong> ${welding.Processo_Soldagem_2 || '-'}<br>
|
|
<small>Arame: ${welding.Arame_2 || '-'}</small><br>
|
|
<small>Gás: ${welding.Gás_Proteção || '-'}</small>
|
|
</div>
|
|
<div>
|
|
<strong>Processo 3:</strong> ${welding.Processo_Soldagem_3 || '-'}<br>
|
|
<small>Arame/Fluxo: ${welding.Arame_Fluxo_3 || '-'}</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; padding-top: 12px; border-top: 1px solid var(--color-border);">
|
|
<div>
|
|
<strong>CEV:</strong> ${welding.CEV || '-'}
|
|
</div>
|
|
<div>
|
|
<strong>Pré-aquecimento:</strong> ${welding.Pré_Aquecimento || '-'}
|
|
</div>
|
|
<div>
|
|
<strong>Norma:</strong> ${welding.Norma_Soldagem || '-'}
|
|
</div>
|
|
<div>
|
|
<strong>Ensaios:</strong> ${welding.Ensaios_NDT || '-'}
|
|
</div>
|
|
</div>
|
|
|
|
${welding.Observações ? `
|
|
<div style="margin-top: 12px; padding: 8px; background: var(--color-bg-2); border-radius: 4px; font-size: 13px;">
|
|
💡 <strong>Observações:</strong> ${welding.Observações}
|
|
</div>
|
|
` : ''}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
/**
|
|
* Format painting recommendation as HTML
|
|
* @param {object} painting - Painting data
|
|
* @returns {string} HTML
|
|
*/
|
|
export function formatPaintingRecommendation(painting) {
|
|
if (!painting) {
|
|
return '<p style="color: var(--color-text-secondary);">Nenhuma recomendação de pintura disponível</p>';
|
|
}
|
|
|
|
return `
|
|
<div class="recommendation-card" style="background: var(--color-bg-3); padding: 16px; border-radius: 8px; margin-bottom: 16px;">
|
|
<h4 style="margin: 0 0 12px 0; color: var(--color-primary);">🎨 Pintura Recomendada</h4>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 12px;">
|
|
<div>
|
|
<strong>Ambiente:</strong> ${painting.Ambiente_Corrosivo || '-'}<br>
|
|
<small>Vida útil: ${painting.Vida_Útil_Esperada || '-'}</small>
|
|
</div>
|
|
<div>
|
|
<strong>Preparação:</strong> ${painting.Preparação_Superfície || '-'}<br>
|
|
<small>Rugosidade: ${painting.Perfil_Rugosidade || '-'}</small>
|
|
</div>
|
|
<div>
|
|
<strong>DFT Total:</strong> ${painting.DFT_Total || '-'}<br>
|
|
<small>Custo: ${painting.Custo_Relativo_m2 || '-'}/m²</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 12px;">
|
|
<strong>Sistema de Pintura (3 camadas):</strong>
|
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 8px;">
|
|
<div style="padding: 8px; background: var(--color-surface); border-radius: 4px; text-align: center;">
|
|
<div style="font-size: 11px; color: var(--color-text-secondary);">PRIMER</div>
|
|
<div style="font-weight: bold; margin: 4px 0;">${painting.Primer || '-'}</div>
|
|
<div style="font-size: 12px;">${painting.Tipo_Tinta_Primer || '-'}</div>
|
|
</div>
|
|
<div style="padding: 8px; background: var(--color-surface); border-radius: 4px; text-align: center;">
|
|
<div style="font-size: 11px; color: var(--color-text-secondary);">INTERMEDIÁRIA</div>
|
|
<div style="font-weight: bold; margin: 4px 0;">${painting.Intermediária || '-'}</div>
|
|
<div style="font-size: 12px;">${painting.Tipo_Tinta_Intermediária || '-'}</div>
|
|
</div>
|
|
<div style="padding: 8px; background: var(--color-surface); border-radius: 4px; text-align: center;">
|
|
<div style="font-size: 11px; color: var(--color-text-secondary);">ACABAMENTO</div>
|
|
<div style="font-weight: bold; margin: 4px 0;">${painting.Acabamento || '-'}</div>
|
|
<div style="font-size: 12px;">${painting.Tipo_Tinta_Acabamento || '-'}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; padding-top: 12px; border-top: 1px solid var(--color-border);">
|
|
<div>
|
|
<strong>Norma:</strong> ${painting.Norma_Pintura || '-'}
|
|
</div>
|
|
<div>
|
|
<strong>Ensaios:</strong> ${painting.Ensaios_Pintura || '-'}
|
|
</div>
|
|
</div>
|
|
|
|
${painting.Observações_Pintura ? `
|
|
<div style="margin-top: 12px; padding: 8px; background: var(--color-bg-2); border-radius: 4px; font-size: 13px;">
|
|
💡 <strong>Observações:</strong> ${painting.Observações_Pintura}
|
|
</div>
|
|
` : ''}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Auto-load on import
|
|
if (typeof window !== 'undefined') {
|
|
loadRelationships();
|
|
}
|