feat(approvals): add chart to track total hours for each type, chart to track expenses, begin work on widget to display detailed shift info.
This commit is contained in:
parent
24a700d6f6
commit
89148343b6
|
|
@ -246,7 +246,7 @@ export default {
|
||||||
newUsers: 'New user',
|
newUsers: 'New user',
|
||||||
updateUsers: 'Update user',
|
updateUsers: 'Update user',
|
||||||
timeSheets: 'Time sheet',
|
timeSheets: 'Time sheet',
|
||||||
timeSheetValidations: 'Time sheet',
|
timeSheetValidations: 'Time sheet approvals',
|
||||||
},
|
},
|
||||||
timeSheet: {
|
timeSheet: {
|
||||||
timeSheetTab_1: 'Shifts',
|
timeSheetTab_1: 'Shifts',
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
import type { PayPeriodEmployeeDetails } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-details-interface';
|
import type { PayPeriodEmployeeDetails } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-details-interface';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
|
||||||
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
|
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
|
||||||
ChartJS.defaults.font.family = '"Roboto", sans-serif';
|
ChartJS.defaults.font.family = '"Roboto", sans-serif';
|
||||||
|
|
@ -21,8 +22,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const hours_worked_labels = ref<string[]>([]);
|
const hours_worked_labels = ref<string[]>([]);
|
||||||
const hours_worked_dataset = ref<ChartDataset<'bar'>[]>([]);
|
const hours_worked_dataset = ref<ChartDataset<'bar'>[]>([]);
|
||||||
|
|
||||||
|
|
||||||
const getHoursWorkedData = (): ChartData<'bar'> => {
|
const getHoursWorkedData = (): ChartData<'bar'> => {
|
||||||
if (props.rawData) {
|
if (props.rawData) {
|
||||||
|
|
@ -63,30 +63,12 @@
|
||||||
datasets: hours_worked_dataset.value,
|
datasets: hours_worked_dataset.value,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Bar
|
<Bar
|
||||||
:data="getHoursWorkedData()"
|
:data="getHoursWorkedData()"
|
||||||
:options="({
|
:options="props.options"
|
||||||
indexAxis: $q.screen.lt.md? 'y' : 'x',
|
|
||||||
plugins: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: t('timeSheetValidations.hoursWorkedChartTitle'),
|
|
||||||
color: '#616161'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
stacked: true,
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
stacked: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
/* eslint-disable */
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Doughnut } from 'vue-chartjs';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement, CategoryScale, LinearScale, type ChartData, type ChartOptions, type Plugin, type ChartDataset } from 'chart.js';
|
||||||
|
import type { PayPeriodOverviewEmployee } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-overview-employee-interface';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale, LinearScale);
|
||||||
|
ChartJS.defaults.font.family = '"Roboto", sans-serif';
|
||||||
|
ChartJS.defaults.maintainAspectRatio = false;
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
rawData: PayPeriodOverviewEmployee | undefined;
|
||||||
|
options?: ChartOptions<"doughnut"> | undefined;
|
||||||
|
plugins?: Plugin<"doughnut">[] | undefined;
|
||||||
|
}>(), {
|
||||||
|
options: () => ({}),
|
||||||
|
plugins: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const shift_type_labels = ref<string[]>([]);
|
||||||
|
const shift_type_totals = ref<ChartDataset<'doughnut'>[]>([{ data: [40, 0, 2, 5], }]);
|
||||||
|
|
||||||
|
if (props.rawData){
|
||||||
|
shift_type_totals.value = [{
|
||||||
|
data: [
|
||||||
|
props.rawData.regular_hours,
|
||||||
|
props.rawData.evening_hours,
|
||||||
|
props.rawData.emergency_hours,
|
||||||
|
props.rawData.overtime_hours,
|
||||||
|
],
|
||||||
|
backgroundColor: [
|
||||||
|
getComputedStyle(document.body).getPropertyValue('--q-primary').trim(),
|
||||||
|
getComputedStyle(document.body).getPropertyValue('--q-info').trim(),
|
||||||
|
getComputedStyle(document.body).getPropertyValue('--q-warning').trim(),
|
||||||
|
getComputedStyle(document.body).getPropertyValue('--q-negative').trim(),
|
||||||
|
]
|
||||||
|
}];
|
||||||
|
|
||||||
|
shift_type_labels.value = [
|
||||||
|
props.rawData.regular_hours.toString() + 'h',
|
||||||
|
props.rawData.evening_hours.toString() + 'h',
|
||||||
|
props.rawData.emergency_hours.toString() + 'h',
|
||||||
|
props.rawData.overtime_hours.toString() + 'h',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
labels: shift_type_labels.value,
|
||||||
|
datasets: shift_type_totals.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Doughnut
|
||||||
|
:data="data"
|
||||||
|
:options="props.options"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
/*eslint-disable*/
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Line } from 'vue-chartjs';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Chart as ChartJS, Title, Tooltip, Legend, LineElement, PointElement, LineController, CategoryScale, LinearScale, TimeScale, type ChartData, type ChartOptions, type Plugin, type ChartDataset } from 'chart.js';
|
||||||
|
import type { PayPeriodEmployeeDetails } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-details-interface';
|
||||||
|
import type { Expense } from 'src/modules/timesheets/types/timesheet-details-interface';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
ChartJS.register(Title, Tooltip, Legend, LineElement, LineController, PointElement, CategoryScale, LinearScale, TimeScale);
|
||||||
|
ChartJS.defaults.font.family = '"Roboto", sans-serif';
|
||||||
|
// ChartJS.defaults.maintainAspectRatio = false;
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
rawData: PayPeriodEmployeeDetails | undefined;
|
||||||
|
options?: ChartOptions<"line"> | undefined;
|
||||||
|
plugins?: Plugin<"line">[] | undefined;
|
||||||
|
}>(), {
|
||||||
|
options: () => ({}),
|
||||||
|
plugins: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const expenses_dataset = ref<ChartDataset<'line'>[]>([]);
|
||||||
|
const expenses_labels = ref<string[]>([]);
|
||||||
|
|
||||||
|
const getExpensesData = (): ChartData<'line'> => {
|
||||||
|
if (props.rawData) {
|
||||||
|
const all_weeks = [props.rawData.week1, props.rawData.week2];
|
||||||
|
const all_days = all_weeks.flatMap( week => Object.values(week.expenses));
|
||||||
|
console.log('all days: ', all_days);
|
||||||
|
const all_days_dates = all_weeks.flatMap( week => Object.values(week.shifts))
|
||||||
|
|
||||||
|
const all_costs = all_days.map( day => getTotalAmounts(day.cash));
|
||||||
|
const all_mileage = all_days.map( day => getTotalAmounts(day.km));
|
||||||
|
|
||||||
|
|
||||||
|
expenses_dataset.value = [
|
||||||
|
{
|
||||||
|
label: t('timeSheet.refund'),
|
||||||
|
data: all_costs,
|
||||||
|
borderColor: getComputedStyle(document.body).getPropertyValue('--q-primary').trim(),
|
||||||
|
backgroundColor: getComputedStyle(document.body).getPropertyValue('--q-primary').trim(),
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('timeSheet.mileage'),
|
||||||
|
data: all_mileage,
|
||||||
|
borderColor: getComputedStyle(document.body).getPropertyValue('--q-info').trim(),
|
||||||
|
backgroundColor: getComputedStyle(document.body).getPropertyValue('--q-info').trim(),
|
||||||
|
borderWidth: 2,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
expenses_labels.value = all_days_dates.map( day => day.short_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
datasets: expenses_dataset.value,
|
||||||
|
labels: expenses_labels.value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTotalAmounts = (expenses: Expense[]): number => {
|
||||||
|
let total_amount = 0;
|
||||||
|
|
||||||
|
for (const expense of expenses) {
|
||||||
|
total_amount += expense.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_amount;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Line
|
||||||
|
:data="getExpensesData()"
|
||||||
|
:options="props.options"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PayPeriodEmployeeDetails } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-employee-details-interface';
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
rawData: PayPeriodEmployeeDetails;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
@ -1,17 +1,25 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PayPeriodEmployeeDetails } from '../types/timesheet-approval-pay-period-employee-details-interface';
|
/*eslint-disable*/
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
import TimesheetApprovalEmployeeDetailsHoursWorkedChart from 'src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-hours-worked-chart.vue';
|
import TimesheetApprovalEmployeeDetailsHoursWorkedChart from 'src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-hours-worked-chart.vue';
|
||||||
|
import TimesheetApprovalEmployeeDetailsShiftTypesChart from 'src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-shift-types-chart.vue';
|
||||||
|
import TimesheetApprovalEmployeeExpensesChart from 'src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-expenses-chart.vue';
|
||||||
|
import type { PayPeriodOverviewEmployee } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-overview-employee-interface';
|
||||||
|
import type { PayPeriodEmployeeDetails } from '../types/timesheet-approval-pay-period-employee-details-interface';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
employeeName: string;
|
employeeName: string;
|
||||||
|
employeeOverview: PayPeriodOverviewEmployee | undefined;
|
||||||
employeeDetails: PayPeriodEmployeeDetails | undefined;
|
employeeDetails: PayPeriodEmployeeDetails | undefined;
|
||||||
updateKey: number;
|
updateKey: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-card class="q-pa-md bg-white shadow-12">
|
<q-card class="q-pa-md bg-white shadow-12 full-width rounded-15">
|
||||||
<!-- loader -->
|
<!-- loader -->
|
||||||
<q-card-section
|
<q-card-section
|
||||||
v-if="props.isLoading"
|
v-if="props.isLoading"
|
||||||
|
|
@ -28,21 +36,90 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<!-- employee name -->
|
<!-- employee name -->
|
||||||
<q-card-section v-if="!props.isLoading" class="text-h5 text-weight-bolder text-center full-width text-primary q-pt-none">
|
<q-card-section v-if="!props.isLoading" class="text-h5 text-weight-bolder text-center full-width text-primary q-pa-none text-uppercase">
|
||||||
{{ props.employeeName }}
|
{{ props.employeeName }}
|
||||||
|
<q-separator class="q-mb-sm" color="accent" size="2px" />
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
|
|
||||||
<!-- employee timesheet details -->
|
<!-- employee timesheet details -->
|
||||||
<q-card-section
|
<q-card-section v-if="!props.isLoading" class="q-pa-none justify-center">
|
||||||
v-if="!props.isLoading"
|
<TimesheetApprovalEmployeeDetailsHoursWorkedChart
|
||||||
class="q-pa-none justify-center"
|
ref="chart1"
|
||||||
:class="$q.screen.lt.lg? 'column': 'row'"
|
|
||||||
>
|
|
||||||
<TimesheetApprovalEmployeeDetailsHoursWorkedChart
|
|
||||||
:key="props.updateKey"
|
:key="props.updateKey"
|
||||||
:raw-data="props.employeeDetails"
|
:raw-data="props.employeeDetails"
|
||||||
style="min-height: 300px;"
|
style="min-height: 300px;"
|
||||||
|
:options="({
|
||||||
|
indexAxis: $q.screen.lt.md? 'y' : 'x',
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
labels: {
|
||||||
|
boxWidth: 15,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: t('timeSheetValidations.hoursWorkedChartTitle'),
|
||||||
|
color: '#616161'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: true,
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"
|
||||||
/>
|
/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator class="q-my-sm"/>
|
||||||
|
|
||||||
|
<q-card-section :horizontal="$q.screen.gt.sm">
|
||||||
|
<q-card-section class="q-pa-none q-ma-none">
|
||||||
|
<TimesheetApprovalEmployeeDetailsShiftTypesChart
|
||||||
|
:key="props.updateKey + 1"
|
||||||
|
style="max-height: 200px;"
|
||||||
|
:raw-data="props.employeeOverview"
|
||||||
|
:options="({
|
||||||
|
plugins:{
|
||||||
|
legend:{
|
||||||
|
labels:{
|
||||||
|
boxWidth: 15,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator :vertical="$q.screen.gt.sm" class="q-my-sm" />
|
||||||
|
<q-card-section class="q-py-none q-ma-none">
|
||||||
|
<TimesheetApprovalEmployeeExpensesChart
|
||||||
|
:style="$q.screen.lt.md ? 'min-height: 200px;': '' "
|
||||||
|
:raw-data="props.employeeDetails"
|
||||||
|
:options="({
|
||||||
|
plugins: {
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: t('timeSheetValidations.reportFilterExpenses'),
|
||||||
|
color: '#616161'
|
||||||
|
},
|
||||||
|
legend:{
|
||||||
|
labels:{
|
||||||
|
boxWidth: 15,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
point:{
|
||||||
|
pointStyle: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
const report_filter_company = ref<boolean[]>([true, true]);
|
const report_filter_company = ref<boolean[]>([true, true]);
|
||||||
const report_filter_type = ref<boolean[]>([true, true, true, true]);
|
const report_filter_type = ref<boolean[]>([true, true, true, true]);
|
||||||
const clicked_employee_name = ref<string>('');
|
const clicked_employee_name = ref<string>('');
|
||||||
|
const clicked_employee_email = ref<string>('');
|
||||||
const update_key = ref<number>(0);
|
const update_key = ref<number>(0);
|
||||||
|
|
||||||
const columns = computed((): QTableColumn<PayPeriodOverviewEmployee>[] => [
|
const columns = computed((): QTableColumn<PayPeriodOverviewEmployee>[] => [
|
||||||
|
|
@ -114,13 +115,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getEmployeeOverview = (email: string): PayPeriodOverviewEmployee | undefined => {
|
||||||
|
return timesheet_approval_api.getPayPeriodOverviewByEmployeeEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
const onDateSelected = async (date_string: string) => {
|
const onDateSelected = async (date_string: string) => {
|
||||||
await timesheet_approval_api.getPayPeriodOverviewByDate(date_string);
|
await timesheet_approval_api.getPayPeriodOverviewByDate(date_string);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClickedDetails = async (email: string, name: string) => {
|
const onClickedDetails = async (email: string, name: string) => {
|
||||||
clicked_employee_name.value = name;
|
clicked_employee_name.value = name;
|
||||||
|
clicked_employee_email.value = email;
|
||||||
is_showing_details.value = true;
|
is_showing_details.value = true;
|
||||||
|
|
||||||
await timesheet_approval_api.getTimesheetsByPayPeriodAndEmail(email);
|
await timesheet_approval_api.getTimesheetsByPayPeriodAndEmail(email);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -143,13 +150,14 @@
|
||||||
transition-show="jump-down"
|
transition-show="jump-down"
|
||||||
transition-hide="jump-down"
|
transition-hide="jump-down"
|
||||||
@before-show="() => update_key += 1"
|
@before-show="() => update_key += 1"
|
||||||
|
class="full-width"
|
||||||
>
|
>
|
||||||
<TimesheetApprovalEmployeeDetails
|
<TimesheetApprovalEmployeeDetails
|
||||||
:is-loading="timesheet_store.is_loading"
|
:is-loading="timesheet_store.is_loading"
|
||||||
:employee-name="clicked_employee_name"
|
:employee-name="clicked_employee_name"
|
||||||
|
:employee-overview="getEmployeeOverview(clicked_employee_email)"
|
||||||
:employee-details="timesheet_store.pay_period_employee_details"
|
:employee-details="timesheet_store.pay_period_employee_details"
|
||||||
:update-key="update_key"
|
:update-key="update_key"
|
||||||
class="full-width"
|
|
||||||
/>
|
/>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useTimesheetStore } from "src/stores/timesheet-store";
|
import { useTimesheetStore } from "src/stores/timesheet-store";
|
||||||
import { useAuthStore } from "src/stores/auth-store";
|
import { useAuthStore } from "src/stores/auth-store";
|
||||||
import type { PayPeriodReportFilters } from "../types/timesheet-approval-pay-period-report-interface";
|
import type { PayPeriodReportFilters } from "../types/timesheet-approval-pay-period-report-interface";
|
||||||
|
import type { PayPeriodOverviewEmployee } from "../types/timesheet-approval-pay-period-overview-employee-interface";
|
||||||
|
|
||||||
export const useTimesheetApprovalApi = () => {
|
export const useTimesheetApprovalApi = () => {
|
||||||
const timesheet_store = useTimesheetStore();
|
const timesheet_store = useTimesheetStore();
|
||||||
|
|
@ -15,6 +16,10 @@ export const useTimesheetApprovalApi = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getPayPeriodOverviewByEmployeeEmail = (email: string): PayPeriodOverviewEmployee | undefined => {
|
||||||
|
return timesheet_store.pay_period_overview_employees.find(overview => overview.email === email);
|
||||||
|
};
|
||||||
|
|
||||||
/* This method attempts to get the next or previous pay period.
|
/* This method attempts to get the next or previous pay period.
|
||||||
It checks if pay period number is within a certain range, adjusts pay period and year accordingly.
|
It checks if pay period number is within a certain range, adjusts pay period and year accordingly.
|
||||||
It then requests the matching pay period object to set as current pay period from server.
|
It then requests the matching pay period object to set as current pay period from server.
|
||||||
|
|
@ -39,11 +44,11 @@ export const useTimesheetApprovalApi = () => {
|
||||||
if (success) {
|
if (success) {
|
||||||
await timesheet_store.getTimesheetApprovalPayPeriodEmployeeOverviews(new_pay_year, new_pay_period_no, auth_store.user.email);
|
await timesheet_store.getTimesheetApprovalPayPeriodEmployeeOverviews(new_pay_year, new_pay_period_no, auth_store.user.email);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const getTimesheetsByPayPeriodAndEmail = async (employee_email: string) => {
|
const getTimesheetsByPayPeriodAndEmail = async (employee_email: string) => {
|
||||||
await timesheet_store.getTimesheetsByPayPeriodAndEmail(employee_email);
|
await timesheet_store.getTimesheetsByPayPeriodAndEmail(employee_email);
|
||||||
}
|
};
|
||||||
|
|
||||||
const getTimesheetApprovalCSVReport = async ( report_filter_company: boolean[], report_filter_type: boolean[] ) => {
|
const getTimesheetApprovalCSVReport = async ( report_filter_company: boolean[], report_filter_type: boolean[] ) => {
|
||||||
const [ targo, solucom ] = report_filter_company;
|
const [ targo, solucom ] = report_filter_company;
|
||||||
|
|
@ -54,11 +59,12 @@ export const useTimesheetApprovalApi = () => {
|
||||||
} as PayPeriodReportFilters;
|
} as PayPeriodReportFilters;
|
||||||
|
|
||||||
await timesheet_store.getTimesheetApprovalCSVReport(options);
|
await timesheet_store.getTimesheetApprovalCSVReport(options);
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getPayPeriodOverviewByDate,
|
getPayPeriodOverviewByDate,
|
||||||
getNextPayPeriodOverview,
|
getNextPayPeriodOverview,
|
||||||
|
getPayPeriodOverviewByEmployeeEmail,
|
||||||
getTimesheetsByPayPeriodAndEmail,
|
getTimesheetsByPayPeriodAndEmail,
|
||||||
getTimesheetApprovalCSVReport
|
getTimesheetApprovalCSVReport
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,12 @@ export const timesheetApprovalService = {
|
||||||
getPayPeriodEmployeeOverviews: async (year: number, period_number: number, supervisor_email: string): Promise<PayPeriodOverview> => {
|
getPayPeriodEmployeeOverviews: async (year: number, period_number: number, supervisor_email: string): Promise<PayPeriodOverview> => {
|
||||||
// TODO: REMOVE MOCK DATA PEFORE PUSHING TO PROD
|
// TODO: REMOVE MOCK DATA PEFORE PUSHING TO PROD
|
||||||
const response = await api.get(`pay-periods/${year}/${period_number}/${supervisor_email}`);
|
const response = await api.get(`pay-periods/${year}/${period_number}/${supervisor_email}`);
|
||||||
console.log('all employee data: ', response.data);
|
console.log('pay period data: ', response.data);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
getTimesheetsByPayPeriodAndEmail: async (year: number, period_no: number, email: string): Promise<PayPeriodEmployeeDetails> => {
|
getTimesheetsByPayPeriodAndEmail: async (year: number, period_no: number, email: string): Promise<PayPeriodEmployeeDetails> => {
|
||||||
const response = await api.get('timesheets', { params: { year, period_no, email, }});
|
const response = await api.get('timesheets', { params: { year, period_no, email, }});
|
||||||
console.log('employee details: ', response.data);
|
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,16 @@ export interface TimesheetDetailsWeek {
|
||||||
expenses: WeekDay<TimesheetDetailsDailyExpenses>;
|
expenses: WeekDay<TimesheetDetailsDailyExpenses>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TimesheetDetailsDailySchedule {
|
||||||
|
shifts: Shift[];
|
||||||
|
regular_hours: number;
|
||||||
|
evening_hours: number;
|
||||||
|
emergency_hours: number;
|
||||||
|
overtime_hours: number;
|
||||||
|
short_date: string; // ex. 08/24
|
||||||
|
break_duration?: number;
|
||||||
|
}
|
||||||
|
|
||||||
type WeekDay<T> = {
|
type WeekDay<T> = {
|
||||||
sun: T;
|
sun: T;
|
||||||
mon: T;
|
mon: T;
|
||||||
|
|
@ -16,23 +26,14 @@ type WeekDay<T> = {
|
||||||
sat: T;
|
sat: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TimesheetDetailsDailySchedule {
|
|
||||||
shifts: Shift[];
|
|
||||||
regular_hours: number;
|
|
||||||
evening_hours: number;
|
|
||||||
emergency_hours: number;
|
|
||||||
overtime_hours: number;
|
|
||||||
short_date: string; // ex. 08/24
|
|
||||||
break_duration?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TimesheetDetailsDailyExpenses {
|
interface TimesheetDetailsDailyExpenses {
|
||||||
costs: Expense[];
|
cash: Expense[];
|
||||||
mileage: Expense[];
|
km: Expense[];
|
||||||
[otherType: string]: Expense[]; //for possible future types of expenses
|
[otherType: string]: Expense[]; //for possible future types of expenses
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Expense {
|
export interface Expense {
|
||||||
is_approved: boolean;
|
is_approved: boolean;
|
||||||
amount: number;
|
amount: number;
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue
Block a user