382 lines
11 KiB
Vue
382 lines
11 KiB
Vue
<template lang="pug">
|
||
.wrapper.flex.w-full.relative.mx-2
|
||
transition(name="schedule", mode="out-in")
|
||
.flex.justify-center.items-center.w-full(v-if="schedulesDataPresence")
|
||
base-loader(
|
||
:width="60",
|
||
:height="60"
|
||
)
|
||
.relative.flex.flex-col.px-6.py-6.h-full.w-full.gap-y-5(v-else)
|
||
schedule-header(
|
||
:start-month="startMonth",
|
||
:change-show-time="changeShowTime",
|
||
:show-time="showTime",
|
||
@switch-previous-month="switchPreviousMonth",
|
||
@switch-next-month="switchNextMonth"
|
||
)
|
||
schedule-table(
|
||
:schedules-employee="fetchSchedulesEmployee",
|
||
:schedule-list="scheduleList",
|
||
:serialized="serialized",
|
||
:buttons="buttons",
|
||
:start-month="startMonth",
|
||
:employees="employees",
|
||
:show-time="showTime",
|
||
:clear-select="clearSelect",
|
||
:select-employee="selectEmployee",
|
||
:replacement-sheet="replacementSheet",
|
||
:template="template",
|
||
:trim-owner-name="trimOwnerName",
|
||
:open-form="openForm",
|
||
:active-cell="activeCell",
|
||
:set-active-cell="setActiveCell",
|
||
:change-shift="postUpdateSchedule",
|
||
@schedule-employee="createScheduleEmployee",
|
||
@schedules="distributeRequest"
|
||
)
|
||
schedule-bar(
|
||
:buttons="buttons",
|
||
:times="times",
|
||
:create-schedules="postCreateSchedules",
|
||
:delete-schedule="deleteSchedule",
|
||
:template="template"
|
||
)
|
||
</template>
|
||
|
||
<script>
|
||
import * as moment from "moment";
|
||
import BaseLoader from "@/components/Loader/BaseLoader.vue";
|
||
import { fetchWrapper } from "@/shared/fetchWrapper.js";
|
||
import ScheduleHeader from "@/pages/schedule/components/ScheduleHeader.vue";
|
||
import ScheduleBar from "@/pages/schedule/components/ScheduleBar.vue";
|
||
import ScheduleTable from "@/pages/schedule/components/ScheduleTable.vue";
|
||
|
||
export default {
|
||
name: "TheSchedule",
|
||
components: {
|
||
ScheduleHeader,
|
||
ScheduleBar,
|
||
ScheduleTable,
|
||
BaseLoader,
|
||
},
|
||
data() {
|
||
return {
|
||
employeeList: [
|
||
{
|
||
initialization: true,
|
||
},
|
||
],
|
||
scheduleList: [],
|
||
employees: [],
|
||
serialized: [],
|
||
selectEmployee: {
|
||
label: "",
|
||
id: null,
|
||
},
|
||
times: { start_time: "", end_time: "" },
|
||
replacementSheet: {
|
||
currentEmployee: "",
|
||
replacementEmployee: "",
|
||
date: null,
|
||
start_time: "",
|
||
end_time: "",
|
||
schedules: [],
|
||
},
|
||
buttons: [
|
||
{
|
||
class: "button-work",
|
||
name: "Работает",
|
||
work: "WORKS",
|
||
active: false,
|
||
color: "#55CD76",
|
||
text: "'Р'",
|
||
},
|
||
{
|
||
class: "button-vacation",
|
||
name: "Отпуск/больничный",
|
||
work: "VACATION",
|
||
active: false,
|
||
color: "var(--btn-blue-color-2)",
|
||
text: "'О'",
|
||
},
|
||
{
|
||
class: "button-free",
|
||
name: "Выходной",
|
||
work: "DAY_OFF",
|
||
active: false,
|
||
color: "#9294A7",
|
||
text: "'В'",
|
||
},
|
||
],
|
||
template: { item: {} },
|
||
startMonth: moment().startOf("month"),
|
||
showTime: false,
|
||
schedulesDate: {},
|
||
currenSchedule: null,
|
||
activeCell: true,
|
||
};
|
||
},
|
||
computed: {
|
||
endMonth() {
|
||
return this.startMonth.clone().endOf("month");
|
||
},
|
||
schedulesDataPresence() {
|
||
return this.employeeList[0]?.initialization;
|
||
},
|
||
},
|
||
methods: {
|
||
openForm(e) {
|
||
this.currenSchedule = e;
|
||
this.replacementSheet.currentEmployee = this.trimOwnerName(
|
||
e.last_name,
|
||
e.first_name,
|
||
e.patronymic
|
||
);
|
||
this.replacementSheet.schedules = e.schedules;
|
||
},
|
||
changeShowTime() {
|
||
this.showTime = !this.showTime;
|
||
},
|
||
trimOwnerName(lastName, firstName, patronymic) {
|
||
let checkedFirstName = firstName !== null ? firstName[0] + "." : "";
|
||
let checkedPatronymic = patronymic !== null ? patronymic[0] + "." : "";
|
||
return `${lastName} ${checkedFirstName}${checkedPatronymic}`;
|
||
},
|
||
setActiveCell() {
|
||
this.activeCell = true;
|
||
},
|
||
clearSelect(employee) {
|
||
if (employee) {
|
||
employee.label = "";
|
||
employee.id = null;
|
||
} else {
|
||
this.selectEmployee.label = "";
|
||
this.selectEmployeeid = null;
|
||
}
|
||
if (this.buttons.find((e) => e.active))
|
||
this.buttons.find((e) => e.active).active = false;
|
||
},
|
||
fetchSchedules() {
|
||
fetchWrapper
|
||
.get("general/employee/")
|
||
.then((res) => {
|
||
this.employeeList = res.results;
|
||
})
|
||
.then(() => this.fetchSchedulesEmployee());
|
||
},
|
||
fetchSchedulesEmployee() {
|
||
this.scheduleList = [];
|
||
this.clearSelect();
|
||
fetchWrapper
|
||
.get(
|
||
`accounts/schedules/?date_after=${this.startMonth.format(
|
||
"YYYY-MM-DD"
|
||
)}&date_before=${this.endMonth.format("YYYY-MM-DD")}`
|
||
)
|
||
.then((data) => {
|
||
this.scheduleList.push(...data.results);
|
||
})
|
||
.then(() => this.filterScheduleEmployee());
|
||
},
|
||
filterScheduleEmployee() {
|
||
let serialized = [];
|
||
this.template.item = {};
|
||
this.scheduleList.forEach((e) => {
|
||
let foundedElem = serialized.find((elem) => elem.id === e.employee.id);
|
||
if (!foundedElem) {
|
||
serialized.push({
|
||
first_name: e.employee.first_name,
|
||
id: e.employee.id,
|
||
last_name: e.employee.last_name,
|
||
patronymic: e.employee.patronymic,
|
||
schedules: [
|
||
{
|
||
date: e.date,
|
||
end_time: e.end_time ? e.end_time.slice(0, -3) : "",
|
||
start_time: e.start_time ? e.start_time.slice(0, -3) : "",
|
||
status: e.status,
|
||
id: e.id,
|
||
title: e.title,
|
||
name: e.name,
|
||
},
|
||
],
|
||
});
|
||
} else {
|
||
foundedElem.schedules.push({
|
||
date: e.date,
|
||
end_time: e.end_time ? e.end_time.slice(0, -3) : "",
|
||
start_time: e.start_time ? e.start_time.slice(0, -3) : "",
|
||
status: e.status,
|
||
id: e.id,
|
||
title: e.title,
|
||
name: e.name,
|
||
});
|
||
}
|
||
});
|
||
this.serialized = serialized;
|
||
this.filterEmployee();
|
||
},
|
||
filterEmployee() {
|
||
this.employees = [];
|
||
this.employees = this.employeeList.filter((item) =>
|
||
this.serialized.every((el) => el.id !== item.id)
|
||
);
|
||
},
|
||
distributeRequest(inside, outside) {
|
||
this.insideSchedules = inside;
|
||
this.outsideSchedules = outside;
|
||
},
|
||
postCreateSchedules() {
|
||
this.activeCell = false;
|
||
let data = {
|
||
employee: this.schedulesDate.id,
|
||
active_flg: true,
|
||
start_time: this.times.start_time,
|
||
end_time: this.times.end_time,
|
||
status: this.buttons.find((e) => e.active)?.work,
|
||
};
|
||
if (this.template.item.label)
|
||
data.kind_template = this.template.item.name;
|
||
if (this.insideSchedules?.length > 0) {
|
||
this.postUpdateSchedule();
|
||
if (this.outsideSchedules) {
|
||
this.outsideSchedules.forEach((el) => {
|
||
fetchWrapper.post("accounts/schedules/create/", {
|
||
...data,
|
||
start_date: el.start_date,
|
||
end_date: el.end_date,
|
||
});
|
||
});
|
||
}
|
||
} else {
|
||
fetchWrapper
|
||
.post("accounts/schedules/create/", {
|
||
...data,
|
||
start_date: this.schedulesDate.start_date,
|
||
end_date: this.schedulesDate.end_date,
|
||
})
|
||
.then(() => this.fetchSchedules());
|
||
}
|
||
},
|
||
postUpdateSchedule() {
|
||
if (this.replacementSheet.date) {
|
||
let scheduleList = this.currenSchedule.schedules.find(
|
||
(el) =>
|
||
el.date === moment(this.replacementSheet.date).format("YYYY-MM-DD")
|
||
);
|
||
fetchWrapper
|
||
.post(`accounts/schedules/${scheduleList.id}/update/`, {
|
||
employee: this.replacementSheet.replacementEmployee.id,
|
||
active_flg: true,
|
||
start_time: this.replacementSheet.start_time,
|
||
end_time: this.replacementSheet.end_time,
|
||
status: scheduleList.status,
|
||
})
|
||
.then(() => this.fetchSchedules());
|
||
} else {
|
||
let ids = "";
|
||
this.insideSchedules.forEach((e) => (ids += e.id + ","));
|
||
ids = ids.slice(0, -1);
|
||
fetchWrapper
|
||
.post(`accounts/schedules/${ids}/update/`, {
|
||
employee: this.insideSchedules[0].employeeId,
|
||
active_flg: true,
|
||
start_time: this.times.start_time,
|
||
end_time: this.times.end_time,
|
||
status: this.buttons.find((e) => e.active).work,
|
||
})
|
||
.then(() => this.fetchSchedules());
|
||
}
|
||
},
|
||
createScheduleEmployee(e, id) {
|
||
this.schedulesDate = {
|
||
start_date: e.start,
|
||
end_date: e.end ? e.end : e.start,
|
||
id: id,
|
||
};
|
||
},
|
||
deleteSchedule() {
|
||
this.activeCell = false;
|
||
let ids = "";
|
||
if (this.insideSchedules?.length > 0) {
|
||
this.insideSchedules.forEach((e) => (ids += e.id + ","));
|
||
ids = ids.slice(0, -1);
|
||
fetchWrapper
|
||
.del(`accounts/schedules/${ids}/delete/`)
|
||
.then(() => this.fetchSchedules());
|
||
}
|
||
},
|
||
switchPreviousMonth() {
|
||
this.startMonth = this.startMonth.clone().subtract(1, "M");
|
||
},
|
||
switchNextMonth() {
|
||
this.startMonth = this.startMonth.clone().add(1, "M");
|
||
},
|
||
setTime() {
|
||
let now = new Date();
|
||
let hour = now.getHours();
|
||
let minute = now.getMinutes();
|
||
let localDatetime =
|
||
(hour < 10 ? "0" + hour.toString() : hour) +
|
||
":" +
|
||
(minute < 10 ? "0" + minute.toString() : minute);
|
||
this.times.start_time = localDatetime;
|
||
this.times.end_time = localDatetime;
|
||
this.replacementSheet.start_time = localDatetime;
|
||
this.replacementSheet.end_time = localDatetime;
|
||
},
|
||
setShiftTime() {
|
||
let dateSchedule = this.replacementSheet.schedules.find(
|
||
(e) =>
|
||
e.date === moment(this.replacementSheet.date).format("YYYY-MM-DD")
|
||
);
|
||
this.replacementSheet.start_time = dateSchedule?.start_time;
|
||
this.replacementSheet.end_time = dateSchedule?.end_time;
|
||
},
|
||
},
|
||
watch: {
|
||
startMonth() {
|
||
this.fetchSchedulesEmployee();
|
||
},
|
||
replacementSheet: {
|
||
immediate: true,
|
||
handler(newVal) {
|
||
if (newVal) this.setShiftTime();
|
||
},
|
||
deep: true,
|
||
},
|
||
},
|
||
mounted() {
|
||
this.fetchSchedules();
|
||
this.setTime();
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="sass" scoped>
|
||
.wrapper
|
||
overflow: auto
|
||
border-top-left-radius: 4px
|
||
border-top-right-radius: 4px
|
||
background-color: var(--default-white)
|
||
|
||
.schedule-enter-from
|
||
opacity: 0
|
||
transform: translateY(0px)
|
||
pointer-events: none
|
||
|
||
.schedule-enter-active
|
||
transition: 0.3s ease
|
||
|
||
.schedule-leave-to
|
||
opacity: 0
|
||
transform: translateY(0px)
|
||
pointer-events: none
|
||
|
||
.schedule-leave-active
|
||
transition: 0.3s ease
|
||
|
||
.schedule-move
|
||
transition: 0.3s ease
|
||
</style>
|