diff --git a/scripts/ralph/prd.json b/scripts/ralph/prd.json index d37e950..7174a8c 100644 --- a/scripts/ralph/prd.json +++ b/scripts/ralph/prd.json @@ -161,8 +161,8 @@ "Click pe Filtrare deschide BottomSheet cu filtrele paginii", "npm run build passes" ], - "passes": false, - "notes": "" + "passes": true, + "notes": "Completed in iteration 6" }, { "id": "US-309", diff --git a/scripts/ralph/progress.txt b/scripts/ralph/progress.txt index 0f91015..a54f1d9 100644 --- a/scripts/ralph/progress.txt +++ b/scripts/ralph/progress.txt @@ -1050,3 +1050,9 @@ User Stories: 11 (US-301 to US-311) [2026-01-12 16:43:01] Working on story: US-303 [2026-01-12 16:43:01] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_5_US-303.log) [2026-01-12 16:46:26] SUCCESS: Story US-303 passed! +[2026-01-12 16:46:26] Changes committed +[2026-01-12 16:46:26] Progress: 7/11 stories completed +[2026-01-12 16:46:28] === Iteration 6/100 === +[2026-01-12 16:46:28] Working on story: US-306 +[2026-01-12 16:46:28] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_6_US-306.log) +[2026-01-12 16:51:00] SUCCESS: Story US-306 passed! diff --git a/src/modules/data-entry/views/receipts/ReceiptsListView.vue b/src/modules/data-entry/views/receipts/ReceiptsListView.vue index 052fdca..be56b58 100644 --- a/src/modules/data-entry/views/receipts/ReceiptsListView.vue +++ b/src/modules/data-entry/views/receipts/ReceiptsListView.vue @@ -1117,7 +1117,7 @@ const toggleFabMenu = (event) => { fabMenuRef.value?.toggle(event) } -// US-103: Top bar actions for MobileTopBar component +// US-103/US-306: Top bar actions for MobileTopBar component const mobileTopBarActions = computed(() => { if (mobileSelectionMode.value) { // Selection mode - show select all action @@ -1125,24 +1125,27 @@ const mobileTopBarActions = computed(() => { { id: 'select-all', icon: 'pi pi-check-square', label: 'Selectează tot', tooltip: 'Selectează tot' } ] } - // Normal mode - show search, filter, more menu + // Normal mode - show filter, export, more menu (US-306) return [ - { id: 'search', icon: 'pi pi-search', active: showFilters.value, tooltip: 'Căutare' }, { id: 'filter', icon: 'pi pi-filter', active: hasActiveFilters.value, tooltip: 'Filtre' }, + { id: 'export', icon: 'pi pi-download', tooltip: 'Export Excel' }, { id: 'more', icon: 'pi pi-ellipsis-v', tooltip: 'Mai multe' } ] }) -// US-103: Handle top bar action clicks +// US-103/US-306: Handle top bar action clicks const handleTopBarAction = (action) => { switch (action.id) { case 'select-all': selectAllMobile() break - case 'search': case 'filter': showFilters.value = !showFilters.value break + case 'export': + // US-306: Export all current receipts + exportAllReceipts() + break case 'more': // The more menu needs to be toggled with the event, but we don't have the event here // So we need to use a different approach - we'll keep using toggleMoreMenu directly @@ -2405,6 +2408,63 @@ const exportSelectedReceipts = () => { } } +/** + * US-306: Export all currently visible receipts to Excel. + * Exports all receipts from the current filtered list (excludes job items). + */ +const exportAllReceipts = () => { + // Filter out job items - only export actual receipts + const receiptsList = unifiedItems.value.filter(item => !isJobItem(item)) + + if (receiptsList.length === 0) { + toast.add({ + severity: 'warn', + summary: 'Atenție', + detail: 'Nu există bonuri de exportat', + life: 3000, + }) + return + } + + // Map receipt data to export format + const exportData = receiptsList.map(r => ({ + 'Magazin': r.store_name || r.partner_name || '-', + 'CUI': r.cui || '-', + 'Data': r.receipt_date ? formatDate(r.receipt_date) : '-', + 'Nr. Bon': r.receipt_number || '-', + 'Tip Document': r.receipt_type === 'receipt' ? 'Bon' : r.receipt_type === 'invoice' ? 'Factură' : r.receipt_type || '-', + 'Direcție': r.direction === 'expense' ? 'Cheltuială' : r.direction === 'income' ? 'Venit' : r.direction || '-', + 'Suma': r.amount || 0, + 'TVA': r.tva_total || 0, + 'Metodă Plată': getPaymentMethodLabel(r) || '-', + 'Status': getStatusLabel(r.status) || '-', + 'Creat de': r.created_by || '-', + 'Creat la': r.created_at ? formatDate(r.created_at) : '-', + })) + + const result = exportToExcel( + exportData, + `bonuri_export_${receiptsList.length}`, + 'Bonuri' + ) + + if (result.success) { + toast.add({ + severity: 'success', + summary: 'Export reușit', + detail: `${receiptsList.length} bonuri exportate cu succes`, + life: 3000, + }) + } else { + toast.add({ + severity: 'error', + summary: 'Eroare', + detail: 'Nu s-a putut exporta lista de bonuri', + life: 5000, + }) + } +} + /** * US-026: Confirmation dialog for bulk delete. * Uses PrimeVue ConfirmDialog to ask user before deleting multiple receipts. diff --git a/src/modules/reports/components/dashboard/cards/MaturityAndDetailsCard.vue b/src/modules/reports/components/dashboard/cards/MaturityAndDetailsCard.vue index 45644fe..1e765fe 100644 --- a/src/modules/reports/components/dashboard/cards/MaturityAndDetailsCard.vue +++ b/src/modules/reports/components/dashboard/cards/MaturityAndDetailsCard.vue @@ -977,6 +977,17 @@ onMounted(() => { loadMaturityData(); } }); + +// US-306: Expose methods for parent component (MobileTopBar actions) +defineExpose({ + exportExcel, + exportPDF, + selectedPeriod, + selectedType, + searchTerm, + handleSearch, + loadDetailedData +});