From f52aa27bdc3c523b87ffbba1b9420b87dc5d27bd Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Sat, 22 Nov 2025 00:31:20 +0200 Subject: [PATCH] chore: Fix .env.test quotes and format frontend code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix TEST_ORACLE_USER quotes in .env.test for shell source compatibility - Format 14 frontend files with Prettier (stores, views, utils) - All 122 tests passing (77 telegram + 35 backend + 10 E2E) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- reports-app/backend/.env.test | 5 +- reports-app/frontend/src/stores/invoices.js | 18 +- reports-app/frontend/src/stores/treasury.js | 14 +- reports-app/frontend/src/utils/exportUtils.js | 252 +++--- .../src/views/BankCashRegisterView.vue | 89 +- .../frontend/src/views/CacheStatsView.vue | 221 +++-- .../frontend/src/views/DashboardView.vue | 815 +++++++++--------- .../frontend/src/views/InvoicesView.vue | 124 ++- reports-app/frontend/src/views/LoginView.vue | 32 +- .../frontend/src/views/TelegramView.vue | 291 +++---- .../frontend/src/views/TrialBalanceView.vue | 163 +++- .../backup_dashboards/CompanySelectorMini.vue | 135 +-- .../backup_dashboards/DashboardHeader.vue | 84 +- .../views/backup_dashboards/DashboardView.vue | 592 +++++++++---- 14 files changed, 1691 insertions(+), 1144 deletions(-) diff --git a/reports-app/backend/.env.test b/reports-app/backend/.env.test index a4d9b9f..0e362c0 100644 --- a/reports-app/backend/.env.test +++ b/reports-app/backend/.env.test @@ -7,8 +7,9 @@ ORACLE_PASSWORD=ROMFASTSOFT ORACLE_DSN=localhost:1526/roa # Test credentials for pytest (user exists in Oracle TEST) -TEST_ORACLE_USER=MARIUS M -TEST_ORACLE_PASS=123 +# Quotes required for shell (source), dotenv strips them automatically +TEST_ORACLE_USER="MARIUS M" +TEST_ORACLE_PASS="123" # Test company - MARIUSM_AUTO schema (only schema with full data in TEST) # Other schemas (ACN, DANUBE, EMS) don't have required tables diff --git a/reports-app/frontend/src/stores/invoices.js b/reports-app/frontend/src/stores/invoices.js index 8b91baa..f240295 100644 --- a/reports-app/frontend/src/stores/invoices.js +++ b/reports-app/frontend/src/stores/invoices.js @@ -67,8 +67,11 @@ export const useInvoicesStore = defineStore("invoices", () => { // Convert Date object to YYYY-MM-DD string format (LOCAL date, not UTC) if (filters.value.dateFrom instanceof Date) { const year = filters.value.dateFrom.getFullYear(); - const month = String(filters.value.dateFrom.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateFrom.getDate()).padStart(2, '0'); + const month = String(filters.value.dateFrom.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateFrom.getDate()).padStart(2, "0"); params.date_from = `${year}-${month}-${day}`; } else { params.date_from = filters.value.dateFrom; @@ -78,8 +81,11 @@ export const useInvoicesStore = defineStore("invoices", () => { // Convert Date object to YYYY-MM-DD string format (LOCAL date, not UTC) if (filters.value.dateTo instanceof Date) { const year = filters.value.dateTo.getFullYear(); - const month = String(filters.value.dateTo.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateTo.getDate()).padStart(2, '0'); + const month = String(filters.value.dateTo.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateTo.getDate()).padStart(2, "0"); params.date_to = `${year}-${month}-${day}`; } else { params.date_to = filters.value.dateTo; @@ -93,8 +99,8 @@ export const useInvoicesStore = defineStore("invoices", () => { const response = await apiService.get(`/invoices/`, { params: { company: companyCode, - ...params - } + ...params, + }, }); invoices.value = response.data.invoices || []; diff --git a/reports-app/frontend/src/stores/treasury.js b/reports-app/frontend/src/stores/treasury.js index c13c36f..cee72d4 100644 --- a/reports-app/frontend/src/stores/treasury.js +++ b/reports-app/frontend/src/stores/treasury.js @@ -13,7 +13,7 @@ export const useTreasuryStore = defineStore("treasury", () => { }); const totals = ref({ total_incasari: 0, - total_plati: 0 + total_plati: 0, }); const loadBankCashRegister = async (companyId, filters = {}) => { @@ -25,18 +25,18 @@ export const useTreasuryStore = defineStore("treasury", () => { company: companyId, page: pagination.value.page + 1, page_size: pagination.value.rows, - ...filters + ...filters, }; - const response = await apiService.get('/treasury/bank-cash-register', { - params + const response = await apiService.get("/treasury/bank-cash-register", { + params, }); registers.value = response.data.registers || []; pagination.value.totalRecords = response.data.total_count || 0; totals.value = { total_incasari: response.data.total_incasari, - total_plati: response.data.total_plati + total_plati: response.data.total_plati, }; return { success: true }; @@ -72,6 +72,6 @@ export const useTreasuryStore = defineStore("treasury", () => { totals, loadBankCashRegister, setPagination, - reset + reset, }; -}); \ No newline at end of file +}); diff --git a/reports-app/frontend/src/utils/exportUtils.js b/reports-app/frontend/src/utils/exportUtils.js index 52a07bd..03f5ea2 100644 --- a/reports-app/frontend/src/utils/exportUtils.js +++ b/reports-app/frontend/src/utils/exportUtils.js @@ -1,17 +1,17 @@ -import * as XLSX from 'xlsx'; -import { jsPDF } from 'jspdf'; -import autoTable from 'jspdf-autotable'; +import * as XLSX from "xlsx"; +import { jsPDF } from "jspdf"; +import autoTable from "jspdf-autotable"; /** * Format currency values for export */ const formatCurrency = (value) => { - if (value == null || value === '-') return '-'; - return new Intl.NumberFormat('ro-RO', { - style: 'currency', - currency: 'RON', + if (value == null || value === "-") return "-"; + return new Intl.NumberFormat("ro-RO", { + style: "currency", + currency: "RON", minimumFractionDigits: 0, - maximumFractionDigits: 0 + maximumFractionDigits: 0, }).format(value); }; @@ -21,15 +21,18 @@ const formatCurrency = (value) => { * @param {String} filename - Name of the file (without extension) * @param {String} sheetName - Name of the Excel sheet */ -export const exportToExcel = (data, filename, sheetName = 'Sheet1') => { +export const exportToExcel = (data, filename, sheetName = "Sheet1") => { try { const ws = XLSX.utils.json_to_sheet(data); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, sheetName); - XLSX.writeFile(wb, `${filename}_${new Date().toISOString().split('T')[0]}.xlsx`); + XLSX.writeFile( + wb, + `${filename}_${new Date().toISOString().split("T")[0]}.xlsx`, + ); return { success: true }; } catch (error) { - console.error('Excel export failed:', error); + console.error("Excel export failed:", error); return { success: false, error }; } }; @@ -38,12 +41,12 @@ export const exportToExcel = (data, filename, sheetName = 'Sheet1') => { * Format number for PDF export */ const formatNumberForPDF = (value) => { - if (value == null || value === '' || value === '-') return '-'; + if (value == null || value === "" || value === "-") return "-"; const num = parseFloat(value); - if (isNaN(num)) return '-'; - return new Intl.NumberFormat('ro-RO', { + if (isNaN(num)) return "-"; + return new Intl.NumberFormat("ro-RO", { minimumFractionDigits: 2, - maximumFractionDigits: 2 + maximumFractionDigits: 2, }).format(num); }; @@ -58,17 +61,17 @@ export const exportToPDF = (data, columns, filename, header) => { try { // Check if data exists if (!data || data.length === 0) { - console.error('No data to export'); - return { success: false, error: 'No data available' }; + console.error("No data to export"); + return { success: false, error: "No data available" }; } // Check if jsPDF is properly imported - if (typeof jsPDF === 'undefined') { - console.error('jsPDF not properly imported'); - return { success: false, error: 'PDF library not available' }; + if (typeof jsPDF === "undefined") { + console.error("jsPDF not properly imported"); + return { success: false, error: "PDF library not available" }; } - const doc = new jsPDF('landscape', 'mm', 'a4'); + const doc = new jsPDF("landscape", "mm", "a4"); const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = doc.internal.pageSize.getHeight(); const marginLeft = 8; @@ -79,38 +82,38 @@ export const exportToPDF = (data, columns, filename, header) => { const addHeader = () => { // Line 1: Company name (left aligned, bold, larger font) doc.setFontSize(13); - doc.setFont(undefined, 'bold'); - const companyName = header.companyName || 'N/A'; + doc.setFont(undefined, "bold"); + const companyName = header.companyName || "N/A"; doc.text(companyName, marginLeft, 15); // Line 2: Title "Balanta de Verificare" (centered) doc.setFontSize(14); - doc.setFont(undefined, 'bold'); - const titleWidth = doc.getTextWidth(header.title || ''); + doc.setFont(undefined, "bold"); + const titleWidth = doc.getTextWidth(header.title || ""); const titleX = marginLeft + (contentWidth - titleWidth) / 2; - doc.text(header.title || '', titleX, 24); + doc.text(header.title || "", titleX, 24); // Line 3: Period (centered, below title) doc.setFontSize(11); - doc.setFont(undefined, 'normal'); - const periodText = header.period || ''; + doc.setFont(undefined, "normal"); + const periodText = header.period || ""; const periodWidth = doc.getTextWidth(periodText); const periodX = marginLeft + (contentWidth - periodWidth) / 2; doc.text(periodText, periodX, 32); }; // Prepare table data - const tableColumns = columns.map(col => col.header); - const tableRows = data.map(row => - columns.map(col => { + const tableColumns = columns.map((col) => col.header); + const tableRows = data.map((row) => + columns.map((col) => { const value = row[col.field]; - if (col.type === 'currency') { + if (col.type === "currency") { return formatCurrency(value); - } else if (col.type === 'number') { + } else if (col.type === "number") { return formatNumberForPDF(value); } - return value || '-'; - }) + return value || "-"; + }), ); // Function to add footer (called for each page) @@ -119,8 +122,12 @@ export const exportToPDF = (data, columns, filename, header) => { // Left side: Generation date doc.setFontSize(8); - doc.setFont(undefined, 'normal'); - doc.text(`Generat: ${new Date().toLocaleString('ro-RO')}`, marginLeft, footerY); + doc.setFont(undefined, "normal"); + doc.text( + `Generat: ${new Date().toLocaleString("ro-RO")}`, + marginLeft, + footerY, + ); // Right side: Page numbers const pageText = `Pagina ${pageNum} din ${totalPages}`; @@ -129,7 +136,7 @@ export const exportToPDF = (data, columns, filename, header) => { }; // Check if autoTable is available - if (typeof autoTable === 'function') { + if (typeof autoTable === "function") { // Build column styles - jspdf-autotable uses numeric keys const columnStyles = {}; @@ -142,37 +149,37 @@ export const exportToPDF = (data, columns, filename, header) => { columns.forEach((col, index) => { // Use custom width if provided, otherwise auto - if (col.width && typeof col.width === 'number') { + if (col.width && typeof col.width === "number") { widthAllocations[index] = totalWidth * col.width; - } else if (col.width === 'auto') { - widthAllocations[index] = 'auto'; + } else if (col.width === "auto") { + widthAllocations[index] = "auto"; } else { // Default width allocation for Trial Balance (8 columns) const defaultWidths = { - 0: totalWidth * 0.07, // Cont: ~20mm - 1: totalWidth * 0.33, // Denumire: ~93mm - 2: totalWidth * 0.10, // Sold Prec D: ~28mm - 3: totalWidth * 0.10, // Sold Prec C: ~28mm - 4: totalWidth * 0.10, // Rulaj D: ~28mm - 5: totalWidth * 0.10, // Rulaj C: ~28mm - 6: totalWidth * 0.10, // Sold Final D: ~28mm - 7: totalWidth * 0.10, // Sold Final C: ~28mm + 0: totalWidth * 0.07, // Cont: ~20mm + 1: totalWidth * 0.33, // Denumire: ~93mm + 2: totalWidth * 0.1, // Sold Prec D: ~28mm + 3: totalWidth * 0.1, // Sold Prec C: ~28mm + 4: totalWidth * 0.1, // Rulaj D: ~28mm + 5: totalWidth * 0.1, // Rulaj C: ~28mm + 6: totalWidth * 0.1, // Sold Final D: ~28mm + 7: totalWidth * 0.1, // Sold Final C: ~28mm }; - widthAllocations[index] = defaultWidths[index] || 'auto'; + widthAllocations[index] = defaultWidths[index] || "auto"; } }); columns.forEach((col, index) => { columnStyles[index] = { - cellWidth: widthAllocations[index] + cellWidth: widthAllocations[index], }; // Set alignment based on type - if (col.type === 'number' || col.type === 'currency') { - columnStyles[index].halign = 'right'; - } else if (col.type === 'text') { + if (col.type === "number" || col.type === "currency") { + columnStyles[index].halign = "right"; + } else if (col.type === "text") { // All text columns aligned left (including Cont) - columnStyles[index].halign = 'left'; + columnStyles[index].halign = "left"; } }); @@ -186,44 +193,49 @@ export const exportToPDF = (data, columns, filename, header) => { styles: { fontSize: 9, cellPadding: 2.5, - valign: 'middle', + valign: "middle", lineColor: [200, 200, 200], lineWidth: 0.1, - overflow: 'linebreak' + overflow: "linebreak", }, headStyles: { fillColor: [41, 128, 185], textColor: 255, - fontStyle: 'bold', - halign: 'center', + fontStyle: "bold", + halign: "center", fontSize: 9, - cellPadding: 2.5 + cellPadding: 2.5, }, alternateRowStyles: { - fillColor: [248, 248, 248] + fillColor: [248, 248, 248], }, columnStyles: columnStyles, - margin: { left: marginLeft, right: marginRight, top: tableStartY, bottom: 15 }, + margin: { + left: marginLeft, + right: marginRight, + top: tableStartY, + bottom: 15, + }, tableWidth: pageWidth - marginLeft - marginRight, // Use full page width - theme: 'grid', - didDrawPage: function(data) { + theme: "grid", + didDrawPage: function (data) { // Add header to each page addHeader(); }, - didParseCell: function(data) { + didParseCell: function (data) { // Force alignment based on column type (body cells only) - if (data.section === 'body') { + if (data.section === "body") { const colIndex = data.column.index; const column = columns[colIndex]; if (column) { - if (column.type === 'number' || column.type === 'currency') { - data.cell.styles.halign = 'right'; - } else if (column.type === 'text') { + if (column.type === "number" || column.type === "currency") { + data.cell.styles.halign = "right"; + } else if (column.type === "text") { if (colIndex === 0) { - data.cell.styles.halign = 'center'; + data.cell.styles.halign = "center"; } else { - data.cell.styles.halign = 'left'; + data.cell.styles.halign = "left"; } } } @@ -247,18 +259,18 @@ export const exportToPDF = (data, columns, filename, header) => { // Draw headers doc.setFontSize(8); - doc.setFont(undefined, 'bold'); + doc.setFont(undefined, "bold"); tableColumns.forEach((header, index) => { - doc.text(header, 14 + (index * 35), yPos); + doc.text(header, 14 + index * 35, yPos); }); // Draw rows - doc.setFont(undefined, 'normal'); + doc.setFont(undefined, "normal"); doc.setFontSize(7); tableRows.forEach((row, rowIndex) => { yPos += 7; row.forEach((cell, cellIndex) => { - doc.text(String(cell), 14 + (cellIndex * 35), yPos); + doc.text(String(cell), 14 + cellIndex * 35, yPos); }); }); @@ -267,11 +279,11 @@ export const exportToPDF = (data, columns, filename, header) => { } // Save PDF - doc.save(`${filename}_${new Date().toISOString().split('T')[0]}.pdf`); + doc.save(`${filename}_${new Date().toISOString().split("T")[0]}.pdf`); return { success: true }; } catch (error) { - console.error('PDF export error details:', error); - return { success: false, error: error.message || 'PDF generation failed' }; + console.error("PDF export error details:", error); + return { success: false, error: error.message || "PDF generation failed" }; } }; @@ -281,31 +293,31 @@ export const exportToPDF = (data, columns, filename, header) => { export const exportGeneralTotals = (summaryData) => { const data = [ { - Tip: 'Clienți', - 'Total Facturat': summaryData?.clienti_total_facturat || 0, - 'Total Încasat': summaryData?.clienti_total_incasat || 0, - 'Sold Net': summaryData?.clienti_sold_total || 0, - 'Sold În Termen': summaryData?.clienti_sold_in_termen || 0, - 'Sold Restant': summaryData?.clienti_sold_restant || 0 + Tip: "Clienți", + "Total Facturat": summaryData?.clienti_total_facturat || 0, + "Total Încasat": summaryData?.clienti_total_incasat || 0, + "Sold Net": summaryData?.clienti_sold_total || 0, + "Sold În Termen": summaryData?.clienti_sold_in_termen || 0, + "Sold Restant": summaryData?.clienti_sold_restant || 0, }, { - Tip: 'Furnizori', - 'Total Facturat': summaryData?.furnizori_total_facturat || 0, - 'Total Achitat': summaryData?.furnizori_total_achitat || 0, - 'Sold Net': summaryData?.furnizori_sold_total || 0, - 'Sold În Termen': summaryData?.furnizori_sold_in_termen || 0, - 'Sold Restant': summaryData?.furnizori_sold_restant || 0 + Tip: "Furnizori", + "Total Facturat": summaryData?.furnizori_total_facturat || 0, + "Total Achitat": summaryData?.furnizori_total_achitat || 0, + "Sold Net": summaryData?.furnizori_sold_total || 0, + "Sold În Termen": summaryData?.furnizori_sold_in_termen || 0, + "Sold Restant": summaryData?.furnizori_sold_restant || 0, }, { - Tip: 'Trezorerie', - 'Total Facturat': '-', - 'Total Încasat/Achitat': '-', - 'Sold Net': summaryData?.trezorerie_sold || 0, - 'Sold În Termen': '-', - 'Sold Restant': '-' - } + Tip: "Trezorerie", + "Total Facturat": "-", + "Total Încasat/Achitat": "-", + "Sold Net": summaryData?.trezorerie_sold || 0, + "Sold În Termen": "-", + "Sold Restant": "-", + }, ]; - + return data; }; @@ -315,27 +327,27 @@ export const exportGeneralTotals = (summaryData) => { export const exportSoldNetBreakdown = (summaryData) => { const data = [ { - Categorie: 'Clienți - Restant', - 'TOTAL': summaryData?.clienti_sold_restant || 0, - '7 zile': summaryData?.clienti_restant_7 || 0, - '14 zile': summaryData?.clienti_restant_14 || 0, - '30 zile': summaryData?.clienti_restant_30 || 0, - '60 zile': summaryData?.clienti_restant_60 || 0, - '90 zile': summaryData?.clienti_restant_90 || 0, - '90+ zile': summaryData?.clienti_restant_over_90 || 0 + Categorie: "Clienți - Restant", + TOTAL: summaryData?.clienti_sold_restant || 0, + "7 zile": summaryData?.clienti_restant_7 || 0, + "14 zile": summaryData?.clienti_restant_14 || 0, + "30 zile": summaryData?.clienti_restant_30 || 0, + "60 zile": summaryData?.clienti_restant_60 || 0, + "90 zile": summaryData?.clienti_restant_90 || 0, + "90+ zile": summaryData?.clienti_restant_over_90 || 0, }, { - Categorie: 'Furnizori - Restant', - 'TOTAL': summaryData?.furnizori_sold_restant || 0, - '7 zile': summaryData?.furnizori_restant_7 || 0, - '14 zile': summaryData?.furnizori_restant_14 || 0, - '30 zile': summaryData?.furnizori_restant_30 || 0, - '60 zile': summaryData?.furnizori_restant_60 || 0, - '90 zile': summaryData?.furnizori_restant_90 || 0, - '90+ zile': summaryData?.furnizori_restant_over_90 || 0 - } + Categorie: "Furnizori - Restant", + TOTAL: summaryData?.furnizori_sold_restant || 0, + "7 zile": summaryData?.furnizori_restant_7 || 0, + "14 zile": summaryData?.furnizori_restant_14 || 0, + "30 zile": summaryData?.furnizori_restant_30 || 0, + "60 zile": summaryData?.furnizori_restant_60 || 0, + "90 zile": summaryData?.furnizori_restant_90 || 0, + "90+ zile": summaryData?.furnizori_restant_over_90 || 0, + }, ]; - + return data; }; @@ -349,14 +361,14 @@ export const exportTrendData = (trendsData, period, chartType) => { const data = trendsData.labels.map((label, index) => { const row = { Perioada: label }; - - trendsData.datasets.forEach(dataset => { + + trendsData.datasets.forEach((dataset) => { const value = dataset.data[index]; row[dataset.label] = value || 0; }); - + return row; }); return data; -}; \ No newline at end of file +}; diff --git a/reports-app/frontend/src/views/BankCashRegisterView.vue b/reports-app/frontend/src/views/BankCashRegisterView.vue index 8a45df2..54ff4ce 100644 --- a/reports-app/frontend/src/views/BankCashRegisterView.vue +++ b/reports-app/frontend/src/views/BankCashRegisterView.vue @@ -26,19 +26,22 @@
- +
-
@@ -54,7 +57,9 @@
-

