fix: Improve bank/cash register display and exports

- Truncate explicatia field to 100 characters in table, Excel, and PDF exports
- Fix summary stats to separate opening balance from transactions:
  - Show Sold Precedent (from rows with null date)
  - Show Încasări and Plăți (only from actual transactions)
  - Show Sold Final (calculated correctly)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-08 17:49:24 +02:00
parent 06066f1702
commit 3c0ab51f87
2 changed files with 70 additions and 24 deletions

View File

@@ -477,6 +477,13 @@ export const exportBankCashRegisterPDF = (data, header, filename) => {
.replace(/[ț]/gi, (m) => (m === m.toLowerCase() ? "t" : "T")); .replace(/[ț]/gi, (m) => (m === m.toLowerCase() ? "t" : "T"));
}; };
// Truncate text helper (limit explicatia to 100 chars)
const truncateText = (text, maxLength = 100) => {
if (!text) return "";
if (text.length <= maxLength) return text;
return text.substring(0, maxLength) + "...";
};
// Group data by bank account (bancasa) // Group data by bank account (bancasa)
const groupedByBank = {}; const groupedByBank = {};
const initialBalances = {}; const initialBalances = {};
@@ -696,7 +703,7 @@ export const exportBankCashRegisterPDF = (data, header, filename) => {
tableRows.push([ tableRows.push([
dateFormatted, dateFormatted,
row.nract || "", row.nract || "",
removeDiacritics(row.explicatia || row.nume || ""), truncateText(removeDiacritics(row.explicatia || row.nume || ""), 100),
formatNumberForPDF(incasari), formatNumberForPDF(incasari),
formatNumberForPDF(plati), formatNumberForPDF(plati),
formatNumberForPDF(row.sold), formatNumberForPDF(row.sold),

View File

@@ -141,23 +141,31 @@
<!-- Summary Stats - Compact, right aligned --> <!-- Summary Stats - Compact, right aligned -->
<div v-if="companyStore.selectedCompany" class="summary-stats-inline"> <div v-if="companyStore.selectedCompany" class="summary-stats-inline">
<div class="stat-item"> <div class="stat-item">
<span class="stat-label">Total Încasări:</span> <span class="stat-label">Sold Precedent:</span>
<span class="stat-value incasari">{{
formatCurrency(treasuryStore.totals.total_incasari)
}}</span>
</div>
<div class="stat-item">
<span class="stat-label">Total Plăți:</span>
<span class="stat-value plati">{{
formatCurrency(treasuryStore.totals.total_plati)
}}</span>
</div>
<div class="stat-item">
<span class="stat-label">Total Sold:</span>
<span <span
class="stat-value" class="stat-value"
:class="totalSold >= 0 ? 'incasari' : 'plati'" :class="computedTotals.soldPrecedent >= 0 ? 'incasari' : 'plati'"
>{{ formatCurrency(totalSold) }}</span >{{ formatCurrency(computedTotals.soldPrecedent) }}</span
>
</div>
<div class="stat-item">
<span class="stat-label">Încasări:</span>
<span class="stat-value incasari">{{
formatCurrency(computedTotals.incasari)
}}</span>
</div>
<div class="stat-item">
<span class="stat-label">Plăți:</span>
<span class="stat-value plati">{{
formatCurrency(computedTotals.plati)
}}</span>
</div>
<div class="stat-item">
<span class="stat-label">Sold Final:</span>
<span
class="stat-value"
:class="computedTotals.soldFinal >= 0 ? 'incasari' : 'plati'"
>{{ formatCurrency(computedTotals.soldFinal) }}</span
> >
</div> </div>
</div> </div>
@@ -262,7 +270,11 @@
field="explicatia" field="explicatia"
header="Explicație" header="Explicație"
class="col-explicatie" class="col-explicatie"
/> >
<template #body="slotProps">
{{ truncateText(slotProps.data.explicatia, 100) }}
</template>
</Column>
</DataTable> </DataTable>
</template> </template>
</Card> </Card>
@@ -330,12 +342,39 @@ const formatDate = (dateString) => {
return format(new Date(dateString), "dd.MM.yyyy"); return format(new Date(dateString), "dd.MM.yyyy");
}; };
// Computed total sold (incasari - plati) // Truncate text to maxLength characters
const totalSold = computed(() => { const truncateText = (text, maxLength = 100) => {
return ( if (!text) return "";
(treasuryStore.totals.total_incasari || 0) - if (text.length <= maxLength) return text;
(treasuryStore.totals.total_plati || 0) return text.substring(0, maxLength) + "...";
); };
// Computed totals - separate sold precedent from actual transactions
// Rows with dataact = null are opening balances (sold precedent)
const computedTotals = computed(() => {
let soldPrecedent = 0;
let incasari = 0;
let plati = 0;
treasuryStore.registers.forEach((row) => {
if (row.dataact === null || row.dataact === undefined) {
// Opening balance row - the sold value is the opening balance
soldPrecedent += parseFloat(row.sold) || 0;
} else {
// Transaction row
incasari += parseFloat(row.incasari) || 0;
plati += parseFloat(row.plati) || 0;
}
});
const soldFinal = soldPrecedent + incasari - plati;
return {
soldPrecedent,
incasari,
plati,
soldFinal,
};
}); });
// Check if current filter is a VALUTA type (to show Valuta column) // Check if current filter is a VALUTA type (to show Valuta column)
@@ -623,7 +662,7 @@ const exportExcel = async () => {
baseData["Încasări"] = parseFloat(row.incasari) || 0; baseData["Încasări"] = parseFloat(row.incasari) || 0;
baseData["Plăți"] = parseFloat(row.plati) || 0; baseData["Plăți"] = parseFloat(row.plati) || 0;
baseData["Sold Cumulat"] = parseFloat(row.sold) || 0; baseData["Sold Cumulat"] = parseFloat(row.sold) || 0;
baseData["Explicație"] = row.explicatia || ""; baseData["Explicație"] = truncateText(row.explicatia, 100);
return baseData; return baseData;
}); });