-
-
-
-
-
- บัญชีรายชื่อข้าราชการผู้ขอพระราชทานเครื่องราชอิสริยาภรณ์
-
-
-
-
-
-
-
- บัญชีระดับผลการประเมินผลการปฏิบัติราชการในรอบ 5 ปี
-
-
+
+
+
+
+
+
-
-
-
-
-
- บัญชีแสดงจำนวนชั้นตราเครื่องราชฯ
-
-
+
+
+
+
+
+
+ ไฟล์ .pdf
+
+
+
+ ไฟล์ .docx
+
+
+
+ ไฟล์ .xlsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ filterSelector(inputValue, doneFn,'round') "
+ >
+
+
+
+ ไม่มีข้อมูล
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ prop.node.orgTreeName }}
+
+
+ {{ prop.node.orgCode == null ? null : prop.node.orgCode }}
+ {{
+ prop.node.orgTreeShortName == null
+ ? null
+ : prop.node.orgTreeShortName
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
@@ -57,4 +439,18 @@ function nextPage(type: string) {
.q-item.hover-green {
padding: 10px;
}
+
+.tree-container {
+ overflow: auto;
+ height: 60vh;
+ border: 1px solid #e6e6e7;
+ border-radius: 10px;
+}
+.my-list-link {
+ color: rgb(118, 168, 222);
+ border-radius: 5px;
+ background: #a3d3fb48 !important;
+ font-weight: 600;
+ border: 1px solid rgba(175, 185, 196, 0.217);
+}
diff --git a/src/modules/09_leave/interface/index/Main.ts b/src/modules/09_leave/interface/index/Main.ts
index 58ada0de4..0f0a59dd5 100644
--- a/src/modules/09_leave/interface/index/Main.ts
+++ b/src/modules/09_leave/interface/index/Main.ts
@@ -6,6 +6,7 @@ interface DataOption2 {
id: number;
name: string;
}
+
interface DataDateMonthObject {
month: number;
year: number;
diff --git a/src/modules/09_leave/router.ts b/src/modules/09_leave/router.ts
index 6666df9f0..fe159a4b3 100644
--- a/src/modules/09_leave/router.ts
+++ b/src/modules/09_leave/router.ts
@@ -10,6 +10,9 @@ const ChangeRoundMain = () =>
const SpecialTimeMain = () =>
import("@/modules/09_leave/views/04_SpecialTimeMain.vue");
const leaveReport = () => import("@/modules/09_leave/views/06_ReportMain.vue");
+
+const CheckinReport = () =>
+ import("@/modules/09_leave/views/07_ReportCheckin.vue");
export default [
{
path: "/round-time",
@@ -91,24 +94,15 @@ export default [
Role: "STAFF",
},
},
- // {
- // path: "/statistics-report",
- // name: "/statistics-report",
- // component: reportMain,
- // meta: {
- // Auth: true,
- // Key: [9],
- // Role: "leave",
- // },
- // },
- // {
- // path: "/statistics-report/:type",
- // name: "/statistics-report-detail",
- // component: reportDetail,
- // meta: {
- // Auth: true,
- // Key: [9],
- // Role: "leave",
- // },
- // },
+
+ {
+ path: "/checkinReport",
+ name: "checkinReport",
+ component: CheckinReport,
+ meta: {
+ Auth: true,
+ Key: "SYS_WORK_REPORT",
+ Role: "STAFF",
+ },
+ },
];
diff --git a/src/modules/09_leave/views/02_WorkingMain.vue b/src/modules/09_leave/views/02_WorkingMain.vue
index 0335224c2..d28f5b1ab 100644
--- a/src/modules/09_leave/views/02_WorkingMain.vue
+++ b/src/modules/09_leave/views/02_WorkingMain.vue
@@ -4,7 +4,7 @@ import { ref } from "vue";
/** import Components */
import Tab1 from "@/modules/09_leave/components/02_WorkList/Tab1.vue";
import Tab2 from "@/modules/09_leave/components/02_WorkList/Tab2.vue";
-import DialogReport from "@/modules/09_leave/components/02_WorkList/DialogReport.vue";
+// import DialogReport from "@/modules/09_leave/components/02_WorkList/DialogReport.vue";
const tab = ref("1");
@@ -18,7 +18,7 @@ function onClickOpenDialog() {
รายการลงเวลาปฏิบัติงาน
-
รายงานสถิติการลงเวลา
-
+ -->
@@ -60,7 +60,7 @@ function onClickOpenDialog() {
-
+
diff --git a/src/modules/09_leave/views/06_ReportMain.vue b/src/modules/09_leave/views/06_ReportMain.vue
index a17e24433..c26c5863b 100644
--- a/src/modules/09_leave/views/06_ReportMain.vue
+++ b/src/modules/09_leave/views/06_ReportMain.vue
@@ -4,33 +4,59 @@ import { ref, onMounted } from "vue";
import { VuePDF, usePDF } from "@tato30/vue-pdf";
import { useQuasar } from "quasar";
-import http from "@/plugins/http";
-import config from "@/app.config";
+import { useRoute } from "vue-router";
import { checkPermission } from "@/utils/permissions";
import { useCounterMixin } from "@/stores/mixin";
+import { useStructureTree } from "@/stores/structureTree";
+import genReportXLSX from "@/plugins/genreportxlsx";
+import http from "@/plugins/http";
+import config from "@/app.config";
-import type { DataOption } from "@/modules/09_leave/interface/index/Main";
+import type { DataStructureTree } from "@/interface/main";
+import type {
+ DataOption,
+ DataDateMonthObject,
+} from "@/modules/09_leave/interface/index/Main";
+
+import LoadView from "@/components/LoadView.vue";
/** use*/
-const mixin = useCounterMixin();
const $q = useQuasar();
-const { showLoader, hideLoader, date2Thai, dateToISO, messageError } = mixin;
-
-const apiGenReport =
- "https://report-server.frappet.synology.me/api/v1/report-template/xlsx";
+const route = useRoute();
+const { fetchStructureTree } = useStructureTree();
+const {
+ showLoader,
+ hideLoader,
+ date2Thai,
+ dateToISO,
+ messageError,
+ monthYear2Thai,
+} = useCounterMixin();
const year = ref
(new Date().getFullYear());
const dateStart = ref(new Date(year.value, 9, 1));
const dateEnd = ref(new Date(year.value + 1, 8, 30));
-const employeeClass = ref("employee");
+const dateMonth = ref({
+ month: new Date().getMonth(),
+ year: new Date().getFullYear(),
+});
+
+const typeReport = ref("");
+const optionReport = ref([
+ { id: "1", name: "รายงานการลางานตามประเภทการลา" },
+ { id: "2", name: "รายงานการลางาน" },
+]);
+
+const employeeClass = ref("officer");
const yearType = ref("FULL");
const employeeClassMain = ref([
- { id: "employee", name: "ลูกจ้างประจำ กทม." },
{ id: "officer", name: "ข้าราชการ กทม. สามัญ" },
+ { id: "employee", name: "ลูกจ้างประจำ กทม." },
]);
const yearTypeOptionMain = ref([
{ id: "FULL", name: "รายปี" },
+ { id: "MONTH", name: "รายเดือน" },
{ id: "FIRSTHAFT", name: "ครึ่งปีแรก" },
{ id: "SECONDHAFT", name: "ครึ่งปีหลัง" },
]);
@@ -38,26 +64,76 @@ const employeeClassOption = ref(employeeClassMain.value);
const yearTypeOptionOption = ref(yearTypeOptionMain.value);
const detailReport = ref();
+const isReport = ref(false);
+const isLoadPDF = ref(false);
+
+/** tree*/
+const filterTree = ref("");
+const nodeId = ref("");
+const nodeLevel = ref(0);
+const node = ref([]);
+const expanded = ref([]);
+
+async function fetchDataTree() {
+ node.value = await fetchStructureTree(route.meta.Key as string, true);
+}
+
+function onSelectedNode(id: string, level: number) {
+ nodeId.value = id;
+ nodeLevel.value = level;
+ updateLeaveday();
+}
/** function อัปเดทบัญชีแสดงวันลา */
async function updateLeaveday() {
- if (yearType.value === "FULL") {
- dateStart.value = new Date(year.value - 1, 9, 1);
- dateEnd.value = new Date(year.value, 8, 30);
- } else if (yearType.value === "FIRSTHAFT") {
- dateStart.value = new Date(year.value - 1, 9, 1);
- dateEnd.value = new Date(year.value, 2, 31);
- } else if (yearType.value === "SECONDHAFT") {
- dateStart.value = new Date(year.value, 3, 1);
- dateEnd.value = new Date(year.value, 8, 30);
+ if (!nodeId.value || !typeReport.value) {
+ return false;
}
- fetchLeaveday(
- employeeClass.value,
- yearType.value,
- dateStart.value,
- dateEnd.value
- );
+ isReport.value = false;
+ isLoadPDF.value = true;
+ pdfSrc.value = undefined;
+ switch (yearType.value) {
+ case "FULL":
+ dateStart.value = new Date(year.value - 1, 9, 1);
+ dateEnd.value = new Date(year.value, 8, 30);
+ break;
+
+ case "MONTH":
+ const mount = dateMonth.value.month + 1;
+ // วันเริ่มต้นของเดือน
+ dateStart.value = new Date(dateMonth.value.year, mount - 1, 1);
+ // วันสิ้นสุดของเดือนถัดไป
+ dateEnd.value = new Date(dateMonth.value.year, mount, 0);
+ break;
+
+ case "FIRSTHAFT":
+ dateStart.value = new Date(year.value - 1, 9, 1);
+ dateEnd.value = new Date(year.value, 2, 31);
+ break;
+
+ case "SECONDHAFT":
+ dateStart.value = new Date(year.value, 3, 1);
+ dateEnd.value = new Date(year.value, 8, 30);
+ break;
+
+ default:
+ break;
+ }
+
+ typeReport.value === "1"
+ ? fetchLeaveday(
+ employeeClass.value,
+ yearType.value,
+ dateStart.value,
+ dateEnd.value
+ )
+ : fetchLeaveday2(
+ employeeClass.value,
+ yearType.value,
+ dateStart.value,
+ dateEnd.value
+ );
}
/**
@@ -73,25 +149,57 @@ async function fetchLeaveday(
startDate: Date,
endDate: Date
) {
- showLoader();
const body = {
- type: year === "FULL" ? "FULL" : "HAFT",
+ type: year === "FULL" ? "FULL" : year === "MONTH" ? "MONTH" : "HAFT",
startDate: dateToISO(startDate),
endDate: dateToISO(endDate),
+ nodeId: nodeId.value,
+ node: nodeLevel.value,
};
await http
.post(config.API.leaveReportLeaveday(type), body)
.then(async (res) => {
const data = res.data.result;
- data && (await genReport(data));
+ data && (await fetchDocumentTemplate(data));
+ isReport.value = data ? true : false;
detailReport.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
- hideLoader();
+ isLoadPDF.value = false;
+ });
+}
+
+async function fetchLeaveday2(
+ type: string,
+ year: string,
+ startDate: Date,
+ endDate: Date
+) {
+ const body = {
+ type: year === "FULL" ? "FULL" : year === "MONTH" ? "MONTH" : "HAFT",
+ startDate: dateToISO(startDate),
+ endDate: dateToISO(endDate),
+ nodeId: nodeId.value,
+ node: nodeLevel.value,
+ };
+
+ await http
+ .post(config.API.leaveReportLeave2(type), body)
+ .then(async (res) => {
+ const data = res.data.result;
+ data && (await fetchDocumentTemplate(data));
+ isReport.value = data ? true : false;
+ detailReport.value = data;
+ })
+ .catch((err) => {
+ messageError($q, err);
+ })
+ .finally(() => {
+ isLoadPDF.value = false;
});
}
@@ -99,7 +207,7 @@ async function fetchLeaveday(
* function เรียกไฟล์ PDF
* @param data ข้อมูลบัญชีวันลา
*/
-async function genReport(data: any) {
+async function fetchDocumentTemplate(data: any) {
await axios
.post(`${config.API.reportTemplate}/xlsx`, data, {
headers: {
@@ -111,7 +219,6 @@ async function genReport(data: any) {
.then(async (res) => {
const blob = new Blob([res.data]);
const objectUrl = URL.createObjectURL(blob);
- fileBlob.value = blob;
const pdfData = await usePDF(`${objectUrl}`);
setTimeout(() => {
@@ -129,53 +236,11 @@ async function genReport(data: any) {
});
}
-/**
- * function เรียกไฟล์ XLSX
- * @param data ข้อมูลบัญชีวันลา
- */
-async function genReportXLSX(data: any) {
- await axios
- .post(`${config.API.reportTemplate}/xlsx`, data, {
- headers: {
- accept:
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- "content-Type": "application/json",
- },
- responseType: "blob",
- })
- .then(async (res) => {
- const blob = new Blob([res.data]);
- downloadReport(blob, "xlsx");
- })
- .catch(async (e) => {
- messageError($q, JSON.parse(await e.response.data.text()));
- })
- .finally(() => {
- hideLoader();
- });
-}
-
-/**
- * function Download ไฟล์
- * @param data ข้อมูลบัญชีวันลา
- * @param type นามสกุลไฟล์
- */
-async function downloadReport(data: any, type: string) {
- const link = document.createElement("a");
- var fileName = "บัญชีแสดงวันลา";
- link.href = window.URL.createObjectURL(new Blob([data]));
- link.setAttribute("download", `${fileName}.${type}`);
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
-}
-
const splitterModel = ref(14);
const numOfPages = ref(0);
const page = ref(1);
const pdfSrc = ref();
-// const modalFull = ref(false);
-const fileBlob = ref();
+
/** ไปหน้าต่อไปของรายงาน */
function nextPage() {
if (page.value < numOfPages.value) {
@@ -190,42 +255,23 @@ function backPage() {
}
}
-/**
- * function ค้นหาข้อมูล Option
- * @param val คำค้นหา
- * @param update function
- * @param type ประเภท option
- */
-function filterFnOptions(val: any, update: Function, type: string) {
- switch (type) {
- case "employeeClass":
- update(() => {
- employeeClassOption.value = employeeClassMain.value.filter(
- (v: DataOption) => v.name.indexOf(val) > -1
- );
- });
- break;
- case "yearType":
- update(() => {
- yearTypeOptionOption.value = yearTypeOptionMain.value.filter(
- (v: DataOption) => v.name.indexOf(val) > -1
- );
- });
- break;
- }
+function monthYearThai(val: DataDateMonthObject) {
+ if (val == null) return "";
+ else return monthYear2Thai(val.month, val.year);
}
onMounted(() => {
- updateLeaveday();
+ fetchDataTree();
});
+
บัญชีแสดงวันลา
-
-
-
-
+
+
+
+
{
label="สถานภาพ"
emit-value
map-options
- hide-selected
- fill-input
option-label="name"
option-value="id"
- use-input
style="width: 230px"
@update:model-value="updateLeaveday"
- @filter="(inputValue: any,
- doneFn: Function) => filterFnOptions(inputValue, doneFn,'employeeClass')"
- >
-
- ไม่มีข้อมูล
-
-
+ >
-
-
- filterFnOptions(inputValue, doneFn,'yearType')"
- >
-
- ไม่มีข้อมูล
-
-
-
-
-
-
+
+
{
{
{
-
-
-
-
- {{ year + 543 }}
- {{
- parseInt(value + 543)
- }}
-
-
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
- {{ year + 543 }}
- {{
- parseInt(value + 543)
- }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ year + 543 }}
- {{
- parseInt(value + 543)
- }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- หน้าที่ {{ page }} จาก {{ numOfPages }}
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ prop.node.orgTreeName }}
+
+
+ {{ prop.node.orgCode == null ? null : prop.node.orgCode }}
+ {{
+ prop.node.orgTreeShortName == null
+ ? null
+ : prop.node.orgTreeShortName
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/modules/09_leave/views/07_ReportCheckin.vue b/src/modules/09_leave/views/07_ReportCheckin.vue
new file mode 100644
index 000000000..8bedf36d6
--- /dev/null
+++ b/src/modules/09_leave/views/07_ReportCheckin.vue
@@ -0,0 +1,649 @@
+
+
+
+
+ รายงานสถิติการลงเวลา
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ filterFnOptions(inputValue, doneFn,)"
+ >
+
+
+
+ ไม่มีข้อมูล
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+ {{
+ parseInt(value + 543)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ prop.node.orgTreeName }}
+
+
+ {{ prop.node.orgCode == null ? null : prop.node.orgCode }}
+ {{
+ prop.node.orgTreeShortName == null
+ ? null
+ : prop.node.orgTreeShortName
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ หน้าที่ {{ page }} จาก {{ numOfPages }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/18_command/components/DialogCreateCommandORG.vue b/src/modules/18_command/components/DialogCreateCommandORG.vue
index c2cc53cb5..621cc9e69 100644
--- a/src/modules/18_command/components/DialogCreateCommandORG.vue
+++ b/src/modules/18_command/components/DialogCreateCommandORG.vue
@@ -78,8 +78,13 @@ const dataMapToSend = computed(() => {
firstName: i.firstName,
lastName: i.lastName,
citizenId: i.citizenId,
+ ...(props.systemName?.includes("SALARY") && {
+ amount: i.positionSalaryAmount,
+ amountSpecial: i.amountSpecial,
+ }),
}));
});
+
//Table
const rows = ref([]);
const selected = ref([]);
@@ -143,6 +148,7 @@ function onSubmit() {
commandNo: commandNo.value,
persons: selected.value ? dataMapToSend.value : [],
};
+
await http
.post(config.API.command + `/person`, body)
.then(async (res) => {
diff --git a/src/modules/18_command/components/Step/0_Main.vue b/src/modules/18_command/components/Step/0_Main.vue
index 6e8df6a8b..0129ef8c7 100644
--- a/src/modules/18_command/components/Step/0_Main.vue
+++ b/src/modules/18_command/components/Step/0_Main.vue
@@ -47,6 +47,7 @@ async function fetchData() {
isDraft.value = data.isDraft;
isSign.value = data.isSign;
isAttachment.value = data.isAttachment;
+ store.isSalary = data.isSalary
})
.catch((err) => {
messageError($q, err);
diff --git a/src/modules/18_command/components/Step/Dialog2_Salary.vue b/src/modules/18_command/components/Step/Dialog2_Salary.vue
index 9e26f1061..b91933301 100644
--- a/src/modules/18_command/components/Step/Dialog2_Salary.vue
+++ b/src/modules/18_command/components/Step/Dialog2_Salary.vue
@@ -6,13 +6,14 @@ import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useCommandMainStore } from "@/modules/18_command/store/Main";
-
+import { useCommandDetail } from "@/modules/18_command/store/DetailStore";
import DialogHeader from "@/components/DialogHeader.vue";
const $q = useQuasar();
const { showLoader, hideLoader, dialogConfirm, messageError, success } =
useCounterMixin();
const store = useCommandMainStore();
+const storeDetail = useCommandDetail();
const props = defineProps({
getData: Function,
@@ -36,6 +37,7 @@ const formData = reactive({
mouthSalaryAmount: null,
remarkVertical: null,
remarkHorizontal: null,
+ amountSpecial: null,
});
const readonly = ref(false);
@@ -167,12 +169,28 @@ watch(
:class="getClass(!readonly)"
mask="###,###,###,###,###,###"
reverse-fill-mask
- :readonly="readonly"
+ :readonly="!storeDetail.isSalary"
:label="`${'เงินเดือน'}`"
:rules="[(val: any) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
/>
-
+
+
+
{
const readonly = ref(false);
const dataCommand = ref();
const status = ref("");
-
+ const isSalary = ref(false)
function checkStep(val: string) {
status.value = val;
switch (val) {
@@ -39,5 +39,6 @@ export const useCommandDetail = defineStore("commandDetailStore", () => {
readonly,
status,
dataCommand,
+ isSalary
};
});