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:
@@ -477,6 +477,13 @@ export const exportBankCashRegisterPDF = (data, header, filename) => {
|
||||
.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)
|
||||
const groupedByBank = {};
|
||||
const initialBalances = {};
|
||||
@@ -696,7 +703,7 @@ export const exportBankCashRegisterPDF = (data, header, filename) => {
|
||||
tableRows.push([
|
||||
dateFormatted,
|
||||
row.nract || "",
|
||||
removeDiacritics(row.explicatia || row.nume || ""),
|
||||
truncateText(removeDiacritics(row.explicatia || row.nume || ""), 100),
|
||||
formatNumberForPDF(incasari),
|
||||
formatNumberForPDF(plati),
|
||||
formatNumberForPDF(row.sold),
|
||||
|
||||
@@ -141,23 +141,31 @@
|
||||
<!-- Summary Stats - Compact, right aligned -->
|
||||
<div v-if="companyStore.selectedCompany" class="summary-stats-inline">
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">Total Încasări:</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 class="stat-label">Sold Precedent:</span>
|
||||
<span
|
||||
class="stat-value"
|
||||
:class="totalSold >= 0 ? 'incasari' : 'plati'"
|
||||
>{{ formatCurrency(totalSold) }}</span
|
||||
:class="computedTotals.soldPrecedent >= 0 ? 'incasari' : 'plati'"
|
||||
>{{ 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>
|
||||
@@ -262,7 +270,11 @@
|
||||
field="explicatia"
|
||||
header="Explicație"
|
||||
class="col-explicatie"
|
||||
/>
|
||||
>
|
||||
<template #body="slotProps">
|
||||
{{ truncateText(slotProps.data.explicatia, 100) }}
|
||||
</template>
|
||||
</Column>
|
||||
</DataTable>
|
||||
</template>
|
||||
</Card>
|
||||
@@ -330,12 +342,39 @@ const formatDate = (dateString) => {
|
||||
return format(new Date(dateString), "dd.MM.yyyy");
|
||||
};
|
||||
|
||||
// Computed total sold (incasari - plati)
|
||||
const totalSold = computed(() => {
|
||||
return (
|
||||
(treasuryStore.totals.total_incasari || 0) -
|
||||
(treasuryStore.totals.total_plati || 0)
|
||||
);
|
||||
// Truncate text to maxLength characters
|
||||
const truncateText = (text, maxLength = 100) => {
|
||||
if (!text) return "";
|
||||
if (text.length <= maxLength) return text;
|
||||
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)
|
||||
@@ -623,7 +662,7 @@ const exportExcel = async () => {
|
||||
baseData["Încasări"] = parseFloat(row.incasari) || 0;
|
||||
baseData["Plăți"] = parseFloat(row.plati) || 0;
|
||||
baseData["Sold Cumulat"] = parseFloat(row.sold) || 0;
|
||||
baseData["Explicație"] = row.explicatia || "";
|
||||
baseData["Explicație"] = truncateText(row.explicatia, 100);
|
||||
|
||||
return baseData;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user