## What
Three small quality improvements to the Superuser > Fakturaer > Periode
page, following the same flow as the earlier Fakturer nu / XL Vask
manual-review cleanup.
## Changes
### 1. User-facing error for 'Fakturer nu' failure
**File:**
`src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/views/InvoicingBillingPeriodViewAll.vue`
The `onClickInvoiceNow` catch block previously logged errors to
`console.error` only. Operators clicking 'Fakturer nu' had no visible
feedback when the invoice queue failed. Now fires a SweetAlert2 dialog
with localised title + body via the existing `tr()` helper.
```js
await Swal.fire({
title: tr("errors.fakturer_nu_failed_title", "Fakturer nu mislykkedes"),
text: tr("errors.fakturer_nu_failed_body", "Kunne ikke oprette faktura for denne kunde. Prøv igen, eller tjek kundens transaktioner."),
icon: "error",
});
```
### 2. Debug console.log removal
**Files:**
-
`src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/displays/layout/SmallCustomerActivityChart.vue`
-
`src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/displays/InvoicingBillingPeriodDatePeriodSelector.vue`
Two `console.log` debugging leftovers removed:
- `SmallCustomerActivityChart.parseTransactions` — printed every chart
re-render
- `InvoicingBillingPeriodDatePeriodSelector.onSelectionChange` — printed
every date-selection change
### 3. Translation entries
**Files:**
-
`src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/services/invoicingPeriodTranslation.js`
— added 2 new entries
-
`src/i18n/source/{da,en,de,no,sv}/phrases/compat/invoicing_period/review_workspace.json`
— added `errors.fakturer_nu_failed_title` and
`errors.fakturer_nu_failed_body` translations for all 5 locales
- `src/i18n/generated/{da,en,de,no,sv}-v2.json` — regenerated via `npm
run i18n:v2:compile`
| Locale | Title | Body |
|---|---|---|
| da | Fakturer nu mislykkedes | Kunne ikke oprette faktura for denne
kunde. Prøv igen, eller tjek kundens transaktioner. |
| en | Invoice now failed | Could not create invoice for this customer.
Try again, or check the customer's transactions. |
| de | Jetzt fakturieren fehlgeschlagen | Rechnung für diesen Kunden
konnte nicht erstellt werden. Erneut versuchen oder Transaktionen
prüfen. |
| no | Fakturer nå mislyktes | Kunne ikke opprette faktura for denne
kunden. Prøv igjen, eller sjekk kundens transaksjoner. |
| sv | Fakturera nu misslyckades | Kunde inte skapa faktura för denna
kund. Försök igen, eller kontrollera kundens transaktioner. |
## Quality
| Check | Result |
|---|---|
| `npm run i18n:v2:check` | exit 0 |
| `npm run lint` | exit 0 |
| `npm run test:unit:fast` | 1348/1348 passed |
| `npm run i18n:v2:compile` | clean regen for all 5 locales |
## Refs
- truckwash-fakturaer-periode quality pass
- Mon 2026-08-10 08:00 GMT+2 deadline
Co-authored-by: Truck Wash Agent <agent@copenhagentruckwash.local>
97 lines
2.4 KiB
Vue
97 lines
2.4 KiB
Vue
<script setup>
|
|
import {ref, watch} from 'vue';
|
|
|
|
|
|
const props = defineProps({
|
|
transactions: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
dates: {
|
|
type: Object,
|
|
required: true,
|
|
default: () => ({
|
|
dateFrom: new Date(new Date().setHours(0, 0, 0, 0)), // Start of the day (Today at 00:00:00)
|
|
dateTo: new Date(new Date().setHours(23, 59, 59, 999)), // End of the day (Today at 23:59:59)
|
|
})
|
|
},
|
|
});
|
|
import {
|
|
Chart as ChartJS,
|
|
Title,
|
|
Tooltip,
|
|
Legend,
|
|
BarElement,
|
|
CategoryScale,
|
|
LinearScale,
|
|
Colors,
|
|
PointElement,
|
|
LineElement
|
|
} from 'chart.js'
|
|
import { Line } from 'vue-chartjs';
|
|
ChartJS.register(Title, Tooltip, Legend, CategoryScale, LinearScale, BarElement, PointElement, LineElement, Colors);
|
|
|
|
const parseTransactions = () => {
|
|
const labels = [];
|
|
const data = [];
|
|
props.transactions.forEach(transaction => {
|
|
const formattedDate = transaction.date.split(' ')[0]; // Format date to YYYY-MM-DD
|
|
if (!labels.includes(formattedDate)) {
|
|
labels.push(formattedDate);
|
|
data.push(0); // Initialize with 0 for the new date
|
|
}
|
|
const index = labels.indexOf(formattedDate);
|
|
data[index] += transaction.amount; // Assuming transaction has an 'amount' field
|
|
});
|
|
// Sort the labels and data arrays based on the labels
|
|
const sortedIndices = labels.map((label, index) => index).sort((a, b) => new Date(labels[a]) - new Date(labels[b]));
|
|
labels.sort((a, b) => new Date(a) - new Date(b));
|
|
data.sort((a, b) => new Date(labels[sortedIndices[data.indexOf(a)]]) - new Date(labels[sortedIndices[data.indexOf(b)]]));
|
|
// Update the parsedList with the sorted labels and data
|
|
parsedList.value.labels = labels;
|
|
parsedList.value.datasets[0].data = data;
|
|
}
|
|
|
|
/** Define the data */
|
|
const options = {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
}
|
|
};
|
|
const parsedList = ref({
|
|
labels: [],
|
|
datasets: [
|
|
{
|
|
label: 'Omsætning',
|
|
backgroundColor: '#f87979',
|
|
data: []
|
|
}
|
|
]
|
|
});
|
|
|
|
// Function to parse purchases and update the chart data
|
|
watch(() => props.transactions, (newTransactions) => {
|
|
if (newTransactions && newTransactions.length > 0) {
|
|
parseTransactions();
|
|
}
|
|
}, { immediate: true });
|
|
// Initial call to parse transactions
|
|
parseTransactions();
|
|
</script>
|
|
|
|
<template>
|
|
<div class="w-full h-96">
|
|
<Line
|
|
:data="parsedList"
|
|
:options="options"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style> |