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 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 costoSeparazioneMensile = speseConvivenza > 0 ? speseTot - speseConvivenza : null;
3440
- const nettoInsiemeCombinato = speseConvivenza > 0 ? (r1 + r2 - speseConvivenza) : null;
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 costoSeparazioneMensile = speseConvivenza > 0 ? speseTot - speseConvivenza : null;
131
- const nettoInsiemeCombinato = speseConvivenza > 0 ? (r1 + r2 - speseConvivenza) : null;
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
@@ -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 costoSeparazioneMensile = speseConvivenza > 0 ? speseTot - speseConvivenza : null;
3440
- const nettoInsiemeCombinato = speseConvivenza > 0 ? (r1 + r2 - speseConvivenza) : null;
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) {
@@ -599,7 +599,7 @@
599
599
  <script src="supabase.min.js"></script>
600
600
  <script src="fabric.min.js"></script>
601
601
  <script src="html2pdf.bundle.min.js"></script>
602
- <script src="app.js?v=2.2.2"></script>
602
+ <script src="app.js?v=2.2.4"></script>
603
603
  </body>
604
604
  </html>
605
605
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mantenimento-app",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "Frontend + backend architecture for the mantenimento calculator",
5
5
  "type": "commonjs",
6
6
  "main": "backend/calculate-model.js",