hotfix: refs #7323 generate code & minor changes #635

Merged
jorgep merged 6 commits from 7323-hotfix-workerFineTunning into master 2024-08-23 06:49:18 +00:00
6 changed files with 99 additions and 41 deletions

View File

@ -152,7 +152,7 @@ const getEventAttrs = (timestamp) => {
if (isFestive) { if (isFestive) {
attrs.class = '--festive'; attrs.class = '--festive';
attrs.label = event.absenceId ?? timestamp.day; attrs.label = timestamp.day;
Review

Esto mostraba el id de la ausencia... en lugar del día. Además, en la lógica de Salix, no he visto nada parecido.

Esto mostraba el id de la ausencia... en lugar del día. Además, en la lógica de Salix, no he visto nada parecido.
} else attrs.class = `--${type}`; } else attrs.class = `--${type}`;
return attrs; return attrs;

View File

@ -93,7 +93,6 @@ const filter = {
/> />
</template> </template>
</VnLv> </VnLv>
<VnLv :label="t('worker.list.email')" :value="worker.user.email" copy />
<VnLv :label="t('worker.summary.boss')" link> <VnLv :label="t('worker.summary.boss')" link>
<template #value> <template #value>
<VnUserLink <VnUserLink
@ -139,29 +138,25 @@ const filter = {
/> />
<VnLv :label="t('worker.summary.fi')" :value="worker.fi" /> <VnLv :label="t('worker.summary.fi')" :value="worker.fi" />
<VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" /> <VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" />
<VnRow class="q-mt-sm" wrap> <VnLv
Review

Uno debajo del otro.

Uno debajo del otro.
<VnLv :label="t('worker.summary.isFreelance')"
:label="t('worker.summary.isFreelance')" :value="worker.isFreelance"
:value="worker.isFreelance" />
/> <VnLv
<VnLv :label="t('worker.summary.isSsDiscounted')"
:label="t('worker.summary.isSsDiscounted')" :value="worker.isSsDiscounted"
:value="worker.isSsDiscounted" />
/> <VnLv
<VnLv :label="t('worker.summary.hasMachineryAuthorized')"
:label="t('worker.summary.hasMachineryAuthorized')" :value="worker.hasMachineryAuthorized"
:value="worker.hasMachineryAuthorized" />
/> <VnLv :label="t('worker.summary.isDisable')" :value="worker.isDisable" />
<VnLv
:label="t('worker.summary.isDisable')"
:value="worker.isDisable"
/>
</VnRow>
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<VnTitle :text="t('worker.summary.userData')" /> <VnTitle :text="t('worker.summary.userData')" />
<VnLv :label="t('worker.summary.userId')" :value="worker.user.id" /> <VnLv :label="t('worker.summary.userId')" :value="worker.user.id" />
<VnLv :label="t('worker.card.name')" :value="worker.user.nickname" /> <VnLv :label="t('worker.card.name')" :value="worker.user.nickname" />
<VnLv :label="t('worker.list.email')" :value="worker.user.email" copy />
<VnLv :label="t('worker.summary.role')"> <VnLv :label="t('worker.summary.role')">
<template #value> <template #value>
<span class="link"> <span class="link">

View File

@ -34,6 +34,10 @@ const weekdayStore = useWeekdayStore();
const weekDays = ref([]); const weekDays = ref([]);
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const { getWeekOfYear } = date; const { getWeekOfYear } = date;
const defaultDate = computed(() => {
const timestamp = route.query.timestamp;
return timestamp ? new Date(timestamp * 1000) : Date.vnNew();
});
const workerTimeFormDialogRef = ref(null); const workerTimeFormDialogRef = ref(null);
const workerTimeReasonFormDialogRef = ref(null); const workerTimeReasonFormDialogRef = ref(null);
@ -56,7 +60,7 @@ const workerTimeFormProps = reactive({
// Array utilizado por QCalendar para seleccionar un rango de fechas // Array utilizado por QCalendar para seleccionar un rango de fechas
const selectedCalendarDates = ref([]); const selectedCalendarDates = ref([]);
// Date formateada para bindear al componente QDate // Date formateada para bindear al componente QDate
const selectedDateFormatted = ref(toDateString(Date.vnNew())); const selectedDateFormatted = ref(toDateString(defaultDate.value));
const arrayData = useArrayData('workerData'); const arrayData = useArrayData('workerData');
@ -423,7 +427,7 @@ onBeforeMount(() => {
}); });
onMounted(async () => { onMounted(async () => {
await setDate(Date.vnNew()); await setDate(defaultDate.value);
await getMailStates(selectedDate.value); await getMailStates(selectedDate.value);
stateStore.rightDrawer = true; stateStore.rightDrawer = true;
}); });
@ -547,7 +551,10 @@ onMounted(async () => {
<QTd <QTd
v-for="(day, index) in props.cols" v-for="(day, index) in props.cols"
:key="index" :key="index"
style="padding: 20px 16px !important" :style="{
padding: '20px 16px !important',
'vertical-align': 'baseline',
Review

Alinea arriba del todo las horas. Probado en Firefox, chorme y Edge.

Alinea arriba del todo las horas. Probado en Firefox, chorme y Edge.
}"
> >
<div class="full-width column items-center"> <div class="full-width column items-center">
<WorkerTimeHourChip <WorkerTimeHourChip

View File

@ -2,7 +2,6 @@
import { onBeforeMount, ref } from 'vue'; import { onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { useUserConfig } from 'src/composables/useUserConfig';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
@ -14,15 +13,26 @@ import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue'; import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
import VnRadio from 'src/components/common/VnRadio.vue'; import VnRadio from 'src/components/common/VnRadio.vue';
import { useState } from 'src/composables/useState';
const { t } = useI18n(); const { t } = useI18n();
const user = useState().getUser();
const companiesOptions = ref([]); const companiesOptions = ref([]);
const workersOptions = ref([]); const workersOptions = ref([]);
const payMethodsOptions = ref([]); const payMethodsOptions = ref([]);
const bankEntitiesOptions = ref([]); const bankEntitiesOptions = ref([]);
const formData = ref({ isFreelance: false }); const formData = ref({ companyFk: user.value.companyFk, isFreelance: false });
const defaultPayMethod = ref(0); const defaultPayMethod = ref();
onBeforeMount(async () => {
defaultPayMethod.value = (
await axios.get('WorkerConfigs/findOne', {
params: { field: ['payMethodFk'] },
})
).data.payMethodFk;
formData.value.payMethodFk = defaultPayMethod.value;
});
function handleLocation(data, location) { function handleLocation(data, location) {
const { town, code, provinceFk, countryFk } = location ?? {}; const { town, code, provinceFk, countryFk } = location ?? {};
@ -32,16 +42,20 @@ function handleLocation(data, location) {
data.countryFk = countryFk; data.countryFk = countryFk;
} }
onBeforeMount(async () => { function generateCodeUser(worker) {
const userInfo = await useUserConfig().fetch(); if (!worker.firstName || !worker.lastNames) return;
formData.value.companyFk = userInfo.companyFk;
const { data } = await axios.get('WorkerConfigs/findOne', { const totalName = worker.firstName.concat(' ' + worker.lastNames).toLowerCase();
params: { field: ['payMethodFk'] }, const totalNameArray = totalName.split(' ');
}); let newCode = '';
defaultPayMethod.value = data.payMethodFk;
formData.value.payMethodFk = defaultPayMethod.value; for (let part of totalNameArray) newCode += part.charAt(0);
});
worker.code = newCode.toUpperCase().slice(0, 3);
worker.name = totalNameArray[0] + newCode.slice(1);
if (!worker.companyFk) worker.companyFk = user.companyFk;
}
</script> </script>
<template> <template>
<FetchData <FetchData
@ -93,11 +107,13 @@ onBeforeMount(async () => {
v-model="data.firstName" v-model="data.firstName"
:label="t('worker.create.name')" :label="t('worker.create.name')"
:rules="validate('Worker.firstName')" :rules="validate('Worker.firstName')"
@update:model-value="generateCodeUser(data)"
/> />
<VnInput <VnInput
v-model="data.lastNames" v-model="data.lastNames"
:label="t('worker.create.lastName')" :label="t('worker.create.lastName')"
:rules="validate('Worker.lastNames')" :rules="validate('Worker.lastNames')"
@update:model-value="generateCodeUser(data)"
/> />
<VnInput <VnInput
v-model="data.code" v-model="data.code"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, ref } from 'vue'; import { onBeforeMount, computed, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
@ -16,6 +16,8 @@ import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import WorkerFilter from './WorkerFilter.vue'; import WorkerFilter from './WorkerFilter.vue';
import { useState } from 'src/composables/useState';
import axios from 'axios';
const { t } = useI18n(); const { t } = useI18n();
const tableRef = ref(); const tableRef = ref();
@ -26,6 +28,8 @@ const payMethodsOptions = ref([]);
const bankEntitiesOptions = ref([]); const bankEntitiesOptions = ref([]);
const postcodesOptions = ref([]); const postcodesOptions = ref([]);
const user = useState().getUser();
const defaultPayMethod = ref();
const columns = computed(() => [ const columns = computed(() => [
{ {
align: 'left', align: 'left',
@ -82,6 +86,14 @@ const columns = computed(() => [
}, },
]); ]);
onBeforeMount(async () => {
defaultPayMethod.value = (
await axios.get('WorkerConfigs/findOne', {
params: { field: ['payMethodFk'] },
})
).data?.payMethodFk;
});
function handleLocation(data, location) { function handleLocation(data, location) {
const { town, code, provinceFk, countryFk } = location ?? {}; const { town, code, provinceFk, countryFk } = location ?? {};
data.postcode = code; data.postcode = code;
@ -98,6 +110,21 @@ function uppercaseStreetModel(data) {
}, },
}; };
} }
function generateCodeUser(worker) {
if (!worker.firstName || !worker.lastNames) return;
const totalName = worker.firstName.concat(' ' + worker.lastNames).toLowerCase();
const totalNameArray = totalName.split(' ');
let newCode = '';
for (let part of totalNameArray) newCode += part.charAt(0);
worker.code = newCode.toUpperCase().slice(0, 3);
worker.name = totalNameArray[0] + newCode.slice(1);
if (!worker.companyFk) worker.companyFk = user.companyFk;
}
</script> </script>
<template> <template>
<VnSearchbar <VnSearchbar
@ -131,6 +158,7 @@ function uppercaseStreetModel(data) {
</template> </template>
</RightMenu> </RightMenu>
<VnTable <VnTable
v-if="defaultPayMethod"
ref="tableRef" ref="tableRef"
data-key="Worker" data-key="Worker"
url="Workers/filter" url="Workers/filter"
@ -139,6 +167,8 @@ function uppercaseStreetModel(data) {
title: t('Create worker'), title: t('Create worker'),
onDataSaved: ({ id }) => tableRef.redirect(id), onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: { formInitialData: {
payMethodFk: defaultPayMethod,
companyFk: user.companyFk,
isFreelance: false, isFreelance: false,
}, },
}" }"
@ -149,7 +179,7 @@ function uppercaseStreetModel(data) {
auto-load auto-load
> >
<template #more-create-dialog="{ data }"> <template #more-create-dialog="{ data }">
<div class="q-pa-lg full-width" style="max-width: 1200px"> <div class="q-pa-lg full-width">

No hacía nada

No hacía nada
<VnRadio <VnRadio
v-model="data.isFreelance" v-model="data.isFreelance"
:val="false" :val="false"
@ -163,10 +193,16 @@ function uppercaseStreetModel(data) {
@update:model-value="delete data.payMethodFk" @update:model-value="delete data.payMethodFk"
/> />
<VnRow> <VnRow>
<VnInput v-model="data.firstName" :label="t('worker.create.name')" /> <VnInput
Review

He creado un punto en la próxima reunión de Salix para que se haga refactor de los componentes create y se pueda usar en los VnTable. Ahora mismo en todos los listados se ha duplicado el código...

He creado un punto en la próxima reunión de Salix para que se haga refactor de los componentes create y se pueda usar en los VnTable. Ahora mismo en todos los listados se ha duplicado el código...
next
v-model="data.firstName"
:label="t('worker.create.name')"
@update:model-value="generateCodeUser(data)"
/>
<VnInput <VnInput
v-model="data.lastNames" v-model="data.lastNames"
:label="t('worker.create.lastName')" :label="t('worker.create.lastName')"
@update:model-value="generateCodeUser(data)"
/> />
<VnInput v-model="data.code" :label="t('worker.create.code')" /> <VnInput v-model="data.code" :label="t('worker.create.code')" />
</VnRow> </VnRow>

View File

@ -2,6 +2,9 @@ describe('WorkerCreate', () => {
const externalRadio = '.q-radio:nth-child(2)'; const externalRadio = '.q-radio:nth-child(2)';
const notification = '.q-notification__message'; const notification = '.q-notification__message';
const developerBossId = 120; const developerBossId = 120;
const payMethodCross =
'.grid-create .full-width > :nth-child(9) .q-select .q-field__append:not(.q-anchor--skip)';
const saveBtn = '.q-mt-lg > .q-btn--standard';
const internal = { const internal = {
Fi: { val: '78457139E' }, Fi: { val: '78457139E' },
@ -36,7 +39,8 @@ describe('WorkerCreate', () => {
it('should throw an error if a pay method has not been selected', () => { it('should throw an error if a pay method has not been selected', () => {
cy.fillInForm(internal); cy.fillInForm(internal);
cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(payMethodCross).click();
cy.get(saveBtn).click();
cy.get(notification).should('contains.text', 'Payment method is required'); cy.get(notification).should('contains.text', 'Payment method is required');
}); });
@ -45,14 +49,14 @@ describe('WorkerCreate', () => {
...internal, ...internal,
'Pay method': { val: 'PayMethod one', type: 'select' }, 'Pay method': { val: 'PayMethod one', type: 'select' },
}); });
cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(saveBtn).click();
cy.get(notification).should('contains.text', 'Data created'); cy.get(notification).should('contains.text', 'Data created');
}); });
it('should create an external', () => { it('should create an external', () => {
cy.get(externalRadio).click(); cy.get(externalRadio).click();
cy.fillInForm(external); cy.fillInForm(external);
cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(saveBtn).click();
cy.get(notification).should('contains.text', 'Data created'); cy.get(notification).should('contains.text', 'Data created');
}); });
}); });