{{ formatCurrency(treasuryStore.totals.total_incasari) }}

+

+ {{ formatCurrency(treasuryStore.totals.total_incasari) }} +

Total Încasări

@@ -67,7 +72,9 @@
-

{{ formatCurrency(treasuryStore.totals.total_plati) }}

+

+ {{ formatCurrency(treasuryStore.totals.total_plati) }} +

Total Plăți

@@ -99,29 +106,53 @@ @@ -146,19 +177,19 @@ const companyStore = useCompanyStore(); const filters = ref({ dateFrom: null, dateTo: null, - partnerName: "" + partnerName: "", }); const pagination = ref({ page: 0, - rows: 50 + rows: 50, }); -const formatCurrency = (amount, currency = 'RON') => { +const formatCurrency = (amount, currency = "RON") => { if (!amount) return "0,00 " + currency; return new Intl.NumberFormat("ro-RO", { style: "currency", - currency: currency + currency: currency, }).format(amount); }; @@ -168,12 +199,12 @@ const formatDate = (dateString) => { }; const getRowClass = (data) => { - return data.tip_registru.includes('BANCA') ? 'bank-row' : 'cash-row'; + return data.tip_registru.includes("BANCA") ? "bank-row" : "cash-row"; }; const getRegisterSeverity = (type) => { - if (type.includes('BANCA')) return 'info'; - if (type.includes('CASA')) return 'warning'; + if (type.includes("BANCA")) return "info"; + if (type.includes("CASA")) return "warning"; return null; }; @@ -191,7 +222,7 @@ const resetFilters = () => { filters.value = { dateFrom: null, dateTo: null, - partnerName: "" + partnerName: "", }; loadData(); }; @@ -206,8 +237,8 @@ const loadData = async () => { { date_from: filters.value.dateFrom?.toISOString().split("T")[0], date_to: filters.value.dateTo?.toISOString().split("T")[0], - partner_name: filters.value.partnerName - } + partner_name: filters.value.partnerName, + }, ); }; @@ -314,4 +345,4 @@ onMounted(() => { flex: 1; } } - \ No newline at end of file + diff --git a/reports-app/frontend/src/views/CacheStatsView.vue b/reports-app/frontend/src/views/CacheStatsView.vue index 728c51b..a9b4eb4 100644 --- a/reports-app/frontend/src/views/CacheStatsView.vue +++ b/reports-app/frontend/src/views/CacheStatsView.vue @@ -38,8 +38,11 @@
- - {{ userCacheEnabled ? 'ON' : 'OFF' }} + + {{ userCacheEnabled ? "ON" : "OFF" }}
@@ -58,7 +61,10 @@ @@ -70,13 +76,23 @@ @@ -102,8 +118,9 @@
Overall Average: - {{ overallAvg.cached }} ms vs {{ overallAvg.oracle }} ms - ({{ overallAvg.improvement }}% faster) + {{ overallAvg.cached }} ms vs {{ overallAvg.oracle }} ms ({{ + overallAvg.improvement + }}% faster)
@@ -113,9 +130,17 @@ @@ -135,150 +160,162 @@
- +
\ No newline at end of file + diff --git a/reports-app/frontend/src/views/InvoicesView.vue b/reports-app/frontend/src/views/InvoicesView.vue index 610115a..4c245fe 100644 --- a/reports-app/frontend/src/views/InvoicesView.vue +++ b/reports-app/frontend/src/views/InvoicesView.vue @@ -189,7 +189,7 @@ @@ -241,10 +241,15 @@
- + @@ -253,7 +258,9 @@
Total Sold: - {{ formatCurrency(totalSold) }} + {{ + formatCurrency(totalSold) + }}
@@ -300,8 +307,18 @@ const totalSold = computed(() => { const accountingPeriodText = computed(() => { const months = [ - "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", - "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie" + "Ianuarie", + "Februarie", + "Martie", + "Aprilie", + "Mai", + "Iunie", + "Iulie", + "August", + "Septembrie", + "Octombrie", + "Noiembrie", + "Decembrie", ]; const luna = invoicesStore.accountingPeriod.luna; const an = invoicesStore.accountingPeriod.an; @@ -405,33 +422,42 @@ const loadInvoices = async () => { invoicesStore.setPagination(pagination.value); const params = { - partner_type: filters.value.type, // FIX: Add partner_type filter + partner_type: filters.value.type, // FIX: Add partner_type filter page: pagination.value.page, page_size: pagination.value.rows, - only_unpaid: filters.value.paymentStatus === "neachitate", // Use filter value + only_unpaid: filters.value.paymentStatus === "neachitate", // Use filter value }; // Add optional filters (use LOCAL date, not UTC) if (filters.value.dateFrom) { const year = filters.value.dateFrom.getFullYear(); - const month = String(filters.value.dateFrom.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateFrom.getDate()).padStart(2, '0'); + const month = String(filters.value.dateFrom.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateFrom.getDate()).padStart(2, "0"); params.date_from = `${year}-${month}-${day}`; } if (filters.value.dateTo) { const year = filters.value.dateTo.getFullYear(); - const month = String(filters.value.dateTo.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateTo.getDate()).padStart(2, '0'); + const month = String(filters.value.dateTo.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateTo.getDate()).padStart(2, "0"); params.date_to = `${year}-${month}-${day}`; } if (filters.value.searchTerm) { - params.partner_name = filters.value.searchTerm; // FIX: Use partner_name not search + params.partner_name = filters.value.searchTerm; // FIX: Use partner_name not search } if (filters.value.cont) { params.cont = filters.value.cont; } - await invoicesStore.loadInvoices(companyStore.selectedCompany.id_firma, params); + await invoicesStore.loadInvoices( + companyStore.selectedCompany.id_firma, + params, + ); } catch (error) { console.error("Failed to load invoices:", error); toast.add({ @@ -462,27 +488,33 @@ const fetchAllInvoicesData = async () => { try { const params = { company: companyStore.selectedCompany.id_firma, - partner_type: filters.value.type, // FIX: Correctly pass partner_type + partner_type: filters.value.type, // FIX: Correctly pass partner_type page: 1, page_size: 999999, // Get all data - only_unpaid: filters.value.paymentStatus === "neachitate", // Use filter value for export + only_unpaid: filters.value.paymentStatus === "neachitate", // Use filter value for export }; // Add optional filters (use LOCAL date, not UTC) if (filters.value.dateFrom) { const year = filters.value.dateFrom.getFullYear(); - const month = String(filters.value.dateFrom.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateFrom.getDate()).padStart(2, '0'); + const month = String(filters.value.dateFrom.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateFrom.getDate()).padStart(2, "0"); params.date_from = `${year}-${month}-${day}`; } if (filters.value.dateTo) { const year = filters.value.dateTo.getFullYear(); - const month = String(filters.value.dateTo.getMonth() + 1).padStart(2, '0'); - const day = String(filters.value.dateTo.getDate()).padStart(2, '0'); + const month = String(filters.value.dateTo.getMonth() + 1).padStart( + 2, + "0", + ); + const day = String(filters.value.dateTo.getDate()).padStart(2, "0"); params.date_to = `${year}-${month}-${day}`; } if (filters.value.searchTerm) { - params.partner_name = filters.value.searchTerm; // FIX: Use partner_name not search + params.partner_name = filters.value.searchTerm; // FIX: Use partner_name not search } if (filters.value.cont) { params.cont = filters.value.cont; @@ -531,22 +563,23 @@ const exportExcel = async () => { // Prepare data for export - Format dates as strings for Excel const exportData = allData.map((row) => ({ - "Cont": row.cont || "", + Cont: row.cont || "", "Numar Doc.": row.nract, "Data Doc.": row.dataact ? formatDate(row.dataact) : "", "Data Scadenta": row.datascad ? formatDate(row.datascad) : "", - "Partener": row.nume, - "Facturat": parseFloat(row.totctva) || 0, - "Achitat": parseFloat(row.achitat) || 0, - "Sold": parseFloat(row.soldfinal) || 0, - "Valuta": row.valuta || "RON", + Partener: row.nume, + Facturat: parseFloat(row.totctva) || 0, + Achitat: parseFloat(row.achitat) || 0, + Sold: parseFloat(row.soldfinal) || 0, + Valuta: row.valuta || "RON", })); - const invoiceType = filters.value.type === "CLIENTI" ? "Clienti" : "Furnizori"; + const invoiceType = + filters.value.type === "CLIENTI" ? "Clienti" : "Furnizori"; const result = exportToExcel( exportData, `facturi_${invoiceType}_${companyStore.selectedCompany.name.replace(/\s+/g, "_")}`, - `Facturi ${invoiceType}` + `Facturi ${invoiceType}`, ); if (result.success) { @@ -613,27 +646,34 @@ const exportPDF = async () => { // Define columns for PDF with optimized widths (proportional percentages) // Compact numeric columns, more space for Partener (company names) const columns = [ - { field: "cont", header: "Cont", type: "text", width: 0.06 }, // 6% - Compact account numbers - { field: "nract", header: "Numar Doc.", type: "text", width: 0.08 }, // 8% - Document numbers - { field: "dataact", header: "Data Doc.", type: "text", width: 0.08 }, // 8% - Dates + { field: "cont", header: "Cont", type: "text", width: 0.06 }, // 6% - Compact account numbers + { field: "nract", header: "Numar Doc.", type: "text", width: 0.08 }, // 8% - Document numbers + { field: "dataact", header: "Data Doc.", type: "text", width: 0.08 }, // 8% - Dates { field: "datascad", header: "Data Scadenta", type: "text", width: 0.09 }, // 9% - Due dates - { field: "nume", header: "Partener", type: "text", width: 0.37 }, // 37% - MORE SPACE for company names + { field: "nume", header: "Partener", type: "text", width: 0.37 }, // 37% - MORE SPACE for company names { field: "totctva", header: "Facturat", type: "number", width: 0.09 }, // 9% - Compact numbers - { field: "achitat", header: "Achitat", type: "number", width: 0.09 }, // 9% - Compact numbers - { field: "soldfinal", header: "Sold", type: "number", width: 0.09 }, // 9% - Compact numbers - { field: "valuta", header: "Valuta", type: "text", width: 0.05 }, // 5% - Very compact (just "RON") + { field: "achitat", header: "Achitat", type: "number", width: 0.09 }, // 9% - Compact numbers + { field: "soldfinal", header: "Sold", type: "number", width: 0.09 }, // 9% - Compact numbers + { field: "valuta", header: "Valuta", type: "text", width: 0.05 }, // 5% - Very compact (just "RON") ]; - const invoiceType = filters.value.type === "CLIENTI" ? "Clienti" : "Furnizori"; + const invoiceType = + filters.value.type === "CLIENTI" ? "Clienti" : "Furnizori"; // Build period string - ALWAYS show accounting period (like Trial Balance) let periodText = accountingPeriodText.value || ""; // Optionally add date filter range if applied if (filters.value.dateFrom || filters.value.dateTo) { - const fromDate = filters.value.dateFrom ? formatDate(filters.value.dateFrom) : "început"; - const toDate = filters.value.dateTo ? formatDate(filters.value.dateTo) : "prezent"; - periodText += periodText ? ` | Filtru dată: ${fromDate} - ${toDate}` : `Filtru dată: ${fromDate} - ${toDate}`; + const fromDate = filters.value.dateFrom + ? formatDate(filters.value.dateFrom) + : "început"; + const toDate = filters.value.dateTo + ? formatDate(filters.value.dateTo) + : "prezent"; + periodText += periodText + ? ` | Filtru dată: ${fromDate} - ${toDate}` + : `Filtru dată: ${fromDate} - ${toDate}`; } const result = exportToPDF( @@ -643,8 +683,8 @@ const exportPDF = async () => { { companyName: companyStore.selectedCompany?.name || "", title: `Facturi ${invoiceType}`, - period: periodText - } + period: periodText, + }, ); if (result.success) { diff --git a/reports-app/frontend/src/views/LoginView.vue b/reports-app/frontend/src/views/LoginView.vue index c038b92..a6f6e6c 100644 --- a/reports-app/frontend/src/views/LoginView.vue +++ b/reports-app/frontend/src/views/LoginView.vue @@ -13,12 +13,14 @@ \ No newline at end of file + toggleUserMenu, + }; + }, +}; + diff --git a/reports-app/frontend/src/views/backup_dashboards/DashboardView.vue b/reports-app/frontend/src/views/backup_dashboards/DashboardView.vue index cd458fe..0a4e1fa 100644 --- a/reports-app/frontend/src/views/backup_dashboards/DashboardView.vue +++ b/reports-app/frontend/src/views/backup_dashboards/DashboardView.vue @@ -1,7 +1,7 @@