Files
pleno-vue/src/views/dashboards/departmentDashboard/other/displays/DepartmentDailyReportThisWeek.vue
T

195 lines
7.4 KiB
Vue

<script setup>
import { computed, ref, watch } from "vue";
import { BSkeleton } from "buefy";
import { departments as loadedDepartments } from "@/components/pagination/departmentTabs.vue";
import { SessionUser } from "@/components/session/token/SessionUser.vue";
import DepartmentDashboardOverviewNavigation from "@/views/dashboards/departmentDashboard/other/displays/DepartmentDashboardOverviewNavigation.vue";
import { finished_loading, is_latest_fetch, is_loading, next_fetch_id } from "@/views/dashboards/departmentDashboard/other/displays/DepartmentsOverviewObject.vue";
import { selected_date, selected_date_to } from "@/views/dashboards/departmentDashboard/modules/daily-report/DepartmentDailyReportObject.vue";
import { buildOutsideHoursBreakdownText, buildOutsideHoursWarningText, createEmptyOutsideHours, normalizeOutsideHours } from "@/views/dashboards/departmentDashboard/modules/daily-report/outsideHours.js";
const props = defineProps({
departments: {
type: Array,
default: [],
required: true,
},
});
const income = ref(0);
const sales = ref(0);
const transactions = ref(0);
const washes = ref(0);
const outsideHours = ref(createEmptyOutsideHours());
const identifier = "DepartmentDailyReportThisWeek";
const departmentSelectionKey = computed(() => (
Array.isArray(props.departments)
? props.departments
.map((department) => Number(department?.id ?? department))
.filter((departmentId) => departmentId > 0)
.join(",")
: ""
));
const resetSummary = () => {
income.value = 0;
sales.value = 0;
transactions.value = 0;
washes.value = 0;
outsideHours.value = createEmptyOutsideHours();
};
const getTransactionsInSelection = async () => {
if (!Array.isArray(props.departments) || props.departments.length === 0) {
resetSummary();
return;
}
const fetch_id = next_fetch_id(identifier);
const tmp = {
income: 0,
sales: 0,
transactions: 0,
washes: 0,
outsideHours: createEmptyOutsideHours(),
};
for (const department of props.departments) {
// eslint-disable-next-line no-await-in-loop
await SessionUser.objects.department_daily_reports.functions.getTransactionCount(
department,
selected_date.value,
selected_date_to.value
).then((response) => {
if (!is_latest_fetch(fetch_id, identifier)) {
finished_loading(fetch_id, identifier);
return;
}
const payload = response?.data?.data || {};
const normalizedOutsideHours = normalizeOutsideHours(payload.outside_hours);
tmp.income += Number(payload.earnings ?? 0);
tmp.sales += Number(payload.products ?? 0);
tmp.transactions += Number(payload.quantity ?? 0);
tmp.washes += Number(payload.washes ?? 0);
tmp.outsideHours.total += normalizedOutsideHours.total;
tmp.outsideHours.by_source.orders += normalizedOutsideHours.by_source.orders;
tmp.outsideHours.by_source.xlvask += normalizedOutsideHours.by_source.xlvask;
tmp.outsideHours.by_source.selfserve += normalizedOutsideHours.by_source.selfserve;
tmp.outsideHours.has_missing_opening_hours = tmp.outsideHours.has_missing_opening_hours
|| normalizedOutsideHours.has_missing_opening_hours;
tmp.outsideHours.missing_department_ids = Array.from(new Set([
...tmp.outsideHours.missing_department_ids,
...normalizedOutsideHours.missing_department_ids,
]));
});
}
if (!is_latest_fetch(fetch_id, identifier)) {
finished_loading(fetch_id, identifier);
return;
}
income.value = tmp.income;
sales.value = tmp.sales;
transactions.value = tmp.transactions;
washes.value = tmp.washes;
outsideHours.value = tmp.outsideHours;
finished_loading(fetch_id, identifier);
};
watch([() => selected_date.value, () => selected_date_to.value, departmentSelectionKey], () => {
getTransactionsInSelection();
}, { immediate: true });
</script>
<template>
<div class="columns is-multiline is-vcentered">
<div class="column is-12">
<DepartmentDashboardOverviewNavigation />
</div>
</div>
<div class="columns is-multiline is-vcentered" data-testid="overview-summary-grid">
<div class="column is-12">
<div class="columns is-multiline is-vcentered">
<div class="column is-3">
<div class="box" data-testid="overview-summary-revenue">
<p class="subtitle is-6">
{{ $t("department_reports.revenue") }} {{ SessionUser.functions.date.isToday(selected_date) && SessionUser.functions.date.isToday(selected_date_to) ? $t("department_reports.today") : "" }}
</p>
<p class="title is-4">
<template v-if="is_loading(identifier)">
<b-skeleton :width="'100%'" :height="'1em'" />
</template>
<template v-else>
{{ SessionUser.functions.currency.toLocal(income) }}
</template>
</p>
</div>
</div>
<div class="column is-3">
<div class="box" data-testid="overview-summary-avg-revenue">
<p class="subtitle is-6">
{{ $t("department_reports.avg_revenue_per_wash") }} {{ SessionUser.functions.date.isToday(selected_date) && SessionUser.functions.date.isToday(selected_date_to) ? $t("department_reports.today") : "" }}
</p>
<p class="title is-4">
<template v-if="is_loading(identifier)">
<b-skeleton :width="'100%'" :height="'1em'" />
</template>
<template v-else>
{{ SessionUser.functions.currency.toLocal((income / washes) || 0) }}
</template>
</p>
</div>
</div>
<div class="column is-3">
<div class="box" data-testid="overview-summary-washes">
<p class="subtitle is-6">
{{ $t("department_reports.washes") }} {{ SessionUser.functions.date.isToday(selected_date) && SessionUser.functions.date.isToday(selected_date_to) ? $t("department_reports.today") : "" }}
</p>
<p class="title is-4">
<template v-if="is_loading(identifier)">
<b-skeleton :width="'100%'" :height="'1em'" />
</template>
<template v-else>
{{ washes }}
</template>
</p>
</div>
</div>
<div class="column is-3">
<div class="box" data-testid="overview-summary-night-washes">
<p class="subtitle is-6">
{{ $t("admin.daily_report.reports.night_washes.title") }}
</p>
<p class="title is-4">
<template v-if="is_loading(identifier)">
<b-skeleton :width="'100%'" :height="'1em'" />
</template>
<template v-else>
<span data-testid="overview-summary-night-washes-total">{{ outsideHours.total }}</span>
</template>
</p>
<p class="is-size-7 has-text-grey-dark" data-testid="overview-summary-night-washes-breakdown">
{{ buildOutsideHoursBreakdownText(outsideHours, $t) }}
</p>
<p
v-if="buildOutsideHoursWarningText(outsideHours, loadedDepartments, $t)"
class="is-size-7 has-text-warning-dark mt-2"
data-testid="overview-summary-night-washes-warning"
>
{{ buildOutsideHoursWarningText(outsideHours, loadedDepartments, $t) }}
</p>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
</style>