mantenimento-app 2.2.2 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +49 -3
- package/backend/calculate-model.js +15 -3
- package/frontend/public/app.js +49 -3
- package/frontend/public/index.html +1 -1
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -385,6 +385,7 @@ const defaultExpenseItems = [
|
|
|
385
385
|
sepCostLossMonthly: "Perdita economica mensile",
|
|
386
386
|
sepCostLossAnnually: "Perdita economica annua",
|
|
387
387
|
sepCostLossSpouse: "Impatto stimato su {spouse}",
|
|
388
|
+
sepCostHousingUtilityAdj: "Adeguamento affitto/utenze (stima minima)",
|
|
388
389
|
sepCostInlineHint: "Duplicazione mensile stimata: {amount}",
|
|
389
390
|
sepCostWarning: "Inserisci le spese mensili in convivenza nel campo sopra per attivare questa analisi.",
|
|
390
391
|
sepCostCurrentTotal: "Totale spese attuali dopo separazione: {amount}",
|
|
@@ -726,6 +727,7 @@ const defaultExpenseItems = [
|
|
|
726
727
|
sepCostLossMonthly: "Monthly economic loss",
|
|
727
728
|
sepCostLossAnnually: "Annual economic loss",
|
|
728
729
|
sepCostLossSpouse: "Estimated impact on {spouse}",
|
|
730
|
+
sepCostHousingUtilityAdj: "Rent/utilities adjustment (minimum estimate)",
|
|
729
731
|
sepCostInlineHint: "Estimated monthly duplication: {amount}",
|
|
730
732
|
sepCostWarning: "Enter the cohabiting monthly expenses above to activate this analysis.",
|
|
731
733
|
sepCostCurrentTotal: "Current total expenses after separation: {amount}",
|
|
@@ -3436,8 +3438,33 @@ const defaultExpenseItems = [
|
|
|
3436
3438
|
|
|
3437
3439
|
// Separation cost analysis (only active when speseConvivenza > 0)
|
|
3438
3440
|
const speseConvivenza = Math.max(0, Number(payload.speseConvivenza || 0));
|
|
3439
|
-
const
|
|
3440
|
-
|
|
3441
|
+
const isHousingUtilityLabel = (rawLabel) => {
|
|
3442
|
+
const label = String(rawLabel || "").toLowerCase();
|
|
3443
|
+
return label.includes("affitto")
|
|
3444
|
+
|| label.includes("utenze")
|
|
3445
|
+
|| label.includes("condominio")
|
|
3446
|
+
|| label.includes("casa")
|
|
3447
|
+
|| label.includes("mutuo");
|
|
3448
|
+
};
|
|
3449
|
+
const sumHousingUtilityBySpouse = (items, spouseKey) => {
|
|
3450
|
+
return (items || []).reduce((acc, amount, idx) => {
|
|
3451
|
+
if (!isHousingUtilityLabel(expenseItems[idx] && expenseItems[idx].label)) return acc;
|
|
3452
|
+
return acc + Number(amount || 0);
|
|
3453
|
+
}, 0);
|
|
3454
|
+
};
|
|
3455
|
+
const housingUtility1 = sumHousingUtilityBySpouse(payload.c1Spese, 1) + quotaMutuoSpese1;
|
|
3456
|
+
const housingUtility2 = sumHousingUtilityBySpouse(payload.c2Spese, 2) + quotaMutuoSpese2;
|
|
3457
|
+
const housingUtilityNonColl = collocatario === 1 ? housingUtility2 : housingUtility1;
|
|
3458
|
+
|
|
3459
|
+
const baseDuplicazione = speseConvivenza > 0 ? (speseTot - speseConvivenza) : null;
|
|
3460
|
+
const separationAdjustmentHousingUtilities = baseDuplicazione !== null && baseDuplicazione <= 0.005
|
|
3461
|
+
? Math.max(0, housingUtilityNonColl)
|
|
3462
|
+
: 0;
|
|
3463
|
+
const speseConvivenzaEffettive = speseConvivenza > 0
|
|
3464
|
+
? Math.max(0, speseConvivenza - separationAdjustmentHousingUtilities)
|
|
3465
|
+
: null;
|
|
3466
|
+
const costoSeparazioneMensile = speseConvivenzaEffettive !== null ? (speseTot - speseConvivenzaEffettive) : null;
|
|
3467
|
+
const nettoInsiemeCombinato = speseConvivenzaEffettive !== null ? (r1 + r2 - speseConvivenzaEffettive) : null;
|
|
3441
3468
|
const nettoSeparatoTotale = post1 + post2;
|
|
3442
3469
|
const perditaMensile = nettoInsiemeCombinato !== null ? nettoInsiemeCombinato - nettoSeparatoTotale : null;
|
|
3443
3470
|
const perditaAnnua = perditaMensile !== null ? perditaMensile * 12 : null;
|
|
@@ -3464,7 +3491,8 @@ const defaultExpenseItems = [
|
|
|
3464
3491
|
compensativeBenefits,
|
|
3465
3492
|
assegnoDa1a2, assegnoDa2a1,
|
|
3466
3493
|
post1, post2,
|
|
3467
|
-
speseConvivenza, costoSeparazioneMensile,
|
|
3494
|
+
speseConvivenza, speseConvivenzaEffettive, costoSeparazioneMensile,
|
|
3495
|
+
separationAdjustmentHousingUtilities,
|
|
3468
3496
|
nettoInsiemeCombinato, nettoSeparatoTotale,
|
|
3469
3497
|
perditaMensile, perditaAnnua,
|
|
3470
3498
|
perditaSpouse1, perditaSpouse2
|
|
@@ -4655,6 +4683,9 @@ const defaultExpenseItems = [
|
|
|
4655
4683
|
</div>
|
|
4656
4684
|
<div class="sep-cost-divider"></div>
|
|
4657
4685
|
<div class="sep-cost-section">
|
|
4686
|
+
${m.separationAdjustmentHousingUtilities > 0
|
|
4687
|
+
? rowHtml(tr("sepCostHousingUtilityAdj"), m.separationAdjustmentHousingUtilities, false)
|
|
4688
|
+
: ""}
|
|
4658
4689
|
${rowHtml(tr("sepCostDuplication"), m.costoSeparazioneMensile, false)}
|
|
4659
4690
|
${rowHtml(tr("sepCostLossMonthly"), m.perditaMensile, true)}
|
|
4660
4691
|
${rowHtml(tr("sepCostLossAnnually"), m.perditaAnnua, true)}
|
|
@@ -4747,6 +4778,21 @@ const defaultExpenseItems = [
|
|
|
4747
4778
|
};
|
|
4748
4779
|
const pdfCalHtml = buildPdfCalendarHtml();
|
|
4749
4780
|
const compBenefits = getCompensativeBenefitRows(m, c1Name, c2Name);
|
|
4781
|
+
const compBenefitsRowsHtml = compBenefits.length
|
|
4782
|
+
? compBenefits.map((row) => `<tr><td>${escapeHtml(row.label)}</td><td class="num">${eur(row.amount)}</td></tr>`).join("")
|
|
4783
|
+
: `<tr><td colspan="2">${tr("pdfCompBenefitsNone")}</td></tr>`;
|
|
4784
|
+
const primaryHomeAssignedLabel = m.primaCasaAssegnataA === "1"
|
|
4785
|
+
? c1NameEsc
|
|
4786
|
+
: m.primaCasaAssegnataA === "2"
|
|
4787
|
+
? c2NameEsc
|
|
4788
|
+
: tr("pdfPrimaryHomeNotDeclared");
|
|
4789
|
+
const primaryHomeSummaryRows = m.primaCasaMutuoEnabled
|
|
4790
|
+
? `
|
|
4791
|
+
<tr><td>${tr("pdfPrimaryHomeAssignedTo")}</td><td>${primaryHomeAssignedLabel}</td></tr>
|
|
4792
|
+
<tr><td>${tr("pdfPrimaryHomeMonthlyAmount")}</td><td>${eur(m.primaCasaMutuoImporto || 0)}</td></tr>
|
|
4793
|
+
<tr><td>${tr("pdfPrimaryHomeSplit")}</td><td>${c1NameEsc} ${(m.primaCasaMutuoPerc1 || 0).toFixed(0)}% · ${c2NameEsc} ${(m.primaCasaMutuoPerc2 || 0).toFixed(0)}%</td></tr>
|
|
4794
|
+
<tr><td>${tr("pdfPrimaryHomeAppliedOnlyColl")}</td><td>${m.primaCasaConsidered ? "OK" : tr("pdfPrimaryHomeNotDeclared")}</td></tr>`
|
|
4795
|
+
: `<tr><td>${tr("pdfPrimaryHomeMortgage")}</td><td>${tr("pdfPrimaryHomeNotDeclared")}</td></tr>`;
|
|
4750
4796
|
|
|
4751
4797
|
let explainResultHtml = `<div class="pdf-explain-result-empty">${tr("calcNoTransferSuggested")}</div>`;
|
|
4752
4798
|
if (m.assegnoDa1a2 > 0.005) {
|
|
@@ -127,8 +127,19 @@ function calculateModel(input) {
|
|
|
127
127
|
|
|
128
128
|
// Separation cost analysis (only active when speseConvivenza > 0)
|
|
129
129
|
const speseConvivenza = Math.max(0, toNumber(input.speseConvivenza));
|
|
130
|
-
const
|
|
131
|
-
const
|
|
130
|
+
const housingIdx = new Set([0, 1, 2, 7]); // Affitto, casa/valore locativo, utenze, condominio
|
|
131
|
+
const housingUtility1 = c1Spese.reduce((acc, n, idx) => acc + (housingIdx.has(idx) ? toNumber(n) : 0), 0) + quotaMutuoSpese1;
|
|
132
|
+
const housingUtility2 = c2Spese.reduce((acc, n, idx) => acc + (housingIdx.has(idx) ? toNumber(n) : 0), 0) + quotaMutuoSpese2;
|
|
133
|
+
const housingUtilityNonColl = collocatario === 1 ? housingUtility2 : housingUtility1;
|
|
134
|
+
const baseDuplicazione = speseConvivenza > 0 ? (speseTot - speseConvivenza) : null;
|
|
135
|
+
const separationAdjustmentHousingUtilities = baseDuplicazione !== null && baseDuplicazione <= 0.005
|
|
136
|
+
? Math.max(0, housingUtilityNonColl)
|
|
137
|
+
: 0;
|
|
138
|
+
const speseConvivenzaEffettive = speseConvivenza > 0
|
|
139
|
+
? Math.max(0, speseConvivenza - separationAdjustmentHousingUtilities)
|
|
140
|
+
: null;
|
|
141
|
+
const costoSeparazioneMensile = speseConvivenzaEffettive !== null ? (speseTot - speseConvivenzaEffettive) : null;
|
|
142
|
+
const nettoInsiemeCombinato = speseConvivenzaEffettive !== null ? (r1 + r2 - speseConvivenzaEffettive) : null;
|
|
132
143
|
const nettoSeparatoTotale = post1 + post2;
|
|
133
144
|
const perditaMensile = nettoInsiemeCombinato !== null ? nettoInsiemeCombinato - nettoSeparatoTotale : null;
|
|
134
145
|
const perditaAnnua = perditaMensile !== null ? perditaMensile * 12 : null;
|
|
@@ -156,7 +167,8 @@ function calculateModel(input) {
|
|
|
156
167
|
compensativeBenefits,
|
|
157
168
|
assegnoDa1a2, assegnoDa2a1,
|
|
158
169
|
post1, post2,
|
|
159
|
-
speseConvivenza, costoSeparazioneMensile,
|
|
170
|
+
speseConvivenza, speseConvivenzaEffettive, costoSeparazioneMensile,
|
|
171
|
+
separationAdjustmentHousingUtilities,
|
|
160
172
|
nettoInsiemeCombinato, nettoSeparatoTotale,
|
|
161
173
|
perditaMensile, perditaAnnua,
|
|
162
174
|
perditaSpouse1, perditaSpouse2
|
package/frontend/public/app.js
CHANGED
|
@@ -385,6 +385,7 @@ const defaultExpenseItems = [
|
|
|
385
385
|
sepCostLossMonthly: "Perdita economica mensile",
|
|
386
386
|
sepCostLossAnnually: "Perdita economica annua",
|
|
387
387
|
sepCostLossSpouse: "Impatto stimato su {spouse}",
|
|
388
|
+
sepCostHousingUtilityAdj: "Adeguamento affitto/utenze (stima minima)",
|
|
388
389
|
sepCostInlineHint: "Duplicazione mensile stimata: {amount}",
|
|
389
390
|
sepCostWarning: "Inserisci le spese mensili in convivenza nel campo sopra per attivare questa analisi.",
|
|
390
391
|
sepCostCurrentTotal: "Totale spese attuali dopo separazione: {amount}",
|
|
@@ -726,6 +727,7 @@ const defaultExpenseItems = [
|
|
|
726
727
|
sepCostLossMonthly: "Monthly economic loss",
|
|
727
728
|
sepCostLossAnnually: "Annual economic loss",
|
|
728
729
|
sepCostLossSpouse: "Estimated impact on {spouse}",
|
|
730
|
+
sepCostHousingUtilityAdj: "Rent/utilities adjustment (minimum estimate)",
|
|
729
731
|
sepCostInlineHint: "Estimated monthly duplication: {amount}",
|
|
730
732
|
sepCostWarning: "Enter the cohabiting monthly expenses above to activate this analysis.",
|
|
731
733
|
sepCostCurrentTotal: "Current total expenses after separation: {amount}",
|
|
@@ -3436,8 +3438,33 @@ const defaultExpenseItems = [
|
|
|
3436
3438
|
|
|
3437
3439
|
// Separation cost analysis (only active when speseConvivenza > 0)
|
|
3438
3440
|
const speseConvivenza = Math.max(0, Number(payload.speseConvivenza || 0));
|
|
3439
|
-
const
|
|
3440
|
-
|
|
3441
|
+
const isHousingUtilityLabel = (rawLabel) => {
|
|
3442
|
+
const label = String(rawLabel || "").toLowerCase();
|
|
3443
|
+
return label.includes("affitto")
|
|
3444
|
+
|| label.includes("utenze")
|
|
3445
|
+
|| label.includes("condominio")
|
|
3446
|
+
|| label.includes("casa")
|
|
3447
|
+
|| label.includes("mutuo");
|
|
3448
|
+
};
|
|
3449
|
+
const sumHousingUtilityBySpouse = (items, spouseKey) => {
|
|
3450
|
+
return (items || []).reduce((acc, amount, idx) => {
|
|
3451
|
+
if (!isHousingUtilityLabel(expenseItems[idx] && expenseItems[idx].label)) return acc;
|
|
3452
|
+
return acc + Number(amount || 0);
|
|
3453
|
+
}, 0);
|
|
3454
|
+
};
|
|
3455
|
+
const housingUtility1 = sumHousingUtilityBySpouse(payload.c1Spese, 1) + quotaMutuoSpese1;
|
|
3456
|
+
const housingUtility2 = sumHousingUtilityBySpouse(payload.c2Spese, 2) + quotaMutuoSpese2;
|
|
3457
|
+
const housingUtilityNonColl = collocatario === 1 ? housingUtility2 : housingUtility1;
|
|
3458
|
+
|
|
3459
|
+
const baseDuplicazione = speseConvivenza > 0 ? (speseTot - speseConvivenza) : null;
|
|
3460
|
+
const separationAdjustmentHousingUtilities = baseDuplicazione !== null && baseDuplicazione <= 0.005
|
|
3461
|
+
? Math.max(0, housingUtilityNonColl)
|
|
3462
|
+
: 0;
|
|
3463
|
+
const speseConvivenzaEffettive = speseConvivenza > 0
|
|
3464
|
+
? Math.max(0, speseConvivenza - separationAdjustmentHousingUtilities)
|
|
3465
|
+
: null;
|
|
3466
|
+
const costoSeparazioneMensile = speseConvivenzaEffettive !== null ? (speseTot - speseConvivenzaEffettive) : null;
|
|
3467
|
+
const nettoInsiemeCombinato = speseConvivenzaEffettive !== null ? (r1 + r2 - speseConvivenzaEffettive) : null;
|
|
3441
3468
|
const nettoSeparatoTotale = post1 + post2;
|
|
3442
3469
|
const perditaMensile = nettoInsiemeCombinato !== null ? nettoInsiemeCombinato - nettoSeparatoTotale : null;
|
|
3443
3470
|
const perditaAnnua = perditaMensile !== null ? perditaMensile * 12 : null;
|
|
@@ -3464,7 +3491,8 @@ const defaultExpenseItems = [
|
|
|
3464
3491
|
compensativeBenefits,
|
|
3465
3492
|
assegnoDa1a2, assegnoDa2a1,
|
|
3466
3493
|
post1, post2,
|
|
3467
|
-
speseConvivenza, costoSeparazioneMensile,
|
|
3494
|
+
speseConvivenza, speseConvivenzaEffettive, costoSeparazioneMensile,
|
|
3495
|
+
separationAdjustmentHousingUtilities,
|
|
3468
3496
|
nettoInsiemeCombinato, nettoSeparatoTotale,
|
|
3469
3497
|
perditaMensile, perditaAnnua,
|
|
3470
3498
|
perditaSpouse1, perditaSpouse2
|
|
@@ -4655,6 +4683,9 @@ const defaultExpenseItems = [
|
|
|
4655
4683
|
</div>
|
|
4656
4684
|
<div class="sep-cost-divider"></div>
|
|
4657
4685
|
<div class="sep-cost-section">
|
|
4686
|
+
${m.separationAdjustmentHousingUtilities > 0
|
|
4687
|
+
? rowHtml(tr("sepCostHousingUtilityAdj"), m.separationAdjustmentHousingUtilities, false)
|
|
4688
|
+
: ""}
|
|
4658
4689
|
${rowHtml(tr("sepCostDuplication"), m.costoSeparazioneMensile, false)}
|
|
4659
4690
|
${rowHtml(tr("sepCostLossMonthly"), m.perditaMensile, true)}
|
|
4660
4691
|
${rowHtml(tr("sepCostLossAnnually"), m.perditaAnnua, true)}
|
|
@@ -4747,6 +4778,21 @@ const defaultExpenseItems = [
|
|
|
4747
4778
|
};
|
|
4748
4779
|
const pdfCalHtml = buildPdfCalendarHtml();
|
|
4749
4780
|
const compBenefits = getCompensativeBenefitRows(m, c1Name, c2Name);
|
|
4781
|
+
const compBenefitsRowsHtml = compBenefits.length
|
|
4782
|
+
? compBenefits.map((row) => `<tr><td>${escapeHtml(row.label)}</td><td class="num">${eur(row.amount)}</td></tr>`).join("")
|
|
4783
|
+
: `<tr><td colspan="2">${tr("pdfCompBenefitsNone")}</td></tr>`;
|
|
4784
|
+
const primaryHomeAssignedLabel = m.primaCasaAssegnataA === "1"
|
|
4785
|
+
? c1NameEsc
|
|
4786
|
+
: m.primaCasaAssegnataA === "2"
|
|
4787
|
+
? c2NameEsc
|
|
4788
|
+
: tr("pdfPrimaryHomeNotDeclared");
|
|
4789
|
+
const primaryHomeSummaryRows = m.primaCasaMutuoEnabled
|
|
4790
|
+
? `
|
|
4791
|
+
<tr><td>${tr("pdfPrimaryHomeAssignedTo")}</td><td>${primaryHomeAssignedLabel}</td></tr>
|
|
4792
|
+
<tr><td>${tr("pdfPrimaryHomeMonthlyAmount")}</td><td>${eur(m.primaCasaMutuoImporto || 0)}</td></tr>
|
|
4793
|
+
<tr><td>${tr("pdfPrimaryHomeSplit")}</td><td>${c1NameEsc} ${(m.primaCasaMutuoPerc1 || 0).toFixed(0)}% · ${c2NameEsc} ${(m.primaCasaMutuoPerc2 || 0).toFixed(0)}%</td></tr>
|
|
4794
|
+
<tr><td>${tr("pdfPrimaryHomeAppliedOnlyColl")}</td><td>${m.primaCasaConsidered ? "OK" : tr("pdfPrimaryHomeNotDeclared")}</td></tr>`
|
|
4795
|
+
: `<tr><td>${tr("pdfPrimaryHomeMortgage")}</td><td>${tr("pdfPrimaryHomeNotDeclared")}</td></tr>`;
|
|
4750
4796
|
|
|
4751
4797
|
let explainResultHtml = `<div class="pdf-explain-result-empty">${tr("calcNoTransferSuggested")}</div>`;
|
|
4752
4798
|
if (m.assegnoDa1a2 > 0.005) {
|