// konfigurator-spara.js
// Visar: spara
// === GENERISK SPARA/AFFÄR FÖR NYA KONFIGURATORER ===
async function saveCfgQuote(category) {
const configData = collectCfgData(category);
const payload = {
category: category,
config_data: JSON.stringify(configData),
total_price: configData.total,
panel_name: configData.description || category,
panel_count: 0,
status: 'utkast',
created_by: gStaffId || null,
customer_name: pendingKalkylCustomer?.name || null,
customer_address: pendingKalkylCustomer?.address || null,
customer_email: pendingKalkylCustomer?.email || null,
customer_phone: pendingKalkylCustomer?.phone || null,
customer_personnummer: (pendingKalkylCustomer?.owner1 && pendingKalkylCustomer.owner1.pnr) || null,
owner_count: pendingKalkylCustomer?.ownerType === '2' ? 2 : (pendingKalkylCustomer?.ownerType === 'brf' ? 0 : 1),
prospect_data: pendingKalkylCustomer?.solarData || null
};
if(currentQuoteId) payload.id = currentQuoteId;
try {
const res = await fetch('/api/quotes.php', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
const data = await res.json();
if(data.error){alert('Fel: '+data.error);return;}
if(data.id) currentQuoteId = data.id;
var pIdx2 = (pendingKalkylCustomer||{}).prospectIdx;
if(pIdx2 >= 0 && faltProspects[pIdx2]){
if(faltProspects[pIdx2].status !== 'offert') faltProspects[pIdx2].status = 'kalkyl';
if(!faltProspects[pIdx2].quoteIds) faltProspects[pIdx2].quoteIds = faltProspects[pIdx2].quoteId ? [faltProspects[pIdx2].quoteId] : [];
if(!faltProspects[pIdx2].quoteIds.includes(currentQuoteId)) faltProspects[pIdx2].quoteIds.push(currentQuoteId);
faltProspects[pIdx2].quoteId = currentQuoteId;
localStorage.setItem('faltProspects', JSON.stringify(faltProspects));
renderFaltMarkers(); renderFaltList(); updateFaltStats(); renderLeadsTable();
}
alert('Kalkyl sparad!');
} catch(e){alert('Fel: '+e.message);}
}
function goToCfgAffar(category){alert('Affär-vy för '+category+' — kommer snart');}
function collectCfgData(cat) {
switch(cat) {
case 'batteri': {
const brand=BAT_BRANDS.find(b=>b.id===_batBrand);
return {description:(brand?brand.name:'')+' '+(_batSize||'')+'kWh',total:_batSizePrice+Object.values(_batAddons).reduce((s,v)=>s+v,0),battery_brand:_batBrand,battery_kwh:_batSize,battery_price:_batSizePrice,addons:_batAddons,deduction:_batDeduction,owners:_batOwners};
}
case 'laddbox': {
const ch=LB_CHARGERS.find(c=>c.id===_lbSelected);
return {description:ch?ch.brand+' '+ch.model:'',total:_lbPrice,charger_id:_lbSelected,charger_price:_lbPrice,deduction:_lbDeduction,owners:_lbOwners};
}
case 'taktvatt': {
const area=parseInt(document.getElementById('ttArea')?.value)||0;
const typ=TT_TYPES.find(t=>t.id===_ttSelectedType);
return {description:(typ?typ.name:'')+' '+area+'m²',total:area*_ttPricePerSqm,type_id:_ttSelectedType,price_sqm:_ttPricePerSqm,area:area,deduction:_ttDeduction,owners:_ttOwners};
}
case 'varmepump': {
const p=VP_PUMPS.find(x=>x.id===_vpSelected);
return {description:p?p.brand+' '+p.model:'',total:_vpPrice+_vpInstall,pump_id:_vpSelected,pump_price:_vpPrice,install_price:_vpInstall,deduction:_vpDeduction,owners:_vpOwners};
}
case 'tak':
return {description:_takYtor.length+' takyta(or)',total:0,ytor:_takYtor,tillbehor:_takTillbehor,deduction:_takDeduction,owners:_takOwners};
case 'isolering': {
const area=parseInt(document.getElementById('isoArea')?.value)||0;
const price=parseInt(document.getElementById('isoPrice')?.value)||0;
return {description:(document.getElementById('isoType')?.value||'Isolering')+' '+area+'m²',total:price,area:area,type:document.getElementById('isoType')?.value,thickness:parseInt(document.getElementById('isoThickness')?.value)||0,price:price,deduction:_isoDeduction,owners:_isoOwners};
}
default: return {description:cat,total:0};
}
}
function closePoForm() {
var ov = document.getElementById('poFormOverlay');
if(ov) ov.remove();
loadInkopDeals();
}
async function saveMeasurements(silent) {
// Always save measurements to deal_measurements
try {
var r = await fetch('api/suppliers.php?action=save_measurements', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({
deal_id: _poFormDealId,
measurements: _poFormPositions
})
});
var res = await r.json();
if(!silent) {
if(res.success) alert('Inmätning sparad! ('+res.saved+' positioner)');
else alert(res.error||'Fel vid sparning');
}
return res.success;
} catch(e) {
if(!silent) alert('Fel: '+e.message);
return false;
}
}
async function savePoForm() {
var suppId = document.getElementById('poLeverantor').value;
if(!suppId) { alert('Välj leverantör under Leverantörsorder'); return; }
// Save measurements first
await saveMeasurements(true);
// Collect positions with data
var items = [];
_poFormPositions.forEach(function(p){
if(!p.product || !p.width || !p.height) return;
items.push({
article_name: p.product + ' ' + p.width + 'x' + p.height,
category: p.product,
quantity: parseInt(p.pcs)||1,
unit: 'st',
width: parseInt(p.width)||null,
height: parseInt(p.height)||null,
notes: [p.model, p.color_in, p.color_out, p.glass, p.profile].filter(Boolean).join(', ')
});
});
// Collect Hedlunds items
_poHedlundsRows.forEach(function(r){
if(!r.article || !r.quantity) return;
items.push({
article_name: r.article,
category: r.category,
quantity: parseInt(r.quantity)||1,
unit: 'st',
length: parseInt(r.length)||null,
notes: r.extra||null,
unit_price: r.price_per_m ? (parseInt(r.length||0)/1000 * parseFloat(r.price_per_m)) : 0
});
});
var notes = [
'Kund: ' + (document.getElementById('poKundNamn').value||''),
'Adress: ' + (document.getElementById('poKundAdress').value||''),
'Montering: ' + (document.getElementById('poKundMontering').value||''),
'Byggnadsår: ' + (document.getElementById('poKundByggnar').value||''),
document.getElementById('poKontrollNotes').value||''
].filter(Boolean).join('\n');
try {
var r = await fetch('api/suppliers.php?action=create_order', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({
deal_id: _poFormDealId,
supplier_id: parseInt(suppId),
order_date: document.getElementById('poOrderDatum').value,
expected_delivery: document.getElementById('poLevDatum').value||null,
notes: notes,
status: 'draft',
items: items
})
});
var res = await r.json();
if(res.success) {
closePoForm();
showOrderDetail(res.id);
} else { alert(res.error||'Fel'); }
} catch(e) { alert('Fel: '+e.message); }
}