214 lines
5.3 KiB
JavaScript
214 lines
5.3 KiB
JavaScript
/**
|
|
* Hent monteringsopgaver til tilbud
|
|
* Simple query functions til at hente installation data
|
|
*/
|
|
|
|
const mysql = require('mysql2/promise');
|
|
|
|
// Database config
|
|
const dbConfig = {
|
|
host: 'localhost',
|
|
user: 'tilbudgivern_service',
|
|
password: process.env.DB_PASSWORD,
|
|
database: 'tilbudgivern',
|
|
charset: 'utf8mb4'
|
|
};
|
|
|
|
/**
|
|
* Hent monteringsopgave for et materiale
|
|
*/
|
|
async function getInstallationTask(productName, quantity = 1) {
|
|
const connection = await mysql.createConnection(dbConfig);
|
|
|
|
try {
|
|
const [rows] = await connection.execute(`
|
|
SELECT
|
|
product_name,
|
|
manufacturer,
|
|
time_estimate_per_unit,
|
|
time_unit,
|
|
skill_level,
|
|
installation_steps,
|
|
key_points,
|
|
weather_conditions,
|
|
required_tools,
|
|
safety_requirements
|
|
FROM installation_manuals
|
|
WHERE product_name LIKE ?
|
|
LIMIT 1
|
|
`, [`%${productName}%`]);
|
|
|
|
if (rows.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
const data = rows[0];
|
|
|
|
// Parse JSON fields
|
|
const steps = JSON.parse(data.installation_steps);
|
|
const keyPoints = JSON.parse(data.key_points);
|
|
const tools = JSON.parse(data.required_tools);
|
|
const safety = JSON.parse(data.safety_requirements);
|
|
|
|
// Beregn tid
|
|
const totalHours = data.time_estimate_per_unit * quantity;
|
|
const workDays = Math.ceil(totalHours / 8);
|
|
|
|
// Formater som opgavebeskrivelse
|
|
return {
|
|
title: `Montering af ${data.product_name}`,
|
|
product: data.product_name,
|
|
manufacturer: data.manufacturer,
|
|
quantity: quantity,
|
|
unit: data.time_unit === 'per_sqm' ? 'm²' : 'stk',
|
|
|
|
// Tidsestimering
|
|
time: {
|
|
per_unit: data.time_estimate_per_unit,
|
|
total_hours: totalHours,
|
|
work_days: workDays
|
|
},
|
|
|
|
// Sværhedsgrad
|
|
difficulty: data.skill_level,
|
|
difficulty_label: {
|
|
'let': 'Let ⭐',
|
|
'medium': 'Medium ⭐⭐',
|
|
'svær': 'Svær ⭐⭐⭐'
|
|
}[data.skill_level],
|
|
|
|
// Monteringstrin (bruges som opgavebeskrivelse)
|
|
steps: steps,
|
|
|
|
// Vigtige punkter
|
|
key_points: keyPoints,
|
|
|
|
// Vejrforhold
|
|
weather: data.weather_conditions,
|
|
|
|
// Værktøj
|
|
tools: tools,
|
|
|
|
// Sikkerhed
|
|
safety: safety,
|
|
|
|
// Formatteret beskrivelse til tilbud PDF
|
|
formatted_description: formatTaskDescription(
|
|
data.product_name,
|
|
steps,
|
|
keyPoints,
|
|
totalHours,
|
|
workDays,
|
|
data.skill_level,
|
|
data.weather_conditions
|
|
)
|
|
};
|
|
|
|
} finally {
|
|
await connection.end();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formater opgavebeskrivelse til tilbud
|
|
*/
|
|
function formatTaskDescription(product, steps, keyPoints, hours, days, difficulty, weather) {
|
|
let desc = `MONTERING AF ${product.toUpperCase()}\n\n`;
|
|
|
|
desc += `Estimeret tid: ${hours.toFixed(1)} timer (ca. ${days} arbejdsdag${days > 1 ? 'e' : ''})\n`;
|
|
desc += `Sværhedsgrad: ${difficulty}\n\n`;
|
|
|
|
desc += `MONTERINGSTRIN:\n`;
|
|
steps.forEach((step, i) => {
|
|
desc += `${i + 1}. ${step}\n`;
|
|
});
|
|
|
|
desc += `\nVIGTIGE PUNKTER:\n`;
|
|
keyPoints.forEach(point => {
|
|
desc += `• ${point}\n`;
|
|
});
|
|
|
|
if (weather) {
|
|
desc += `\nVEJRFORHOLD:\n${weather}\n`;
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
|
|
/**
|
|
* Hent opgaver for flere materialer (til smart package)
|
|
*/
|
|
async function getInstallationTasksForMaterials(materials) {
|
|
const tasks = [];
|
|
|
|
for (const material of materials) {
|
|
const task = await getInstallationTask(
|
|
material.product_name || material.name,
|
|
material.quantity || 1
|
|
);
|
|
|
|
if (task) {
|
|
tasks.push(task);
|
|
}
|
|
}
|
|
|
|
return tasks;
|
|
}
|
|
|
|
/**
|
|
* Beregn total monteringstid for tilbud
|
|
*/
|
|
async function calculateTotalInstallationTime(materials) {
|
|
const tasks = await getInstallationTasksForMaterials(materials);
|
|
|
|
const totalHours = tasks.reduce((sum, task) => sum + task.time.total_hours, 0);
|
|
const totalDays = Math.ceil(totalHours / 8);
|
|
|
|
return {
|
|
total_hours: totalHours,
|
|
total_days: totalDays,
|
|
tasks: tasks.map(t => ({
|
|
product: t.product,
|
|
quantity: t.quantity,
|
|
hours: t.time.total_hours
|
|
}))
|
|
};
|
|
}
|
|
|
|
// CLI test
|
|
if (require.main === module) {
|
|
(async () => {
|
|
console.log('🧪 Testing Installation Tasks Query\n');
|
|
|
|
// Test: Hent opgave for bølgeplader
|
|
const task = await getInstallationTask('Montagevejledning', 50);
|
|
|
|
if (task) {
|
|
console.log('✅ Found installation task:\n');
|
|
console.log(`Produkt: ${task.product}`);
|
|
console.log(`Mængde: ${task.quantity} ${task.unit}`);
|
|
console.log(`Tid: ${task.time.total_hours} timer (${task.time.work_days} dage)`);
|
|
console.log(`Sværhedsgrad: ${task.difficulty_label}`);
|
|
console.log(`\nAntal monteringstrin: ${task.steps.length}`);
|
|
console.log(`\nFørste 3 trin:`);
|
|
task.steps.slice(0, 3).forEach((step, i) => {
|
|
console.log(` ${i + 1}. ${step}`);
|
|
});
|
|
|
|
console.log(`\n${'='.repeat(70)}`);
|
|
console.log('FORMATTERET OPGAVEBESKRIVELSE TIL TILBUD:');
|
|
console.log('='.repeat(70));
|
|
console.log(task.formatted_description);
|
|
|
|
} else {
|
|
console.log('❌ No task found');
|
|
}
|
|
})();
|
|
}
|
|
|
|
module.exports = {
|
|
getInstallationTask,
|
|
getInstallationTasksForMaterials,
|
|
calculateTotalInstallationTime
|
|
};
|