diff --git a/cypress.config.js b/cypress.config.js
index f8e771093..e9aeb547a 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -1,4 +1,7 @@
 const { defineConfig } = require('cypress');
+// https://docs.cypress.io/app/tooling/reporters
+// https://docs.cypress.io/app/references/configuration
+// https://www.npmjs.com/package/cypress-mochawesome-reporter
 
 module.exports = defineConfig({
     e2e: {
@@ -16,6 +19,7 @@ module.exports = defineConfig({
         reporterOptions: {
             charts: true,
             reportPageTitle: 'Cypress Inline Reporter',
+            reportFilename: '[status]_[datetime]-report',
             embeddedScreenshots: true,
             reportDir: 'test/cypress/reports',
             inlineAssets: true,
diff --git a/package.json b/package.json
index 0ee43ce12..04b75a0b0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "24.48.0",
+    "version": "24.50.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
diff --git a/src/components/CreateManualInvoiceForm.vue b/src/components/CreateManualInvoiceForm.vue
deleted file mode 100644
index da006e024..000000000
--- a/src/components/CreateManualInvoiceForm.vue
+++ /dev/null
@@ -1,155 +0,0 @@
-<script setup>
-import { reactive, ref, computed } from 'vue';
-import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
-
-import FetchData from 'components/FetchData.vue';
-import VnRow from 'components/ui/VnRow.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import FormModelPopup from './FormModelPopup.vue';
-import VnInputDate from './common/VnInputDate.vue';
-
-const emit = defineEmits(['onDataSaved']);
-
-const { t } = useI18n();
-const router = useRouter();
-
-const manualInvoiceFormData = reactive({
-    maxShipped: Date.vnNew(),
-});
-
-const formModelPopupRef = ref();
-const invoiceOutSerialsOptions = ref([]);
-const taxAreasOptions = ref([]);
-const ticketsOptions = ref([]);
-const clientsOptions = ref([]);
-const isLoading = computed(() => formModelPopupRef.value?.isLoading);
-
-const onDataSaved = async (formData, requestResponse) => {
-    emit('onDataSaved', formData, requestResponse);
-    if (requestResponse && requestResponse.id)
-        router.push({ name: 'InvoiceOutSummary', params: { id: requestResponse.id } });
-};
-</script>
-
-<template>
-    <FetchData
-        url="InvoiceOutSerials"
-        :filter="{ where: { code: { neq: 'R' } }, order: ['code'] }"
-        @on-fetch="(data) => (invoiceOutSerialsOptions = data)"
-        auto-load
-    />
-    <FetchData
-        url="TaxAreas"
-        :filter="{ order: ['code'] }"
-        @on-fetch="(data) => (taxAreasOptions = data)"
-        auto-load
-    />
-    <FormModelPopup
-        ref="formModelPopupRef"
-        :title="t('Create manual invoice')"
-        url-create="InvoiceOuts/createManualInvoice"
-        model="invoiceOut"
-        :form-initial-data="manualInvoiceFormData"
-        @on-data-saved="onDataSaved"
-    >
-        <template #form-inputs="{ data }">
-            <span v-if="isLoading" class="text-primary invoicing-text">
-                <QIcon name="warning" class="fill-icon q-mr-sm" size="md" />
-                {{ t('Invoicing in progress...') }}
-            </span>
-            <VnRow>
-                <VnSelect
-                    :label="t('Ticket')"
-                    :options="ticketsOptions"
-                    hide-selected
-                    option-label="id"
-                    option-value="id"
-                    v-model="data.ticketFk"
-                    @update:model-value="data.clientFk = null"
-                    url="Tickets"
-                    :where="{ refFk: null }"
-                    :fields="['id', 'nickname']"
-                    :filter-options="{ order: 'shipped DESC' }"
-                >
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
-                                <QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
-                <span class="row items-center" style="max-width: max-content">{{
-                    t('Or')
-                }}</span>
-                <VnSelect
-                    :label="t('Client')"
-                    :options="clientsOptions"
-                    hide-selected
-                    option-label="name"
-                    option-value="id"
-                    v-model="data.clientFk"
-                    @update:model-value="data.ticketFk = null"
-                    url="Clients"
-                    :fields="['id', 'name']"
-                    :filter-options="{ order: 'name ASC' }"
-                />
-                <VnInputDate :label="t('Max date')" v-model="data.maxShipped" />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    :label="t('Serial')"
-                    :options="invoiceOutSerialsOptions"
-                    hide-selected
-                    option-label="description"
-                    option-value="code"
-                    v-model="data.serial"
-                />
-                <VnSelect
-                    :label="t('Area')"
-                    :options="taxAreasOptions"
-                    hide-selected
-                    option-label="code"
-                    option-value="code"
-                    v-model="data.taxArea"
-                />
-            </VnRow>
-            <VnRow>
-                <VnInput
-                    :label="t('Reference')"
-                    type="textarea"
-                    v-model="data.reference"
-                    fill-input
-                    autogrow
-                />
-            </VnRow>
-        </template>
-    </FormModelPopup>
-</template>
-
-<style lang="scss" scoped>
-.invoicing-text {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    color: $primary;
-    font-size: 24px;
-    margin-bottom: 8px;
-}
-</style>
-
-<i18n>
-es:
-    Create manual invoice: Crear factura manual
-    Ticket: Ticket
-    Client: Cliente
-    Max date: Fecha límite
-    Serial: Serie
-    Area: Area
-    Reference: Referencia
-    Or: O
-    Invoicing in progress...: Facturación en progreso...
-</i18n>
diff --git a/src/components/CreateNewCityForm.vue b/src/components/CreateNewCityForm.vue
index 85d13beb1..1cbba42fc 100644
--- a/src/components/CreateNewCityForm.vue
+++ b/src/components/CreateNewCityForm.vue
@@ -17,10 +17,6 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
-    provinces: {
-        type: Array,
-        default: () => [],
-    },
 });
 const { t } = useI18n();
 
@@ -48,15 +44,16 @@ const onDataSaved = (...args) => {
         <template #form-inputs="{ data, validate }">
             <VnRow>
                 <VnInput
-                    :label="t('Names')"
+                    :label="t('Name')"
                     v-model="data.name"
                     :rules="validate('city.name')"
+                    required
                 />
                 <VnSelectProvince
                     :province-selected="$props.provinceSelected"
                     :country-fk="$props.countryFk"
                     v-model="data.provinceFk"
-                    :provinces="$props.provinces"
+                    required
                 />
             </VnRow>
         </template>
diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue
index 03cba8ac7..232f86a49 100644
--- a/src/components/CreateNewPostcodeForm.vue
+++ b/src/components/CreateNewPostcodeForm.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { reactive, ref, watch } from 'vue';
+import { computed, reactive, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 
 import FetchData from 'components/FetchData.vue';
@@ -22,12 +22,14 @@ const postcodeFormData = reactive({
     townFk: null,
 });
 
-const townsFetchDataRef = ref(null);
-const provincesFetchDataRef = ref(null);
-const countriesOptions = ref([]);
+const townsFetchDataRef = ref(false);
+const countriesRef = ref(false);
+const townsRef = ref(false);
+const provincesFetchDataRef = ref(false);
 const provincesOptions = ref([]);
-const townsOptions = ref([]);
 const town = ref({});
+const townFilter = ref({});
+const countryFilter = ref({});
 
 function onDataSaved(formData) {
     const newPostcode = {
@@ -39,7 +41,7 @@ function onDataSaved(formData) {
         ({ id }) => id === formData.provinceFk
     );
     newPostcode.province = provinceObject?.name;
-    const countryObject = countriesOptions.value.find(
+    const countryObject = countriesRef.value.opts.find(
         ({ id }) => id === formData.countryFk
     );
     newPostcode.country = countryObject?.name;
@@ -56,10 +58,19 @@ async function onCityCreated(newTown, formData) {
 }
 
 function setTown(newTown, data) {
-    if (!newTown) return;
     town.value = newTown;
-    data.provinceFk = newTown.provinceFk;
-    data.countryFk = newTown.province.countryFk;
+    data.provinceFk = newTown?.provinceFk ?? newTown;
+    data.countryFk = newTown?.province?.countryFk ?? newTown;
+}
+
+async function setCountry(countryFk, data) {
+    data.townFk = null;
+    data.provinceFk = null;
+    data.countryFk = countryFk;
+}
+
+async function handleProvinces(data) {
+    provincesOptions.value = data;
 }
 
 async function setProvince(id, data) {
@@ -73,61 +84,16 @@ async function onProvinceCreated(data) {
     await provincesFetchDataRef.value.fetch({
         where: { countryFk: postcodeFormData.countryFk },
     });
-    postcodeFormData.provinceFk.value = data.id;
+    postcodeFormData.provinceFk = data.id;
 }
 
-watch(
-    () => [postcodeFormData.countryFk],
-    async (newCountryFk, oldValueFk) => {
-        if (Array.isArray(newCountryFk)) {
-            newCountryFk = newCountryFk[0];
-        }
-        if (Array.isArray(oldValueFk)) {
-            oldValueFk = oldValueFk[0];
-        }
-        if (!!oldValueFk && newCountryFk !== oldValueFk) {
-            postcodeFormData.provinceFk = null;
-            postcodeFormData.townFk = null;
-        }
-        if (oldValueFk !== newCountryFk) {
-            await provincesFetchDataRef.value.fetch({
-                where: {
-                    countryFk: newCountryFk,
-                },
-            });
-            await townsFetchDataRef.value.fetch({
-                where: {
-                    provinceFk: {
-                        inq: provincesOptions.value.map(({ id }) => id),
-                    },
-                },
-            });
-        }
-    }
-);
-
-watch(
-    () => postcodeFormData.provinceFk,
-    async (newProvinceFk, oldValueFk) => {
-        if (Array.isArray(newProvinceFk)) {
-            newProvinceFk = newProvinceFk[0];
-        }
-        if (newProvinceFk !== oldValueFk) {
-            await townsFetchDataRef.value.fetch({
-                where: { provinceFk: newProvinceFk },
-            });
-        }
-    }
-);
-async function handleProvinces(data) {
-    provincesOptions.value = data;
-}
-async function handleTowns(data) {
-    townsOptions.value = data;
-}
-async function handleCountries(data) {
-    countriesOptions.value = data;
-}
+const whereTowns = computed(() => {
+    return {
+        provinceFk: {
+            inq: provincesOptions.value.map(({ id }) => id),
+        },
+    };
+});
 </script>
 
 <template>
@@ -139,14 +105,6 @@ async function handleCountries(data) {
         auto-load
         url="Provinces/location"
     />
-    <FetchData
-        ref="townsFetchDataRef"
-        :sort-by="['name ASC']"
-        :limit="30"
-        @on-fetch="handleTowns"
-        auto-load
-        url="Towns/location"
-    />
 
     <FormModelPopup
         url-create="postcodes"
@@ -164,19 +122,26 @@ async function handleCountries(data) {
                     v-model="data.code"
                     :rules="validate('postcode.code')"
                     clearable
+                    required
                 />
                 <VnSelectDialog
+                    ref="townsRef"
+                    :sort-by="['name ASC']"
+                    :limit="30"
+                    auto-load
+                    url="Towns/location"
+                    :where="whereTowns"
                     :label="t('City')"
                     @update:model-value="(value) => setTown(value, data)"
                     :tooltip="t('Create city')"
                     v-model="data.townFk"
-                    :options="townsOptions"
                     option-label="name"
                     option-value="id"
                     :rules="validate('postcode.city')"
                     :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                     :emit-value="false"
                     :clearable="true"
+                    required
                 >
                     <template #option="{ itemProps, opt }">
                         <QItem v-bind="itemProps">
@@ -193,7 +158,6 @@ async function handleCountries(data) {
                         <CreateNewCityForm
                             :country-fk="data.countryFk"
                             :province-selected="data.provinceFk"
-                            :provinces="provincesOptions"
                             @on-data-saved="
                                 (_, requestResponse) =>
                                     onCityCreated(requestResponse, data)
@@ -208,20 +172,25 @@ async function handleCountries(data) {
                     :province-selected="data.provinceFk"
                     @update:model-value="(value) => setProvince(value, data)"
                     v-model="data.provinceFk"
-                    :clearable="true"
-                    :provinces="provincesOptions"
+                    @on-province-fetched="handleProvinces"
                     @on-province-created="onProvinceCreated"
+                    required
                 />
                 <VnSelect
-                    url="Countries"
+                    ref="countriesRef"
+                    :limit="30"
+                    :filter="countryFilter"
                     :sort-by="['name ASC']"
+                    auto-load
+                    url="Countries"
+                    required
                     :label="t('Country')"
-                    @update:options="handleCountries"
                     hide-selected
                     option-label="name"
                     option-value="id"
                     v-model="data.countryFk"
                     :rules="validate('postcode.countryFk')"
+                    @update:model-value="(value) => setCountry(value, data)"
                 />
             </VnRow>
         </template>
diff --git a/src/components/CreateNewProvinceForm.vue b/src/components/CreateNewProvinceForm.vue
index d7df38f9f..887ca957c 100644
--- a/src/components/CreateNewProvinceForm.vue
+++ b/src/components/CreateNewProvinceForm.vue
@@ -1,8 +1,7 @@
 <script setup>
-import { reactive, ref } from 'vue';
+import { computed, reactive, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 
-import FetchData from 'components/FetchData.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInput from 'src/components/common/VnInput.vue';
@@ -21,34 +20,24 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
-    provinces: {
-        type: Array,
-        default: () => [],
-    },
 });
-const autonomiesOptions = ref([]);
+const autonomiesRef = ref([]);
 
 const onDataSaved = (dataSaved, requestResponse) => {
-    requestResponse.autonomy = autonomiesOptions.value.find(
+    requestResponse.autonomy = autonomiesRef.value.opts.find(
         (autonomy) => autonomy.id == requestResponse.autonomyFk
     );
     emit('onDataSaved', dataSaved, requestResponse);
 };
+const where = computed(() => {
+    if (!$props.countryFk) {
+        return {};
+    }
+    return { countryFk: $props.countryFk };
+});
 </script>
 
 <template>
-    <FetchData
-        @on-fetch="(data) => (autonomiesOptions = data)"
-        auto-load
-        :filter="{
-            where: {
-                countryFk: $props.countryFk,
-            },
-        }"
-        url="Autonomies/location"
-        :sort-by="['name ASC']"
-        :limit="30"
-    />
     <FormModelPopup
         :title="t('New province')"
         :subtitle="t('Please, ensure you put the correct data!')"
@@ -63,10 +52,17 @@ const onDataSaved = (dataSaved, requestResponse) => {
                     :label="t('Name')"
                     v-model="data.name"
                     :rules="validate('province.name')"
+                    required
                 />
                 <VnSelect
+                    required
+                    ref="autonomiesRef"
+                    auto-load
+                    :where="where"
+                    url="Autonomies/location"
+                    :sort-by="['name ASC']"
+                    :limit="30"
                     :label="t('Autonomy')"
-                    :options="autonomiesOptions"
                     hide-selected
                     option-label="name"
                     option-value="id"
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index b1c7606e6..e992334b5 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -373,6 +373,7 @@ watch(formUrl, async () => {
                 @click="onSubmit"
                 :disable="!hasChanges"
                 :title="t('globals.save')"
+                data-cy="crudModelDefaultSaveBtn"
             />
             <slot name="moreAfterActions" />
         </QBtnGroup>
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index 4504ea6ad..2cb6ad8e6 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -91,6 +91,10 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
+    maxWidth: {
+        type: [String, Boolean],
+        default: '800px',
+    },
 });
 const emit = defineEmits(['onFetch', 'onDataSaved']);
 const modelValue = computed(
@@ -287,6 +291,7 @@ defineExpose({
             @submit="save"
             @reset="reset"
             class="q-pa-md"
+            :style="maxWidth ? 'max-width: ' + maxWidth : ''"
             id="formModel"
         >
             <QCard>
@@ -376,7 +381,6 @@ defineExpose({
     color: black;
 }
 #formModel {
-    max-width: 800px;
     width: 100%;
 }
 
diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue
new file mode 100644
index 000000000..2965396b1
--- /dev/null
+++ b/src/components/TicketProblems.vue
@@ -0,0 +1,40 @@
+<script setup>
+defineProps({ row: { type: Object, required: true } });
+</script>
+<template>
+    <span>
+        <QIcon
+            v-if="row.isTaxDataChecked === 0"
+            name="vn:no036"
+            color="primary"
+            size="xs"
+        >
+            <QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.hasTicketRequest" name="vn:buyrequest" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.itemShortage" name="vn:unavailable" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
+        </QIcon>
+        <QIcon
+            v-if="row.risk"
+            name="vn:risk"
+            :color="row.hasHighRisk ? 'negative' : 'primary'"
+            size="xs"
+        >
+            <QTooltip>
+                {{ $t('salesTicketsTable.risk') }}: {{ row.risk - row.credit }}
+            </QTooltip>
+        </QIcon>
+        <QIcon v-if="row.hasComponentLack" name="vn:components" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.isTooLittle" name="vn:isTooLittle" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
+        </QIcon>
+    </span>
+</template>
diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue
index 9fcbef11e..bfc4ab7b7 100644
--- a/src/components/VnSelectProvince.vue
+++ b/src/components/VnSelectProvince.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
 import { useValidator } from 'src/composables/useValidator';
 import { useI18n } from 'vue-i18n';
 
@@ -7,7 +7,7 @@ import VnSelectDialog from 'components/common/VnSelectDialog.vue';
 import FetchData from 'components/FetchData.vue';
 import CreateNewProvinceForm from './CreateNewProvinceForm.vue';
 
-const emit = defineEmits(['onProvinceCreated']);
+const emit = defineEmits(['onProvinceCreated', 'onProvinceFetched']);
 const $props = defineProps({
     countryFk: {
         type: Number,
@@ -17,20 +17,23 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
-    provinces: {
-        type: Array,
-        default: () => [],
-    },
 });
 const provinceFk = defineModel({ type: Number, default: null });
 
 const { validate } = useValidator();
 const { t } = useI18n();
-
+const filter = ref({
+    include: { relation: 'country' },
+    where: {
+        countryFk: $props.countryFk,
+    },
+});
 const provincesOptions = ref($props.provinces);
-provinceFk.value = $props.provinceSelected;
 const provincesFetchDataRef = ref();
-
+provinceFk.value = $props.provinceSelected;
+if (!$props.countryFk) {
+    filter.value.where = {};
+}
 async function onProvinceCreated(_, data) {
     await provincesFetchDataRef.value.fetch({ where: { countryFk: $props.countryFk } });
     provinceFk.value = data.id;
@@ -39,25 +42,33 @@ async function onProvinceCreated(_, data) {
 async function handleProvinces(data) {
     provincesOptions.value = data;
 }
+
+watch(
+    () => $props.countryFk,
+    async () => {
+        if ($props.countryFk) {
+            filter.value.where.countryFk = $props.countryFk;
+        } else filter.value.where = {};
+        await provincesFetchDataRef.value.fetch({});
+        emit('onProvinceFetched', provincesOptions.value);
+    }
+);
 </script>
 
 <template>
     <FetchData
         ref="provincesFetchDataRef"
-        :filter="{
-            include: { relation: 'country' },
-            where: {
-                countryFk: $props.countryFk,
-            },
-        }"
+        :filter="filter"
         @on-fetch="handleProvinces"
         url="Provinces"
+        auto-load
     />
     <VnSelectDialog
         :label="t('Province')"
-        :options="$props.provinces"
+        :options="provincesOptions"
         :tooltip="t('Create province')"
         hide-selected
+        :clearable="true"
         v-model="provinceFk"
         :rules="validate && validate('postcode.provinceFk')"
         :acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index 86802ee92..999133130 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -143,6 +143,10 @@ function alignRow() {
 const showFilter = computed(
     () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
 );
+
+const onTabPressed = async () => {
+    if (model.value) enterEvent['keyup.enter']();
+};
 </script>
 <template>
     <div
@@ -157,6 +161,7 @@ const showFilter = computed(
             v-model="model"
             :components="components"
             component-prop="columnFilter"
+            @keydown.tab="onTabPressed"
         />
     </div>
 </template>
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 941477084..ea7cf1dda 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -162,9 +162,7 @@ onMounted(() => {
             : $props.defaultMode;
     stateStore.rightDrawer = quasar.screen.gt.xs;
     columnsVisibilitySkipped.value = [
-        ...splittedColumns.value.columns
-            .filter((c) => c.visible == false)
-            .map((c) => c.name),
+        ...splittedColumns.value.columns.filter((c) => !c.visible).map((c) => c.name),
         ...['tableActions'],
     ];
     createForm.value = $props.create;
@@ -237,7 +235,7 @@ function splitColumns(columns) {
         if (col.create) splittedColumns.value.create.push(col);
         if (col.cardVisible) splittedColumns.value.cardVisible.push(col);
         if ($props.isEditable && col.disable == null) col.disable = false;
-        if ($props.useModel && col.columnFilter != false)
+        if ($props.useModel && col.columnFilter !== false)
             col.columnFilter = { inWhere: true, ...col.columnFilter };
         splittedColumns.value.columns.push(col);
     }
@@ -396,7 +394,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                             :name="col.orderBy ?? col.name"
                             :data-key="$attrs['data-key']"
                             :search-url="searchUrl"
-                            :vertical="true"
+                            :vertical="false"
                         />
                     </div>
                     <slot
@@ -739,6 +737,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
             fab
             icon="add"
             shortcut="+"
+            data-cy="vnTableCreateBtn"
         />
         <QTooltip self="top right">
             {{ createForm?.title }}
diff --git a/src/components/common/VnAccountNumber.vue b/src/components/common/VnAccountNumber.vue
index f7273a72d..c4fa78674 100644
--- a/src/components/common/VnAccountNumber.vue
+++ b/src/components/common/VnAccountNumber.vue
@@ -1,20 +1,24 @@
 <script setup>
-import { ref, watch } from 'vue';
+import { nextTick, ref, watch } from 'vue';
 import { QInput } from 'quasar';
 
-const props = defineProps({
+const $props = defineProps({
     modelValue: {
         type: String,
         default: '',
     },
+    insertable: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const emit = defineEmits(['update:modelValue', 'accountShortToStandard']);
 
-let internalValue = ref(props.modelValue);
+let internalValue = ref($props.modelValue);
 
 watch(
-    () => props.modelValue,
+    () => $props.modelValue,
     (newVal) => {
         internalValue.value = newVal;
     }
@@ -28,8 +32,46 @@ watch(
     }
 );
 
+const handleKeydown = (e) => {
+    if (e.key === 'Backspace') return;
+    if (e.key === '.') {
+        accountShortToStandard();
+        // TODO: Fix this setTimeout, with nextTick doesn't work
+        setTimeout(() => {
+            setCursorPosition(0, e.target);
+        }, 1);
+        return;
+    }
+
+    if ($props.insertable && e.key.match(/[0-9]/)) {
+        handleInsertMode(e);
+    }
+};
+function setCursorPosition(pos, el = vnInputRef.value) {
+    el.focus();
+    el.setSelectionRange(pos, pos);
+}
+const vnInputRef = ref(false);
+const handleInsertMode = (e) => {
+    e.preventDefault();
+    const input = e.target;
+    const cursorPos = input.selectionStart;
+    const { maxlength } = vnInputRef.value;
+    let currentValue = internalValue.value;
+    if (!currentValue) currentValue = e.key;
+    const newValue = e.key;
+    if (newValue && !isNaN(newValue) && cursorPos < maxlength) {
+        internalValue.value =
+            currentValue.substring(0, cursorPos) +
+            newValue +
+            currentValue.substring(cursorPos + 1);
+    }
+    nextTick(() => {
+        input.setSelectionRange(cursorPos + 1, cursorPos + 1);
+    });
+};
 function accountShortToStandard() {
-    internalValue.value = internalValue.value.replace(
+    internalValue.value = internalValue.value?.replace(
         '.',
         '0'.repeat(11 - internalValue.value.length)
     );
@@ -37,5 +79,5 @@ function accountShortToStandard() {
 </script>
 
 <template>
-    <q-input v-model="internalValue" />
+    <QInput @keydown="handleKeydown" ref="vnInputRef" v-model="internalValue" />
 </template>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 4672529c6..57a495ac3 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { computed, ref, useAttrs } from 'vue';
+import { computed, ref, useAttrs, nextTick } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRequired } from 'src/composables/useRequired';
 
@@ -34,6 +34,14 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
+    insertable: {
+        type: Boolean,
+        default: false,
+    },
+    maxlength: {
+        type: Number,
+        default: null,
+    },
 });
 
 const vnInputRef = ref(null);
@@ -69,6 +77,9 @@ const mixinRules = [
     requiredFieldRule,
     ...($attrs.rules ?? []),
     (val) => {
+        const { maxlength } = vnInputRef.value;
+        if (maxlength && +val.length > maxlength)
+            return t(`maxLength`, { value: maxlength });
         const { min, max } = vnInputRef.value.$attrs;
         if (!min) return null;
         if (min >= 0) if (Math.floor(val) < min) return t('inputMin', { value: min });
@@ -78,6 +89,33 @@ const mixinRules = [
         }
     },
 ];
+
+const handleKeydown = (e) => {
+    if (e.key === 'Backspace') return;
+
+    if ($props.insertable && e.key.match(/[0-9]/)) {
+        handleInsertMode(e);
+    }
+};
+
+const handleInsertMode = (e) => {
+    e.preventDefault();
+    const input = e.target;
+    const cursorPos = input.selectionStart;
+    const { maxlength } = vnInputRef.value;
+    let currentValue = value.value;
+    if (!currentValue) currentValue = e.key;
+    const newValue = e.key;
+    if (newValue && !isNaN(newValue) && cursorPos < maxlength) {
+        value.value =
+            currentValue.substring(0, cursorPos) +
+            newValue +
+            currentValue.substring(cursorPos + 1);
+    }
+    nextTick(() => {
+        input.setSelectionRange(cursorPos + 1, cursorPos + 1);
+    });
+};
 </script>
 
 <template>
@@ -89,10 +127,12 @@ const mixinRules = [
             :type="$attrs.type"
             :class="{ required: isRequired }"
             @keyup.enter="emit('keyup.enter')"
+            @keydown="handleKeydown"
             :clearable="false"
             :rules="mixinRules"
             :lazy-rules="true"
             hide-bottom-space
+            :data-cy="$attrs.dataCy ?? $attrs.label + '_input'"
         >
             <template v-if="$slots.prepend" #prepend>
                 <slot name="prepend" />
@@ -129,9 +169,11 @@ const mixinRules = [
 <i18n>
     en:
         inputMin: Must be more than {value}
+        maxLength: The value exceeds {value} characters
         inputMax: Must be less than {value}
     es:
         inputMin: Debe ser mayor a {value}
+        maxLength: El valor excede los {value} carácteres
         inputMax: Debe ser menor a {value}
 </i18n>
 <style lang="scss">
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index fcc04ddf7..eb9dc0f38 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -1,8 +1,7 @@
 <script setup>
-import { onMounted, watch, computed, ref } from 'vue';
+import { onMounted, watch, computed, ref, useAttrs } from 'vue';
 import { date } from 'quasar';
 import { useI18n } from 'vue-i18n';
-import { useAttrs } from 'vue';
 import VnDate from './VnDate.vue';
 import { useRequired } from 'src/composables/useRequired';
 
diff --git a/src/components/common/VnRadio.vue b/src/components/common/VnRadio.vue
index 4eeb9dbe9..69b1501a2 100644
--- a/src/components/common/VnRadio.vue
+++ b/src/components/common/VnRadio.vue
@@ -2,5 +2,12 @@
 const model = defineModel({ type: Boolean, required: true });
 </script>
 <template>
-    <QRadio v-model="model" v-bind="$attrs" dense :dark="true" class="q-mr-sm" />
+    <QRadio
+        v-model="model"
+        v-bind="$attrs"
+        dense
+        :dark="true"
+        class="q-mr-sm"
+        size="xs"
+    />
 </template>
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 14005e1cc..cd8716194 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -138,8 +138,6 @@ onMounted(() => {
     if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
 });
 
-defineExpose({ opts: myOptions });
-
 const arrayDataKey =
     $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
 
@@ -259,6 +257,30 @@ async function onScroll({ to, direction, from, index }) {
         isLoading.value = false;
     }
 }
+
+defineExpose({ opts: myOptions });
+
+function handleKeyDown(event) {
+    if (event.key === 'Tab') {
+        event.preventDefault();
+
+        const inputValue = vnSelectRef.value?.inputValue;
+
+        if (inputValue) {
+            const matchingOption = myOptions.value.find(
+                (option) =>
+                    option[optionLabel.value].toLowerCase() === inputValue.toLowerCase()
+            );
+
+            if (matchingOption) {
+                emit('update:modelValue', matchingOption[optionValue.value]);
+            } else {
+                emit('update:modelValue', inputValue);
+            }
+            vnSelectRef.value?.hidePopup();
+        }
+    }
+}
 </script>
 
 <template>
@@ -269,6 +291,7 @@ async function onScroll({ to, direction, from, index }) {
         :option-value="optionValue"
         v-bind="$attrs"
         @filter="filterHandler"
+        @keydown="handleKeyDown"
         :emit-value="nullishToTrue($attrs['emit-value'])"
         :map-options="nullishToTrue($attrs['map-options'])"
         :use-input="nullishToTrue($attrs['use-input'])"
@@ -283,6 +306,7 @@ async function onScroll({ to, direction, from, index }) {
         :input-debounce="useURL ? '300' : '0'"
         :loading="isLoading"
         @virtual-scroll="onScroll"
+        :data-cy="$attrs.dataCy ?? $attrs.label + '_select'"
     >
         <template #append>
             <QIcon
diff --git a/src/components/common/VnSmsDialog.vue b/src/components/common/VnSmsDialog.vue
index 064394445..8851a33b2 100644
--- a/src/components/common/VnSmsDialog.vue
+++ b/src/components/common/VnSmsDialog.vue
@@ -86,7 +86,7 @@ async function send() {
 </script>
 
 <template>
-    <QDialog ref="dialogRef">
+    <QDialog ref="dialogRef" data-cy="vnSmsDialog">
         <QCard class="q-pa-sm">
             <QCardSection class="row items-center q-pb-none">
                 <span class="text-h6 text-grey">
@@ -161,6 +161,7 @@ async function send() {
                     :loading="isLoading"
                     color="primary"
                     unelevated
+                    data-cy="sendSmsBtn"
                 />
             </QCardActions>
         </QCard>
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index b188bde48..8c0dbda94 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -37,7 +37,7 @@ const $props = defineProps({
     },
     hiddenTags: {
         type: Array,
-        default: () => ['filter', 'search', 'or', 'and'],
+        default: () => ['filter', 'or', 'and'],
     },
     customTags: {
         type: Array,
@@ -61,7 +61,6 @@ const emit = defineEmits([
     'update:modelValue',
     'refresh',
     'clear',
-    'search',
     'init',
     'remove',
     'setUserParams',
@@ -274,6 +273,7 @@ function sanitizer(params) {
                         :key="chip.label"
                         :removable="!unremovableParams?.includes(chip.label)"
                         @remove="remove(chip.label)"
+                        data-cy="vnFilterPanelChip"
                     >
                         <slot name="tags" :tag="chip" :format-fn="formatValue">
                             <div class="q-gutter-x-xs">
diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue
index 4068498cd..027244609 100644
--- a/src/components/ui/VnLinkPhone.vue
+++ b/src/components/ui/VnLinkPhone.vue
@@ -2,6 +2,7 @@
 import { reactive, useAttrs, onBeforeMount, capitalize } from 'vue';
 import axios from 'axios';
 import { parsePhone } from 'src/filters';
+import useOpenURL from 'src/composables/useOpenURL';
 const props = defineProps({
     phoneNumber: { type: [String, Number], default: null },
     channel: { type: Number, default: null },
@@ -11,25 +12,31 @@ const config = reactive({
     sip: { icon: 'phone', href: `sip:${props.phoneNumber}` },
     'say-simple': {
         icon: 'vn:saysimple',
-        href: null,
         channel: props.channel,
+        url: null,
     },
 });
 const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip';
 
 onBeforeMount(async () => {
-    let { channel } = config[type];
+    let { channel, url } = config[type];
 
     if (type === 'say-simple') {
-        const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne'))
-            .data;
-        if (!channel) channel = defaultChannel;
-
-        config[type].href = `${url}?customerIdentity=%2B${parsePhone(
-            props.phoneNumber
-        )}&channelId=${channel}`;
+        const { url: defaultUrl, defaultChannel } = (
+            await axios.get('SaySimpleConfigs/findOne')
+        ).data;
+        if (!channel) config[type].channel = defaultChannel;
+        if (!url) config[type].url = defaultUrl;
     }
 });
+
+function openSaySimple() {
+    useOpenURL(
+        `${config[type].url}?customerIdentity=%2B${parsePhone(
+            props.phoneNumber
+        )}&channelId=${config[type].channel}`
+    );
+}
 </script>
 <template>
     <QBtn
@@ -40,8 +47,7 @@ onBeforeMount(async () => {
         size="sm"
         color="primary"
         padding="none"
-        :href="config[type].href"
-        @click.stop
+        @click.stop="openSaySimple"
     >
         <QTooltip>
             {{ capitalize(type).replace('-', '') }}
diff --git a/src/components/ui/VnRow.vue b/src/components/ui/VnRow.vue
index 40dabf610..b57489a98 100644
--- a/src/components/ui/VnRow.vue
+++ b/src/components/ui/VnRow.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="vn-row q-gutter-md q-mb-md">
+    <div class="vn-row q-gutter-md">
         <slot />
     </div>
 </template>
@@ -18,6 +18,9 @@
         &:not(.wrap) {
             flex-direction: column;
         }
+        &[fixed] {
+            flex-direction: row;
+        }
     }
 }
 </style>
diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue
index da2d370fe..ccf87c6d6 100644
--- a/src/components/ui/VnSearchbar.vue
+++ b/src/components/ui/VnSearchbar.vue
@@ -130,6 +130,7 @@ async function search() {
                 dense
                 standout
                 autofocus
+                data-cy="vnSearchBar"
             >
                 <template #prepend>
                     <QIcon
diff --git a/src/composables/downloadFile.js b/src/composables/downloadFile.js
index 12639dcd6..4588265a2 100644
--- a/src/composables/downloadFile.js
+++ b/src/composables/downloadFile.js
@@ -1,11 +1,24 @@
 import { useSession } from 'src/composables/useSession';
 import { getUrl } from './getUrl';
+import axios from 'axios';
+import { exportFile } from 'quasar';
 
 const { getTokenMultimedia } = useSession();
 const token = getTokenMultimedia();
 
 export async function downloadFile(id, model = 'dms', urlPath = '/downloadFile', url) {
-    let appUrl = await getUrl('', 'lilium');
-    appUrl = appUrl.replace('/#/', '');
-    window.open(url ?? `${appUrl}/api/${model}/${id}${urlPath}?access_token=${token}`);
+    const appUrl = (await getUrl('', 'lilium')).replace('/#/', '');
+    const response = await axios.get(
+        url ?? `${appUrl}/api/${model}/${id}${urlPath}?access_token=${token}`,
+        { responseType: 'blob' }
+    );
+
+    const contentDisposition = response.headers['content-disposition'];
+    const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition);
+    const filename =
+        matches != null && matches[1]
+            ? matches[1].replace(/['"]/g, '')
+            : 'downloaded-file';
+
+    exportFile(filename, response.data);
 }
diff --git a/src/css/app.scss b/src/css/app.scss
index d4c76ad6b..63a9f5c46 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -241,7 +241,7 @@ input::-webkit-inner-spin-button {
     th,
     td {
         padding: 1px 10px 1px 10px;
-        max-width: 100px;
+        max-width: 130px;
         div span {
             overflow: hidden;
             white-space: nowrap;
diff --git a/src/filters/parsePhone.js b/src/filters/parsePhone.js
index 696f55007..cded224b9 100644
--- a/src/filters/parsePhone.js
+++ b/src/filters/parsePhone.js
@@ -1,4 +1,7 @@
 export default function (phone, prefix = 34) {
+    if (!phone) {
+        return;
+    }
     if (phone.startsWith('+')) {
         return `${phone.slice(1)}`;
     }
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index 31a6931a4..ecfa2c8fe 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -298,6 +298,7 @@ globals:
         clientsActionsMonitor: Clients and actions
         serial: Serial
         medical: Mutual
+        pit: IRPF
         RouteExtendedList: Router
         wasteRecalc: Waste recaclulate
         operator: Operator
@@ -506,6 +507,7 @@ invoiceOut:
             invoiceWithFutureDate: Exists an invoice with a future date
             noTicketsToInvoice: There are not tickets to invoice
             criticalInvoiceError: 'Critical invoicing error, process stopped'
+            invalidSerialTypeForAll: The serial type must be global when invoicing all clients
         table:
             addressId: Address id
             streetAddress: Street
@@ -858,6 +860,7 @@ components:
         downloadFile: Download file
         openCard: View
         openSummary: Summary
+        viewSummary: Summary
     cardDescriptor:
         mainList: Main list
         summary: Summary
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index ccc21e225..def0b0696 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -303,6 +303,7 @@ globals:
         clientsActionsMonitor: Clientes y acciones
         serial: Facturas por serie
         medical: Mutua
+        pit: IRPF
         wasteRecalc: Recalcular mermas
         operator: Operario
         parking: Parking
@@ -509,6 +510,7 @@ invoiceOut:
             invoiceWithFutureDate: Existe una factura con una fecha futura
             noTicketsToInvoice: No existen tickets para facturar
             criticalInvoiceError: Error crítico en la facturación proceso detenido
+            invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
         table:
             addressId: Id dirección
             streetAddress: Dirección fiscal
diff --git a/src/pages/Claim/Card/ClaimDescriptorMenu.vue b/src/pages/Claim/Card/ClaimDescriptorMenu.vue
index d88c3d120..d87091887 100644
--- a/src/pages/Claim/Card/ClaimDescriptorMenu.vue
+++ b/src/pages/Claim/Card/ClaimDescriptorMenu.vue
@@ -100,7 +100,7 @@ async function remove() {
         </QMenu>
     </QItem>
     <QSeparator />
-    <QItem @click="confirmRemove()" v-ripple clickable>
+    <QItem @click="confirmRemove()" v-ripple clickable data-cy="deleteClaim">
         <QItemSection avatar>
             <QIcon name="delete" />
         </QItemSection>
diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue
index 9f15130c0..450efe624 100644
--- a/src/pages/Entry/EntryLatestBuys.vue
+++ b/src/pages/Entry/EntryLatestBuys.vue
@@ -12,6 +12,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
 
 const stateStore = useStateStore();
 const { t } = useI18n();
+const tableRef = ref();
 const columns = [
     {
         align: 'center',
@@ -234,7 +235,6 @@ const columns = [
         format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)),
     },
 ];
-const tableRef = ref();
 
 onMounted(async () => {
     stateStore.rightDrawer = true;
diff --git a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
index e85f1f44c..3fd3104bf 100644
--- a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
+++ b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
@@ -183,7 +183,7 @@ onMounted(async () => {
 <i18n>
 en:
     invoiceDate: Invoice date
-    maxShipped: Max date
+    maxShipped: Max date ticket
     allClients: All clients
     oneClient: One client
     company: Company
@@ -195,7 +195,7 @@ en:
 
 es:
     invoiceDate: Fecha de factura
-    maxShipped: Fecha límite
+    maxShipped: Fecha límite ticket
     allClients: Todos los clientes
     oneClient: Un solo cliente
     company: Empresa
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index f5a4f7d80..c8fffb0ef 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -6,15 +6,19 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import { usePrintService } from 'composables/usePrintService';
-import VnTable from 'components/VnTable/VnTable.vue';
+import { usePrintService } from 'src/composables/usePrintService';
+import VnTable from 'src/components/VnTable/VnTable.vue';
 import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
 import { toCurrency, toDate } from 'src/filters/index';
 import { useStateStore } from 'stores/useStateStore';
 import { QBtn } from 'quasar';
-import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
+import axios from 'axios';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import InvoiceOutFilter from './InvoiceOutFilter.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
+import VnRadio from 'src/components/common/VnRadio.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
 
 const { t } = useI18n();
 const stateStore = useStateStore();
@@ -26,19 +30,29 @@ const selectedRows = ref([]);
 const hasSelectedCards = computed(() => selectedRows.value.length > 0);
 const MODEL = 'InvoiceOuts';
 const { openReport } = usePrintService();
+const addressOptions = ref([]);
+const selectedOption = ref('ticket');
+async function fetchClientAddress(id) {
+    const { data } = await axios.get(
+        `Clients/${id}/addresses?filter[order]=isActive DESC`
+    );
+    addressOptions.value = data;
+}
+
+const exprBuilder = (_, value) => {
+    return {
+        or: [{ code: value }, { description: { like: `%${value}%` } }],
+    };
+};
 
 const columns = computed(() => [
     {
         align: 'center',
         name: 'id',
         label: t('invoiceOutList.tableVisibleColumns.id'),
-        chip: {
-            condition: () => true,
-        },
+        chip: { condition: () => true },
         isId: true,
-        columnFilter: {
-            name: 'search',
-        },
+        columnFilter: { name: 'search' },
     },
     {
         align: 'left',
@@ -58,68 +72,51 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'Issued',
-        label: t('invoiceOutList.tableVisibleColumns.issued'),
+        name: 'issued',
+        label: t('invoiceOut.summary.issued'),
         component: 'date',
         format: (row) => toDate(row.issued),
-        columnField: {
-            component: null,
-        },
+        columnField: { component: null },
     },
     {
         align: 'left',
         name: 'clientFk',
-        label: t('invoiceOutModule.customer'),
+        label: t('globals.client'),
         cardVisible: true,
         component: 'select',
-        attrs: {
-            url: 'Clients',
-            fields: ['id', 'name'],
-        },
-        columnField: {
-            component: null,
-        },
+        attrs: { url: 'Clients', fields: ['id', 'name'] },
+        columnField: { component: null },
     },
     {
         align: 'left',
         name: 'companyCode',
-        label: t('invoiceOutModule.company'),
+        label: t('globals.company'),
         cardVisible: true,
         component: 'select',
-        attrs: {
-            url: 'Companies',
-            optionLabel: 'code',
-            optionValue: 'id',
-        },
-        columnField: {
-            component: null,
-        },
+        attrs: { url: 'Companies', optionLabel: 'code', optionValue: 'id' },
+        columnField: { component: null },
     },
     {
         align: 'left',
         name: 'amount',
-        label: t('invoiceOutModule.amount'),
+        label: t('globals.amount'),
         cardVisible: true,
         format: (row) => toCurrency(row.amount),
     },
     {
         align: 'left',
         name: 'created',
-        label: t('invoiceOutList.tableVisibleColumns.created'),
+        label: t('globals.created'),
         component: 'date',
-        columnField: {
-            component: null,
-        },
+        columnField: { component: null },
         format: (row) => toDate(row.created),
     },
     {
         align: 'left',
         name: 'dued',
-        label: t('invoiceOutList.tableVisibleColumns.dueDate'),
+        label: t('invoiceOut.summary.dued'),
         component: 'date',
-        columnField: {
-            component: null,
-        },
+        columnField: { component: null },
         format: (row) => toDate(row.dued),
     },
     {
@@ -129,11 +126,12 @@ const columns = computed(() => [
             {
                 title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
+                isPrimary: true,
                 action: (row) => viewSummary(row.id, InvoiceOutSummary),
             },
             {
-                title: t('DownloadPdf'),
-                icon: 'vn:ticket',
+                title: t('globals.downloadPdf'),
+                icon: 'cloud_download',
                 isPrimary: true,
                 action: (row) => openPdf(row.id),
             },
@@ -172,7 +170,7 @@ watchEffect(selectedRows);
 <template>
     <VnSearchbar
         :info="t('youCanSearchByInvoiceReference')"
-        :label="t('searchInvoice')"
+        :label="t('Search invoice')"
         data-key="invoiceOutList"
     />
     <RightMenu>
@@ -188,7 +186,7 @@ watchEffect(selectedRows);
                 @click="downloadPdf()"
                 :disable="!hasSelectedCards"
             >
-                <QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
+                <QTooltip>{{ t('downloadPdf') }}</QTooltip>
             </QBtn>
         </template>
     </VnSubToolbar>
@@ -198,11 +196,9 @@ watchEffect(selectedRows);
         :url="`${MODEL}/filter`"
         :create="{
             urlCreate: 'InvoiceOuts/createManualInvoice',
-            title: t('Create manual invoice'),
+            title: t('createManualInvoice'),
             onDataSaved: ({ id }) => tableRef.redirect(id),
-            formInitialData: {
-                active: true,
-            },
+            formInitialData: { active: true },
         }"
         :right-search="false"
         v-model:selected="selectedRows"
@@ -222,74 +218,199 @@ watchEffect(selectedRows);
             </span>
         </template>
         <template #more-create-dialog="{ data }">
-            <div class="flex no-wrap flex-center">
-                <VnSelect
-                    url="Tickets"
-                    v-model="data.ticketFk"
-                    :label="t('invoiceOutList.tableVisibleColumns.ticket')"
-                    option-label="id"
-                    option-value="id"
-                >
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
-                                <QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
-                <span class="q-ml-md">O</span>
+            <div class="row q-col-gutter-xs">
+                <div class="col-12">
+                    <div class="q-col-gutter-xs">
+                        <VnRow fixed>
+                            <VnRadio
+                                v-model="selectedOption"
+                                val="ticket"
+                                :label="t('globals.ticket')"
+                                class="q-my-none q-mr-md"
+                            />
+
+                            <VnInput
+                                v-show="selectedOption === 'ticket'"
+                                v-model="data.ticketFk"
+                                :label="t('globals.ticket')"
+                                style="flex: 1"
+                            />
+
+                            <div
+                                class="row q-col-gutter-xs q-ml-none"
+                                v-show="selectedOption !== 'ticket'"
+                            >
+                                <div class="col">
+                                    <VnSelect
+                                        v-model="data.clientFk"
+                                        :label="t('globals.client')"
+                                        url="Clients"
+                                        :options="customerOptions"
+                                        option-label="name"
+                                        option-value="id"
+                                        @update:model-value="fetchClientAddress"
+                                    >
+                                        <template #option="scope">
+                                            <QItem v-bind="scope.itemProps">
+                                                <QItemSection>
+                                                    <QItemLabel>
+                                                        #{{ scope.opt?.id }} -
+                                                        {{ scope.opt?.name }}
+                                                    </QItemLabel>
+                                                </QItemSection>
+                                            </QItem>
+                                        </template>
+                                    </VnSelect>
+                                </div>
+                                <div class="col">
+                                    <VnSelect
+                                        v-model="data.addressFk"
+                                        :label="t('ticket.summary.consignee')"
+                                        :options="addressOptions"
+                                        option-label="nickname"
+                                        option-value="id"
+                                        v-if="
+                                            data.clientFk &&
+                                            selectedOption === 'consignatario'
+                                        "
+                                    >
+                                        <template #option="scope">
+                                            <QItem v-bind="scope.itemProps">
+                                                <QItemSection>
+                                                    <QItemLabel
+                                                        :class="{
+                                                            'color-vn-label':
+                                                                !scope.opt?.isActive,
+                                                        }"
+                                                    >
+                                                        {{
+                                                            `${
+                                                                !scope.opt?.isActive
+                                                                    ? t('inactive')
+                                                                    : ''
+                                                            } `
+                                                        }}
+                                                        <span>{{
+                                                            scope.opt?.nickname
+                                                        }}</span>
+                                                        <span
+                                                            v-if="
+                                                                scope.opt?.province ||
+                                                                scope.opt?.city ||
+                                                                scope.opt?.street
+                                                            "
+                                                        >
+                                                            , {{ scope.opt?.street }},
+                                                            {{ scope.opt?.city }},
+                                                            {{
+                                                                scope.opt?.province?.name
+                                                            }}
+                                                            -
+                                                            {{
+                                                                scope.opt?.agencyMode
+                                                                    ?.name
+                                                            }}
+                                                        </span>
+                                                    </QItemLabel>
+                                                </QItemSection>
+                                            </QItem>
+                                        </template>
+                                    </VnSelect>
+                                </div>
+                            </div>
+                        </VnRow>
+                        <VnRow fixed>
+                            <VnRadio
+                                v-model="selectedOption"
+                                val="cliente"
+                                :label="t('globals.client')"
+                                class="q-my-none q-mr-md"
+                            />
+                        </VnRow>
+                        <VnRow fixed>
+                            <VnRadio
+                                v-model="selectedOption"
+                                val="consignatario"
+                                :label="t('ticket.summary.consignee')"
+                                class="q-my-none q-mr-md"
+                            />
+                        </VnRow>
+                    </div>
+                </div>
+                <div class="full-width">
+                    <VnRow class="row q-col-gutter-xs">
+                        <VnSelect
+                            url="InvoiceOutSerials"
+                            v-model="data.serial"
+                            :label="t('invoiceIn.serial')"
+                            :options="invoiceOutSerialsOptions"
+                            option-label="description"
+                            option-value="code"
+                            option-filter
+                            :expr-builder="exprBuilder"
+                        >
+                            <template #option="scope">
+                                <QItem v-bind="scope.itemProps">
+                                    <QItemSection>
+                                        <QItemLabel>
+                                            {{ scope.opt?.code }} -
+                                            {{ scope.opt?.description }}
+                                        </QItemLabel>
+                                    </QItemSection>
+                                </QItem>
+                            </template>
+                        </VnSelect>
+                        <VnInputDate
+                            :label="t('invoiceOut.summary.dued')"
+                            v-model="data.maxShipped"
+                        />
+                    </VnRow>
+                    <VnRow class="row q-col-gutter-xs">
+                        <VnSelect
+                            url="TaxAreas"
+                            v-model="data.taxArea"
+                            :label="t('invoiceOutList.tableVisibleColumns.taxArea')"
+                            :options="taxAreasOptions"
+                            option-label="code"
+                            option-value="code"
+                        />
+                        <VnInput
+                            v-model="data.reference"
+                            :label="t('globals.reference')"
+                        />
+                    </VnRow>
+                </div>
             </div>
-            <VnSelect
-                url="Clients"
-                v-model="data.clientFk"
-                :label="t('invoiceOutModule.customer')"
-                :options="customerOptions"
-                option-label="name"
-                option-value="id"
-            />
-            <VnSelect
-                url="InvoiceOutSerials"
-                v-model="data.serial"
-                :label="t('invoiceOutList.tableVisibleColumns.invoiceOutSerial')"
-                :options="invoiceOutSerialsOptions"
-                option-label="description"
-                option-value="code"
-            />
-            <VnInputDate
-                :label="t('invoiceOutList.tableVisibleColumns.dueDate')"
-                v-model="data.maxShipped"
-            />
-            <VnSelect
-                url="TaxAreas"
-                v-model="data.taxArea"
-                :label="t('invoiceOutList.tableVisibleColumns.taxArea')"
-                :options="taxAreasOptions"
-                option-label="code"
-                option-value="code"
-            />
-            <QInput
-                v-model="data.reference"
-                :label="t('invoiceOutList.tableVisibleColumns.ref')"
-            />
         </template>
     </VnTable>
 </template>
 
+<style lang="scss" scoped>
+#formModel .vn-row {
+    min-height: 45px;
+
+    .q-radio {
+        align-self: flex-end;
+        flex: 0.3;
+    }
+
+    > .q-input,
+    > .q-select {
+        flex: 0.75;
+    }
+}
+</style>
+
 <i18n>
-en:
-    searchInvoice: Search issued invoice
-    fileDenied: Browser denied file download...
-    fileAllowed: Successful download of CSV file
-    youCanSearchByInvoiceReference: You can search by invoice reference
-    createInvoice: Make invoice
-    Create manual invoice: Create manual invoice
-es:
-    searchInvoice: Buscar factura emitida
-    fileDenied: El navegador denegó la descarga de archivos...
-    fileAllowed: Descarga exitosa de archivo CSV
-    youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
-    createInvoice: Crear factura
-    Create manual invoice: Crear factura manual
+    en:
+        invoiceId: Invoice ID
+        youCanSearchByInvoiceReference: You can search by invoice reference
+        createManualInvoice: Create Manual Invoice
+        inactive: (Inactive)
+
+    es:
+        invoiceId: ID de factura
+        youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
+        createManualInvoice: Crear factura manual
+        inactive: (Inactivo)
 </i18n>
diff --git a/src/pages/InvoiceOut/locale/en.yml b/src/pages/InvoiceOut/locale/en.yml
index 5ad92ed09..8cefe8bdc 100644
--- a/src/pages/InvoiceOut/locale/en.yml
+++ b/src/pages/InvoiceOut/locale/en.yml
@@ -2,6 +2,7 @@ invoiceOutModule:
     customer: Client
     amount: Amount
     company: Company
+    address: Address
 invoiceOutList:
     tableVisibleColumns:
         id: ID
@@ -15,11 +16,11 @@ invoiceOutList:
 DownloadPdf: Download PDF
 InvoiceOutSummary: Summary
 negativeBases:
-        country: Country
-        clientId: Client ID
-        base: Base
-        ticketId: Ticket
-        active: Active
-        hasToInvoice: Has to invoice
-        verifiedData: Verified data
-        commercial: Commercial
\ No newline at end of file
+    country: Country
+    clientId: Client ID
+    base: Base
+    ticketId: Ticket
+    active: Active
+    hasToInvoice: Has to invoice
+    verifiedData: Verified data
+    commercial: Commercial
diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml
index 192f5b26f..bf5126641 100644
--- a/src/pages/InvoiceOut/locale/es.yml
+++ b/src/pages/InvoiceOut/locale/es.yml
@@ -4,6 +4,7 @@ invoiceOutModule:
     customer: Cliente
     amount: Importe
     company: Empresa
+    address: Consignatario
 invoiceOutList:
     tableVisibleColumns:
         id: ID
diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue
index 253316a09..e5fea3003 100644
--- a/src/pages/Monitor/Ticket/MonitorTickets.vue
+++ b/src/pages/Monitor/Ticket/MonitorTickets.vue
@@ -15,6 +15,7 @@ import { toCurrency, dateRange, dashIfEmpty } from 'src/filters';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
 import MonitorTicketFilter from './MonitorTicketFilter.vue';
+import TicketProblems from 'src/components/TicketProblems.vue';
 
 const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms
 const { t } = useI18n();
@@ -23,9 +24,15 @@ const tableRef = ref(null);
 const provinceOpts = ref([]);
 const stateOpts = ref([]);
 const zoneOpts = ref([]);
-const visibleColumns = ref([]);
 const { viewSummary } = useSummaryDialog();
+
 const [from, to] = dateRange(Date.vnNew());
+const stateColors = {
+    notice: 'info',
+    success: 'positive',
+    warning: 'warning',
+    alert: 'negative',
+};
 
 function exprBuilder(param, value) {
     switch (param) {
@@ -220,7 +227,7 @@ const columns = computed(() => [
             {
                 title: t('salesTicketsTable.goToLines'),
                 icon: 'vn:lines',
-                color: 'priamry',
+                color: 'primary',
                 action: (row) => openTab(row.id),
                 isPrimary: true,
                 attrs: {
@@ -231,7 +238,7 @@ const columns = computed(() => [
             {
                 title: t('salesTicketsTable.preview'),
                 icon: 'preview',
-                color: 'priamry',
+                color: 'primary',
                 action: (row) => viewSummary(row.id, TicketSummary),
                 isPrimary: true,
                 attrs: {
@@ -249,10 +256,10 @@ const getBadgeAttrs = (date) => {
     let timeTicket = new Date(date);
     timeTicket.setHours(0, 0, 0, 0);
 
-    let comparation = today - timeTicket;
+    let timeDiff = today - timeTicket;
 
-    if (comparation == 0) return { color: 'warning', 'text-color': 'black' };
-    if (comparation < 0) return { color: 'success', 'text-color': 'black' };
+    if (timeDiff == 0) return { color: 'warning', 'text-color': 'black' };
+    if (timeDiff < 0) return { color: 'success', 'text-color': 'black' };
     return { color: 'transparent', 'text-color': 'white' };
 };
 
@@ -267,13 +274,6 @@ const autoRefreshHandler = (value) => {
     }
 };
 
-const stateColors = {
-    notice: 'info',
-    success: 'positive',
-    warning: 'warning',
-    alert: 'negative',
-};
-
 const totalPriceColor = (ticket) => {
     const total = parseInt(ticket.totalWithVat);
     if (total > 0 && total < 50) return 'warning';
@@ -281,10 +281,10 @@ const totalPriceColor = (ticket) => {
 
 const formatShippedDate = (date) => {
     if (!date) return '-';
-    const split1 = date.split('T');
-    const [year, month, day] = split1[0].split('-');
-    const _date = new Date(year, month - 1, day);
-    return toDateFormat(_date);
+    const dateSplit = date.split('T');
+    const [year, month, day] = dateSplit[0].split('-');
+    const newDate = new Date(year, month - 1, day);
+    return toDateFormat(newDate);
 };
 
 const openTab = (id) =>
@@ -332,7 +332,6 @@ const openTab = (id) =>
         :expr-builder="exprBuilder"
         :offset="50"
         :columns="columns"
-        :visible-columns="visibleColumns"
         :right-search="false"
         default-mode="table"
         auto-load
@@ -362,61 +361,7 @@ const openTab = (id) =>
             </QCheckbox>
         </template>
         <template #column-totalProblems="{ row }">
-            <span>
-                <QIcon
-                    v-if="row.isTaxDataChecked === 0"
-                    name="vn:no036"
-                    color="primary"
-                    size="xs"
-                >
-                    <QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.hasTicketRequest"
-                    name="vn:buyrequest"
-                    color="primary"
-                    size="xs"
-                >
-                    <QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.itemShortage"
-                    name="vn:unavailable"
-                    color="primary"
-                    size="xs"
-                >
-                    <QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
-                </QIcon>
-                <QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
-                    <QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.risk"
-                    name="vn:risk"
-                    :color="row.hasHighRisk ? 'negative' : 'primary'"
-                    size="xs"
-                >
-                    <QTooltip
-                        >{{ $t('salesTicketsTable.risk') }}: {{ row.risk }}</QTooltip
-                    >
-                </QIcon>
-                <QIcon
-                    v-if="row.hasComponentLack"
-                    name="vn:components"
-                    color="primary"
-                    size="xs"
-                >
-                    <QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.isTooLittle"
-                    name="vn:isTooLittle"
-                    color="primary"
-                    size="xs"
-                >
-                    <QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
-                </QIcon>
-            </span>
+            <TicketProblems :row="row" />
         </template>
         <template #column-id="{ row }">
             <span class="link" @click.stop.prevent>
@@ -471,7 +416,7 @@ const openTab = (id) =>
             </QIcon>
         </template>
         <template #column-zoneFk="{ row }">
-            <div @click.stop.prevent :title="row.zoneName">
+            <div v-if="row.zoneFk" @click.stop.prevent :title="row.zoneName">
                 <span class="link">{{ row.zoneName }}</span>
                 <ZoneDescriptorProxy :id="row.zoneFk" />
             </div>
diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue
index 53bb87f8d..b91e7d229 100644
--- a/src/pages/Order/Card/CatalogFilterValueDialog.vue
+++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue
@@ -49,7 +49,7 @@ const getSelectedTagValues = async (tag) => {
 
 <template>
     <QForm @submit="applyTags()" class="all-pointer-events">
-        <QCard class="q-pa-sm column q-pa-lg">
+        <QCard class="q-pa-sm column q-pa-lg" data-cy="catalogFilterValueDialog">
             <VnSelect
                 :label="t('params.tag')"
                 v-model="selectedTag"
@@ -63,6 +63,7 @@ const getSelectedTagValues = async (tag) => {
                 :emit-value="false"
                 use-input
                 @update:model-value="getSelectedTagValues"
+                data-cy="catalogFilterValueDialogTagSelect"
             />
             <div
                 v-for="(value, index) in tagValues"
@@ -93,6 +94,7 @@ const getSelectedTagValues = async (tag) => {
                         :disable="!value"
                         is-outlined
                         class="col"
+                        data-cy="catalogFilterValueDialogValueInput"
                     />
                     <QBtn
                         icon="delete"
diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue
index 90bce38fd..a71065521 100644
--- a/src/pages/Order/Card/OrderCatalog.vue
+++ b/src/pages/Order/Card/OrderCatalog.vue
@@ -98,7 +98,7 @@ watch(
             />
         </QScrollArea>
     </QDrawer>
-    <QPage class="column items-center q-pa-md">
+    <QPage class="column items-center q-pa-md" data-cy="orderCatalogPage">
         <div class="full-width">
             <VnPaginate
                 :data-key="dataKey"
@@ -118,6 +118,7 @@ watch(
                             :item="row"
                             is-catalog
                             class="fill-icon"
+                            data-cy="orderCatalogItem"
                         />
                     </div>
                 </template>
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 6202a6f90..1dd569fb5 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -178,6 +178,7 @@ function addOrder(value, field, params) {
                             ? resetCategory(params, searchFn)
                             : removeTagGroupParam(params, searchFn, valIndex)
                     "
+                    data-cy="catalogFilterCustomTag"
                 >
                     <strong v-if="customTag.label === 'categoryFk' && categoryList">
                         {{
@@ -211,6 +212,7 @@ function addOrder(value, field, params) {
                         :name="category.icon"
                         class="category-icon"
                         @click="selectCategory(params, category, searchFn)"
+                        data-cy="catalogFilterCategory"
                     >
                         <QTooltip>
                             {{ t(category.name) }}
@@ -234,6 +236,7 @@ function addOrder(value, field, params) {
                         sort-by="name ASC"
                         :disable="!params.categoryFk"
                         @update:model-value="searchFn()"
+                        data-cy="catalogFilterType"
                     >
                         <template #option="{ itemProps, opt }">
                             <QItem v-bind="itemProps">
@@ -285,6 +288,7 @@ function addOrder(value, field, params) {
                     :is-clearable="false"
                     v-model="searchByTag"
                     @keyup.enter="(val) => onSearchByTag(val, params)"
+                    data-cy="catalogFilterValueInput"
                 >
                     <template #prepend>
                         <QIcon name="search" />
@@ -297,6 +301,7 @@ function addOrder(value, field, params) {
                             color="primary"
                             size="md"
                             dense
+                            data-cy="catalogFilterValueDialogBtn"
                         />
                         <QPopupProxy>
                             <CatalogFilterValueDialog
diff --git a/src/pages/Order/Card/OrderCreateDialog.vue b/src/pages/Order/Card/OrderCreateDialog.vue
index 3f6cc914b..c78b04d7f 100644
--- a/src/pages/Order/Card/OrderCreateDialog.vue
+++ b/src/pages/Order/Card/OrderCreateDialog.vue
@@ -1,6 +1,6 @@
 <script setup>
 import { useRouter } from 'vue-router';
-import { onMounted, ref } from 'vue';
+import { reactive, onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
 import { useState } from 'composables/useState';
@@ -9,7 +9,6 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import { useDialogPluginComponent } from 'quasar';
-import { reactive } from 'vue';
 
 const { t } = useI18n();
 const state = useState();
@@ -48,10 +47,6 @@ const fetchAgencyList = async (landed, addressFk) => {
     agencyList.value = data;
 };
 
-// const fetchOrderDetails = (order) => {
-//     fetchAddressList(order?.addressFk);
-//     fetchAgencyList(order?.landed, order?.addressFk);
-// };
 const $props = defineProps({
     clientFk: {
         type: Number,
@@ -63,39 +58,6 @@ const initialFormState = reactive({
     addressId: null,
     clientFk: $props.clientFk,
 });
-// const orderMapper = (order) => {
-//     return {
-//         addressId: order.addressFk,
-//         agencyModeId: order.agencyModeFk,
-//         landed: new Date(order.landed).toISOString(),
-//     };
-// };
-// const orderFilter = {
-//     include: [
-//         { relation: 'agencyMode', scope: { fields: ['name'] } },
-//         {
-//             relation: 'address',
-//             scope: { fields: ['nickname'] },
-//         },
-//         { relation: 'rows', scope: { fields: ['id'] } },
-//         {
-//             relation: 'client',
-//             scope: {
-//                 fields: [
-//                     'salesPersonFk',
-//                     'name',
-//                     'isActive',
-//                     'isFreezed',
-//                     'isTaxDataChecked',
-//                 ],
-//                 include: {
-//                     relation: 'salesPersonUser',
-//                     scope: { fields: ['id', 'name'] },
-//                 },
-//             },
-//         },
-//     ],
-// };
 
 const onClientChange = async (clientId = $props.clientFk) => {
     const { data } = await axios.get(`Clients/${clientId}`);
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index 547842960..1a79be8bc 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
+import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -100,10 +101,13 @@ function handleLocation(data, location) {
                 />
             </VnRow>
             <VnRow>
-                <VnInput
+                <VnAccountNumber
                     v-model="data.account"
                     :label="t('supplier.fiscalData.account')"
                     clearable
+                    data-cy="supplierFiscalDataAccount"
+                    insertable
+                    :maxlength="10"
                 />
                 <VnSelect
                     :label="t('supplier.fiscalData.sageTaxTypeFk')"
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index 1fc54f486..0c53552fe 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -33,6 +33,7 @@ const canEditZone = useAcl().hasAny([
 const agencyFetchRef = ref();
 const warehousesOptions = ref([]);
 const companiesOptions = ref([]);
+const currenciesOptions = ref([]);
 const agenciesOptions = ref([]);
 const zonesOptions = ref([]);
 const addresses = ref([]);
diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue
index f8ffb43ed..4e77b633f 100644
--- a/src/pages/Ticket/Card/TicketDescriptor.vue
+++ b/src/pages/Ticket/Card/TicketDescriptor.vue
@@ -130,6 +130,7 @@ function ticketFilter(ticket) {
                     <QBadge
                         text-color="black"
                         :color="entity.ticketState.state.classColor"
+                        data-cy="ticketDescriptorStateBadge"
                     >
                         {{ entity.ticketState.state.name }}
                     </QBadge>
@@ -174,7 +175,7 @@ function ticketFilter(ticket) {
                     <QTooltip>{{ t('Client Frozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="entity.problem.includes('hasRisk')"
+                    v-if="entity?.problem?.includes('hasRisk')"
                     name="vn:risk"
                     size="xs"
                     color="primary"
diff --git a/src/pages/Ticket/Card/TicketEditMana.vue b/src/pages/Ticket/Card/TicketEditMana.vue
index 3d5b04a41..693875712 100644
--- a/src/pages/Ticket/Card/TicketEditMana.vue
+++ b/src/pages/Ticket/Card/TicketEditMana.vue
@@ -75,6 +75,7 @@ const cancel = () => {
                     dense
                     style="width: 50%"
                     @click="save()"
+                    data-cy="saveManaBtn"
                 >
                     {{ t('globals.save') }}
                 </QBtn>
diff --git a/src/pages/Ticket/Card/TicketNotes.vue b/src/pages/Ticket/Card/TicketNotes.vue
index 6861cf000..f558b71cc 100644
--- a/src/pages/Ticket/Card/TicketNotes.vue
+++ b/src/pages/Ticket/Card/TicketNotes.vue
@@ -80,12 +80,14 @@ async function handleSave() {
                             option-value="id"
                             v-model="row.observationTypeFk"
                             :disable="!!row.id"
+                            data-cy="ticketNotesObservationType"
                         />
                         <VnInput
                             :label="t('basicData.description')"
                             v-model="row.description"
                             class="col"
                             @keyup.enter="handleSave"
+                            data-cy="ticketNotesDescription"
                         />
                         <QIcon
                             name="delete"
@@ -93,6 +95,7 @@ async function handleSave() {
                             class="cursor-pointer"
                             color="primary"
                             @click="handleDelete(row)"
+                            data-cy="ticketNotesRemoveNoteBtn"
                         >
                             <QTooltip>
                                 {{ t('ticketNotes.removeNote') }}
@@ -107,6 +110,7 @@ async function handleSave() {
                             class="fill-icon-on-hover q-ml-md"
                             color="primary"
                             @click="ticketNotesCrudRef.insert()"
+                            data-cy="ticketNotesAddNoteBtn"
                         >
                             <QTooltip>
                                 {{ t('ticketNotes.addNote') }}
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 95ef3118e..b534170c9 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -555,6 +555,7 @@ watch(
                     color="primary"
                     :disable="!isTicketEditable || ticketState === 'OK'"
                     @click="changeTicketState('OK')"
+                    data-cy="ticketSaleOkStateBtn"
                 >
                     <QTooltip>{{ t(`Change ticket state to 'Ok'`) }}</QTooltip>
                 </QBtn>
@@ -563,6 +564,7 @@ watch(
                     color="primary"
                     :label="t('ticketList.state')"
                     :disable="!isTicketEditable"
+                    data-cy="ticketSaleStateDropdown"
                 >
                     <VnSelect
                         :options="editableStatesOptions"
@@ -572,6 +574,7 @@ watch(
                         hide-dropdown-icon
                         focus-on-mount
                         @update:model-value="changeTicketState"
+                        data-cy="ticketSaleStateSelect"
                     />
                 </QBtnDropdown>
                 <TicketSaleMoreActions
@@ -604,6 +607,7 @@ watch(
                     icon="vn:splitline"
                     :disable="!isTicketEditable || !hasSelectedRows"
                     @click="setTransferParams()"
+                    data-cy="ticketSaleTransferBtn"
                 >
                     <QTooltip>{{ t('Transfer lines') }}</QTooltip>
                     <TicketTransfer
@@ -683,7 +687,13 @@ watch(
                     {{ t('ticketSale.visible') }}: {{ row.visible || 0 }}
                 </QTooltip>
             </QIcon>
-            <QIcon v-if="row.reserved" color="primary" name="vn:reserva" size="xs">
+            <QIcon
+                v-if="row.reserved"
+                color="primary"
+                name="vn:reserva"
+                size="xs"
+                data-cy="ticketSaleReservedIcon"
+            >
                 <QTooltip>
                     {{ t('ticketSale.reserved') }}
                 </QTooltip>
@@ -832,7 +842,14 @@ watch(
     </VnTable>
 
     <QPageSticky :offset="[20, 20]" style="z-index: 2">
-        <QBtn @click="newOrderFromTicket()" color="primary" fab icon="add" shortcut="+" />
+        <QBtn
+            @click="newOrderFromTicket()"
+            color="primary"
+            fab
+            icon="add"
+            shortcut="+"
+            data-cy="ticketSaleAddToBasketBtn"
+        />
         <QTooltip class="text-no-wrap">
             {{ t('Add item to basket') }}
         </QTooltip>
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 87e1d2a48..bd2099756 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -175,6 +175,7 @@ const createRefund = async (withWarehouse) => {
         color="primary"
         :label="t('ticketSale.more')"
         :disable="disable"
+        data-cy="ticketSaleMoreActionsDropdown"
     >
         <template #label>
             <QTooltip>{{ t('Select lines to see the options') }}</QTooltip>
@@ -186,6 +187,7 @@ const createRefund = async (withWarehouse) => {
                 v-close-popup
                 v-ripple
                 @click="showSmsDialog('productNotAvailable')"
+                data-cy="sendShortageSMSItem"
             >
                 <QItemSection>
                     <QItemLabel>{{ t('Send shortage SMS') }}</QItemLabel>
@@ -197,12 +199,18 @@ const createRefund = async (withWarehouse) => {
                 v-close-popup
                 v-ripple
                 @click="calculateSalePrice()"
+                data-cy="recalculatePriceItem"
             >
                 <QItemSection>
                     <QItemLabel>{{ t('Recalculate price') }}</QItemLabel>
                 </QItemSection>
             </QItem>
-            <QItem clickable v-ripple @click="emit('getMana')">
+            <QItem
+                clickable
+                v-ripple
+                @click="emit('getMana')"
+                data-cy="updateDiscountItem"
+            >
                 <QItemSection>
                     <QItemLabel>{{ t('Update discount') }}</QItemLabel>
                 </QItemSection>
@@ -211,6 +219,7 @@ const createRefund = async (withWarehouse) => {
                         v-model.number="newDiscount"
                         :label="t('ticketSale.discount')"
                         type="number"
+                        data-cy="ticketSaleDiscountInput"
                     />
                 </TicketEditManaProxy>
             </QItem>
@@ -220,6 +229,7 @@ const createRefund = async (withWarehouse) => {
                 v-close-popup
                 v-ripple
                 @click="createClaim()"
+                data-cy="createClaimItem"
             >
                 <QItemSection>
                     <QItemLabel>{{ t('Add claim') }}</QItemLabel>
@@ -231,6 +241,7 @@ const createRefund = async (withWarehouse) => {
                 v-close-popup
                 v-ripple
                 @click="setReserved(true)"
+                data-cy="markAsReservedItem"
             >
                 <QItemSection>
                     <QItemLabel>{{ t('Mark as reserved') }}</QItemLabel>
@@ -242,12 +253,13 @@ const createRefund = async (withWarehouse) => {
                 v-close-popup
                 v-ripple
                 @click="setReserved(false)"
+                data-cy="unmarkAsReservedItem"
             >
                 <QItemSection>
                     <QItemLabel>{{ t('Unmark as reserved') }}</QItemLabel>
                 </QItemSection>
             </QItem>
-            <QItem clickable v-ripple>
+            <QItem clickable v-ripple data-cy="ticketSaleRefundItem">
                 <QItemSection>
                     <QItemLabel>{{ t('Refund') }}</QItemLabel>
                 </QItemSection>
@@ -256,12 +268,22 @@ const createRefund = async (withWarehouse) => {
                 </QItemSection>
                 <QMenu anchor="top end" self="top start" auto-close bordered>
                     <QList>
-                        <QItem v-ripple clickable @click="createRefund(true)">
+                        <QItem
+                            v-ripple
+                            clickable
+                            @click="createRefund(true)"
+                            data-cy="ticketSaleRefundWithWarehouse"
+                        >
                             <QItemSection>
                                 {{ t('with warehouse') }}
                             </QItemSection>
                         </QItem>
-                        <QItem v-ripple clickable @click="createRefund(false)">
+                        <QItem
+                            v-ripple
+                            clickable
+                            @click="createRefund(false)"
+                            data-cy="ticketSaleRefundWithoutWarehouse"
+                        >
                             <QItemSection>
                                 {{ t('without warehouse') }}
                             </QItemSection>
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 5bda60cba..2f5f69e1c 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -96,6 +96,7 @@ function toTicketUrl(section) {
         ref="summaryRef"
         :url="`Tickets/${entityId}/summary`"
         data-key="TicketSummary"
+        data-cy="ticketSummary"
     >
         <template #header-left>
             <VnToSummary
diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue
index d7aff3ef7..005d74a0e 100644
--- a/src/pages/Ticket/Card/TicketTransfer.vue
+++ b/src/pages/Ticket/Card/TicketTransfer.vue
@@ -91,7 +91,7 @@ onMounted(() => (_transfer.value = $props.transfer));
 </script>
 
 <template>
-    <QPopupProxy ref="QPopupProxyRef">
+    <QPopupProxy ref="QPopupProxyRef" data-cy="ticketTransferPopup">
         <QCard class="q-px-md" style="display: flex; width: 80vw">
             <QTable
                 :rows="transfer.sales"
diff --git a/src/pages/Ticket/Card/TicketTransferForm.vue b/src/pages/Ticket/Card/TicketTransferForm.vue
index d07a9d2e7..ece3a3b97 100644
--- a/src/pages/Ticket/Card/TicketTransferForm.vue
+++ b/src/pages/Ticket/Card/TicketTransferForm.vue
@@ -57,6 +57,7 @@ defineExpose({ transferSales });
             v-model.number="_transfer.ticketId"
             :label="t('Transfer to ticket')"
             :clearable="false"
+            data-cy="ticketTransferDestinationTicketInput"
         >
             <template #append>
                 <QBtn
@@ -64,6 +65,7 @@ defineExpose({ transferSales });
                     color="primary"
                     @click="transferSales(_transfer.ticketId)"
                     style="width: 30px"
+                    data-cy="ticketTransferTransferBtn"
                 />
             </template>
         </VnInput>
@@ -72,6 +74,7 @@ defineExpose({ transferSales });
             color="primary"
             class="full-width q-my-lg"
             @click="transferSales()"
+            data-cy="ticketTransferNewTicketBtn"
         />
     </QForm>
 </template>
diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue
index 8de602b37..71e3926ac 100644
--- a/src/pages/Ticket/TicketAdvance.vue
+++ b/src/pages/Ticket/TicketAdvance.vue
@@ -215,7 +215,7 @@ const requestComponentUpdate = async (ticket, isWithoutNegatives) => {
 
         if (!newLanded) {
             notify(t('advanceTickets.noDeliveryZone'), 'negative');
-            return;
+            throw new Error(t('advanceTickets.noDeliveryZone'));
         }
 
         ticket.landed = newLanded.landed;
@@ -299,10 +299,10 @@ const splitTickets = async () => {
                 const { query, params } = await requestComponentUpdate(ticket, true);
                 await axios.post(query, params);
                 progressAdd(ticket.futureId);
-            } catch (error) {
+            } catch (e) {
                 splitErrors.value.push({
                     id: ticket.futureId,
-                    reason: error.response?.data?.error?.message,
+                    reason: e.message || e.response?.data?.error?.message,
                 });
                 progressAdd(ticket.futureId);
             }
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 6f6c556ca..2fe4fcddc 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -22,6 +22,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
 import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
 import { toTimeFormat } from 'src/filters/date';
 import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
+import TicketProblems from 'src/components/TicketProblems.vue';
 
 const route = useRoute();
 const router = useRouter();
@@ -455,6 +456,7 @@ function setReference(data) {
         data-key="TicketList"
         :label="t('Search ticket')"
         :info="t('You can search by ticket id or alias')"
+        data-cy="ticketListSearchBar"
     />
     <RightMenu>
         <template #right-panel>
@@ -482,68 +484,10 @@ function setReference(data) {
             'row-key': 'id',
             selection: 'multiple',
         }"
+        data-cy="ticketListTable"
     >
         <template #column-statusIcons="{ row }">
-            <div class="q-gutter-x-xs">
-                <QIcon
-                    v-if="row.isTaxDataChecked === 0"
-                    color="primary"
-                    name="vn:no036"
-                    size="xs"
-                >
-                    <QTooltip>
-                        {{ t('No verified data') }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.hasTicketRequest"
-                    color="primary"
-                    name="vn:buyrequest"
-                    size="xs"
-                >
-                    <QTooltip>
-                        {{ t('Purchase request') }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.itemShortage"
-                    color="primary"
-                    name="vn:unavailable"
-                    size="xs"
-                >
-                    <QTooltip>
-                        {{ t('Not visible') }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon v-if="row.isFreezed" color="primary" name="vn:frozen" size="xs">
-                    <QTooltip>
-                        {{ t('Client frozen') }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
-                    <QTooltip> {{ t('Risk') }}: {{ row.risk }} </QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.hasComponentLack"
-                    color="primary"
-                    name="vn:components"
-                    size="xs"
-                >
-                    <QTooltip>
-                        {{ t('Component lack') }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.hasRounding"
-                    color="primary"
-                    name="sync_problem"
-                    size="xs"
-                >
-                    <QTooltip>
-                        {{ t('Rounding') }}
-                    </QTooltip>
-                </QIcon>
-            </div>
+            <TicketProblems :row="row" />
         </template>
         <template #column-salesPersonFk="{ row }">
             <span class="link" @click.stop>
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index f4331ccb2..be1a12406 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -300,10 +300,6 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                 <VnLv :label="t('globals.reference')" :value="travel.ref" />
                 <VnLv label="m³" :value="travel.m3" />
                 <VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
-                <VnLv
-                    :label="t('travel.basicData.daysInForward')"
-                    :value="travel?.daysInForward"
-                />
             </QCard>
             <QCard class="full-width">
                 <VnTitle :text="t('travel.summary.entries')" />
diff --git a/src/pages/Worker/Card/WorkerPit.vue b/src/pages/Worker/Card/WorkerPit.vue
new file mode 100644
index 000000000..c58196c7b
--- /dev/null
+++ b/src/pages/Worker/Card/WorkerPit.vue
@@ -0,0 +1,263 @@
+<script setup>
+import { ref } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import axios from 'axios';
+import FetchData from 'components/FetchData.vue';
+import FormModel from 'src/components/FormModel.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import CrudModel from 'components/CrudModel.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
+import { useQuasar } from 'quasar';
+import VnConfirm from 'components/ui/VnConfirm.vue';
+import useNotify from 'src/composables/useNotify.js';
+const { notify } = useNotify();
+const route = useRoute();
+const { t } = useI18n();
+const disabilityGradesOptions = ref();
+const workerPitCrudRef = ref({});
+const insertTag = () => {
+    workerPitCrudRef.value.insert();
+};
+const quasar = useQuasar();
+const deleteRelative = async (id) => {
+    await new Promise((resolve) => {
+        quasar
+            .dialog({
+                component: VnConfirm,
+                componentProps: {
+                    title: t('Remove Relative'),
+                    message: t('Do you want to remove this relative?'),
+                },
+            })
+            .onOk(() => {
+                resolve(true);
+            })
+            .onCancel(() => {
+                resolve(false);
+            });
+    });
+    await axios.delete(`WorkerRelatives/${id}`);
+    workerPitCrudRef.value.reload();
+    notify('Relative removed', 'positive');
+};
+</script>
+
+<template>
+    <FetchData
+        url="DisabilityGrades"
+        @on-fetch="(data) => (disabilityGradesOptions = data)"
+        auto-load
+    />
+
+    <FormModel
+        url="WorkerIrpfs"
+        :filter="{ where: { workerFk: route.params.id } }"
+        auto-load
+        data-key="workerIrpfs"
+        :max-width="false"
+    >
+        <template #form="{ data }">
+            <QCard class="q-px-lg q-py-lg">
+                <VnTitle :text="t('IRPF')" />
+                <VnRow>
+                    <VnInput
+                        :label="t('familySituation')"
+                        clearable
+                        v-model="data.familySituation"
+                    />
+                    <VnInput :label="t('spouseNif')" clearable v-model="data.spouseNif" />
+                </VnRow>
+                <VnRow>
+                    <VnSelect
+                        :label="t('disabilityGrades')"
+                        :options="disabilityGradesOptions"
+                        option-label="description"
+                        option-value="id"
+                        v-model="data.disabilityGradeFk"
+                        id="disabilityGrades"
+                        data-cy="disabilityGrades"
+                        hide-selected
+                    />
+
+                    <VnInputDate
+                        :label="t('geographicMobilityDate')"
+                        v-model="data.geographicMobilityDate"
+                    />
+                </VnRow>
+                <VnRow>
+                    <VnInput
+                        clearable
+                        v-model="data.childPension"
+                        :label="t(`childPension`)"
+                    />
+                    <VnInput
+                        clearable
+                        v-model="data.spousePension"
+                        :label="t(`spousePension`)"
+                    />
+                </VnRow>
+                <VnRow>
+                    <QCheckbox v-model="data.isDependend" :label="t(`isDependend`)" />
+                    <QCheckbox
+                        v-model="data.hasHousingPaymentBefore"
+                        :label="t(`hasHousingPaymentBefore`)"
+                    />
+                </VnRow>
+                <VnRow>
+                    <QCheckbox
+                        v-model="data.hasHousingPaymentAfter"
+                        :label="t(`hasHousingPaymentAfter`)"
+                    />
+                    <QCheckbox
+                        v-model="data.hasExtendedWorking"
+                        :label="t(`hasExtendedWorking`)"
+                    />
+                </VnRow>
+            </QCard>
+
+            <CrudModel
+                ref="workerPitCrudRef"
+                data-key="workerPit"
+                url="WorkerRelatives"
+                auto-load
+                :filter="{
+                    where: { workerFk: route.params.id },
+                }"
+                :data-required="{ workerFk: route.params.id }"
+                :has-sub-toolbar="false"
+            >
+                <template #body="{ rows }">
+                    <QCard class="q-px-lg q-py-lg" flat>
+                        <div class="row no-wrap justify-between q-pb-md">
+                            <VnTitle :text="t('Relatives')" />
+                            <QBtnGroup push style="column-gap: 10px">
+                                <QBtn
+                                    color="primary"
+                                    icon="restart_alt"
+                                    flat
+                                    @click="workerPitCrudRef.reset"
+                                    :disable="!workerPitCrudRef.hasChanges"
+                                    :title="t('globals.reset')"
+                                />
+                                <QBtn
+                                    ref="saveButtonRef"
+                                    color="primary"
+                                    icon="save"
+                                    @click="workerPitCrudRef.onSubmit"
+                                    :disable="!workerPitCrudRef.hasChanges"
+                                    :title="t('globals.save')"
+                                    data-cy="workerPitRelativeSaveBtn"
+                                />
+                            </QBtnGroup>
+                        </div>
+                        <div
+                            v-for="(row, index) in rows"
+                            :key="index"
+                            class="row no-wrap q-mb-lg q-gutter-lg"
+                            padding="none"
+                        >
+                            <VnSelect
+                                :options="[
+                                    { id: 0, name: 'Ascendiente' },
+                                    { id: 1, name: 'Descendiente' },
+                                ]"
+                                :label="t('isDescendant')"
+                                v-model="row.isDescendant"
+                                class="q-gutter-xs q-mb-xs"
+                            />
+                            <VnSelect
+                                :label="t('disabilityGrades')"
+                                :options="disabilityGradesOptions"
+                                option-label="description"
+                                option-value="id"
+                                v-model="row.disabilityGradeFk"
+                                class="q-gutter-xs q-mb-xs"
+                            />
+                            <VnInput
+                                type="number"
+                                v-model="row.birthed"
+                                :label="t(`birthed`)"
+                            />
+
+                            <VnInput
+                                type="number"
+                                v-model="row.adoptionYear"
+                                :label="t(`adoptionYear`)"
+                            />
+                            <QCheckbox
+                                v-model="row.isDependend"
+                                :label="t(`isDependend`)"
+                            />
+                            <QCheckbox
+                                v-model="row.isJointCustody"
+                                :label="t(`isJointCustody`)"
+                                size="xs"
+                            />
+                            <QBtn
+                                @click="deleteRelative(rows[0].id)"
+                                class="cursor-pointer"
+                                color="primary"
+                                flat
+                                icon="delete"
+                                style="flex: 0"
+                            />
+                        </div>
+                        <VnRow class="justify-left items-center">
+                            <QBtn
+                                @click="insertTag(rows)"
+                                class="cursor-pointer"
+                                color="primary"
+                                flat
+                                icon="add"
+                                shortcut="+"
+                                style="flex: 0"
+                                data-cy="addRelative"
+                            />
+                        </VnRow>
+                    </QCard>
+                </template>
+            </CrudModel>
+        </template>
+    </FormModel>
+</template>
+
+<i18n>
+es:
+    familySituation: Situación familiar
+    disabilityGrades: Discapacidad
+    geographicMobilityDate: Movilidad geografica
+    childPension: Pensión hijos
+    spousePension: Pensión cónyuge
+    isDependend: Ayuda / Movilidad reducida
+    spouseNif: NIF cónyuge
+    hasHousingPaymentBefore: Pagos vivienda anterior 2011
+    hasHousingPaymentAfter: Pagos vivienda posterior 2011
+    hasExtendedWorking: Prolongación actividad laboral
+    isDescendant: Descen/Ascen
+    disabilityGradeFk: Discapacidad
+    birthed: Año nacimiento
+    adoptionYear: Año adopción
+    isJointCustody: Computo por entero
+    Relatives: Relacionados
+en:
+    familySituation: Family Situation
+    disabilityGrades: Disability Grades
+    geographicMobilityDate: Geographic Mobility Date
+    childPension: Child Pension
+    spousePension: Spouse Pension
+    isDependend: Dependent Suport / Reduced Mobility
+    spouseNif: Spouse NIF (Tax ID)
+    hasHousingPaymentBefore: Housing Payments Before 2011
+    hasHousingPaymentAfter: Housing Payments After 2011
+    hasExtendedWorking: Extended Work Activity
+    isDescendant: Descendant/Ascendant
+    disabilityGradeFk: Disability Grade
+    birthed: Birth Year
+    adoptionYear: Adoption Year
+    isJointCustody: Joint custody
+    Relatives: Relatives
+</i18n>
diff --git a/src/router/modules/Supplier.js b/src/router/modules/Supplier.js
index 143d7c824..c08fb5961 100644
--- a/src/router/modules/Supplier.js
+++ b/src/router/modules/Supplier.js
@@ -113,7 +113,7 @@ export default {
                     name: 'SupplierAccounts',
                     meta: {
                         title: 'accounts',
-                        icon: 'vn:account',
+                        icon: 'vn:credit',
                     },
                     component: () =>
                         import('src/pages/Supplier/Card/SupplierAccounts.vue'),
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index d1feff23d..925019734 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -24,6 +24,7 @@ export default {
             'WorkerDms',
             'WorkerTimeControl',
             'WorkerLocker',
+            'WorkerPit',
             'WorkerBalance',
             'WorkerFormation',
             'WorkerMedical',
@@ -216,6 +217,15 @@ export default {
                     },
                     component: () => import('src/pages/Worker/Card/WorkerMedical.vue'),
                 },
+                {
+                    name: 'WorkerPit',
+                    path: 'pit',
+                    meta: {
+                        title: 'pit',
+                        icon: 'lock',
+                    },
+                    component: () => import('src/pages/Worker/Card/WorkerPit.vue'),
+                },
                 {
                     name: 'WorkerOperator',
                     path: 'operator',
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index 35f834f3d..332494aa8 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -162,6 +162,15 @@ export const useInvoiceOutGlobalStore = defineStore({
                 );
                 throw new Error('Invalid Serial Type');
             }
+
+            if (clientsToInvoice === 'all' && params.serialType !== 'global') {
+                notify(
+                    'invoiceOut.globalInvoices.errors.invalidSerialTypeForAll',
+                    'negative'
+                );
+                throw new Error('For "all" clients, the serialType must be "global"');
+            }
+
             if (!params.companyFk) {
                 notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
                 throw new Error('Invalid company');
diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/Order/orderCatalog.spec.js
new file mode 100644
index 000000000..45eda6f1f
--- /dev/null
+++ b/test/cypress/integration/Order/orderCatalog.spec.js
@@ -0,0 +1,112 @@
+/// <reference types="cypress" />
+describe('OrderCatalog', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 720);
+        cy.visit('/#/order/8/catalog');
+    });
+
+    const checkCustomFilterTag = (filterName = 'Plant') => {
+        cy.dataCy('catalogFilterCustomTag').should('exist');
+        cy.dataCy('catalogFilterCustomTag').contains(filterName);
+    };
+
+    const checkFilterTag = (filterName = 'Plant') => {
+        cy.dataCy('vnFilterPanelChip').should('exist');
+        cy.dataCy('vnFilterPanelChip').contains(filterName);
+    };
+
+    const selectCategory = (categoryIndex = 1, categoryName = 'Plant') => {
+        cy.get(
+            `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+        ).should('exist');
+        cy.get(
+            `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+        ).click();
+        checkCustomFilterTag(categoryName);
+    };
+
+    const searchByCustomTagInput = (option) => {
+        cy.dataCy('catalogFilterValueInput').find('input').last().focus();
+        cy.dataCy('catalogFilterValueInput').find('input').last().type(option);
+        cy.dataCy('catalogFilterValueInput').find('input').last().type('{enter}');
+        checkCustomFilterTag(option);
+    };
+
+    const selectTypeFilter = (option) => {
+        cy.selectOption(
+            'div.q-page-container div.list > div:nth-of-type(2) div:nth-of-type(3)',
+            option
+        );
+        checkFilterTag(option);
+    };
+
+    it('Shows empty state', () => {
+        cy.dataCy('orderCatalogPage').should('exist');
+        cy.dataCy('orderCatalogPage').contains('No data to display');
+    });
+
+    it('filter by category', () => {
+        selectCategory();
+        cy.dataCy('orderCatalogItem').should('exist');
+    });
+
+    it('filters by type', () => {
+        selectCategory();
+        selectTypeFilter('Anthurium');
+    });
+
+    it('filters by custom value select', () => {
+        selectCategory();
+        searchByCustomTagInput('Silver');
+    });
+
+    it('filters by custom value dialog', () => {
+        Cypress.on('uncaught:exception', (err) => {
+            if (err.message.includes('canceled')) {
+                return false;
+            }
+        });
+        selectCategory();
+        cy.dataCy('catalogFilterValueDialogBtn').should('exist');
+        cy.dataCy('catalogFilterValueDialogBtn').last().click();
+        cy.dataCy('catalogFilterValueDialogTagSelect').should('exist');
+        cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
+        cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
+        cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
+        cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('{enter}');
+        checkCustomFilterTag('2');
+    });
+
+    it('removes a secondary tag', () => {
+        selectCategory();
+        selectTypeFilter('Anthurium');
+        cy.dataCy('vnFilterPanelChip').should('exist');
+        cy.get(
+            "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+        )
+            .contains('cancel')
+            .should('exist');
+        cy.get(
+            "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+        )
+            .contains('cancel')
+            .click();
+        cy.dataCy('vnFilterPanelChip').should('not.exist');
+    });
+
+    it('Removes category tag', () => {
+        selectCategory();
+        cy.get(
+            "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+        )
+            .contains('cancel')
+            .should('exist');
+        cy.get(
+            "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+        )
+            .contains('cancel')
+            .click();
+        cy.dataCy('catalogFilterCustomTag').should('not.exist');
+    });
+});
diff --git a/test/cypress/integration/item/01_summary.spec.js b/test/cypress/integration/item/01_summary.spec.js
new file mode 100644
index 000000000..c44f4d047
--- /dev/null
+++ b/test/cypress/integration/item/01_summary.spec.js
@@ -0,0 +1,25 @@
+describe.skip('Item summary path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should search for an item', async () => {});
+    it(`should check the item summary preview shows fields from basic data`, async () => {});
+    it(`should check the item summary preview shows fields from tags`, async () => {});
+    it(`should check the item summary preview shows fields from botanical`, async () => {});
+    it(`should check the item summary preview shows fields from barcode`, async () => {});
+    it(`should close the summary popup`, async () => {});
+    it('should search for other item', async () => {});
+    it(`should now check the item summary preview shows fields from basic data`, async () => {});
+    it(`should now check the item summary preview shows fields from tags`, async () => {});
+    it(`should now check the item summary preview shows fields from botanical`, async () => {});
+    it(`should now close the summary popup`, async () => {});
+    it(`should navigate to one of the items detailed section`, async () => {});
+    it(`should check the descritor edit button is not visible for employee`, async () => {});
+    it(`should check the item summary shows fields from basic data section`, async () => {});
+    it(`should check the item summary shows fields from tags section`, async () => {});
+    it(`should check the item summary shows fields from botanical section`, async () => {});
+    it(`should check the item summary shows fields from barcodes section`, async () => {});
+});
diff --git a/test/cypress/integration/item/02_basic_data.spec.js b/test/cypress/integration/item/02_basic_data.spec.js
new file mode 100644
index 000000000..ada9ef57c
--- /dev/null
+++ b/test/cypress/integration/item/02_basic_data.spec.js
@@ -0,0 +1,10 @@
+describe.skip('Item Edit basic data path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it(`should edit the item basic data and confirm the item data was edited`, async () => {});
+    it(`should create a new intrastat and save it`, async () => {});
+});
diff --git a/test/cypress/integration/item/03_tax.spec.js b/test/cypress/integration/item/03_tax.spec.js
new file mode 100644
index 000000000..593dbfb36
--- /dev/null
+++ b/test/cypress/integration/item/03_tax.spec.js
@@ -0,0 +1,12 @@
+describe.skip('Item edit tax path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it(`should add the item tax to all countries`, async () => {});
+    it(`should confirm the first item tax class was edited`, async () => {});
+    it(`should confirm the second item tax class was edited`, async () => {});
+    it(`should edit the first class without saving the form`, async () => {});
+});
diff --git a/test/cypress/integration/item/04_tags.spec.js b/test/cypress/integration/item/04_tags.spec.js
new file mode 100644
index 000000000..720d19a89
--- /dev/null
+++ b/test/cypress/integration/item/04_tags.spec.js
@@ -0,0 +1,12 @@
+describe.skip('Item create tags path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should create a new tag and delete a former one', async () => {});
+    it('should confirm the fourth row data is the expected one', async () => {});
+    it('should confirm the fifth row data is the expected one', async () => {});
+    it('should confirm the sixth row data is the expected one', async () => {});
+});
diff --git a/test/cypress/integration/item/05_botanical.spec.js b/test/cypress/integration/item/05_botanical.spec.js
new file mode 100644
index 000000000..72e7f3fee
--- /dev/null
+++ b/test/cypress/integration/item/05_botanical.spec.js
@@ -0,0 +1,14 @@
+describe.skip('Item Create botanical path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it(`should create a new botanical for the item`, async () => {});
+    it(`should confirm the Genus for the item was created`, async () => {});
+    it(`should confirm the Species for the item was created`, async () => {});
+    it(`should edit botanical for the item`, async () => {});
+    it(`should confirm the Genus for the item was edited`, async () => {});
+    it(`should confirm the Species for the item was edited`, async () => {});
+});
diff --git a/test/cypress/integration/item/06_barcode.spec.js b/test/cypress/integration/item/06_barcode.spec.js
new file mode 100644
index 000000000..cea3c13f2
--- /dev/null
+++ b/test/cypress/integration/item/06_barcode.spec.js
@@ -0,0 +1,10 @@
+describe.skip('Item Create barcodes path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it(`should click create a new code and delete a former one`, async () => {});
+    it(`should confirm the barcode 5 is created and it is now the third barcode as the first was deleted`, async () => {});
+});
diff --git a/test/cypress/integration/item/07_create.spec.js b/test/cypress/integration/item/07_create.spec.js
new file mode 100644
index 000000000..7555d6927
--- /dev/null
+++ b/test/cypress/integration/item/07_create.spec.js
@@ -0,0 +1,13 @@
+describe.skip('Item Create', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should access to the create item view by clicking the create floating button', async () => {});
+    it('should return to the item index by clickig the cancel button', async () => {});
+    it('should now access to the create item view by clicking the create floating button', async () => {});
+    it('should throw an error when insert an invalid priority', async () => {});
+    it('should create the Infinity Gauntlet item', async () => {});
+});
diff --git a/test/cypress/integration/item/08_regularize.spec.js b/test/cypress/integration/item/08_regularize.spec.js
new file mode 100644
index 000000000..74d12846f
--- /dev/null
+++ b/test/cypress/integration/item/08_regularize.spec.js
@@ -0,0 +1,24 @@
+describe.skip('Item regularize path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should edit the user local warehouse', async () => {});
+    it('should check the local settings were saved', async () => {});
+    it('should search for a specific item', async () => {});
+    it('should open the regularize dialog and check the warehouse matches the local user settings', async () => {});
+    it('should regularize the item', async () => {});
+    it('should click on the Tickets button of the top bar menu', async () => {});
+    it('should clear the user local settings now', async () => {});
+    it('should search for the ticket with alias missing', async () => {});
+    it(`should check the ticket sale quantity is showing a negative value`, async () => {});
+    it(`should check the ticket sale discount is 100%`, async () => {});
+    it('should now click on the Items button of the top bar menu', async () => {});
+    it('should search for the item once again', async () => {});
+    it('should regularize the item once more', async () => {});
+    it('should again click on the Tickets button of the top bar menu', async () => {});
+    it('should search for the ticket missing once again', async () => {});
+    it(`should check the ticket contains now two sales`, async () => {});
+});
diff --git a/test/cypress/integration/item/09_index.spec.js b/test/cypress/integration/item/09_index.spec.js
new file mode 100644
index 000000000..5648a8b5f
--- /dev/null
+++ b/test/cypress/integration/item/09_index.spec.js
@@ -0,0 +1,14 @@
+describe.skip('Item index path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should click on the fields to show button to open the list of columns to show', async () => {});
+    it('should unmark all checkboxes except the first and the last ones', async () => {});
+    it('should navigate forth and back to see the images column is still visible', async () => {});
+    it('should check the ids column is not visible', async () => {});
+    it('should mark all unchecked boxes to leave the index as it was', async () => {});
+    it('should now navigate forth and back to see the ids column is now visible', async () => {});
+});
diff --git a/test/cypress/integration/item/10_item_log.spec.js b/test/cypress/integration/item/10_item_log.spec.js
new file mode 100644
index 000000000..3cc64dbbb
--- /dev/null
+++ b/test/cypress/integration/item/10_item_log.spec.js
@@ -0,0 +1,12 @@
+describe.skip('Item log path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it(`should search for the Knowledge artifact to confirm it isn't created yet`, async () => {});
+    it('should access to the create item view by clicking the create floating button', async () => {});
+    it('should create the Knowledge artifact item', async () => {});
+    it('should return to the items index by clicking the return to items button', async () => {});
+});
diff --git a/test/cypress/integration/item/11_descriptor.spec.js b/test/cypress/integration/item/11_descriptor.spec.js
new file mode 100644
index 000000000..6ea89c365
--- /dev/null
+++ b/test/cypress/integration/item/11_descriptor.spec.js
@@ -0,0 +1,11 @@
+describe.skip('Item descriptor path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should set the item to inactive', async () => {});
+    it('should reload the section and check the inactive icon is visible', async () => {});
+    it('should set the item back to active', async () => {});
+});
diff --git a/test/cypress/integration/item/12_request.spec.js b/test/cypress/integration/item/12_request.spec.js
new file mode 100644
index 000000000..f4e26f421
--- /dev/null
+++ b/test/cypress/integration/item/12_request.spec.js
@@ -0,0 +1,12 @@
+describe.skip('Item request path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should reach the item request section', async () => {});
+    it('should fill the id and quantity then check the concept was updated', async () => {});
+    it('should check the status of the request should now be accepted', async () => {});
+    it('should now click on the second declain request icon then type the reason', async () => {});
+});
diff --git a/test/cypress/integration/item/13_fixedPrice.spec.js b/test/cypress/integration/item/13_fixedPrice.spec.js
new file mode 100644
index 000000000..44fdfde46
--- /dev/null
+++ b/test/cypress/integration/item/13_fixedPrice.spec.js
@@ -0,0 +1,12 @@
+describe.skip('Item fixed prices path', () => {
+    beforeEach(() => {
+        const itemId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/item/${itemId}`);
+    });
+    it('should filter using all the fields', async () => {});
+    it('should click on the add new fixed price button', async () => {});
+    it('should fill the fixed price data', async () => {});
+    it('should reload the section and check the created price has the expected ID', async () => {});
+});
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
new file mode 100644
index 000000000..bbdbcea92
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -0,0 +1,54 @@
+/// <reference types="cypress" />
+describe('TicketList', () => {
+    const firstRow = 'tbody > :nth-child(1)';
+
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/list');
+    });
+
+    const searchResults = (search) => {
+        cy.dataCy('vnSearchBar').find('input').focus();
+        if (search) cy.dataCy('vnSearchBar').find('input').type(search);
+        cy.dataCy('vnSearchBar').find('input').type('{enter}');
+        cy.dataCy('ticketListTable').should('exist');
+        cy.get(firstRow).should('exist');
+    };
+
+    it('should search results', () => {
+        cy.dataCy('ticketListTable').should('not.exist');
+        cy.get('.q-field__control').should('exist');
+        searchResults();
+    });
+
+    it('should open ticket sales', () => {
+        searchResults();
+        cy.window().then((win) => {
+            cy.stub(win, 'open').as('windowOpen');
+        });
+        cy.get(firstRow).find('.q-btn:first').click();
+        cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/);
+    });
+
+    it('should open ticket summary', () => {
+        searchResults();
+        cy.get(firstRow).find('.q-btn:last').click();
+        cy.dataCy('ticketSummary').should('exist');
+    });
+
+    it('Client list create new client', () => {
+        cy.dataCy('vnTableCreateBtn').should('exist');
+        cy.dataCy('vnTableCreateBtn').click();
+        const data = {
+            Customer: { val: 1, type: 'select' },
+            Warehouse: { val: 'Warehouse One', type: 'select' },
+            Address: { val: 'employee', type: 'select' },
+            Landed: { val: '01-01-2024', type: 'date' },
+        };
+        cy.fillInForm(data);
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.checkNotification('Data created');
+        cy.url().should('match', /\/ticket\/\d+\/summary/);
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketNotes.spec.js b/test/cypress/integration/ticket/ticketNotes.spec.js
new file mode 100644
index 000000000..ef196c783
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketNotes.spec.js
@@ -0,0 +1,25 @@
+/// <reference types="cypress" />
+describe('TicketRequest', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/observation');
+    });
+
+    it('Creates and deletes a note', () => {
+        cy.dataCy('ticketNotesAddNoteBtn').should('exist');
+        cy.dataCy('ticketNotesAddNoteBtn').click();
+        cy.dataCy('ticketNotesObservationType').should('exist');
+        cy.selectOption('[data-cy="ticketNotesObservationType"]:last', 'Weight');
+        cy.dataCy('ticketNotesDescription').should('exist');
+        cy.get('[data-cy="ticketNotesDescription"]:last').type(
+            'This is a note description'
+        );
+        cy.dataCy('crudModelDefaultSaveBtn').click();
+        cy.checkNotification('Data saved');
+        cy.dataCy('ticketNotesRemoveNoteBtn').should('exist');
+        cy.dataCy('ticketNotesRemoveNoteBtn').click();
+        cy.dataCy('VnConfirm_confirm').click();
+        cy.checkNotification('Data saved');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketRequest.spec.js b/test/cypress/integration/ticket/ticketRequest.spec.js
new file mode 100644
index 000000000..b9dc509ef
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketRequest.spec.js
@@ -0,0 +1,22 @@
+/// <reference types="cypress" />
+describe('TicketRequest', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/request');
+    });
+
+    it('Creates a new request', () => {
+        cy.dataCy('vnTableCreateBtn').should('exist');
+        cy.dataCy('vnTableCreateBtn').click();
+        const data = {
+            Description: { val: 'Purchase description' },
+            Atender: { val: 'buyerNick', type: 'select' },
+            Quantity: { val: 2 },
+            Price: { val: 123 },
+        };
+        cy.fillInForm(data);
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.checkNotification('Data created');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
new file mode 100644
index 000000000..60f31dbf6
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -0,0 +1,131 @@
+/// <reference types="cypress" />
+
+const c = require('croppie');
+
+describe('TicketSale', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/sale');
+    });
+
+    const firstRow = 'tbody > :nth-child(1)';
+
+    const selectFirstRow = () => {
+        cy.waitForElement(firstRow);
+        cy.get(firstRow).find('.q-checkbox__inner').click();
+    };
+
+    it('it should add item to basket', () => {
+        cy.window().then((win) => {
+            cy.stub(win, 'open').as('windowOpen');
+        });
+        cy.dataCy('ticketSaleAddToBasketBtn').should('exist');
+        cy.dataCy('ticketSaleAddToBasketBtn').click();
+        cy.get('@windowOpen').should('be.calledWithMatch', /\/order\/\d+\/catalog/);
+    });
+
+    it('should send SMS', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.waitForElement('[data-cy="sendShortageSMSItem"]');
+        cy.dataCy('sendShortageSMSItem').should('exist');
+        cy.dataCy('sendShortageSMSItem').click();
+        cy.dataCy('vnSmsDialog').should('exist');
+        cy.dataCy('sendSmsBtn').click();
+        cy.checkNotification('SMS sent');
+    });
+
+    it('should recalculate price when "Recalculate price" is clicked', () => {
+        cy.intercept('POST', '**/recalculatePrice').as('recalculatePrice');
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.waitForElement('[data-cy="recalculatePriceItem"]');
+        cy.dataCy('recalculatePriceItem').should('exist');
+        cy.dataCy('recalculatePriceItem').click();
+        cy.wait('@recalculatePrice').its('response.statusCode').should('eq', 200);
+        cy.checkNotification('Data saved');
+    });
+
+    it('should update discount when "Update discount" is clicked', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.waitForElement('[data-cy="updateDiscountItem"]');
+        cy.dataCy('updateDiscountItem').should('exist');
+        cy.dataCy('updateDiscountItem').click();
+        cy.waitForElement('[data-cy="ticketSaleDiscountInput"]');
+        cy.dataCy('ticketSaleDiscountInput').find('input').focus();
+        cy.dataCy('ticketSaleDiscountInput').find('input').type('10');
+        cy.dataCy('saveManaBtn').click();
+        cy.waitForElement('.q-notification__message');
+        cy.checkNotification('Data saved');
+    });
+
+    it('adds claim', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.dataCy('createClaimItem').click();
+        cy.dataCy('VnConfirm_confirm').click();
+        cy.url().should('match', /\/claim\/\d+\/basic-data/);
+        // Delete created claim to avoid cluttering the database
+        cy.dataCy('descriptor-more-opts').click();
+        cy.dataCy('deleteClaim').click();
+        cy.dataCy('VnConfirm_confirm').click();
+        cy.checkNotification('Data deleted');
+    });
+
+    it('marks row as reserved', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.waitForElement('[data-cy="markAsReservedItem"]');
+        cy.dataCy('markAsReservedItem').click();
+        cy.dataCy('ticketSaleReservedIcon').should('exist');
+    });
+
+    it('unmarks row as reserved', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
+        cy.dataCy('unmarkAsReservedItem').click();
+        cy.dataCy('ticketSaleReservedIcon').should('not.exist');
+    });
+
+    it('refunds row with warehouse', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.dataCy('ticketSaleRefundItem').click();
+        cy.dataCy('ticketSaleRefundWithWarehouse').click();
+        cy.checkNotification('The following refund ticket have been created');
+    });
+
+    it('refunds row without warehouse', () => {
+        selectFirstRow();
+        cy.dataCy('ticketSaleMoreActionsDropdown').click();
+        cy.dataCy('ticketSaleRefundItem').click();
+        cy.dataCy('ticketSaleRefundWithoutWarehouse').click();
+        cy.checkNotification('The following refund ticket have been created');
+    });
+
+    it('transfers ticket', () => {
+        cy.visit('/#/ticket/32/sale');
+        selectFirstRow();
+        cy.dataCy('ticketSaleTransferBtn').click();
+        cy.dataCy('ticketTransferPopup').should('exist');
+        cy.dataCy('ticketTransferNewTicketBtn').click();
+        // existen 3 elementos "tbody" necesito checkear que el segundo elemento tbody tenga una row sola
+        cy.get('tbody').eq(1).find('tr').should('have.length', 1);
+        selectFirstRow();
+        cy.dataCy('ticketSaleTransferBtn').click();
+        cy.dataCy('ticketTransferPopup').should('exist');
+        cy.dataCy('ticketTransferDestinationTicketInput').find('input').focus();
+        cy.dataCy('ticketTransferDestinationTicketInput').find('input').type('32');
+        cy.dataCy('ticketTransferTransferBtn').click();
+        // checkear que la url contenga /ticket/1000002/sale
+        cy.url().should('match', /\/ticket\/32\/sale/);
+    });
+
+    it('should redirect to ticket logs', () => {
+        cy.get(firstRow).find('.q-btn:last').click();
+        cy.url().should('match', /\/ticket\/31\/log/);
+    });
+});
diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
new file mode 100644
index 000000000..000c2151d
--- /dev/null
+++ b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
@@ -0,0 +1,39 @@
+describe('VnInput Component', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/supplier/1/fiscal-data');
+        cy.domContentLoad();
+    });
+
+    it('should replace character at cursor position in insert mode', () => {
+        // Simula escribir en el input
+        cy.dataCy('supplierFiscalDataAccount').clear();
+        cy.dataCy('supplierFiscalDataAccount').type('4100000001');
+        // Coloca el cursor en la posición 0
+        cy.dataCy('supplierFiscalDataAccount').type('{movetostart}');
+        // Escribe un número y verifica que se reemplace correctamente
+        cy.dataCy('supplierFiscalDataAccount').type('999');
+        cy.dataCy('supplierFiscalDataAccount')
+        .should('have.value', '9990000001');
+    });
+
+    it('should replace character at cursor position in insert mode', () => {
+        // Simula escribir en el input
+        cy.dataCy('supplierFiscalDataAccount').clear();
+        cy.dataCy('supplierFiscalDataAccount').type('4100000001');
+        // Coloca el cursor en la posición 0
+        cy.dataCy('supplierFiscalDataAccount').type('{movetostart}');
+        // Escribe un número y verifica que se reemplace correctamente en la posicion incial
+        cy.dataCy('supplierFiscalDataAccount').type('999');
+        cy.dataCy('supplierFiscalDataAccount')
+        .should('have.value', '9990000001');
+    });
+
+    it('should respect maxlength prop', () => {
+        cy.dataCy('supplierFiscalDataAccount').clear();
+        cy.dataCy('supplierFiscalDataAccount').type('123456789012345');
+        cy.dataCy('supplierFiscalDataAccount')
+        .should('have.value', '1234567890'); // asumiendo que maxlength es 10
+    });
+});
diff --git a/test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js b/test/cypress/integration/vnComponent/VnBreadcrumbs.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js
rename to test/cypress/integration/vnComponent/VnBreadcrumbs.spec.js
diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/VnLocation.spec.js
similarity index 71%
rename from test/cypress/integration/vnComponent/vnLocation.spec.js
rename to test/cypress/integration/vnComponent/VnLocation.spec.js
index 06c23f4ee..b98d42fdd 100644
--- a/test/cypress/integration/vnComponent/vnLocation.spec.js
+++ b/test/cypress/integration/vnComponent/VnLocation.spec.js
@@ -1,3 +1,5 @@
+const { randomNumber, randomString } = require('../../support');
+
 describe('VnLocation', () => {
     const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-item';
     const dialogInputs = '.q-dialog label input';
@@ -99,7 +101,7 @@ describe('VnLocation', () => {
         });
 
         it('Create postCode', () => {
-            const postCode = '1234475';
+            const postCode = Math.floor(100000 + Math.random() * 900000);
             const province = 'Valencia';
             cy.get(createLocationButton).click();
             cy.get('.q-card > h1').should('have.text', 'New postcode');
@@ -115,9 +117,10 @@ describe('VnLocation', () => {
 
             checkVnLocation(postCode, province);
         });
-        it('Create city', () => {
-            const postCode = '9011';
-            const province = 'Saskatchew';
+
+        it('Create city without country', () => {
+            const postCode = randomNumber();
+            const province = randomString({ length: 4 });
             cy.get(createLocationButton).click();
             cy.get(dialogInputs).eq(0).type(postCode);
             cy.get(
@@ -131,6 +134,58 @@ describe('VnLocation', () => {
             checkVnLocation(postCode, province);
         });
 
+        it('Create province without country', () => {
+            const provinceName = 'Saskatchew'.concat(Math.random(1 * 100));
+            cy.get(createLocationButton).click();
+            cy.get(
+                `${createForm.prefix} > :nth-child(5) > .q-select > ${createForm.sufix} > :nth-child(2) `
+            )
+                .eq(0)
+                .click();
+            cy.selectOption('#q-portal--dialog--3 .q-select', 'one');
+            cy.countSelectOptions('#q-portal--dialog--3 .q-select', 4);
+            cy.get('#q-portal--dialog--3 .q-input').type(provinceName);
+
+            cy.get('#q-portal--dialog--3 .q-btn--standard').click();
+        });
+
+        it('Create city with country', () => {
+            const cityName = 'Saskatchew'.concat(Math.random(1 * 100));
+            cy.get(createLocationButton).click();
+            cy.selectOption(
+                `${createForm.prefix} > :nth-child(5) > :nth-child(3) `,
+                'Italia'
+            );
+            cy.get(
+                `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(2) > .q-icon`
+            ).click();
+            cy.selectOption('#q-portal--dialog--4 .q-select', 'Province four');
+            cy.countSelectOptions('#q-portal--dialog--4 .q-select', 1);
+
+            cy.get('#q-portal--dialog--4 .q-input').type(cityName);
+            cy.get('#q-portal--dialog--4 .q-btn--standard').click();
+        });
+
+        it('Create province with country', () => {
+            const provinceName = 'Saskatchew'.concat(Math.random(1 * 100));
+            cy.get(createLocationButton).click();
+            cy.selectOption(
+                `${createForm.prefix} > :nth-child(5) > :nth-child(3) `,
+                'España'
+            );
+            cy.get(
+                `${createForm.prefix} > :nth-child(5) > .q-select > ${createForm.sufix} > :nth-child(2) `
+            )
+                .eq(0)
+                .click();
+
+            cy.selectOption('#q-portal--dialog--4 .q-select', 'one');
+            cy.countSelectOptions('#q-portal--dialog--4 .q-select', 2);
+
+            cy.get('#q-portal--dialog--4 .q-input').type(provinceName);
+            cy.get('#q-portal--dialog--4 .q-btn--standard').click();
+        });
+
         function checkVnLocation(postCode, province) {
             cy.get(`${createForm.prefix}`).should('not.exist');
             cy.get('.q-form > .q-card > .vn-row:nth-child(6)')
diff --git a/test/cypress/integration/vnComponent/vnLog.spec.js b/test/cypress/integration/vnComponent/VnLog.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnLog.spec.js
rename to test/cypress/integration/vnComponent/VnLog.spec.js
diff --git a/test/cypress/integration/vnComponent/vnSearchBar.spec.js b/test/cypress/integration/vnComponent/VnSearchBar.spec.js
similarity index 100%
rename from test/cypress/integration/vnComponent/vnSearchBar.spec.js
rename to test/cypress/integration/vnComponent/VnSearchBar.spec.js
diff --git a/test/cypress/integration/worker/workerPit.spec.js b/test/cypress/integration/worker/workerPit.spec.js
new file mode 100644
index 000000000..cc3a87637
--- /dev/null
+++ b/test/cypress/integration/worker/workerPit.spec.js
@@ -0,0 +1,40 @@
+describe('WorkerPit', () => {
+    const familySituationInput = '[data-cy="Family Situation_input"]';
+    const familySituation = '1';
+    const childPensionInput = '[data-cy="Child Pension_input"]';
+    const childPension = '120';
+    const spouseNifInput = '[data-cy="Spouse Pension_input"]';
+    const spouseNif = '65117125P';
+    const spousePensionInput = '[data-cy="Spouse Pension_input"]';
+    const spousePension = '120';
+    const addRelative = '[data-cy="addRelative"]';
+    const isDescendantSelect = '[data-cy="Descendant/Ascendant_select"]';
+    const birthedInput = '[data-cy="Birth Year_input"]';
+    const birthed = '2002';
+    const adoptionYearInput = '[data-cy="Adoption Year_input"]';
+    const adoptionYear = '2004';
+    const saveRelative = '[data-cy="workerPitRelativeSaveBtn"]';
+    const savePIT = '#st-actions > .q-btn-group > .q-btn--standard';
+
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('developer');
+        cy.visit(`/#/worker/1107/pit`);
+    });
+
+    it('complete PIT', () => {
+        cy.get(familySituationInput).type(familySituation);
+        cy.get(childPensionInput).type(childPension);
+        cy.get(spouseNifInput).type(spouseNif);
+        cy.get(spousePensionInput).type(spousePension);
+        cy.get(savePIT).click();
+    });
+
+    it('complete relative', () => {
+        cy.get(addRelative).click();
+        cy.get(isDescendantSelect).type('{downArrow}{downArrow}{enter}');
+        cy.get(birthedInput).type(birthed);
+        cy.get(adoptionYearInput).type(adoptionYear);
+        cy.get(saveRelative).click();
+    });
+});
diff --git a/test/cypress/integration/zone/01_basic-data.spec.js b/test/cypress/integration/zone/01_basic-data.spec.js
new file mode 100644
index 000000000..111f2495c
--- /dev/null
+++ b/test/cypress/integration/zone/01_basic-data.spec.js
@@ -0,0 +1,20 @@
+describe.skip('Zone basic data path', () => {
+    beforeEach(() => {
+        const zoneId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/zone/${zoneId}`);
+    });
+    it('should reach the basic data section', async () => {});
+    it('should edit de form and then save', async () => {});
+    it('should now reload the section', async () => {});
+    it('should confirm the name was updated', async () => {});
+    it('should confirm the agency was updated', async () => {});
+    it('should confirm the max volume was updated', async () => {});
+    it('should confirm the traveling days were updated', async () => {});
+    it('should confirm the closing hour was updated', async () => {});
+    it('should confirm the price was updated', async () => {});
+    it('should confirm the bonus was updated', async () => {});
+    it('should confirm the inflation was updated', async () => {});
+    it('should confirm the volumetric checkbox was checked', async () => {});
+});
diff --git a/test/cypress/integration/zone/02_descriptor.spec.js b/test/cypress/integration/zone/02_descriptor.spec.js
new file mode 100644
index 000000000..02f2d30ce
--- /dev/null
+++ b/test/cypress/integration/zone/02_descriptor.spec.js
@@ -0,0 +1,10 @@
+describe('Zone descriptor path', () => {
+    beforeEach(() => {
+        const zoneId = 1;
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/zone/${zoneId}`);
+    });
+    it('should eliminate the zone using the descriptor option', async () => {});
+    it('should search for the deleted zone to find no results', async () => {});
+});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index cb1d3de44..21121d9df 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -86,11 +86,17 @@ Cypress.Commands.add('getValue', (selector) => {
 });
 
 // Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option) => {
+Cypress.Commands.add('selectOption', (selector, option, timeout) => {
     cy.waitForElement(selector);
     cy.get(selector).click();
+    cy.wait(timeout || 1000);
     cy.get('.q-menu .q-item').contains(option).click();
 });
+Cypress.Commands.add('countSelectOptions', (selector, option) => {
+    cy.waitForElement(selector);
+    cy.get(selector).click();
+    cy.get('.q-menu .q-item').should('have.length', option);
+});
 
 Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
     cy.waitForElement('.q-form > .q-card');
diff --git a/test/cypress/support/index.js b/test/cypress/support/index.js
index 4385698ec..c57c1a303 100644
--- a/test/cypress/support/index.js
+++ b/test/cypress/support/index.js
@@ -15,3 +15,19 @@
 
 import './commands';
 
+function randomString(options = { length: 10 }) {
+    let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+    return randomizeValue(possible, options);
+}
+
+function randomNumber(options = { length: 10 }) {
+    let possible = '0123456789';
+    return randomizeValue(possible, options);
+}
+
+function randomizeValue(characterSet, options) {
+    return Array.from({ length: options.length }, () =>
+        characterSet.charAt(Math.floor(Math.random() * characterSet.length))
+    ).join('');
+}
+export { randomString, randomNumber, randomizeValue };
diff --git a/test/vitest/__tests__/components/common/VnLinkPhone.spec.js b/test/vitest/__tests__/components/common/VnLinkPhone.spec.js
index e460ab2fc..e31bff4a8 100644
--- a/test/vitest/__tests__/components/common/VnLinkPhone.spec.js
+++ b/test/vitest/__tests__/components/common/VnLinkPhone.spec.js
@@ -2,6 +2,14 @@ import { describe, it, expect } from 'vitest';
 import parsePhone from 'src/filters/parsePhone';
 
 describe('parsePhone filter', () => {
+    it('no phone', () => {
+        const resultado = parsePhone(null, '34');
+        expect(resultado).toBe(undefined);
+    });
+    it('no phone and no prefix', () => {
+        const resultado = parsePhone(null, null);
+        expect(resultado).toBe(undefined);
+    });
     it("adds prefix +34 if it doesn't have one", () => {
         const resultado = parsePhone('123456789', '34');
         expect(resultado).toBe('34123456789');
diff --git a/test/vitest/__tests__/composables/downloadFile.spec.js b/test/vitest/__tests__/composables/downloadFile.spec.js
index f611479bf..f53b56b3e 100644
--- a/test/vitest/__tests__/composables/downloadFile.spec.js
+++ b/test/vitest/__tests__/composables/downloadFile.spec.js
@@ -1,25 +1,36 @@
-import { vi, describe, expect, it } from 'vitest';
+import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest';
 import { axios } from 'app/test/vitest/helper';
 import { downloadFile } from 'src/composables/downloadFile';
 import { useSession } from 'src/composables/useSession';
-
 const session = useSession();
 const token = session.getToken();
 
 describe('downloadFile', () => {
+    const baseUrl = 'http://localhost:9000';
+    let defaulCreateObjectURL;
+
+    beforeAll(() => {
+        defaulCreateObjectURL = window.URL.createObjectURL;
+        window.URL.createObjectURL = vi.fn(() => 'blob:http://localhost:9000/blob-id');
+    });
+
+    afterAll(() => (window.URL.createObjectURL = defaulCreateObjectURL));
+
     it('should open a new window to download the file', async () => {
-        const url = 'http://localhost:9000';
-
-        vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: url });
-
-        const mockWindowOpen = vi.spyOn(window, 'open');
+        const res = {
+            data: new Blob(['file content'], { type: 'application/octet-stream' }),
+            headers: { 'content-disposition': 'attachment; filename="test-file.txt"' },
+        };
+        vi.spyOn(axios, 'get').mockImplementation((url) => {
+            if (url == 'Urls/getUrl') return Promise.resolve({ data: baseUrl });
+            else if (url.includes('downloadFile')) return Promise.resolve(res);
+        });
 
         await downloadFile(1);
 
-        expect(mockWindowOpen).toHaveBeenCalledWith(
-            `${url}/api/dms/1/downloadFile?access_token=${token}`
+        expect(axios.get).toHaveBeenCalledWith(
+            `${baseUrl}/api/dms/1/downloadFile?access_token=${token}`,
+            { responseType: 'blob' }
         );
-
-        mockWindowOpen.mockRestore();
     });
 });