Add detailed daily report functionalities to department dashboard
Implemented new components for product sales and daily report form. Enhanced existing report displays with dynamic transaction and product count data. Introduced backend integration for fetching product and transaction details and updated UI to display relevant metrics.
This commit is contained in:
@@ -113,6 +113,18 @@ import {ref} from "vue";
|
||||
showDeleteObjectForm: (id, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showDeleteObjectForm(DepartmentDailyReports, id, onAfterSubmit);
|
||||
},
|
||||
getProductCount: async (department_id,product_id, date) => {
|
||||
return authenticatedRequest(
|
||||
"/departments/daily-reports/product-count?product_id=" + product_id + "&date=" + date + "&department_id=" + department_id,
|
||||
"GET"
|
||||
);
|
||||
},
|
||||
getTransactionCount: async (department_id, date) => {
|
||||
return authenticatedRequest(
|
||||
"/departments/daily-reports/transaction-count?date=" + date + "&department_id=" + department_id,
|
||||
"GET"
|
||||
);
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Show the create object form
|
||||
|
||||
+83
-13
@@ -7,10 +7,23 @@ import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrap
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import BookingsPagination from "@/components/displays/pagination/models/UserDashboard/BookingsPagination.vue";
|
||||
import DepartmentDashboardPageWrapper from "@/views/dashboards/departmentDashboard/DepartmentDashboardPageWrapper.vue";
|
||||
import DepartmentDashboardDailyReportCount
|
||||
from "@/views/dashboards/departmentDashboard/modules/daily-report/displays/DepartmentDashboardDailyReportCount.vue";
|
||||
import DepartmentDashboardDailyReportCount from "@/views/dashboards/departmentDashboard/modules/daily-report/displays/DepartmentDashboardDailyReportCount.vue";
|
||||
import {ref} from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import DepartmentDashboardDailyReportProductSales
|
||||
from "@/views/dashboards/departmentDashboard/modules/daily-report/displays/DepartmentDashboardDailyReportProductSales.vue";
|
||||
import DepartmentDashboardDailyReportTodayForm
|
||||
from "@/views/dashboards/departmentDashboard/modules/daily-report/displays/DepartmentDashboardDailyReportTodayForm.vue";
|
||||
import { Colors } from "@/ThemeConfig.vue";
|
||||
|
||||
/**
|
||||
* Get the current date
|
||||
* @returns {string} The current date (YYYY-MM-DD)
|
||||
*/
|
||||
const getDate = () => {
|
||||
const date = new Date();
|
||||
return date.toISOString().split('T')[0];
|
||||
};
|
||||
|
||||
// Get the department ID from the route
|
||||
const router = useRouter();
|
||||
@@ -19,24 +32,66 @@ console.log(department_id.value);
|
||||
|
||||
// Define the reactive variables
|
||||
const daily_reports = ref(null);
|
||||
const transactions = ref(null);
|
||||
const products_sold = ref(null);
|
||||
|
||||
|
||||
|
||||
// Get the transactions for the current day
|
||||
const getTransactions = async () => {
|
||||
await SessionUser.objects.department_daily_reports.functions.getTransactionCount(department_id.value, getDate())
|
||||
.then(response => {
|
||||
transactions.value = response.data.data.quantity;
|
||||
products_sold.value = response.data.data.products;
|
||||
});
|
||||
};
|
||||
|
||||
// Get the transactions
|
||||
getTransactions();
|
||||
|
||||
const reports = ref([
|
||||
{
|
||||
title: 'Transaktioner',
|
||||
subtitle: 'Dagens transaktioner',
|
||||
count: 10,
|
||||
icon: 'fas fa-money-bill-wave',
|
||||
color: 'primary',
|
||||
buttons: [
|
||||
{
|
||||
id: 1,
|
||||
href: '#',
|
||||
icon: 'fas fa-list',
|
||||
text: 'Se alle'
|
||||
}
|
||||
]
|
||||
count: transactions,
|
||||
icon: 'fas fa-exchange-alt',
|
||||
color: Colors.global.primaryColor,
|
||||
buttons: []
|
||||
},
|
||||
{
|
||||
title: 'Produkter solgt',
|
||||
subtitle: 'Dagens produkter solgt',
|
||||
count: products_sold,
|
||||
icon: 'fas fa-shopping-cart',
|
||||
color: Colors.global.primaryColor,
|
||||
buttons: []
|
||||
}
|
||||
]);
|
||||
|
||||
const product_ids = ref([
|
||||
/** Add the product IDs here */
|
||||
// Undervognsskyld pr. enhed
|
||||
{
|
||||
id: 21,
|
||||
out_of: 100,
|
||||
},
|
||||
// Spot Free (Varevogn)
|
||||
{
|
||||
id: 23,
|
||||
out_of: 100,
|
||||
},
|
||||
// Spot Free (Lastbil)
|
||||
{
|
||||
id: 24,
|
||||
out_of: 100,
|
||||
},
|
||||
// Fælg flex pr. enhed
|
||||
{
|
||||
id: 25,
|
||||
out_of: 100,
|
||||
},
|
||||
]);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -59,6 +114,16 @@ const reports = ref([
|
||||
</div>
|
||||
<!-- At the top of the page, we want to have a button that allows the user to create a new daily report -->
|
||||
<div class="columns is-multiline">
|
||||
<!-- Display the daily report product sales -->
|
||||
<div class="column is-4" v-for="product in product_ids" :key="product.id">
|
||||
<DepartmentDashboardDailyReportProductSales
|
||||
:product_id="product.id"
|
||||
:date="getDate()"
|
||||
:department_id="department_id"
|
||||
:color="Colors.global.primaryColor"
|
||||
/>
|
||||
</div>
|
||||
<!-- Display the daily report counts -->
|
||||
<div class="column is-4" v-for="report in reports" :key="report.title">
|
||||
<DepartmentDashboardDailyReportCount
|
||||
:title="report.title"
|
||||
@@ -70,6 +135,11 @@ const reports = ref([
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Form to create a new daily report -->
|
||||
<DepartmentDashboardDailyReportTodayForm
|
||||
:department_id="department_id"
|
||||
:date="getDate()"
|
||||
/>
|
||||
</DepartmentDashboardPageWrapper>
|
||||
</RestrictedPageWrapper>
|
||||
</template>
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@ const props = defineProps({
|
||||
title: String,
|
||||
subtitle: String,
|
||||
count: Number,
|
||||
out_of: Number,
|
||||
icon: String,
|
||||
color: String,
|
||||
buttons: Array,
|
||||
@@ -17,7 +18,7 @@ const props = defineProps({
|
||||
<div class="media">
|
||||
<div class="media-left is-flex p-2">
|
||||
<figure class="image is-48x48">
|
||||
<span class="icon has-text-primary">
|
||||
<span class="icon" :style="{ color: color }">
|
||||
<i :class="icon" class="fa-3x"></i>
|
||||
</span>
|
||||
</figure>
|
||||
@@ -28,8 +29,8 @@ const props = defineProps({
|
||||
</div>
|
||||
</div>
|
||||
<div class="content has-text-centered">
|
||||
<p class="title is-1">{{ count }}</p>
|
||||
<p class="subtitle is-6">Antal</p>
|
||||
<p class="title is-1"><span>{{ count }}</span> <span class="has-text-grey-light is-size-6" v-if="out_of > 0">/ {{ out_of }}</span></p>
|
||||
<p class="subtitle is-6"><span>Antal solgte</span><span v-if="out_of > 0" class="has-text-grey"> / Mulige solgte</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="card-footer">
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<script setup>
|
||||
import { ref, defineProps } from "vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import { Colors } from "@/ThemeConfig.vue";
|
||||
import DepartmentDashboardDailyReportCount from "@/views/dashboards/departmentDashboard/modules/daily-report/displays/DepartmentDashboardDailyReportCount.vue";
|
||||
|
||||
const props = defineProps({
|
||||
product_id: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
date: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
department_id: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: Colors.global.primaryColor
|
||||
}
|
||||
});
|
||||
|
||||
const generateTitle = () => {
|
||||
return product_name.value;
|
||||
};
|
||||
|
||||
const generateSubtitle = () => {
|
||||
return "Dagens salg af produktet";
|
||||
};
|
||||
|
||||
const generateCount = () => {
|
||||
return product_count.value;
|
||||
};
|
||||
|
||||
const generateIcon = () => {
|
||||
return "fas fa-shopping-cart";
|
||||
};
|
||||
|
||||
const generateColor = () => {
|
||||
return props.color;
|
||||
};
|
||||
|
||||
const product_name = ref(null);
|
||||
const get_product_name = async () => {
|
||||
await SessionUser.objects.products.get.single(props.product_id)
|
||||
.then(response => {
|
||||
product_name.value = response.name;
|
||||
});
|
||||
};
|
||||
|
||||
get_product_name();
|
||||
|
||||
const product_count = ref(null);
|
||||
const product_out_of = ref(null);
|
||||
const get_product_count = async () => {
|
||||
await SessionUser.objects.department_daily_reports.functions.getProductCount(props.department_id, props.product_id, props.date)
|
||||
.then(response => {
|
||||
product_count.value = response.data.data.quantity;
|
||||
product_out_of.value = response.data.data.out_of;
|
||||
});
|
||||
};
|
||||
|
||||
get_product_count();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DepartmentDashboardDailyReportCount
|
||||
:title="product_name"
|
||||
:subtitle="generateSubtitle()"
|
||||
:count="generateCount()"
|
||||
:out_of="product_out_of"
|
||||
:icon="generateIcon()"
|
||||
:color="generateColor()"
|
||||
>
|
||||
|
||||
</DepartmentDashboardDailyReportCount>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, defineProps } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
department_id: Number,
|
||||
date: String,
|
||||
});
|
||||
|
||||
// Define the form fields
|
||||
const water_usage = ref(0);
|
||||
const water_usage_morning = ref(0);
|
||||
|
||||
const onFormSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
console.log('Form submitted');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form @submit="onFormSubmit">
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-12">
|
||||
<h1 class="title">Dagens rapport</h1>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">Vandforbrug morgen (m3)</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" v-model="water_usage_morning" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">Vandforbrug (m3)</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" v-model="water_usage" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button class="button is-dark is-fullwidth">Gem</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user