Files
kreios/src/js/price_calculator.js
T
carmine.savino 1e352eb2ef feat: Implement price list management and import functionality
- Added ListinoRelationManager for managing price lists associated with models.
- Introduced ImportaListiniAction for importing price lists from Excel files.
- Created ListinoPrezzo model to represent price entries in the database.
- Developed ListinoExcelParser for parsing Excel files containing price lists.
- Implemented ListinoImporter to handle the import logic and associations.
- Added migration for creating listino_prezzi table and converting measures to mm.
- Updated frontend logic to handle new price list features and validations.
- Enhanced tests for price list import and conversion functionalities.
2026-10-19 16:51:24 +02:00

126 lines
3.7 KiB
JavaScript

let listini = null;
const toPercentuale = (valore) => {
const perc = parseFloat(valore);
return isNaN(perc) ? 0 : perc / 100;
};
const toPrezzo = (valore) => {
const prezzo = parseFloat(valore);
return isNaN(prezzo) ? 0 : prezzo;
};
const PriceCalculator = {
init: async (data) => {
listini = data;
},
getMinSize: () => {
const firstSize = listini.misure.find(item => item.prezzo !== 0);
return firstSize;
},
// Misure in mm: entro min/max del listino si usa la prima misura >= a quella
// richiesta (le griglie non sono sempre a passo regolare, es. traslanti da 1450 mm).
getGridPrice: (width, height) => {
const larghezza = PriceCalculator.misuraListino('larghezza', width);
const altezza = PriceCalculator.misuraListino('altezza', height);
if (larghezza == null || altezza == null) return -1;
const misure = listini.misure.find(el => el.altezza == altezza && el.larghezza == larghezza);
if(misure == null) return -1;
return misure.prezzo;
},
misuraListino: (campo, valore) => {
const v = parseFloat(valore);
if (isNaN(v)) return null;
const misure = [...new Set(listini.misure.map(el => el[campo]))].sort((a, b) => a - b);
// Min/max del listino vincolanti: fuori range la misura non è disponibile.
if (!misure.length || v < misure[0]) return null;
return misure.find(m => m >= v) ?? null;
},
getConfigurationPrice: (data) => {
let prezzo_finale = data.prezzo_base;
let percentuale_finiture = 0;
let prezzo_accessori = 0;
let percentuale_vetro = 0;
let percentuale_accessori = 0;
const config = {};
if(data.finitura && data.override_supplemento_finitura !== true){
let supplemento = (listini.finiture ?? []).find((el) => el.finitura === data.finitura);
config.tipo_finitura = supplemento;
percentuale_finiture = toPercentuale(supplemento?.percentuale);
}
if(data.cerniere_scomparsa != null){
let supplemento = listini.cerniere.find((el) => {
if(el.valore == data.cerniere_scomparsa)
return el;
});
config.cerniere_scomparsa = supplemento;
prezzo_accessori += toPrezzo(supplemento?.prezzo);
}
if(data.altezza_maniglia != null){
let supplemento = listini.altezza_maniglia.find((el) => {
if(el.valore == data.altezza_maniglia)
return el;
});
config.altezza_maniglia = supplemento;
prezzo_accessori += toPrezzo(supplemento?.prezzo);
}
if(data.azionamento != null){
let supplemento = listini.azionamento.find((el) => {
if(el.valore == data.azionamento)
return el;
});
config.azionamento = supplemento;
prezzo_accessori += toPrezzo(supplemento?.prezzo);
}
if(data.vetro != null){
let vetro = listini.vetri.find((el) => {
if(el.id == data.vetro)
return el;
});
config.vetro = vetro;
percentuale_vetro = toPercentuale(vetro?.percentuale);
}
prezzo_finale = (prezzo_finale * (1 + percentuale_finiture+percentuale_vetro+data.percentuale_accessori)) + prezzo_accessori;
// IVA disabilitata: i prezzi sono IVA esclusa
// prezzo_finale += prezzo_finale * 22 / 100;
return {
prezzo: prezzo_finale,
configurazione: config
}
}
}
export default PriceCalculator;