diff --git a/data-entry-app/CLAUDE.md b/data-entry-app/CLAUDE.md
index 806a463..336a3ae 100644
--- a/data-entry-app/CLAUDE.md
+++ b/data-entry-app/CLAUDE.md
@@ -1,5 +1,10 @@
# CLAUDE.md - Data Entry App
+## IMPORTANT - Reguli pentru Claude
+
+- **Pentru teste folosește DOAR `./start-data-entry-test.sh`** (server TEST 10.0.20.121)
+- **NU folosi `./start-data-entry-dev.sh`** decât la instrucțiuni explicite de la utilizator (server PRODUCȚIE 10.0.20.36)
+
## Scop
Aplicatie pentru introducere date in ERP (bonuri fiscale, chitante) cu workflow de aprobare.
diff --git a/data-entry-app/frontend/src/App.vue b/data-entry-app/frontend/src/App.vue
index de1f1b2..059fd86 100644
--- a/data-entry-app/frontend/src/App.vue
+++ b/data-entry-app/frontend/src/App.vue
@@ -64,12 +64,6 @@ const dataEntryMenuItems = computed(() => [
items: [
{ to: '/', icon: 'pi pi-list', label: 'Lista Bonuri' },
{ to: '/create', icon: 'pi pi-plus', label: 'Bon Nou' },
- {
- to: '/approval',
- icon: 'pi pi-check-circle',
- label: 'Aprobare',
- badge: pendingCount.value > 0 ? pendingCount.value : null
- },
]
}
])
diff --git a/data-entry-app/frontend/src/router/index.js b/data-entry-app/frontend/src/router/index.js
index 8b69abf..f093470 100644
--- a/data-entry-app/frontend/src/router/index.js
+++ b/data-entry-app/frontend/src/router/index.js
@@ -32,12 +32,6 @@ const routes = [
component: () => import('../views/receipts/ReceiptCreateView.vue'),
meta: { title: 'Editare Bon', requiresAuth: true }
},
- {
- path: '/approval',
- name: 'ReceiptApproval',
- component: () => import('../views/receipts/ReceiptApprovalView.vue'),
- meta: { title: 'Aprobare Bonuri', requiresAuth: true }
- }
]
const router = createRouter({
diff --git a/data-entry-app/frontend/src/views/receipts/ReceiptApprovalView.vue b/data-entry-app/frontend/src/views/receipts/ReceiptApprovalView.vue
deleted file mode 100644
index e8254b9..0000000
--- a/data-entry-app/frontend/src/views/receipts/ReceiptApprovalView.vue
+++ /dev/null
@@ -1,488 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
Niciun bon de aprobat
-
Toate bonurile au fost procesate
-
-
-
-
-
-
-
-
-
- {{ formatDate(data.receipt_date) }}
-
-
-
-
-
- {{ data.partner_name || '-' }}
-
-
-
-
-
- {{ formatAmount(data.amount) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/data-entry-app/frontend/src/views/receipts/ReceiptsListView.vue b/data-entry-app/frontend/src/views/receipts/ReceiptsListView.vue
index f37faee..cabeb4e 100644
--- a/data-entry-app/frontend/src/views/receipts/ReceiptsListView.vue
+++ b/data-entry-app/frontend/src/views/receipts/ReceiptsListView.vue
@@ -206,7 +206,34 @@
+
+
+
+
+ {{ selectedReceipts.length }} selectate
+
+
+
+
+
+
+
+
{{ formatDate(data.receipt_date) }}
@@ -357,6 +386,10 @@ const rejectDialogVisible = ref(false)
const rejectReason = ref('')
const receiptToReject = ref(null)
+// Bulk selection state
+const selectedReceipts = ref([])
+const bulkApproving = ref(false)
+
// Mobile detection
const isMobile = ref(window.innerWidth < 768)
const handleResize = () => {
@@ -509,6 +542,7 @@ const filterByStatus = async (status) => {
}
const onFilterChange = async () => {
+ selectedReceipts.value = [] // Clear selection on filter change
store.setFilters({
status: filters.value.status,
search: filters.value.search,
@@ -524,6 +558,7 @@ const onFilterChange = async () => {
}
const clearFilters = async () => {
+ selectedReceipts.value = [] // Clear selection on filter reset
filters.value = {
status: null,
search: '',
@@ -536,6 +571,7 @@ const clearFilters = async () => {
}
const onPageChange = async (event) => {
+ selectedReceipts.value = [] // Clear selection on page change
store.setPage(event.page + 1)
await store.fetchReceipts()
}
@@ -747,6 +783,50 @@ const confirmResubmit = (receipt) => {
},
})
}
+
+// ============ Bulk Actions ============
+
+const approveSelected = async () => {
+ const pendingOnly = selectedReceipts.value.filter(r => r.status === 'pending_review')
+ if (!pendingOnly.length) return
+
+ bulkApproving.value = true
+ let successCount = 0
+ let errorCount = 0
+
+ for (const receipt of pendingOnly) {
+ try {
+ await store.approveReceipt(receipt.id)
+ successCount++
+ } catch (error) {
+ errorCount++
+ }
+ }
+
+ bulkApproving.value = false
+ selectedReceipts.value = []
+
+ if (successCount > 0) {
+ toast.add({
+ severity: 'success',
+ summary: 'Succes',
+ detail: `${successCount} bonuri validate`,
+ life: 3000,
+ })
+ }
+
+ if (errorCount > 0) {
+ toast.add({
+ severity: 'warn',
+ summary: 'Atenție',
+ detail: `${errorCount} bonuri nu au putut fi validate`,
+ life: 5000,
+ })
+ }
+
+ await store.fetchReceipts()
+ await store.fetchStats()
+}