feat(unified-mobile-material-design): Complete US-113 - Batch Actions per Module contextuale

Implemented by Ralph autonomous loop.
Iteration: 2

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 11:12:51 +00:00
parent 25af73dae2
commit 20c45a1f1e
3 changed files with 72 additions and 3 deletions

View File

@@ -258,8 +258,8 @@
"Fiecare acțiune are icon, label, severity, handler", "Fiecare acțiune are icon, label, severity, handler",
"npm run build passes" "npm run build passes"
], ],
"passes": false, "passes": true,
"notes": "" "notes": "Completed in iteration 2"
}, },
{ {
"id": "US-118", "id": "US-118",

View File

@@ -532,3 +532,9 @@ Mon Jan 12 09:44:54 AM UTC 2026
[2026-01-12 11:07:56] Working on story: US-111 [2026-01-12 11:07:56] Working on story: US-111
[2026-01-12 11:07:56] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_1_US-111.log) [2026-01-12 11:07:56] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_1_US-111.log)
[2026-01-12 11:10:08] SUCCESS: Story US-111 passed! [2026-01-12 11:10:08] SUCCESS: Story US-111 passed!
[2026-01-12 11:10:08] Changes committed
[2026-01-12 11:10:08] Progress: 14/20 stories completed
[2026-01-12 11:10:10] === Iteration 2/50 ===
[2026-01-12 11:10:10] Working on story: US-113
[2026-01-12 11:10:10] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-113.log)
[2026-01-12 11:12:51] SUCCESS: Story US-113 passed!

View File

@@ -984,6 +984,7 @@ import DragDropOverlay from '@data-entry/components/bulk/DragDropOverlay.vue'
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue' import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue' import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
import MobileSelectionFooter from '@shared/components/mobile/MobileSelectionFooter.vue' import MobileSelectionFooter from '@shared/components/mobile/MobileSelectionFooter.vue'
import { exportToExcel } from '@reports/utils/exportUtils'
import BatchGroupHeader from '@data-entry/components/bulk/BatchGroupHeader.vue' import BatchGroupHeader from '@data-entry/components/bulk/BatchGroupHeader.vue'
import ProcessingStatusCell from '@data-entry/components/bulk/ProcessingStatusCell.vue' import ProcessingStatusCell from '@data-entry/components/bulk/ProcessingStatusCell.vue'
import Paginator from 'primevue/paginator' import Paginator from 'primevue/paginator'
@@ -1147,13 +1148,20 @@ const handleBottomNavClick = (item) => {
} }
} }
// US-103: Selection footer actions for MobileSelectionFooter component // US-103/US-113: Selection footer actions for MobileSelectionFooter component
// Bonuri batch actions: Delete + Export
const mobileSelectionActions = computed(() => [ const mobileSelectionActions = computed(() => [
{ {
label: 'Șterge', label: 'Șterge',
icon: 'pi pi-trash', icon: 'pi pi-trash',
severity: 'danger', severity: 'danger',
handler: () => confirmBulkDelete() handler: () => confirmBulkDelete()
},
{
label: 'Export',
icon: 'pi pi-download',
severity: 'secondary',
handler: () => exportSelectedReceipts()
} }
]) ])
@@ -2329,6 +2337,61 @@ const approveSelected = async () => {
await store.fetchStats() await store.fetchStats()
} }
/**
* US-113: Export selected receipts to Excel.
* Exports receipt data including store name, date, amount, VAT, status etc.
*/
const exportSelectedReceipts = () => {
const receipts = selectedReceipts.value
if (receipts.length === 0) {
toast.add({
severity: 'warn',
summary: 'Atenție',
detail: 'Nu există bonuri selectate pentru export',
life: 3000,
})
return
}
// Map receipt data to export format
const exportData = receipts.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_selectate_${receipts.length}`,
'Bonuri'
)
if (result.success) {
toast.add({
severity: 'success',
summary: 'Export reușit',
detail: `${receipts.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. * US-026: Confirmation dialog for bulk delete.
* Uses PrimeVue ConfirmDialog to ask user before deleting multiple receipts. * Uses PrimeVue ConfirmDialog to ask user before deleting multiple receipts.