Compare commits
94 Commits
7065-testU
...
dev
Author | SHA1 | Date |
---|---|---|
Jon Elias | 909e6674d6 | |
Jon Elias | 0fe63abba6 | |
PAU ROVIRA ROSALENY | 5ae5cec9f9 | |
PAU ROVIRA ROSALENY | a09f430c60 | |
Jon Elias | 0fcd969c97 | |
Jon Elias | e710d45011 | |
Carlos Satorres | ccff995680 | |
Carlos Satorres | d94cd801cc | |
PAU ROVIRA ROSALENY | 4eebfd8769 | |
PAU ROVIRA ROSALENY | 39d6e818f5 | |
PAU ROVIRA ROSALENY | f69ed548f0 | |
Jon Elias | f6439ed356 | |
Jon Elias | fea59a729e | |
Jon Elias | c2a6dd7979 | |
PAU ROVIRA ROSALENY | 5b2987c95e | |
Jon Elias | 4246275759 | |
Jon Elias | f70dd41a37 | |
PAU ROVIRA ROSALENY | e5a449c80c | |
PAU ROVIRA ROSALENY | 0de8af81d3 | |
PAU ROVIRA ROSALENY | 6cd0df04e6 | |
PAU ROVIRA ROSALENY | 374118133a | |
PAU ROVIRA ROSALENY | 860f92cb42 | |
PAU ROVIRA ROSALENY | b2414f861b | |
PAU ROVIRA ROSALENY | 42e46a88fb | |
Jorge Penadés | c0e3a14e8b | |
Jorge Penadés | 7759a49f3a | |
PAU ROVIRA ROSALENY | 0d7d60a1e8 | |
PAU ROVIRA ROSALENY | 3e8b35e2e1 | |
PAU ROVIRA ROSALENY | 983b91fbdd | |
Carlos Satorres | 962ae4ca96 | |
Jon Elias | caffb672bc | |
Jon Elias | a8b28de2a4 | |
Carlos Satorres | 4034320ff7 | |
Carlos Satorres | c64aad02e1 | |
PAU ROVIRA ROSALENY | 6cba927ebc | |
Carlos Satorres | 1ee8b68fce | |
Carlos Satorres | b7e71044b0 | |
Carlos Satorres | c8fe115fec | |
Carlos Satorres | 7144bb3871 | |
Carlos Satorres | 46cdd9e62b | |
Carlos Satorres | 3fc7f34899 | |
Carlos Satorres | 38a180f92b | |
Carlos Satorres | 72f141315e | |
Carlos Satorres | 55dda496f3 | |
Carlos Satorres | 57aa38c84c | |
Carlos Satorres | f8428a5591 | |
Carlos Satorres | 5a869f0722 | |
Carlos Satorres | f904c8cfd2 | |
Carlos Satorres | 8aba370063 | |
Carlos Satorres | b479ce83e0 | |
Carlos Satorres | 3e16357878 | |
Carlos Satorres | 66db2f0bd7 | |
Carlos Satorres | f139be4fcd | |
Carlos Satorres | 3dbace5336 | |
Carlos Satorres | 63fb45b22d | |
Carlos Satorres | 916842ba93 | |
Carlos Satorres | 9ab6ac9718 | |
Carlos Satorres | 950bd5f3a7 | |
Carlos Satorres | 7619a5b4f5 | |
Carlos Satorres | 96e942af11 | |
Carlos Satorres | 3a060c9c6a | |
Carlos Satorres | f903432e74 | |
Carlos Satorres | 04d30186c2 | |
Carlos Satorres | f7fb18cf0a | |
Carlos Satorres | 02129591cf | |
Carlos Satorres | bf4d11545d | |
Carlos Satorres | 70847176ca | |
Carlos Satorres | 97ce44242c | |
Carlos Satorres | c75e4cbf95 | |
Carlos Satorres | 60e9accd99 | |
Carlos Satorres | 00cd6feb12 | |
Carlos Satorres | 8f925401d5 | |
Carlos Satorres | 8363f813de | |
Carlos Satorres | 68d1d0dbb0 | |
Carlos Satorres | 0e7abe5fa4 | |
Carlos Satorres | 9c5620f340 | |
Carlos Satorres | 41e1d365f3 | |
Carlos Satorres | b6836fc59e | |
Alex Moreno | 81591b4f67 | |
Alex Moreno | 83a0ec7eb8 | |
Alex Moreno | 8d60754682 | |
Alex Moreno | ba57c2fcd9 | |
Carlos Satorres | 8490f24438 | |
Carlos Satorres | db3ff0416c | |
Carlos Satorres | d7044cfdcc | |
Carlos Satorres | f4792d7921 | |
Carlos Satorres | 960129f86c | |
Carlos Satorres | 6e261b7793 | |
Carlos Satorres | 4b44b9a979 | |
Carlos Satorres | 8f1ddb08b3 | |
Carlos Satorres | 330b1c1ec2 | |
Carlos Satorres | 6205feaca4 | |
Carlos Satorres | 0e691436e9 | |
Carlos Satorres | 81e6870f71 |
|
@ -10,12 +10,13 @@ import routes from 'src/router/modules';
|
|||
import LeftMenuItem from './LeftMenuItem.vue';
|
||||
import LeftMenuItemGroup from './LeftMenuItemGroup.vue';
|
||||
import VnInput from './common/VnInput.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const navigation = useNavigationStore();
|
||||
|
||||
const router = useRouter();
|
||||
const props = defineProps({
|
||||
source: {
|
||||
type: String,
|
||||
|
@ -174,6 +175,10 @@ function normalize(text) {
|
|||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.toLowerCase();
|
||||
}
|
||||
const searchModule = () => {
|
||||
const [item] = filteredItems.value;
|
||||
if (item) router.push({ name: item.name });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -188,10 +193,11 @@ function normalize(text) {
|
|||
filled
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter.stop="searchModule()"
|
||||
/>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<template v-if="filteredPinnedModules.size">
|
||||
<template v-if="filteredPinnedModules.size && !search">
|
||||
<LeftMenuItem
|
||||
v-for="[key, pinnedModule] of filteredPinnedModules"
|
||||
:key="key"
|
||||
|
@ -215,11 +221,11 @@ function normalize(text) {
|
|||
</LeftMenuItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
<template v-for="item in filteredItems" :key="item.name">
|
||||
<template v-for="(item, index) in filteredItems" :key="item.name">
|
||||
<template
|
||||
v-if="item.children && !filteredPinnedModules.has(item.name)"
|
||||
v-if="search ||item.children && !filteredPinnedModules.has(item.name)"
|
||||
>
|
||||
<LeftMenuItem :item="item" group="modules">
|
||||
<LeftMenuItem :item="item" group="modules" :class="search && index === 0 ? 'searched' : ''">
|
||||
<template #side>
|
||||
<QBtn
|
||||
v-if="item.isPinned === true"
|
||||
|
@ -336,6 +342,9 @@ function normalize(text) {
|
|||
.header {
|
||||
color: var(--vn-label-color);
|
||||
}
|
||||
.searched{
|
||||
background-color: var(--vn-section-hover-color);
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
import { vi, describe, expect, it, beforeEach, beforeAll, afterEach } from 'vitest';
|
||||
import { createWrapper } from 'app/test/vitest/helper';
|
||||
import UserPanel from 'src/components/UserPanel.vue';
|
||||
import axios from 'axios';
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
vi.mock('axios');
|
||||
|
||||
describe('UserPanel', () => {
|
||||
let wrapper;
|
||||
let vm;
|
||||
let state;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper(UserPanel, {});
|
||||
state = useState();
|
||||
state.setUser({
|
||||
id: 115,
|
||||
name: 'itmanagement',
|
||||
nickname: 'itManagementNick',
|
||||
lang: 'en',
|
||||
darkMode: false,
|
||||
companyFk: 442,
|
||||
warehouseFk: 1,
|
||||
});
|
||||
wrapper = wrapper.wrapper;
|
||||
vm = wrapper.vm;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should fetch warehouses data on mounted', async () => {
|
||||
const fetchData = wrapper.findComponent({ name: 'FetchData' });
|
||||
expect(fetchData.props('url')).toBe('Warehouses');
|
||||
expect(fetchData.props('autoLoad')).toBe(true);
|
||||
});
|
||||
|
||||
it('should toggle dark mode correctly and update preferences', async () => {
|
||||
await vm.saveDarkMode(true);
|
||||
expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
|
||||
expect(vm.user.darkMode).toBe(true);
|
||||
vm.updatePreferences();
|
||||
expect(vm.darkMode).toBe(true);
|
||||
});
|
||||
|
||||
it('should change user language and update preferences', async () => {
|
||||
const userLanguage = 'es';
|
||||
await vm.saveLanguage(userLanguage);
|
||||
expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
|
||||
expect(vm.user.lang).toBe(userLanguage);
|
||||
vm.updatePreferences();
|
||||
expect(vm.locale).toBe(userLanguage);
|
||||
});
|
||||
|
||||
it('should update user data', async () => {
|
||||
const key = 'name';
|
||||
const value = 'itboss';
|
||||
await vm.saveUserData(key, value);
|
||||
expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
|
||||
});
|
||||
});
|
|
@ -53,6 +53,7 @@ const url = computed(() => {
|
|||
:fields="['id', 'name', 'nickname', 'code']"
|
||||
:filter-options="['id', 'name', 'nickname', 'code']"
|
||||
sort-by="nickname ASC"
|
||||
data-cy="vnWorkerSelect"
|
||||
>
|
||||
<template #prepend v-if="$props.hasAvatar">
|
||||
<VnAvatar :worker-id="value" color="primary" v-bind="$attrs" />
|
||||
|
|
|
@ -123,7 +123,7 @@ watch(
|
|||
() => props.data,
|
||||
() => {
|
||||
store.data = props.data;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
|
@ -132,12 +132,12 @@ watch(
|
|||
if (!mounted.value) return;
|
||||
emit('onChange', data);
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [props.url, props.filter],
|
||||
([url, filter]) => mounted.value && fetch({ url, filter })
|
||||
([url, filter]) => mounted.value && fetch({ url, filter }),
|
||||
);
|
||||
const addFilter = async (filter, params) => {
|
||||
await arrayData.addFilter({ filter, params });
|
||||
|
@ -198,7 +198,7 @@ function endPagination() {
|
|||
async function onLoad(index, done) {
|
||||
if (!store.data || !mounted.value) return done();
|
||||
|
||||
if (store.data.length === 0 || !props.url) return done(false);
|
||||
if (store.data.length === 0 || !arrayData.store.url) return done(false);
|
||||
|
||||
pagination.value.page = pagination.value.page + 1;
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ globals:
|
|||
ticketsMonitor: Tickets monitor
|
||||
clientsActionsMonitor: Clients and actions
|
||||
serial: Serial
|
||||
business: Business
|
||||
medical: Mutual
|
||||
pit: IRPF
|
||||
wasteRecalc: Waste recaclulate
|
||||
|
@ -509,6 +510,24 @@ department:
|
|||
hasToSendMail: Send check-ins by email
|
||||
departmentRemoved: Department removed
|
||||
worker:
|
||||
pageTitles:
|
||||
workers: Workers
|
||||
list: List
|
||||
basicData: Basic data
|
||||
summary: Summary
|
||||
notifications: Notifications
|
||||
workerCreate: New worker
|
||||
department: Department
|
||||
pda: PDA
|
||||
notes: Notas
|
||||
dms: My documentation
|
||||
pbx: Private Branch Exchange
|
||||
log: Log
|
||||
calendar: Calendar
|
||||
timeControl: Time control
|
||||
locker: Locker
|
||||
balance: Balance
|
||||
medical: Medical
|
||||
list:
|
||||
department: Department
|
||||
schedule: Schedule
|
||||
|
@ -524,15 +543,24 @@ worker:
|
|||
role: Role
|
||||
sipExtension: Extension
|
||||
locker: Locker
|
||||
fiDueDate: FI due date
|
||||
fiDueDate: DNI expiration date
|
||||
sex: Sex
|
||||
seniority: Seniority
|
||||
seniority: Antiquity
|
||||
fi: DNI/NIE/NIF
|
||||
birth: Birth
|
||||
isFreelance: Freelance
|
||||
isSsDiscounted: SS Bonification
|
||||
hasMachineryAuthorized: Machinery authorized
|
||||
isDisable: Disable
|
||||
business: Business
|
||||
started: Started
|
||||
ended: Ended
|
||||
reasonEnd: Reason End
|
||||
department: Departament
|
||||
workerBusinessCategory: Worker Business Category
|
||||
notes: Notes
|
||||
workCenter: Center
|
||||
professionalCategory: Professional Category
|
||||
notificationsManager:
|
||||
activeNotifications: Active notifications
|
||||
availableNotifications: Available notifications
|
||||
|
@ -591,6 +619,23 @@ worker:
|
|||
sizeLimit: Size limit
|
||||
isOnReservationMode: Reservation mode
|
||||
machine: Machine
|
||||
business:
|
||||
tableVisibleColumns:
|
||||
started: Start Date
|
||||
ended: End Date
|
||||
company: Company
|
||||
reasonEnd: Reason for Termination
|
||||
department: Department
|
||||
professionalCategory: Professional Category
|
||||
calendarType: Work Calendar
|
||||
workCenter: Work Center
|
||||
payrollCategories: Contract Category
|
||||
occupationCode: Contribution Code
|
||||
rate: Rate
|
||||
businessType: Contract Type
|
||||
amount: Salary
|
||||
basicSalary: Transport Workers Salary
|
||||
notes: Notes
|
||||
wagon:
|
||||
type:
|
||||
submit: Submit
|
||||
|
|
|
@ -326,6 +326,7 @@ globals:
|
|||
ticketsMonitor: Monitor de tickets
|
||||
clientsActionsMonitor: Clientes y acciones
|
||||
serial: Facturas por serie
|
||||
business: Contratos
|
||||
medical: Mutua
|
||||
pit: IRPF
|
||||
wasteRecalc: Recalcular mermas
|
||||
|
@ -481,6 +482,26 @@ department:
|
|||
hasToSendMail: Enviar fichadas por mail
|
||||
departmentRemoved: Departamento eliminado
|
||||
worker:
|
||||
pageTitles:
|
||||
workers: Trabajadores
|
||||
list: Listado
|
||||
basicData: Datos básicos
|
||||
summary: Resumen
|
||||
notifications: Notificaciones
|
||||
workerCreate: Nuevo trabajador
|
||||
department: Departamentos
|
||||
pda: PDA
|
||||
notes: Notas
|
||||
dms: Mi documentación
|
||||
pbx: Centralita
|
||||
log: Historial
|
||||
calendar: Calendario
|
||||
timeControl: Control de horario
|
||||
locker: Taquilla
|
||||
balance: Balance
|
||||
business: Contrato
|
||||
formation: Formación
|
||||
medical: Mutua
|
||||
list:
|
||||
department: Departamento
|
||||
schedule: Horario
|
||||
|
@ -505,6 +526,15 @@ worker:
|
|||
isSsDiscounted: Bonificación SS
|
||||
hasMachineryAuthorized: Autorizado para maquinaria
|
||||
isDisable: Deshabilitado
|
||||
business: Contrato
|
||||
started: Antigüedad
|
||||
ended: Fin
|
||||
reasonEnd: Motivo finalización
|
||||
department: Departamento
|
||||
workerBusinessCategory: Categoria profesional
|
||||
notes: Notas
|
||||
workCenter: Centro
|
||||
professionalCategory: Categoria profesional
|
||||
notificationsManager:
|
||||
activeNotifications: Notificaciones activas
|
||||
availableNotifications: Notificaciones disponibles
|
||||
|
@ -551,6 +581,23 @@ worker:
|
|||
debit: Debe
|
||||
credit: Haber
|
||||
concept: Concepto
|
||||
business:
|
||||
tableVisibleColumns:
|
||||
started: Fecha inicio
|
||||
ended: Fecha fin
|
||||
company: Empresa
|
||||
reasonEnd: Motivo finalización
|
||||
department: Departamento
|
||||
professionalCategory: Categoria profesional
|
||||
calendarType: Calendario laboral
|
||||
workCenter: Centro
|
||||
payrollCategories: Categoria contrato
|
||||
occupationCode: Cotización
|
||||
rate: Tarifa
|
||||
businessType: Contrato
|
||||
amount: Salario
|
||||
basicSalary: Salario transportistas
|
||||
notes: Notas
|
||||
operator:
|
||||
numberOfWagons: Número de vagones
|
||||
train: tren
|
||||
|
@ -563,7 +610,6 @@ worker:
|
|||
sizeLimit: Tamaño límite
|
||||
isOnReservationMode: Modo de reserva
|
||||
machine: Máquina
|
||||
|
||||
wagon:
|
||||
type:
|
||||
submit: Guardar
|
||||
|
|
|
@ -5,6 +5,9 @@ import VnTable from 'components/VnTable/VnTable.vue';
|
|||
import FetchData from 'components/FetchData.vue';
|
||||
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const tableRef = ref();
|
||||
|
@ -60,20 +63,17 @@ const columns = computed(() => [
|
|||
label: t('code'),
|
||||
isTitle: true,
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'name',
|
||||
label: t('globals.name'),
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker'),
|
||||
name: 'workerFk',
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'Workers/search',
|
||||
|
@ -100,7 +100,6 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
name: 'categoryFk',
|
||||
label: t('ItemCategory'),
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
options: itemCategoriesOptions.value,
|
||||
|
@ -112,7 +111,6 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
name: 'Temperature',
|
||||
label: t('Temperature'),
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
options: temperatureOptions.value,
|
||||
|
@ -180,6 +178,29 @@ const columns = computed(() => [
|
|||
<WorkerDescriptorProxy :id="row.workerFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnInput v-model="data.code" :label="t('code')" data-cy="codeInput" />
|
||||
<VnInput
|
||||
v-model="data.name"
|
||||
:label="t('globals.name')"
|
||||
data-cy="nameInput"
|
||||
/>
|
||||
<VnSelectWorker v-model="data.workerFk" />
|
||||
<VnSelect
|
||||
:label="t('ItemCategory')"
|
||||
v-model="data.categoryFk"
|
||||
:options="itemCategoriesOptions"
|
||||
hide-selected
|
||||
data-cy="itemCategorySelect"
|
||||
/>
|
||||
<VnSelect
|
||||
:label="t('Temperature')"
|
||||
v-model="data.temperatureFk"
|
||||
:options="temperatureOptions"
|
||||
hide-selected
|
||||
data-cy="temperatureSelect"
|
||||
/>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
</VnSection>
|
||||
|
|
|
@ -22,7 +22,6 @@ const catalogParams = {
|
|||
};
|
||||
const arrayData = useArrayData(dataKey, {
|
||||
url: 'Orders/CatalogFilter',
|
||||
limit: 50,
|
||||
userParams: catalogParams,
|
||||
});
|
||||
const store = arrayData.store;
|
||||
|
@ -66,7 +65,7 @@ function extractValueTags(items) {
|
|||
.filter((k) => /^value\d+$/.test(k))
|
||||
.map((v) => x[v])
|
||||
.filter((v) => v)
|
||||
.sort()
|
||||
.sort(),
|
||||
);
|
||||
tagValue.value = resultValueTags;
|
||||
}
|
||||
|
@ -76,7 +75,7 @@ watch(
|
|||
(val) => {
|
||||
extractTags(val);
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import { toDate } from 'src/filters';
|
||||
import { useQuasar } from 'quasar';
|
||||
import axios from 'axios';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const tableRef = ref();
|
||||
const entityId = computed(() => route.params.id);
|
||||
const quasar = useQuasar();
|
||||
|
||||
async function reactivateWorker() {
|
||||
const hasToReactive = tableRef.value.CrudModelRef.formData.find(
|
||||
(data) => !data.ended
|
||||
);
|
||||
if (hasToReactive) {
|
||||
quasar
|
||||
.dialog({
|
||||
message: t('Do you want to reactivate the user?'),
|
||||
ok: {
|
||||
push: true,
|
||||
color: 'primary',
|
||||
},
|
||||
cancel: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
await axios.patch(`Workers/${entityId.value}`, {
|
||||
isDisable: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'started',
|
||||
label: t('worker.business.tableVisibleColumns.started'),
|
||||
align: 'left',
|
||||
format: ({ started }) => toDate(started),
|
||||
component: 'date',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'ended',
|
||||
label: t('worker.business.tableVisibleColumns.ended'),
|
||||
align: 'left',
|
||||
format: ({ ended }) => toDate(ended),
|
||||
component: 'date',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
label: t('worker.business.tableVisibleColumns.company'),
|
||||
align: 'left',
|
||||
name: 'companyCodeFk',
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'Companies',
|
||||
fields: ['code'],
|
||||
optionLabel: 'code',
|
||||
optionValue: 'code',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'reasonEndFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.reasonEnd'),
|
||||
attrs: {
|
||||
url: 'BusinessReasonEnds',
|
||||
fields: ['id', 'reason'],
|
||||
optionLabel: 'reason',
|
||||
},
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'departmentFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.department'),
|
||||
attrs: {
|
||||
url: 'Departments',
|
||||
fields: ['id', 'name'],
|
||||
optionLabel: 'name',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessProfessionalCategoryFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.professionalCategory'),
|
||||
attrs: {
|
||||
url: 'WorkerBusinessProfessionalCategories',
|
||||
fields: ['id', 'description', 'code'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'calendarTypeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.calendarType'),
|
||||
attrs: {
|
||||
url: 'CalendarTypes',
|
||||
fields: ['id', 'description'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workcenterFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.workCenter'),
|
||||
attrs: {
|
||||
url: 'WorkCenters',
|
||||
fields: ['id', 'name'],
|
||||
optionLabel: 'name',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessCategoryFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.payrollCategories'),
|
||||
attrs: {
|
||||
url: 'payrollCategories',
|
||||
fields: ['id', 'description'],
|
||||
optionLabel: 'description',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'occupationCodeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.occupationCode'),
|
||||
attrs: {
|
||||
url: 'OccupationCodes',
|
||||
fields: ['code', 'name'],
|
||||
optionValue: 'code',
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'rate',
|
||||
label: t('worker.business.tableVisibleColumns.rate'),
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
name: 'workerBusinessTypeFk',
|
||||
component: 'select',
|
||||
label: t('worker.business.tableVisibleColumns.businessType'),
|
||||
attrs: {
|
||||
url: 'WorkerBusinessTypes',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker.business.tableVisibleColumns.amount'),
|
||||
name: 'amount',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('worker.business.tableVisibleColumns.basicSalary'),
|
||||
name: 'basicSalary',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
label: t('worker.business.tableVisibleColumns.notes'),
|
||||
align: 'left',
|
||||
component: 'input',
|
||||
cardVisible: true,
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="WorkerBusiness"
|
||||
:url="`Workers/${entityId}/Business`"
|
||||
save-url="/Businesses/crud"
|
||||
:create="{
|
||||
urlCreate: `Workers/${entityId}/Business`,
|
||||
title: 'Create business',
|
||||
onDataSaved: () => tableRef.reload(),
|
||||
formInitialData: {},
|
||||
}"
|
||||
order="id DESC"
|
||||
:columns="columns"
|
||||
default-mode="card"
|
||||
auto-load
|
||||
:disable-option="{ table: true }"
|
||||
:right-search="false"
|
||||
card-class="grid-two q-gutter-x-xl q-gutter-y-md q-pr-lg q-py-lg"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
@save-changes="(data) => reactivateWorker(data)"
|
||||
/>
|
||||
</template>
|
||||
<i18n>
|
||||
es:
|
||||
Do you want to reactivate the user?: desea reactivar el usuario?
|
||||
</i18n>
|
|
@ -12,6 +12,7 @@ import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy
|
|||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
||||
import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
|
||||
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
|
||||
import axios from 'axios';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -27,6 +28,76 @@ const entityId = computed(() => $props.id || route.params.id);
|
|||
const basicDataUrl = ref(null);
|
||||
const advancedSummary = ref();
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name', 'nickname', 'roleFk'],
|
||||
|
||||
include: [
|
||||
{
|
||||
relation: 'role',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'department',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'department',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'boss',
|
||||
},
|
||||
{
|
||||
relation: 'client',
|
||||
},
|
||||
{
|
||||
relation: 'sip',
|
||||
},
|
||||
{
|
||||
relation: 'business',
|
||||
scope: {
|
||||
include: [
|
||||
{
|
||||
relation: 'department',
|
||||
scope: {
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'reasonEnd',
|
||||
scope: {
|
||||
fields: ['id', 'reason'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'workerBusinessProfessionalCategory',
|
||||
scope: {
|
||||
fields: ['id', 'description'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
onBeforeMount(async () => {
|
||||
advancedSummary.value = await useAdvancedSummary('Workers', entityId.value);
|
||||
basicDataUrl.value = `#/worker/${entityId.value}/basic-data`;
|
||||
|
@ -37,7 +108,7 @@ onBeforeMount(async () => {
|
|||
<CardSummary
|
||||
ref="summary"
|
||||
:url="`Workers/summary`"
|
||||
:filter="{ where: { id: entityId } }"
|
||||
:user-filter="{ where: { id: entityId }, filter }"
|
||||
data-key="Worker"
|
||||
>
|
||||
<template #header="{ entity }">
|
||||
|
@ -143,6 +214,29 @@ onBeforeMount(async () => {
|
|||
</VnLv>
|
||||
<VnLv :label="t('queue')" :value="worker.sip?.queueMember?.queue" />
|
||||
</QCard>
|
||||
<QCard class="vn-one" v-if="advancedSummary">
|
||||
<VnTitle
|
||||
:url="`#/worker/${entityId}/business`"
|
||||
:text="t('worker.summary.business')"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.started')"
|
||||
:value="toDate(advancedSummary.currentBusiness?.started)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.ended')"
|
||||
:value="toDate(advancedSummary.currentBusiness?.ended)"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('worker.summary.reasonEnd')"
|
||||
:value="advancedSummary.currentBusiness?.reasonEnd?.reason"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('worker.summary.notes')"
|
||||
:value="advancedSummary.currentBusiness?.notes"
|
||||
/>
|
||||
</QCard>
|
||||
</template>
|
||||
</CardSummary>
|
||||
</template>
|
||||
|
|
|
@ -8,6 +8,7 @@ const workerCard = {
|
|||
meta: {
|
||||
menu: [
|
||||
'WorkerBasicData',
|
||||
'WorkerBusiness',
|
||||
'WorkerNotes',
|
||||
'WorkerPda',
|
||||
'WorkerNotificationsManager',
|
||||
|
@ -50,6 +51,15 @@ const workerCard = {
|
|||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerBasicData.vue'),
|
||||
},
|
||||
{
|
||||
path: 'business',
|
||||
name: 'WorkerBusiness',
|
||||
meta: {
|
||||
title: 'business',
|
||||
icon: 'handshake',
|
||||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerBusiness.vue'),
|
||||
},
|
||||
{
|
||||
path: 'notes',
|
||||
name: 'NotesCard',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
describe('InvoiceInDescriptor', () => {
|
||||
const dialogBtns = '.q-card__actions button';
|
||||
const firstDescritorOpt = '.q-menu > .q-list > :nth-child(1) > .q-item__section';
|
||||
const isBookedField = '.q-card:nth-child(3) .vn-label-value:nth-child(5) .q-checkbox';
|
||||
const book = '.summaryHeader > .no-wrap > .q-btn';
|
||||
const firstDescritorOpt = '.q-menu > .q-list > :nth-child(5) > .q-item__section';
|
||||
const checkbox = ':nth-child(5) > .q-checkbox';
|
||||
|
||||
it('should booking and unbooking the invoice properly', () => {
|
||||
cy.viewport(1280, 720);
|
||||
|
@ -9,13 +9,13 @@ describe('InvoiceInDescriptor', () => {
|
|||
cy.visit('/#/invoice-in/1/summary');
|
||||
cy.waitForElement('.q-page');
|
||||
|
||||
cy.openActionsDescriptor();
|
||||
cy.get(firstDescritorOpt).click();
|
||||
cy.get(dialogBtns).eq(1).click();
|
||||
cy.get(isBookedField).should('have.attr', 'aria-checked', 'true');
|
||||
cy.get(book).click();
|
||||
cy.dataCy('VnConfirm_confirm').click();
|
||||
cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'true');
|
||||
|
||||
cy.dataCy('descriptor-more-opts').first().click();
|
||||
cy.get(firstDescritorOpt).click();
|
||||
cy.get(dialogBtns).eq(1).click();
|
||||
cy.get(isBookedField).should('have.attr', 'aria-checked', 'false');
|
||||
cy.dataCy('VnConfirm_confirm').click();
|
||||
cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'false');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('Item shelving', () => {
|
||||
describe('ItemBarcodes', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('Item type', () => {
|
||||
const workerError = 'employeeNick';
|
||||
const worker = 'buyerNick';
|
||||
const category = 'Artificial';
|
||||
const type = 'Flower';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
|
@ -8,32 +13,24 @@ describe('Item type', () => {
|
|||
|
||||
it('should throw an error if the code already exists', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Code_input"]'
|
||||
).type('ALS');
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Name_input"]'
|
||||
).type('Alstroemeria');
|
||||
cy.dataCy('Worker_select').type('employeeNick');
|
||||
cy.get('.q-menu .q-item').contains('employeeNick').click();
|
||||
cy.dataCy('ItemCategory_select').type('Artificial');
|
||||
cy.get('.q-menu .q-item').contains('Artificial').click();
|
||||
cy.dataCy('codeInput').type('ALS');
|
||||
cy.dataCy('nameInput').type('Alstroemeria');
|
||||
cy.dataCy('vnWorkerSelect').type(workerError);
|
||||
cy.get('.q-menu .q-item').contains(workerError).click();
|
||||
cy.dataCy('itemCategorySelect').type(category);
|
||||
cy.get('.q-menu .q-item').contains(category).click();
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('An item type with the same code already exists');
|
||||
});
|
||||
|
||||
it('should create a new type', () => {
|
||||
cy.dataCy('vnTableCreateBtn').click();
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Code_input"]'
|
||||
).type('LIL');
|
||||
cy.get(
|
||||
'div.fit > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Name_input"]'
|
||||
).type('Lilium');
|
||||
cy.dataCy('Worker_select').type('buyerNick');
|
||||
cy.get('.q-menu .q-item').contains('buyerNick').click();
|
||||
cy.dataCy('ItemCategory_select').type('Flower');
|
||||
cy.get('.q-menu .q-item').contains('Flower').click();
|
||||
cy.dataCy('codeInput').type('LIL');
|
||||
cy.dataCy('nameInput').type('Lilium');
|
||||
cy.dataCy('vnWorkerSelect').type(worker);
|
||||
cy.get('.q-menu .q-item').contains(worker).click();
|
||||
cy.dataCy('itemCategorySelect').type(type);
|
||||
cy.get('.q-menu .q-item').contains(type).click();
|
||||
cy.dataCy('FormModelPopup_save').click();
|
||||
cy.checkNotification('Data created');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue