This commit is contained in:
Warunee Tamkoo 2024-06-27 12:30:40 +07:00
parent 5e8c8589cb
commit 11e5e13039
11 changed files with 118 additions and 149 deletions

View file

@ -8,16 +8,14 @@ export default {
searchCommander: `${org}/profile/search/commander`, searchCommander: `${org}/profile/search/commander`,
proFileType:`${profileOrg}/type`, proFileType: `${profileOrg}/type`,
dataUserInformation: `${profileOrg}/user`, dataUserInformation: `${profileOrg}/user`,
dataUserChangeName: `${profileOrg}/changeName/user`, dataUserChangeName: `${profileOrg}/changeName/user`,
dataUserAddress: `${profileOrg}/address/user`, dataUserAddress: `${profileOrg}/address/user`,
dataUserFamily:(type:string)=> `${profileOrg}/family/${type}/user`, dataUserFamily: (type: string) => `${profileOrg}/family/${type}/user`,
dataUserEducations: `${profileOrg}/educations/user`, dataUserEducations: `${profileOrg}/educations/user`,
dataUserAbility: `${profileOrg}/ability/user`, dataUserAbility: `${profileOrg}/ability/user`,
dataUserGovernment: `${profileOrg}/government/user`, dataUserGovernment: `${profileOrg}/government/user`,
dataUserDiscipline: `${profileOrg}/discipline/user`, dataUserDiscipline: `${profileOrg}/discipline/user`,
dataUserLeave: `${profileOrg}/leave/user`, dataUserLeave: `${profileOrg}/leave/user`,
@ -26,37 +24,46 @@ export default {
dataUserSalary: `${profileOrg}/salary/user`, dataUserSalary: `${profileOrg}/salary/user`,
dataUserNopaid: `${profileOrg}/nopaid/user`, dataUserNopaid: `${profileOrg}/nopaid/user`,
dataUserCertificate:(type:string) => `${profileOrg}/${type}/user`, dataUserCertificate: (type: string) => `${profileOrg}/${type}/user`,
dataUserOther:`${profileOrg}/other/user`, dataUserOther: `${profileOrg}/other/user`,
profileReportId: (profileId: string) => `${report}kk1/${profileId}`, profileReportId: (profileId: string) => `${report}kk1/${profileId}`,
profileKp7ShortId: (profileId: string) => `${report}kp7-short/${profileId}`, profileKp7ShortId: (profileId: string) => `${report}kp7-short/${profileId}`,
/** history */ /** history */
dataUserInformatioHistory:(type:string)=> `${profileOrg}${type}/history/user`, dataUserInformatioHistory: (type: string) =>
`${profileOrg}${type}/history/user`,
dataUserChangeNameHistory: `${profileOrg}/changeName/history`, dataUserChangeNameHistory: `${profileOrg}/changeName/history`,
dataUserHistory:(type:string)=> `${profileOrg}${type}/address/history/user`, dataUserHistory: (type: string) =>
dataUserFamilyHistory:(type:string,emType:string,id:string)=> `${profileOrg}${emType}/family/${type}/history/${id}`, `${profileOrg}${type}/address/history/user`,
dataUserEducationsHistory:(id:string)=> `${profileOrg}/educations/history/${id}`, dataUserFamilyHistory: (type: string, emType: string, id: string) =>
dataUserAbilityHistory:(id:string)=> `${profileOrg}/ability/history/${id}`, `${profileOrg}${emType}/family/${type}/history/${id}`,
dataUserEducationsHistory: (id: string) =>
`${profileOrg}/educations/history/${id}`,
dataUserAbilityHistory: (id: string) => `${profileOrg}/ability/history/${id}`,
dataUserGovernmentHistory:(type:string)=> `${profileOrg}${type}/government/history/user`, dataUserGovernmentHistory: (type: string) =>
dataUserDisciplineHistory:(id:string)=> `${profileOrg}/discipline/history/${id}`, `${profileOrg}${type}/government/history/user`,
dataUserLeaveHistory: (id:string)=>`${profileOrg}/leave/history/${id}`, dataUserDisciplineHistory: (id: string) =>
dataUserDutyHistory:(id:string)=> `${profileOrg}/duty/history/${id}`, `${profileOrg}/discipline/history/${id}`,
dataUserLeaveHistory: (id: string) => `${profileOrg}/leave/history/${id}`,
dataUserDutyHistory: (id: string) => `${profileOrg}/duty/history/${id}`,
dataUserSalaryHistory: (id:string)=>`${profileOrg}/salary/history/${id}`, dataUserSalaryHistory: (id: string) => `${profileOrg}/salary/history/${id}`,
dataUserSalaryNopaidHistory: (id:string)=>`${profileOrg}/nopaid/history/${id}`, dataUserSalaryNopaidHistory: (id: string) =>
`${profileOrg}/nopaid/history/${id}`,
dataUserCertificateHistory:(type:string,id:string) => `${profileOrg}/${type}/history/${id}`, dataUserCertificateHistory: (type: string, id: string) =>
dataUserHonorHistory:(type:string,emType:string,id:string) => `${profileOrg}${emType}/${type}/history/${id}`, `${profileOrg}/${type}/history/${id}`,
dataUserOtherHistory:(id:string)=>`${profileOrg}/other/history/${id}`, dataUserHonorHistory: (type: string, emType: string, id: string) =>
`${profileOrg}${emType}/${type}/history/${id}`,
dataUserOtherHistory: (id: string) => `${profileOrg}/other/history/${id}`,
orgCheckAvatar: (id: string) => `${profileOrg}/avatar/profileId/${id}`,
orgActive: `${org}/active`,
orgActive:`${org}/active`, /** struct-chart*/
/** struct-chart*/ orgStructChart: (id: string, type: string) =>
orgStructChart: (id: string, type: string) => `${org}/struct-chart/${id}/${type}`,
`${org}/struct-chart/${id}/${type}`,
}; };

View file

@ -1,11 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index"; import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index";
import type { FormQuery } from "@/modules/08_KPI/interface/request/index"; import type { FormQuery } from "@/modules/08_KPI/interface/request/index";
const store = useKpiDataStore();
const router = useRouter(); const router = useRouter();
const visibleColumns = defineModel<string[]>("visibleColumns", { const visibleColumns = defineModel<string[]>("visibleColumns", {
required: true, required: true,
@ -23,7 +25,8 @@ const props = defineProps({
fetchList: { type: Function }, fetchList: { type: Function },
}); });
function redirectViewDetail(id: string) { async function redirectViewDetail(id: string) {
store.tabMain = await "";
router.push(`/KPI-evaluator/${id}`); router.push(`/KPI-evaluator/${id}`);
} }

View file

@ -21,14 +21,8 @@ const dataListCriteria = ref<ListCriteria[]>([]);
const modalCriteria = ref<boolean>(false); const modalCriteria = ref<boolean>(false);
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
const { const { hideLoader, messageError, success, showLoader, dialogRemove } =
hideLoader, useCounterMixin();
messageError,
date2Thai,
success,
showLoader,
dialogRemove,
} = useCounterMixin();
const store = useKpiDataStore(); const store = useKpiDataStore();
const evaluationId = ref<string>(route.params.id.toString()); const evaluationId = ref<string>(route.params.id.toString());
@ -165,7 +159,7 @@ function getCriteria() {
} }
const isShowScore = computed(() => { const isShowScore = computed(() => {
return store.tabOpen === 3 && store.tabMain === "3"; return store.tabMain === "3";
}); });
watch( watch(
@ -192,15 +186,13 @@ watch(
store.indicatorScoreVal = store.indicatorScoreVal =
store.indicatorPercentVal * (store.indicatorScore / 100); store.indicatorPercentVal * (store.indicatorScore / 100);
if ( if (store.isUpdate && store.tabMain === "3") {
store.isUpdate &&
store.tabMain === "3" &&
(store.dataEvaluation.evaluationStatus === "EVALUATOR" ||
store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR")
) {
http http
.put(config.API.updatePoint(evaluationId.value), { .put(config.API.updatePoint(evaluationId.value), {
totalPoint1: store.indicatorScoreVal.toFixed(2), totalPoint1: (
store.indicatorPercentVal *
(store.indicatorScore / 100)
).toFixed(2),
summaryPoint: ( summaryPoint: (
store.indicatorScoreVal + store.indicatorScoreVal +
store.competencyScoreVal + store.competencyScoreVal +

View file

@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import DialogHeader from "@/components/DialogHeader.vue";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
@ -41,52 +40,9 @@ const weight1 = ref<number>(0);
const result1 = ref<number>(0); const result1 = ref<number>(0);
const weight2 = ref<number>(0); const weight2 = ref<number>(0);
const result2 = ref<number>(0); const result2 = ref<number>(0);
const sumWeight = computed(() => { const sumWeight = ref<number>(0);
return weight1.value + weight2.value; const sumResult = ref<number>(0);
}); const result = ref<string>("");
const sumResult = computed(() => {
return result1.value + result2.value;
});
const group = computed(() => {
return convert(sumResult.value);
});
// const options = ref<any[]>([
// {
// label: " ( . )",
// value: "EXCELLENT",
// },
// {
// label: " ( . - .)",
// value: "VERYGOOD",
// },
// {
// label: " ( . - .)",
// value: "GOOD",
// },
// {
// label: " ( . - .)",
// value: "FAIR",
// },
// {
// label: " ( .)",
// value: "IMPROVEMENT",
// },
// ]);
function convert(score: any): string {
if (score >= 90) {
return "EXCELLENT";
} else if (score >= 80) {
return "VERYGOOD";
} else if (score >= 70) {
return "GOOD";
} else if (score >= 60) {
return "FAIR";
} else {
return "IMPROVEMENT";
}
}
function onSubmit() { function onSubmit() {
dialogConfirm($q, () => { dialogConfirm($q, () => {
@ -173,14 +129,22 @@ function resetCommanderHigh() {
additionalSuperiorCommentRef.value.resetValidation(); additionalSuperiorCommentRef.value.resetValidation();
} }
/**
* งขอมลการประเม
*/
async function fetchEvaluation() { async function fetchEvaluation() {
await http await http
.get(config.API.kpiEvaluation + `/${id.value}`) .get(config.API.kpiEvaluation + `/${id.value}`)
.then(async (res) => { .then(async (res) => {
const data = res.data.result; const data = res.data.result;
// store
store.dataEvaluation = await data; store.dataEvaluation = await data;
if (data.profileId == store.dataProfile.profileId) { //
if (
!store.dataEvaluation.isOpen &&
data.profileId == store.dataProfile.profileId
) {
userOpen(); userOpen();
} }
}) })
@ -207,25 +171,26 @@ function getData() {
developmentMethod.value = data.developEvaluator; developmentMethod.value = data.developEvaluator;
developmentPeriod.value = data.timeEvaluator; developmentPeriod.value = data.timeEvaluator;
evaluatorComment.value = data.reasonEvaluator; evaluatorComment.value = data.reasonEvaluator;
superiorCommentCheck.value = data.isReasonCommander superiorCommentCheck.value = data.isReasonCommander.toString();
? data.isReasonCommander.toString()
: "";
superiorComment.value = data.reasonCommander; superiorComment.value = data.reasonCommander;
additionalSuperiorCheck.value = data.isReasonCommanderHigh additionalSuperiorCheck.value = data.isReasonCommanderHigh.toString();
? data.isReasonCommanderHigh.toString()
: "";
additionalSuperiorComment.value = data.reasonCommanderHigh; additionalSuperiorComment.value = data.reasonCommanderHigh;
result1.value = data.totalPoint1; result1.value = data.totalPoint1;
result2.value = data.totalPoint2_1 + data.totalPoint2_2; result2.value = data.totalPoint2_1 + data.totalPoint2_2;
weight1.value = data.weightPoint1; weight1.value = data.weightPoint1;
weight2.value = data.weightPoint2; weight2.value = data.weightPoint2;
sumWeight.value = data.weightPoint1 + data.weightPoint2;
sumResult.value = data.summaryPoint;
result.value = data.evaluationResults;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
}) })
.finally(() => {}); .finally(() => {});
} }
onMounted(() => { onMounted(() => {
getData(); getData();
fetchEvaluation(); fetchEvaluation();
@ -292,35 +257,35 @@ onMounted(() => {
<div class="col-12 no-pointer"> <div class="col-12 no-pointer">
<div class="column"> <div class="column">
<q-radio <q-radio
v-model="group" v-model="result"
checked-icon="task_alt" checked-icon="task_alt"
unchecked-icon="panorama_fish_eye" unchecked-icon="panorama_fish_eye"
val="EXCELLENT" val="EXCELLENT"
label="ดีเด่น (คะแนนร้อยละ 90.00 ขึ้นไป)" label="ดีเด่น (คะแนนร้อยละ 90.00 ขึ้นไป)"
/> />
<q-radio <q-radio
v-model="group" v-model="result"
checked-icon="task_alt" checked-icon="task_alt"
unchecked-icon="panorama_fish_eye" unchecked-icon="panorama_fish_eye"
val="VERYGOOD" val="VERY_GOOD"
label="ดีมาก (คะแนนร้อยละ 80.00 - 89.99)" label="ดีมาก (คะแนนร้อยละ 80.00 - 89.99)"
/> />
<q-radio <q-radio
v-model="group" v-model="result"
checked-icon="task_alt" checked-icon="task_alt"
unchecked-icon="panorama_fish_eye" unchecked-icon="panorama_fish_eye"
val="GOOD" val="GOOD"
label="ดี (คะแนนร้อยละ 70.00 - 79.99)" label="ดี (คะแนนร้อยละ 70.00 - 79.99)"
/> />
<q-radio <q-radio
v-model="group" v-model="result"
checked-icon="task_alt" checked-icon="task_alt"
unchecked-icon="panorama_fish_eye" unchecked-icon="panorama_fish_eye"
val="FAIR" val="FAIR"
label="พอใช้ (คะแนนร้อยละ 60.00 - 69.99)" label="พอใช้ (คะแนนร้อยละ 60.00 - 69.99)"
/> />
<q-radio <q-radio
v-model="group" v-model="result"
checked-icon="task_alt" checked-icon="task_alt"
unchecked-icon="panorama_fish_eye" unchecked-icon="panorama_fish_eye"
val="IMPROVEMENT" val="IMPROVEMENT"

View file

@ -196,7 +196,7 @@ function onSubmit() {
function getData() { function getData() {
showLoader(); showLoader();
http http
.get(config.API.KpiCapacity + `?type=${type.value}`) .get(config.API.KpiCapacity + `?type=${type.value}&pageSize=100`)
.then((res) => { .then((res) => {
const data = res.data.result.data; const data = res.data.result.data;
listTarget.value = data; listTarget.value = data;

View file

@ -1,16 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from "vue"; import { ref } from "vue";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import { useRoute } from "vue-router";
import Assessment from "@/modules/08_KPI/components/Tab/01_Assessment.vue"; import Assessment from "@/modules/08_KPI/components/Tab/01_Assessment.vue";
import Result from "@/modules/08_KPI/components/Tab/04_Result.vue"; import Result from "@/modules/08_KPI/components/Tab/04_Result.vue";
// import CommanderAbove from "@/modules/08_KPI/components/Tab/03_CommanderAbove.vue";
// import CommanderAboveOneStep from "@/modules/08_KPI/components/Tab/04_CommanderAboveOneStep.vue";
import File from "@/modules/08_KPI/components/Tab/05_File.vue"; import File from "@/modules/08_KPI/components/Tab/05_File.vue";
const store = useKpiDataStore(); const store = useKpiDataStore();
const route = useRoute();
const itemsTab = ref<any>([ const itemsTab = ref<any>([
{ {
@ -52,11 +48,11 @@ const splitterModel = ref<number>(12);
class="text-grey-7 text-weight-light" class="text-grey-7 text-weight-light"
active-class="bg-blue-1 text-blue-8 text-weight-bold" active-class="bg-blue-1 text-blue-8 text-weight-bold"
> >
<q-tab name="1" label="จัดทำข้อตกลง" /> <q-tab name="1" label="จัดทำข้อตกลง" :disable="store.tabOpen != 1" />
<q-tab <q-tab
name="2" name="2"
label="รายงานความก้าวหน้า" label="รายงานความก้าวหน้า"
:disable="store.tabOpen < 2" :disable="store.tabOpen != 2"
/> />
<q-tab <q-tab
name="3" name="3"

View file

@ -213,9 +213,6 @@ const isEditStep3 = computed(() => {
store.rolePerson === "USER" && store.rolePerson === "USER" &&
store.tabMain === "3") || store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" && (store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "3")||
(store.dataEvaluation.evaluationStatus === "EVALUATING" &&
store.rolePerson === "EVALUATOR" && store.rolePerson === "EVALUATOR" &&
store.tabMain === "3") store.tabMain === "3")
); );

View file

@ -315,7 +315,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="!isEditStep1" v-if="isEditStep1 && item.id != 'HEAD' && item.id != 'GROUP'"
class="q-ml-xs" class="q-ml-xs"
flat flat
round round
@ -460,8 +460,12 @@ onMounted(() => {
<q-btn <q-btn
flat flat
round round
icon="edit" :icon="
color="edit" item.id == 'HEAD' || item.id == 'GROUP'
? 'mdi-eye'
: 'edit'
"
color="info"
@click.stop.pervent="onEdit(props.row, item.id)" @click.stop.pervent="onEdit(props.row, item.id)"
> >
<q-tooltip>แกไข </q-tooltip> <q-tooltip>แกไข </q-tooltip>

View file

@ -203,9 +203,6 @@ const isEditStep3 = computed(() => {
store.rolePerson === "USER" && store.rolePerson === "USER" &&
store.tabMain === "3") || store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" && (store.dataEvaluation.evaluationStatus === "EVALUATING_EVALUATOR" &&
store.rolePerson === "EVALUATOR" &&
store.tabMain === "3") ||
(store.dataEvaluation.evaluationStatus === "EVALUATING" &&
store.rolePerson === "EVALUATOR" && store.rolePerson === "EVALUATOR" &&
store.tabMain === "3") store.tabMain === "3")
); );

View file

@ -10,16 +10,7 @@ import { useQuasar } from "quasar";
export const useKpiDataStore = defineStore("KPIDate", () => { export const useKpiDataStore = defineStore("KPIDate", () => {
const $q = useQuasar(); const $q = useQuasar();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { const { showLoader, hideLoader, messageError } = mixin;
dialogConfirm,
success,
showLoader,
hideLoader,
messageError,
findPosMasterNoOld,
findOrgNameOld,
date2Thai,
} = mixin;
const isUpdate = ref<boolean>(false); const isUpdate = ref<boolean>(false);
const tabMainevaluator = ref<string>("1"); const tabMainevaluator = ref<string>("1");
@ -32,7 +23,7 @@ export const useKpiDataStore = defineStore("KPIDate", () => {
}); });
const selected = ref([]); const selected = ref([]);
const work = ref<boolean>(false); const work = ref<boolean>(false);
const tabMain = ref<string>("1"); const tabMain = ref<string>("");
const dataProfile = ref<any>({ const dataProfile = ref<any>({
profileId: null, profileId: null,
prefix: "", prefix: "",
@ -138,14 +129,18 @@ export const useKpiDataStore = defineStore("KPIDate", () => {
function convertResults(val: string) { function convertResults(val: string) {
switch (val) { switch (val) {
case "PENDING": case "EXCELLENT":
return "รอดำเนินการ"; return "ดีเด่น";
case "PASSED": case "VERY_GOOD":
return "ผ่านการประเมิน"; return "ดีมาก";
case "NOTPASSED": case "GOOD":
return "ไม่ผ่านการประเมิน"; return "ดี";
case "FAIR":
return "พอใช้";
case "IMPROVEMENT":
return "ต้องปรับปรุง";
default: default:
break; return "รอดำเนินการ";
} }
} }

View file

@ -103,11 +103,22 @@ async function getProfile() {
async function fetchProfile(id: string) { async function fetchProfile(id: string) {
await http await http
.get( .get(config.API.orgCheckAvatar(id))
config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, `profile-${id}`)
)
.then(async (res) => { .then(async (res) => {
store.dataEvaluation.avartar = res.data.downloadUrl; if (res.data.result.avatarName) {
http
.get(
config.API.fileByFile(
"ทะเบียนประวัติ",
"โปรไฟล์",
id,
res.data.result.avatarName
)
)
.then(async (res) => {
store.dataEvaluation.avartar = res.data.downloadUrl;
});
}
}) })
.catch(() => { .catch(() => {
// profilePicture.value = avatar; // profilePicture.value = avatar;
@ -119,7 +130,6 @@ function close() {
evaluatorId.value = null; evaluatorId.value = null;
commanderId.value = null; commanderId.value = null;
commanderHighId.value = null; commanderHighId.value = null;
getAll();
} }
function onSubmit() { function onSubmit() {
@ -135,8 +145,10 @@ function onSubmit() {
: null, : null,
}) })
.then((res) => { .then((res) => {
success($q, "บันทึกสำเร็จ"); fetchEvaluation();
getOrgOp();
close(); close();
success($q, "บันทึกสำเร็จ");
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -268,7 +280,7 @@ function sendToEvaluatore() {
}) })
.then((res) => { .then((res) => {
success($q, "ส่งข้อตกลงให้ผู้ประเมินอนุมัติสำเร็จ"); success($q, "ส่งข้อตกลงให้ผู้ประเมินอนุมัติสำเร็จ");
close(); fetchEvaluation();
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -295,7 +307,7 @@ function sendToEvaluateEvaluatore() {
}) })
.then((res) => { .then((res) => {
success($q, "ส่งให้ผู้ประเมินรายงานผลสำเร็จของงานสำเร็จ"); success($q, "ส่งให้ผู้ประเมินรายงานผลสำเร็จของงานสำเร็จ");
close(); fetchEvaluation();
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -346,7 +358,7 @@ function requireEdit() {
}) })
.then((res) => { .then((res) => {
success($q, "ขอแก้ไขสำเร็จ"); success($q, "ขอแก้ไขสำเร็จ");
close(); fetchEvaluation();
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -397,8 +409,9 @@ function goToSummary() {
http http
.get(config.API.sendToSummary(store.dataEvaluation.id)) .get(config.API.sendToSummary(store.dataEvaluation.id))
.then(async (res) => { .then(async (res) => {
await getAll(); await fetchEvaluation();
store.tabMain = "4"; store.tabMain = "4";
store.tabOpen = 4;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);