kpi updated

This commit is contained in:
Warunee Tamkoo 2024-05-14 23:48:29 +07:00
parent 56a38622e5
commit 6c532a0202
8 changed files with 266 additions and 182 deletions

View file

@ -16,19 +16,6 @@ import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { ListCriteria } from "@/modules/08_KPI/interface/request/index"; import type { ListCriteria } from "@/modules/08_KPI/interface/request/index";
const indicatorWeightTotal = defineModel("indicatorWeightTotal", {
type: Number,
default: 0,
});
const indicatorWeight1Total = defineModel("indicatorWeight1Total", {
type: Number,
default: 0,
});
const indicatorWeight2Total = defineModel("indicatorWeight2Total", {
type: Number,
default: 0,
});
const dataListCriteria = ref<ListCriteria[]>([]); const dataListCriteria = ref<ListCriteria[]>([]);
const modalCriteria = ref<boolean>(false); const modalCriteria = ref<boolean>(false);
@ -58,6 +45,9 @@ const totalResults3 = ref<number>(0);
const weightPlanned = ref<number>(0); const weightPlanned = ref<number>(0);
const weightRole = ref<number>(0); const weightRole = ref<number>(0);
const weightAssigned = ref<number>(0); const weightAssigned = ref<number>(0);
const resultPlanned = ref<number>(0);
const resultRole = ref<number>(0);
const resultAssigned = ref<number>(0);
function fetchListPlanned() { function fetchListPlanned() {
http http
.get(config.API.kpiAchievement("planned") + `?id=${evaluationId.value}`) .get(config.API.kpiAchievement("planned") + `?id=${evaluationId.value}`)
@ -70,21 +60,23 @@ function fetchListPlanned() {
rows_01.value = newRow; rows_01.value = newRow;
if (newRow.length > 0) { if (newRow.length > 0) {
const result = newRow.reduce( resultPlanned.value = newRow.reduce(
(sum: number, e: any) => sum + e.evaluationResults, (sum: number, e: any) => sum + e.evaluationResults,
0 0
); );
store.excusiveIndicator1PercentVal = resultPlanned.value;
const weight = newRow.reduce( const weight = newRow.reduce(
(sum: number, e: any) => sum + e.weight, (sum: number, e: any) => sum + e.weight,
0 0
); );
weightPlanned.value = weight; weightPlanned.value = weight;
indicatorWeight1Total.value = Number(weight); store.indicatorWeight1Total = Number(weight);
store.indicatorScoreVal = result;
totalResults1.value = totalResults1.value =
(result * store.dataEvaluation.plannedPoint) / weight; (resultPlanned.value * store.excusiveIndicator1Weight) / weight;
store.excusiveIndicator1ScoreVal = totalResults1.value;
} }
}) })
.catch((err) => { .catch((err) => {
@ -104,20 +96,17 @@ function fetchListRole() {
rows_02.value = newRow; rows_02.value = newRow;
if (newRow.length > 0) { if (newRow.length > 0) {
const result = newRow.reduce( resultRole.value = newRow.reduce(
(sum: number, e: any) => sum + e.evaluationResults, (sum: number, e: any) => sum + e.evaluationResults,
0 0
); );
const weight = newRow.reduce( const weight = newRow.reduce(
(sum: number, e: any) => sum + e.weight, (sum: number, e: any) => sum + e.weight,
0 0
); );
weightRole.value = weight; weightRole.value = weight;
indicatorWeight1Total.value = Number(weight);
totalResults2.value =
(result * store.dataEvaluation.rolePoint) / weight;
} }
}) })
.catch((err) => { .catch((err) => {
@ -138,19 +127,24 @@ function fetchAssigned() {
rows_03.value = newRow; rows_03.value = newRow;
if (newRow.length > 0) { if (newRow.length > 0) {
const result = newRow.reduce( resultAssigned.value = newRow.reduce(
(sum: number, e: any) => sum + e.evaluationResults, (sum: number, e: any) => sum + e.evaluationResults,
0 0
); );
store.excusiveIndicator2PercentVal = resultAssigned.value;
const weight = newRow.reduce( const weight = newRow.reduce(
(sum: number, e: any) => sum + e.weight, (sum: number, e: any) => sum + e.weight,
0 0
); );
weightAssigned.value = weight; weightAssigned.value = weight;
store.indicatorWeight2Total = Number(weight);
totalResults3.value = totalResults3.value =
(result * store.dataEvaluation.specialPoint) / weight; (resultAssigned.value * store.excusiveIndicator2Weight) / weight;
store.excusiveIndicator2ScoreVal = totalResults3.value;
} }
}) })
.catch((err) => { .catch((err) => {
@ -162,11 +156,6 @@ function onInfo() {
modalCriteria.value = true; modalCriteria.value = true;
} }
const resultWork = computed(() => {
const total = totalResults1.value + totalResults2.value + totalResults3.value;
return total.toFixed(2);
});
function getCriteria() { function getCriteria() {
http http
.get(config.API.KpiEvaluationInfo) .get(config.API.KpiEvaluationInfo)
@ -182,6 +171,7 @@ function getCriteria() {
const isShowScore = computed(() => { const isShowScore = computed(() => {
return ( return (
store.tabOpen === 3 && store.tabOpen === 3 &&
store.tabMain === "3" &&
store.dataEvaluation.evaluationStatus === "EVALUATING" store.dataEvaluation.evaluationStatus === "EVALUATING"
); );
}); });
@ -190,7 +180,7 @@ watch(
[weightPlanned, weightRole, weightAssigned], [weightPlanned, weightRole, weightAssigned],
([newA, newB, newC], [prevA, prevB, prevC]) => { ([newA, newB, newC], [prevA, prevB, prevC]) => {
if (newA !== prevA || newB !== prevB || newC !== prevC) { if (newA !== prevA || newB !== prevB || newC !== prevC) {
indicatorWeightTotal.value = store.indicatorWeightTotal =
Number(weightPlanned.value) + Number(weightPlanned.value) +
Number(weightAssigned.value) + Number(weightAssigned.value) +
Number(weightRole.value); Number(weightRole.value);
@ -198,12 +188,20 @@ watch(
} }
); );
async function getAll() { watch(
await getCriteria(); [resultPlanned, resultRole, resultAssigned],
await fetchListPlanned(); ([newA, newB, newC], [prevA, prevB, prevC]) => {
await fetchListRole(); if (newA !== prevA || newB !== prevB || newC !== prevC) {
await fetchAssigned(); store.indicatorPercentVal =
} Number(resultPlanned.value) +
Number(resultRole.value) +
Number(resultAssigned.value);
store.indicatorScoreVal =
store.indicatorPercentVal * (store.indicatorScore / 100);
}
}
);
onMounted(() => { onMounted(() => {
getCriteria(); getCriteria();
@ -225,7 +223,6 @@ onMounted(() => {
<span class="txt-under text-blue-6">องคประกอบท 1 </span> <span class="txt-under text-blue-6">องคประกอบท 1 </span>
<span class="q-ml-sm"> ผลสมฤทธของงาน</span> <span class="q-ml-sm"> ผลสมฤทธของงาน</span>
</div> </div>
<div class="q-gutter-md q-mt-sm"> <div class="q-gutter-md q-mt-sm">
<!-- องคประกอบท 1 --> <!-- องคประกอบท 1 -->
<div v-if="store.dataProfile.posExecutiveName != null"> <div v-if="store.dataProfile.posExecutiveName != null">
@ -245,11 +242,11 @@ onMounted(() => {
:rows="[ :rows="[
{ {
name: 'รวมผลการประเมิน (ร้อยละ)', name: 'รวมผลการประเมิน (ร้อยละ)',
value: store.excusiveIndicator1PercentVal, value: store.excusiveIndicator1PercentVal.toFixed(2),
}, },
{ {
name: 'ผลการประเมินมิติที่ 1 (คะแนน)', name: 'ผลการประเมินมิติที่ 1 (คะแนน)',
value: store.excusiveIndicator1ScoreVal, value: store.excusiveIndicator1ScoreVal.toFixed(2),
}, },
]" ]"
:columns="[ :columns="[
@ -289,13 +286,13 @@ onMounted(() => {
dense dense
bordered bordered
:rows="[ :rows="[
{ // {
name: 'รวมผลการประเมิน (ร้อยละ)', // name: ' ()',
value: store.excusiveIndicator2PercentVal, // value: store.excusiveIndicator2PercentVal.toFixed(2),
}, // },
{ {
name: 'ผลการประเมินมิติที่ 2 (คะแนน)', name: 'ผลการประเมินมิติที่ 2 (คะแนน)',
value: store.excusiveIndicator2ScoreVal, value: store.excusiveIndicator2ScoreVal.toFixed(2),
}, },
]" ]"
:columns="[ :columns="[
@ -327,7 +324,12 @@ onMounted(() => {
คะแนน)</span คะแนน)</span
> >
<div class="text-primary q-pl-md"> <div class="text-primary q-pl-md">
{{ store.indicatorScoreVal }} {{
(
store.excusiveIndicator1ScoreVal +
store.excusiveIndicator2ScoreVal
).toFixed(2)
}}
</div> </div>
</div> </div>
</div> </div>
@ -365,7 +367,7 @@ onMounted(() => {
:rows="[ :rows="[
{ {
name: 'รวมผลการประเมิน (ร้อยละ)', name: 'รวมผลการประเมิน (ร้อยละ)',
value: store.indicatorPercentVal, value: store.indicatorPercentVal.toFixed(2),
}, },
]" ]"
:columns="[ :columns="[
@ -396,7 +398,7 @@ onMounted(() => {
คะแนน)</span คะแนน)</span
> >
<div class="text-primary q-pl-md"> <div class="text-primary q-pl-md">
{{ store.indicatorScoreVal }} {{ store.indicatorScoreVal.toFixed(2) }}
</div> </div>
</div> </div>
</div> </div>
@ -435,7 +437,7 @@ onMounted(() => {
? store.competencyScore ? store.competencyScore
: store.excusiveCompetencyScore : store.excusiveCompetencyScore
} คะแนน)`, } คะแนน)`,
value: store.competencyScoreVal, value: store.competencyScoreVal.toFixed(2),
}, },
]" ]"
:columns="[ :columns="[
@ -469,7 +471,7 @@ onMounted(() => {
:rows="[ :rows="[
{ {
name: `ผลการประเมินการพัฒนาตนเอง (คะแนนเต็ม ${store.devScore} คะแนน)`, name: `ผลการประเมินการพัฒนาตนเอง (คะแนนเต็ม ${store.devScore} คะแนน)`,
value: store.devScoreVal, value: store.devScoreVal.toFixed(2),
}, },
]" ]"
:columns="[ :columns="[
@ -492,9 +494,11 @@ onMounted(() => {
class="q-mt-xs q-mb-md" class="q-mt-xs q-mb-md"
/> />
</div> </div>
</div>
<div v-if="isShowScore">
<div <div
v-if="isShowScore && !store.dataProfile.posExecutiveName" v-if="store.dataProfile.posExecutiveName == null"
class="row text-body2 text-weight-bold" class="row text-body2 text-weight-bold"
> >
<div class="col-12 text-center row justify-center"> <div class="col-12 text-center row justify-center">
@ -503,7 +507,7 @@ onMounted(() => {
(คะแนนเต {{ store.competencyDevScore }} คะแนน)</span (คะแนนเต {{ store.competencyDevScore }} คะแนน)</span
> >
<div class="text-primary q-pl-md"> <div class="text-primary q-pl-md">
{{ store.competencyDevScoreVal }} {{ (store.competencyScoreVal + store.devScoreVal).toFixed(2) }}
</div> </div>
</div> </div>
</div> </div>
@ -514,7 +518,7 @@ onMounted(() => {
{{ store.competencyScore }} คะแนน)</span {{ store.competencyScore }} คะแนน)</span
> >
<div class="text-primary q-pl-md"> <div class="text-primary q-pl-md">
{{ store.competencyScoreVal }} {{ store.competencyScoreVal.toFixed(2) }}
</div> </div>
</div> </div>
</div> </div>

View file

@ -16,6 +16,10 @@ const store = useKpiDataStore();
const { showLoader, hideLoader, messageError, dialogConfirm, success } = const { showLoader, hideLoader, messageError, dialogConfirm, success } =
useCounterMixin(); useCounterMixin();
const props = defineProps({
fetchList: { type: Function, required: true },
});
const modal = defineModel<boolean>("modal", { required: true }); const modal = defineModel<boolean>("modal", { required: true });
const rows = defineModel<any>("data", { required: true }); const rows = defineModel<any>("data", { required: true });
const numpage = defineModel<number>("numpage", { required: true }); const numpage = defineModel<number>("numpage", { required: true });
@ -142,7 +146,9 @@ function onSubmit() {
: numpage.value === 3 : numpage.value === 3
? config.API.kpiAchievementPoint("special") ? config.API.kpiAchievementPoint("special")
: ""; : "";
await http.post(url, formData); await http.post(url, formData).then((res) => {
props.fetchList();
});
success($q, "บันทึกข้อมูลสำเร็จ"); success($q, "บันทึกข้อมูลสำเร็จ");
} catch (err) { } catch (err) {
messageError($q, err); messageError($q, err);

View file

@ -11,18 +11,6 @@ import File from "@/modules/08_KPI/components/Tab/05_File.vue";
const store = useKpiDataStore(); const store = useKpiDataStore();
const route = useRoute(); const route = useRoute();
const indicatorWeightTotal = defineModel("indicatorWeightTotal", {
type: Number,
default: 0,
});
const indicatorWeight1Total = defineModel("indicatorWeight1Total", {
type: Number,
default: 0,
});
const indicatorWeight2Total = defineModel("indicatorWeight2Total", {
type: Number,
default: 0,
});
const itemsTab = ref<any>([ const itemsTab = ref<any>([
{ {
@ -37,14 +25,6 @@ const itemsTab = ref<any>([
name: "3", name: "3",
label: "รายงานผลสำเร็จของงาน", label: "รายงานผลสำเร็จของงาน",
}, },
// {
// name: "3",
// label: "",
// },
// {
// name: "4",
// label: "",
// },
{ {
name: "5", name: "5",
label: "ไฟล์เอกสาร", label: "ไฟล์เอกสาร",
@ -107,12 +87,7 @@ const splitterModel = ref<number>(12);
:name="tab.name" :name="tab.name"
class="q-pa-none" class="q-pa-none"
> >
<Assessment <Assessment v-if="store.tabMain === '1'" />
v-if="store.tabMain === '1'"
v-model:indicatorWeightTotal="indicatorWeightTotal"
v-model:indicatorWeight1Total="indicatorWeight1Total"
v-model:indicatorWeight2Total="indicatorWeight2Total"
/>
<Assessment v-if="store.tabMain === '2'" :type="'evaluator'" /> <Assessment v-if="store.tabMain === '2'" :type="'evaluator'" />
<Assessment v-if="store.tabMain === '3'" :type="'commander'" /> <Assessment v-if="store.tabMain === '3'" :type="'commander'" />
<Assessment v-if="store.tabMain === '4'" :type="'commanderHigh'" /> <Assessment v-if="store.tabMain === '4'" :type="'commanderHigh'" />

View file

@ -29,18 +29,16 @@ const {
success, success,
} = useCounterMixin(); } = useCounterMixin();
const isReadonly = <boolean>(route.name === "KPIEditEvaluator" ? true : false);
const title = defineModel<string>("title", { required: true }); const title = defineModel<string>("title", { required: true });
const rows = defineModel<any>("data", { required: true }); const rows = defineModel<any>("data", { required: true });
const numpage = defineModel<number>("page", { required: true }); const numpage = defineModel<number>("page", { required: true });
const evaluationTotal = defineModel<number>("total", { required: true });
const props = defineProps({ const props = defineProps({
fetchList: { type: Function, required: true }, fetchList: { type: Function, required: true },
}); });
const visibleColumns = ref<string[]>( const visibleColumns = ref<string[]>(
store.tabOpen === 3 store.tabOpen === 3 && store.tabMain === "3"
? [ ? [
"includingName", "includingName",
"target", "target",
@ -143,7 +141,7 @@ function onClickView(id: string) {
modalViewInfo.value = true; modalViewInfo.value = true;
} }
function onEvaluate() { async function onEvaluate() {
modalEvaluate.value = true; modalEvaluate.value = true;
} }
@ -198,6 +196,28 @@ watch(
} }
); );
const isEditStep1 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "NEW" &&
store.rolePerson === "USER" &&
store.tabMain === "1") ||
(store.dataEvaluation.evaluationStatus === "NEW_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "1")
);
});
const isEditStep3 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "EVALUATING" &&
store.rolePerson === "USER" &&
store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "3")
);
});
// watch( // watch(
// () => modalAssigned.value, // () => modalAssigned.value,
// () => { // () => {
@ -216,6 +236,7 @@ watch(
// } // }
// ); // );
</script> </script>
<template> <template>
<q-card bordered style="border-radius: 5px" class="no-shadow"> <q-card bordered style="border-radius: 5px" class="no-shadow">
<q-card-section class="bg-grey-2 q-py-sm"> <q-card-section class="bg-grey-2 q-py-sm">
@ -223,10 +244,7 @@ watch(
<div class="col"> <div class="col">
<span class="text-weight-medium">{{ title }}</span> <span class="text-weight-medium">{{ title }}</span>
<q-btn <q-btn
v-if=" v-if="isEditStep1"
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
class="q-ml-xs" class="q-ml-xs"
flat flat
round round
@ -241,10 +259,7 @@ watch(
</div> </div>
<div class="col-auto"> <div class="col-auto">
<q-btn <q-btn
v-if=" v-if="isEditStep3"
store.rolePerson === 'USER' &&
store.dataEvaluation.evaluationStatus === 'EVALUATING'
"
flat flat
round round
icon="mdi-clipboard-check-outline" icon="mdi-clipboard-check-outline"
@ -388,13 +403,7 @@ watch(
</q-btn> </q-btn>
</div> </div>
<div <div v-if="isEditStep1">
v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER' &&
store.tabMain === '1'
"
>
<q-btn <q-btn
flat flat
round round
@ -408,10 +417,6 @@ watch(
</q-btn> </q-btn>
<q-btn <q-btn
v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
flat flat
round round
icon="delete" icon="delete"
@ -448,6 +453,7 @@ watch(
v-model:modal="modalEvaluate" v-model:modal="modalEvaluate"
:data="rows" :data="rows"
:numpage="numpage" :numpage="numpage"
:fetchList="fetchList"
/> />
<DialogViewInfo <DialogViewInfo

View file

@ -2,6 +2,8 @@
import { onMounted, ref, computed, watch } from "vue"; import { onMounted, ref, computed, watch } from "vue";
import Dialog from "@/modules/08_KPI/components/Tab/Dialog/04_FormCompetency.vue"; import Dialog from "@/modules/08_KPI/components/Tab/Dialog/04_FormCompetency.vue";
import DialogEvaluate from "@/modules/08_KPI/components/Tab/DialogEvaluate/02_Competenct.vue"; import DialogEvaluate from "@/modules/08_KPI/components/Tab/DialogEvaluate/02_Competenct.vue";
import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue";
import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
@ -104,7 +106,7 @@ const columns = ref<QTableProps["columns"]>([
]); ]);
const visibleColumns = ref<string[]>( const visibleColumns = ref<string[]>(
store.tabOpen === 3 store.tabOpen === 3 && store.tabMain === "3"
? ["name", "level", "point", "weight", "summary"] ? ["name", "level", "point", "weight", "summary"]
: ["name", "level", "weight"] : ["name", "level", "weight"]
); );
@ -159,11 +161,18 @@ function getData(type: string) {
if (total > 0) { if (total > 0) {
let weightAvg = weight / total; let weightAvg = weight / total;
let resultAvg = result / total; let resultAvg = result / total;
let sum =
weightAvg != 0 if (store.dataProfile.posExecutiveName != null) {
? (resultAvg / weightAvg) * store.dataEvaluation.capacityPoint store.competencyScoreVal =
: 0; weightAvg != 0
// resultEvaluation.value = sum.toFixed(2); ? (resultAvg / weightAvg) * store.excusiveCompetencyScore
: 0;
} else {
store.competencyScoreVal =
weightAvg != 0
? (resultAvg / weightAvg) * store.competencyScore
: 0;
}
} }
}); });
} }
@ -200,16 +209,41 @@ function onEvaluate(type: string) {
const modalProgress = ref<boolean>(false); const modalProgress = ref<boolean>(false);
const modalProblem = ref<boolean>(false); const modalProblem = ref<boolean>(false);
const type = ref<string>(""); const type = ref<string>("");
function openPopupProgress() { const idList = ref<string>("");
function openPopupProgress(id: string) {
modalProgress.value = true; modalProgress.value = true;
type.value = rows.value ? "plan" : rows.value ? "role" : "special"; type.value = "capacity";
idList.value = id;
} }
function openPopupProblem() { function openPopupProblem(id: string) {
modalProblem.value = true; modalProblem.value = true;
type.value = rows.value ? "plan" : rows.value ? "role" : "special"; type.value = "capacity";
idList.value = id;
} }
const isEditStep1 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "NEW" &&
store.rolePerson === "USER" &&
store.tabMain === "1") ||
(store.dataEvaluation.evaluationStatus === "NEW_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "1")
);
});
const isEditStep3 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "EVALUATING" &&
store.rolePerson === "USER" &&
store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "3")
);
});
watch( watch(
() => store.dataEvaluation.capacityPoint, () => store.dataEvaluation.capacityPoint,
(newValue, oldValue) => { (newValue, oldValue) => {
@ -238,10 +272,7 @@ onMounted(() => {
<div class="col"> <div class="col">
<span class="text-weight-medium">{{ item.name }}</span> <span class="text-weight-medium">{{ item.name }}</span>
<q-btn <q-btn
v-if=" v-if="isEditStep1"
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
class="q-ml-xs" class="q-ml-xs"
flat flat
round round
@ -257,7 +288,7 @@ onMounted(() => {
<q-space /> <q-space />
<q-btn <q-btn
v-if="store.dataEvaluation.evaluationStatus == 'EVALUATING'" v-if="isEditStep3"
flat flat
round round
icon="mdi-clipboard-check-outline" icon="mdi-clipboard-check-outline"
@ -366,7 +397,7 @@ onMounted(() => {
color="blue-6" color="blue-6"
size="12px" size="12px"
dense dense
@click="openPopupProgress()" @click="openPopupProgress(props.row.id)"
> >
<q-tooltip>รายงานความกาวหน</q-tooltip> <q-tooltip>รายงานความกาวหน</q-tooltip>
</q-btn> </q-btn>
@ -378,19 +409,13 @@ onMounted(() => {
size="12px" size="12px"
dense dense
main="problem" main="problem"
@click="openPopupProblem()" @click="openPopupProblem(props.row.id)"
> >
<q-tooltip>รายงานปญหา</q-tooltip> <q-tooltip>รายงานปญหา</q-tooltip>
</q-btn> </q-btn>
</div> </div>
<div <div v-if="isEditStep1">
v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER' &&
store.tabMain === '1'
"
>
<q-btn <q-btn
flat flat
round round
@ -401,10 +426,6 @@ onMounted(() => {
<q-tooltip>แกไข </q-tooltip> <q-tooltip>แกไข </q-tooltip>
</q-btn> </q-btn>
<q-btn <q-btn
v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
flat flat
round round
icon="delete" icon="delete"
@ -437,7 +458,16 @@ onMounted(() => {
:get-data="getData" :get-data="getData"
/> />
<DialogProgress
v-model:modal="modalProgress"
v-model:type="type"
:idList="idList"
/>
<DialogProblem
v-model:modal="modalProblem"
v-model:type="type"
:idList="idList"
/>
</template> </template>
<style scoped> <style scoped>

View file

@ -2,6 +2,8 @@
import { onMounted, ref, computed, watch, reactive } from "vue"; import { onMounted, ref, computed, watch, reactive } from "vue";
import DialogDevelop from "@/modules/08_KPI/components/Tab/Dialog/DialogDevelop.vue"; import DialogDevelop from "@/modules/08_KPI/components/Tab/Dialog/DialogDevelop.vue";
import DialogEvalutionDevelop from "@/modules/08_KPI/components/Tab/DialogEvaluate/03_DialogEvalutionDevelop.vue"; import DialogEvalutionDevelop from "@/modules/08_KPI/components/Tab/DialogEvaluate/03_DialogEvalutionDevelop.vue";
import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue";
import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
@ -94,7 +96,7 @@ const columns = ref<QTableProps["columns"]>([
]); ]);
const visibleColumns = ref<string[]>( const visibleColumns = ref<string[]>(
store.tabOpen === 3 store.tabOpen === 3 && store.tabMain === "3"
? ["name", "develop", "target", "achievement", "summary"] ? ["name", "develop", "target", "achievement", "summary"]
: ["name", "develop", "target"] : ["name", "develop", "target"]
); );
@ -114,6 +116,11 @@ function getDevelop() {
.then((res) => { .then((res) => {
const data = res.data.result; const data = res.data.result;
rows.value = data; rows.value = data;
store.devScoreVal = rows.value.reduce(
(sum: number, e: any) => sum + e.summary,
0
);
}); });
} }
@ -142,16 +149,42 @@ function onDelete(id: string) {
const modalProgress = ref<boolean>(false); const modalProgress = ref<boolean>(false);
const modalProblem = ref<boolean>(false); const modalProblem = ref<boolean>(false);
const type = ref<string>(""); const type = ref<string>("");
function openPopupProgress() { const idList = ref<string>("");
function openPopupProgress(id: string) {
modalProgress.value = true; modalProgress.value = true;
type.value = rows.value ? "plan" : rows.value ? "role" : "special"; type.value = "develop";
idList.value = id;
} }
function openPopupProblem() { function openPopupProblem(id: string) {
modalProblem.value = true; modalProblem.value = true;
type.value = rows.value ? "plan" : rows.value ? "role" : "special";
type.value = "develop";
idList.value = id;
} }
const isEditStep1 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "NEW" &&
store.rolePerson === "USER" &&
store.tabMain === "1") ||
(store.dataEvaluation.evaluationStatus === "NEW_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "1")
);
});
const isEditStep3 = computed(() => {
return (
(store.dataEvaluation.evaluationStatus === "EVALUATING" &&
store.rolePerson === "USER" &&
store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "3")
);
});
onMounted(() => { onMounted(() => {
getDevelop(); getDevelop();
}); });
@ -164,10 +197,7 @@ onMounted(() => {
<div class="col"> <div class="col">
<span class="text-weight-medium">การพฒนาตนเอง</span> <span class="text-weight-medium">การพฒนาตนเอง</span>
<q-btn <q-btn
v-if=" v-if="isEditStep1"
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
class="q-ml-xs" class="q-ml-xs"
flat flat
round round
@ -183,10 +213,7 @@ onMounted(() => {
<q-space /> <q-space />
<q-btn <q-btn
v-if=" v-if="isEditStep3"
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
flat flat
round round
icon="mdi-clipboard-check-outline" icon="mdi-clipboard-check-outline"
@ -300,7 +327,7 @@ onMounted(() => {
color="blue-6" color="blue-6"
size="12px" size="12px"
dense dense
@click="openPopupProgress()" @click="openPopupProgress(props.row.id)"
> >
<q-tooltip>รายงานความกาวหน</q-tooltip> <q-tooltip>รายงานความกาวหน</q-tooltip>
</q-btn> </q-btn>
@ -312,19 +339,13 @@ onMounted(() => {
size="12px" size="12px"
dense dense
main="problem" main="problem"
@click="openPopupProblem()" @click="openPopupProblem(props.row.id)"
> >
<q-tooltip>รายงานปญหา</q-tooltip> <q-tooltip>รายงานปญหา</q-tooltip>
</q-btn> </q-btn>
</div> </div>
<div <div v-if="isEditStep1">
v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER' &&
store.tabMain === '2'
"
>
<q-btn <q-btn
flat flat
round round
@ -362,6 +383,17 @@ onMounted(() => {
v-model:data="rows" v-model:data="rows"
:get-all="getDevelop" :get-all="getDevelop"
/> />
<DialogProgress
v-model:modal="modalProgress"
v-model:type="type"
:idList="idList"
/>
<DialogProblem
v-model:modal="modalProblem"
v-model:type="type"
:idList="idList"
/>
</template> </template>
<style scoped> <style scoped>

View file

@ -307,6 +307,10 @@ export const useKpiDataStore = defineStore("KPIDate", () => {
} }
// SUMMARY GENERAL CASE // SUMMARY GENERAL CASE
const indicatorWeightTotal = ref<number>(0); // น้ำหนักรวมกรณีทั่วไป
const indicatorWeight1Total = ref<number>(0); // น้ำหนักรวมมิติที่ 1 ต้องไม่เกิน 100%
const indicatorWeight2Total = ref<number>(0); // น้ำหนักรวมมิติที่ 2 ต้องไม่เกิน 20
const indicatorPercent = ref<number>(100); // รวมผลการประเมิน (ร้อยละ) const indicatorPercent = ref<number>(100); // รวมผลการประเมิน (ร้อยละ)
const indicatorPercentVal = ref<number>(0); // รวมผลการประเมิน (ร้อยละ) ที่ได้จริง const indicatorPercentVal = ref<number>(0); // รวมผลการประเมิน (ร้อยละ) ที่ได้จริง
const indicatorScore = ref<number>(70); // สรุปผลการประเมินผลสัมฤทธิ์ของงาน ( คะแนนเต็ม indicatorScore คะแนน) const indicatorScore = ref<number>(70); // สรุปผลการประเมินผลสัมฤทธิ์ของงาน ( คะแนนเต็ม indicatorScore คะแนน)
@ -348,6 +352,9 @@ export const useKpiDataStore = defineStore("KPIDate", () => {
rolePerson, rolePerson,
// score // score
indicatorWeightTotal,
indicatorWeight1Total,
indicatorWeight2Total,
indicatorPercent, indicatorPercent,
indicatorPercentVal, indicatorPercentVal,
indicatorScore, indicatorScore,

View file

@ -291,7 +291,7 @@ async function getAll() {
await getOrgOp(); await getOrgOp();
} }
function sendToEvaluatore() { function sendToEvaluatore(status: string) {
dialogConfirm( dialogConfirm(
$q, $q,
() => { () => {
@ -299,7 +299,7 @@ function sendToEvaluatore() {
showLoader(); showLoader();
http http
.put(config.API.kpiSendToStatus(id.value), { .put(config.API.kpiSendToStatus(id.value), {
status: "NEW_EVALUATOR", status: status,
}) })
.then((res) => { .then((res) => {
success($q, "ส่งข้อตกลงให้ผู้ประเมินอนุมัติสำเร็จ"); success($q, "ส่งข้อตกลงให้ผู้ประเมินอนุมัติสำเร็จ");
@ -345,9 +345,6 @@ function requireEdit() {
); );
} }
const indicatorWeightTotal = ref<number>(0);
const indicatorWeight1Total = ref<number>(0);
const indicatorWeight2Total = ref<number>(0);
onMounted(async () => { onMounted(async () => {
showLoader(); showLoader();
await getAll(); await getAll();
@ -355,8 +352,6 @@ onMounted(async () => {
</script> </script>
<template> <template>
<!-- evaluationStatus={{ store.dataEvaluation.evaluationStatus }} | tabOpen =
{{ store.tabOpen }} | rolePerson = {{ store.rolePerson }} | -->
<div class="col-12 row justify-center"> <div class="col-12 row justify-center">
<div class="col-xs-12 col-sm-12 col-md-11"> <div class="col-xs-12 col-sm-12 col-md-11">
<div class="toptitle text-white col-12 row items-center"> <div class="toptitle text-white col-12 row items-center">
@ -400,14 +395,18 @@ onMounted(async () => {
}}</span> }}</span>
<q-space /> <q-space />
<div class="q-gutter-x-sm"> <div class="q-gutter-x-sm">
<!-- {{
store.dataProfile.posExecutiveName == null &&
store.indicatorWeightTotal != 100
}}
| {{ store.indicatorWeightTotal }} | -->
<span <span
v-if=" v-if="
(store.dataProfile.posExecutiveName == null && (store.dataProfile.posExecutiveName == null &&
indicatorWeightTotal > 0 && store.indicatorWeightTotal != 100) ||
indicatorWeightTotal != 100) || (store.dataEvaluation.posExecutiveName != null &&
(store.dataEvaluation.evaluatorId != null && (store.indicatorWeight1Total != 100 ||
indicatorWeight1Total != 100 && store.indicatorWeight2Total != 20))
indicatorWeight2Total != 20)
" "
class="text-red" class="text-red"
>*ำหน(อยละ) ผลสมฤทธของงานไมกตอง</span >*ำหน(อยละ) ผลสมฤทธของงานไมกตอง</span
@ -419,11 +418,10 @@ onMounted(async () => {
" "
:disabled=" :disabled="
(store.dataProfile.posExecutiveName == null && (store.dataProfile.posExecutiveName == null &&
indicatorWeightTotal > 0 && store.indicatorWeightTotal != 100) ||
indicatorWeightTotal != 100) || (store.dataEvaluation.posExecutiveName != null &&
(store.dataEvaluation.evaluatorId != null && (store.indicatorWeight1Total != 100 ||
indicatorWeight1Total != 100 && store.indicatorWeight2Total != 20))
indicatorWeight2Total != 20)
" "
unelevated unelevated
round round
@ -431,10 +429,27 @@ onMounted(async () => {
color="grey-2" color="grey-2"
text-color="blue-6" text-color="blue-6"
size="md" size="md"
@click="sendToEvaluatore()" @click="sendToEvaluatore('NEW_EVALUATOR')"
> >
<q-tooltip>งใหประเมนอน</q-tooltip> <q-tooltip>งใหประเมนอน</q-tooltip>
</q-btn> </q-btn>
<q-btn
v-if="
store.rolePerson == 'USER' &&
store.dataEvaluation.evaluationStatus == 'EVALUATING'
"
unelevated
round
icon="mdi-send"
color="grey-2"
text-color="blue-6"
size="md"
@click="sendToEvaluatore('EVALUATING_EVALUATOR')"
>
<q-tooltip>งใหประเมนอนผลการประเม</q-tooltip>
</q-btn>
<q-btn <q-btn
v-if=" v-if="
store.rolePerson == 'USER' && store.rolePerson == 'USER' &&
@ -468,7 +483,10 @@ onMounted(async () => {
<q-tooltip>แกไขคะแนนเต</q-tooltip> <q-tooltip>แกไขคะแนนเต</q-tooltip>
</q-btn> --> </q-btn> -->
<q-btn <q-btn
v-if="!isReadonly" v-if="
store.dataEvaluation.evaluationStatus === 'NEW' &&
store.rolePerson === 'USER'
"
unelevated unelevated
round round
icon="edit" icon="edit"
@ -550,9 +568,21 @@ onMounted(async () => {
<div class="col-2"> <div class="col-2">
<div class="column"> <div class="column">
<span class="text-grey-6">คะแนนประเม</span> <span class="text-grey-6">คะแนนประเม</span>
<span class="text-weight-medium text-primary">{{ <span class="text-weight-medium text-primary">
(indicatorScore + competencyScore).toFixed(2) {{
}}</span> store.dataProfile.posExecutiveName == null
? (
store.indicatorScoreVal +
store.competencyScoreVal +
store.devScoreVal
).toFixed(2)
: (
store.excusiveIndicator1ScoreVal +
store.excusiveIndicator2ScoreVal +
store.competencyScore
).toFixed(2)
}}
</span>
</div> </div>
</div> </div>
</div> </div>
@ -562,13 +592,7 @@ onMounted(async () => {
</q-card> </q-card>
<q-card class="q-mt-md rounded"> <q-card class="q-mt-md rounded">
<TabMain <TabMain />
v-model:indicatorScore="indicatorScore"
v-model:competencyScore="competencyScore"
v-model:indicatorWeightTotal="indicatorWeightTotal"
v-model:indicatorWeight1Total="indicatorWeight1Total"
v-model:indicatorWeight2Total="indicatorWeight2Total"
/>
</q-card> </q-card>
</div> </div>
</div> </div>