diff --git a/apps/dashboard/src/modules/financial/routes.ts b/apps/dashboard/src/modules/financial/routes.ts
index a4b4e57e..85644125 100644
--- a/apps/dashboard/src/modules/financial/routes.ts
+++ b/apps/dashboard/src/modules/financial/routes.ts
@@ -5,6 +5,7 @@ import PayoutsView from "@/modules/financial/views/payouts/PayoutsView.vue";
import { UserRole } from "@/utils/rbacUtils";
import InvoiceOverview from "@/modules/financial/views/invoice/InvoiceOverview.vue";
import InvoiceInfoView from "@/modules/financial/views/invoice/InvoiceInfoView.vue";
+import InvoiceCreateView from "@/modules/financial/views/invoice/InvoiceCreateView.vue";
export function financialRoutes(): RouteRecordRaw[] {
return [
@@ -14,42 +15,62 @@ export function financialRoutes(): RouteRecordRaw[] {
meta: { requiresAuth: true },
children: [
{
- path: '/fine',
- component: FineView,
- name: 'fine',
- meta: {
- requiresAuth: true,
- rolesAllowed: [UserRole.BAC_PM]
- }
- },
- {
- path: '/invoice',
- component: InvoiceOverview,
- name: 'invoice',
- meta: {
- requiresAuth: true,
- rolesAllowed: [UserRole.BAC_PM]
- }
- },
- {
- path: '/invoice/:id/info',
- name: 'invoiceInfo',
- component: InvoiceInfoView,
- props: true,
- meta: {
- requiresAuth: true,
- rolesAllowed: [UserRole.BAC_PM]
- }
- },
- {
- path: '/payouts',
- component: PayoutsView,
- name: 'payouts',
- meta: {
- requiresAuth: true,
- rolesAllowed: [UserRole.BAC_PM]
+ path: '/fine',
+ component: FineView,
+ name: 'fine',
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
+ },
+ {
+ path: '/invoice',
+ component: InvoiceOverview,
+ name: 'invoice',
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
+ },
+ {
+ path: '/invoice/create',
+ component: InvoiceCreateView,
+ name: 'invoiceCreate',
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
+ },
+ {
+ path: '/invoice/:id',
+ redirect: to => {
+ const { id } = to.params;
+ return `/invoice/${id}/info`;
+ },
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
+ },
+ {
+ path: '/invoice/:id/info',
+ name: 'invoiceInfo',
+ component: InvoiceInfoView,
+ props: true,
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
+ },
+ {
+ path: '/payouts',
+ component: PayoutsView,
+ name: 'payouts',
+ meta: {
+ requiresAuth: true,
+ rolesAllowed: [UserRole.BAC_PM]
+ }
}
- }
]
}
];
diff --git a/apps/dashboard/src/modules/financial/views/FineView.vue b/apps/dashboard/src/modules/financial/views/FineView.vue
index 559636f6..578469e4 100644
--- a/apps/dashboard/src/modules/financial/views/FineView.vue
+++ b/apps/dashboard/src/modules/financial/views/FineView.vue
@@ -205,7 +205,7 @@ const handlePickedDates = handleSubmit(async (values) => {
[values.firstDate.toISOString(), values.secondDate.toISOString()],
["MEMBER"]);
const userFullNameMap: { [key: number]: string } = {};
- userStore.users.forEach((user: any) => {
+ Object.values(userStore.users).forEach((user: any) => {
userFullNameMap[user.id] = `${user.firstName} ${user.lastName}`;
});
const deletedUsers = userStore.getDeletedUsers.map((u: UserResponse) => u.id);
diff --git a/apps/dashboard/src/modules/financial/views/invoice/InvoiceCreateView.vue b/apps/dashboard/src/modules/financial/views/invoice/InvoiceCreateView.vue
new file mode 100644
index 00000000..80517a68
--- /dev/null
+++ b/apps/dashboard/src/modules/financial/views/invoice/InvoiceCreateView.vue
@@ -0,0 +1,36 @@
+
+
+
{{ t('modules.financial.invoice.create.create') }}
+
+
+
+
+
+
+
diff --git a/apps/dashboard/src/modules/financial/views/invoice/InvoiceInfoView.vue b/apps/dashboard/src/modules/financial/views/invoice/InvoiceInfoView.vue
index a1726401..4959a980 100644
--- a/apps/dashboard/src/modules/financial/views/invoice/InvoiceInfoView.vue
+++ b/apps/dashboard/src/modules/financial/views/invoice/InvoiceInfoView.vue
@@ -3,15 +3,20 @@
- {{ isCredit ? t("modules.financial.invoice.credit") : t("modules.financial.invoice.invoice") }}
+ {{ t("modules.financial.invoice.invoice") }}
{{ invoice.reference + ": " }} {{ invoice.description }}
+
+
+ {{ t("modules.financial.invoice.dirty") }}
+
-
+
+
@@ -39,19 +44,18 @@ import InvoiceStepsCard from "@/modules/financial/components/invoice/InvoiceStep
import InvoicePdf from "@/modules/financial/components/invoice/InvoicePdf.vue";
import InvoiceInfo from "@/modules/financial/components/invoice/InvoiceInfo.vue";
import { useI18n } from "vue-i18n";
+import InvoiceAmountCard from "@/modules/financial/components/invoice/InvoiceAmountCard.vue";
+import { isDirty } from "@/utils/invoiceUtil";
const { t } = useI18n();
-
const toast = useToast();
const route = useRoute();
+const invoiceStore = useInvoiceStore();
const invoice: Ref
= ref(undefined);
-const invoiceStore = useInvoiceStore();
-const isCredit = computed(() => {
- if (!invoice.value) return false;
- return invoice.value?.transfer?.to === undefined;
-});
+// Invoice is considered dirty if entry total does not match transfer total
+const dirty = computed(() => isDirty(invoice.value as InvoiceResponse));
onBeforeMount(async () => {
const id = Number(route.params.id);
diff --git a/apps/dashboard/src/modules/financial/views/invoice/InvoiceOverview.vue b/apps/dashboard/src/modules/financial/views/invoice/InvoiceOverview.vue
index b2a02984..951dfeba 100644
--- a/apps/dashboard/src/modules/financial/views/invoice/InvoiceOverview.vue
+++ b/apps/dashboard/src/modules/financial/views/invoice/InvoiceOverview.vue
@@ -1,7 +1,17 @@
{{ t('modules.financial.invoice.title') }}
-
+
+
+
+
@@ -17,12 +27,17 @@ import TabPanel from "primevue/tabpanel";
import TabView from "primevue/tabview";
import { InvoiceStatusResponseStateEnum } from "@sudosos/sudosos-client/src/api";
import { useI18n } from "vue-i18n";
+import Button from "primevue/button";
+import router from "@/router";
const { t } = useI18n();
const states = [ InvoiceStatusResponseStateEnum.Created, InvoiceStatusResponseStateEnum.Sent,
InvoiceStatusResponseStateEnum.Paid, InvoiceStatusResponseStateEnum.Deleted ];
+const navigateToCreateInvoice = () => {
+ router.push({ name: 'invoiceCreate' });
+};
\ No newline at end of file
diff --git a/apps/dashboard/tsconfig.node.json b/apps/dashboard/tsconfig.node.json
index bb67dfcb..72eb3b3b 100644
--- a/apps/dashboard/tsconfig.node.json
+++ b/apps/dashboard/tsconfig.node.json
@@ -1,5 +1,5 @@
{
- "extends": "@tsconfig/node18/tsconfig.json",
+ "extends": "@tsconfig/node-lts/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
diff --git a/apps/dashboard/vite.config.ts b/apps/dashboard/vite.config.ts
index 4f50d07a..259c178d 100644
--- a/apps/dashboard/vite.config.ts
+++ b/apps/dashboard/vite.config.ts
@@ -18,6 +18,13 @@ export default defineConfig(({ mode }) => {
optimizeDeps: {
exclude: ['ToastService'],
},
+ css: {
+ preprocessorOptions: {
+ scss: {
+ api: 'modern-compiler'
+ }
+ }
+ },
server: {
port: 5173,
proxy: {
diff --git a/apps/point-of-sale/index.html b/apps/point-of-sale/index.html
index d01a855a..619bc486 100644
--- a/apps/point-of-sale/index.html
+++ b/apps/point-of-sale/index.html
@@ -8,6 +8,10 @@
SudoSOS Point Of Sale
+
+
+
+
diff --git a/apps/point-of-sale/package.json b/apps/point-of-sale/package.json
index 51b51925..2d9e9b64 100644
--- a/apps/point-of-sale/package.json
+++ b/apps/point-of-sale/package.json
@@ -16,47 +16,9 @@
"format": "prettier --write src/"
},
"dependencies": {
- "@popperjs/core": "^2.11.8",
- "@sudosos/sudosos-client": "github:GEWIS/sudosos-client#cfcc3dad2494d8eb1911002fe0526c1e2e29cd25",
- "@sudosos/sudosos-frontend-common": "workspace:^",
- "bootstrap": "^5.3.0",
- "dinero": "^1.0.1",
- "dinero.js": "^1.9.1",
- "fuse.js": "^7.0.0",
- "jwt-decode": "^4.0.0",
- "pinia": "^2.1.3",
- "primeflex": "^3.3.1",
- "primeicons": "^6.0.1",
- "primevue": "^3.49.0",
- "vue": "^3.4.5",
- "vue-router": "^4.2.2"
+ "@sudosos/sudosos-frontend-common": "workspace:^"
},
"devDependencies": {
- "@intlify/eslint-plugin-vue-i18n": "^2.0.0",
- "@rushstack/eslint-patch": "^1.2.0",
- "@tsconfig/node18": "^18.2.2",
- "@types/eslint": "^9",
- "@types/lodash": "^4.14.196",
- "@types/node": "^18.16.19",
- "@types/vue": "^2.0.0",
- "@typescript-eslint/eslint-plugin": "^6.18.0",
- "@typescript-eslint/parser": "^6.18.0",
- "@vitejs/plugin-vue": "^5.0.0",
- "@vue/eslint-config-prettier": "^9.0.0",
- "@vue/eslint-config-typescript": "^12.0.0",
- "@vue/tsconfig": "^0.5.1",
- "axios": "^1.6.8",
- "eslint": "^8.50.0",
- "eslint-plugin-import": "^2.27.5",
- "eslint-plugin-vue": "^9.15.1",
- "husky": "^8.0.3",
- "lint-staged": "^15.2.0",
- "lodash": "^4.17.21",
- "npm-run-all": "^4.1.5",
- "prettier": "^3.1.1",
- "sass": "^1.69.7",
- "typescript": "^5.3.3",
- "vite": "^5.0.11",
- "vue-tsc": "^2.0.29"
+ "lint-staged": "^15.2.10"
}
}
diff --git a/apps/point-of-sale/public/bier_margin_green.png b/apps/point-of-sale/public/bier_margin_green.png
new file mode 100644
index 00000000..96758476
Binary files /dev/null and b/apps/point-of-sale/public/bier_margin_green.png differ
diff --git a/apps/point-of-sale/src/App.vue b/apps/point-of-sale/src/App.vue
index 64cde661..6155fb67 100644
--- a/apps/point-of-sale/src/App.vue
+++ b/apps/point-of-sale/src/App.vue
@@ -1,15 +1,22 @@
-
-
+
+
diff --git a/apps/point-of-sale/src/assets/splash.svg b/apps/point-of-sale/src/assets/splash.svg
new file mode 100644
index 00000000..b854dda6
--- /dev/null
+++ b/apps/point-of-sale/src/assets/splash.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/apps/point-of-sale/src/components/Banner/BannerComponent.vue b/apps/point-of-sale/src/components/Banner/BannerComponent.vue
index b86aa3dc..d4b470b9 100644
--- a/apps/point-of-sale/src/components/Banner/BannerComponent.vue
+++ b/apps/point-of-sale/src/components/Banner/BannerComponent.vue
@@ -10,7 +10,7 @@