@@ -404,7 +425,6 @@ watchEffect(selectedRows);
:label="
t('invoiceOutList.tableVisibleColumns.taxArea')
"
- :options="taxAreasOptions"
option-label="code"
option-value="code"
/>
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
index b062678a0..432cd07d7 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
@@ -8,7 +8,7 @@ import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import { useArrayData } from 'src/composables/useArrayData';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
-import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
@@ -115,18 +115,16 @@ const columns = computed(() => [
},
{
align: 'left',
- label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
- name: 'workerName',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
component: 'select',
attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- where: { role: 'salesPerson' },
+ url: 'Departments',
},
columnField: {
component: null,
},
- format: (row, dashIfEmpty) => dashIfEmpty(row.workerName),
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
]);
@@ -198,10 +196,10 @@ const downloadCSV = async () => {
-
+
- {{ row.workerName }}
-
+ {{ row.departmentName }}
+
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
index cd9836bb7..1e2f80ec2 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
@@ -20,7 +20,7 @@ const props = defineProps({
@@ -35,17 +35,13 @@ const props = defineProps({
-
+
@@ -57,8 +53,7 @@ const props = defineProps({
option-label="code"
option-value="code"
dense
- outlined
- rounded
+ filled
@update:model-value="searchFn()"
>
@@ -84,9 +79,8 @@ const props = defineProps({
v-model="params.country"
option-label="name"
option-value="name"
- outlined
dense
- rounded
+ filled
@update:model-value="searchFn()"
>
@@ -110,9 +104,8 @@ const props = defineProps({
url="Clients"
:label="t('globals.client')"
v-model="params.clientId"
- outlined
dense
- rounded
+ filled
@update:model-value="searchFn()"
/>
@@ -122,19 +115,21 @@ const props = defineProps({
-
diff --git a/src/pages/InvoiceOut/locale/en.yml b/src/pages/InvoiceOut/locale/en.yml
index bc73bb0ff..9d6a4a244 100644
--- a/src/pages/InvoiceOut/locale/en.yml
+++ b/src/pages/InvoiceOut/locale/en.yml
@@ -13,7 +13,6 @@ invoiceOut:
isActive: Active
hasToInvoice: Has to invoice
hasVerifiedData: Verified data
- workerName: Worker
isTaxDataChecked: Verified data
amount: Amount
clientFk: Client
@@ -27,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Has PDF
search: Contains
+ departmentFk: Department
card:
issued: Issued
customerCard: Customer card
diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml
index 45b948f28..f9448cd9b 100644
--- a/src/pages/InvoiceOut/locale/es.yml
+++ b/src/pages/InvoiceOut/locale/es.yml
@@ -13,7 +13,6 @@ invoiceOut:
isActive: Activo
hasToInvoice: Debe facturar
hasVerifiedData: Datos verificados
- workerName: Comercial
isTaxDataChecked: Datos comprobados
amount: Importe
clientFk: Cliente
@@ -27,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Tiene PDF
search: Contiene
+ departmentFk: Departamento
card:
issued: Fecha emisión
customerCard: Ficha del cliente
diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue
index 610b77a02..ddd21fe36 100644
--- a/src/pages/Item/Card/ItemCard.vue
+++ b/src/pages/Item/Card/ItemCard.vue
@@ -1,9 +1,9 @@
- {
- {
-
+
diff --git a/src/pages/Item/ItemFixedPriceFilter.vue b/src/pages/Item/ItemFixedPriceFilter.vue
index 8d92e245d..d68b966c6 100644
--- a/src/pages/Item/ItemFixedPriceFilter.vue
+++ b/src/pages/Item/ItemFixedPriceFilter.vue
@@ -13,7 +13,6 @@ const props = defineProps({
required: true,
},
});
-
@@ -28,8 +27,7 @@ const props = defineProps({
:fields="['id', 'nickname']"
option-label="nickname"
dense
- outlined
- rounded
+ filled
use-input
@update:model-value="searchFn()"
sort-by="nickname ASC"
@@ -46,8 +44,7 @@ const props = defineProps({
:label="t('params.warehouseFk')"
v-model="params.warehouseFk"
dense
- outlined
- rounded
+ filled
use-input
@update:model-value="searchFn()"
/>
@@ -58,7 +55,7 @@ const props = defineProps({
@@ -68,7 +65,7 @@ const props = defineProps({
diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue
index 22e948e06..f4500d5fa 100644
--- a/src/pages/Item/ItemListFilter.vue
+++ b/src/pages/Item/ItemListFilter.vue
@@ -177,11 +177,7 @@ onMounted(async () => {
-
+
@@ -197,8 +193,7 @@ onMounted(async () => {
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -213,8 +208,7 @@ onMounted(async () => {
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
>
@@ -240,8 +234,7 @@ onMounted(async () => {
option-label="nickname"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -252,8 +245,7 @@ onMounted(async () => {
@update:model-value="searchFn()"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -282,8 +274,7 @@ onMounted(async () => {
:options="tagOptions"
option-label="name"
dense
- outlined
- rounded
+ filled
:emit-value="false"
use-input
:is-clearable="false"
@@ -299,8 +290,7 @@ onMounted(async () => {
option-value="value"
option-label="value"
dense
- outlined
- rounded
+ filled
emit-value
use-input
:disable="!tag"
@@ -312,7 +302,7 @@ onMounted(async () => {
v-model="tag.value"
:label="t('params.value')"
:disable="!tag"
- is-outlined
+ filled
:is-clearable="false"
@keydown.enter.prevent="applyTags(params, searchFn)"
/>
@@ -351,8 +341,7 @@ onMounted(async () => {
option-label="label"
option-value="label"
dense
- outlined
- rounded
+ filled
:emit-value="false"
use-input
:is-clearable="false"
@@ -377,7 +366,7 @@ onMounted(async () => {
v-model="fieldFilter.value"
:label="t('params.value')"
:disable="!fieldFilter.selectedField"
- is-outlined
+ filled
@keydown.enter="applyFieldFilters(params, searchFn)"
/>
diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue
index 43fc611d8..ccae98025 100644
--- a/src/pages/Item/ItemRequest.vue
+++ b/src/pages/Item/ItemRequest.vue
@@ -3,6 +3,7 @@ import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'filters/index';
import useNotify from 'src/composables/useNotify.js';
@@ -61,6 +62,7 @@ const columns = computed(() => [
columnClass: 'expand',
},
{
+ align: 'left',
label: t('item.buyRequest.requester'),
name: 'requesterName',
component: 'select',
@@ -77,6 +79,19 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
+ {
+ align: 'left',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
+ },
+ columnField: {
+ component: null,
+ },
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
+ },
{
label: t('item.buyRequest.requested'),
name: 'quantity',
@@ -107,6 +122,7 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
+
{
label: t('globals.item'),
name: 'item',
@@ -262,6 +278,12 @@ const onDenyAccept = (_, responseData) => {
+
+
+ {{ row.departmentName }}
+
+
+
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index c2a63ddd9..68f36c566 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -87,11 +87,7 @@ onMounted(async () => {
-
+
@@ -99,7 +95,7 @@ onMounted(async () => {
@@ -114,8 +110,7 @@ onMounted(async () => {
option-label="nickname"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -124,7 +119,7 @@ onMounted(async () => {
@@ -139,8 +134,7 @@ onMounted(async () => {
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -153,25 +147,16 @@ onMounted(async () => {
:params="{ departmentCodes: ['VT'] }"
hide-selected
dense
- outlined
- rounded
+ filled
/>
-
+
-
+
@@ -180,7 +165,7 @@ onMounted(async () => {
:label="t('params.daysOnward')"
v-model="params.daysOnward"
lazy-rules
- is-outlined
+ filled
/>
@@ -195,8 +180,7 @@ onMounted(async () => {
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -221,7 +205,7 @@ en:
attenderFk: Atender
clientFk: Client id
warehouseFk: Warehouse
- requesterFk: Salesperson
+ requesterFk: Requester
from: From
to: To
mine: For me
@@ -239,7 +223,7 @@ es:
attenderFk: Comprador
clientFk: Id cliente
warehouseFk: Almacén
- requesterFk: Comercial
+ requesterFk: Solicitante
from: Desde
to: Hasta
mine: Para mi
diff --git a/src/pages/Item/ItemType/Card/ItemTypeCard.vue b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
index 84e810de5..bd41b1be2 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeCard.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
@@ -1,11 +1,11 @@
- {
});
-
@@ -45,5 +46,5 @@ const entityId = computed(() => {
:value="entity.category?.name"
/>
-
+
diff --git a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
index 3b63c4b63..ba294e144 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
@@ -7,6 +7,7 @@ import filter from './ItemTypeFilter.js';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
onUpdated(() => summaryRef.value.fetch());
@@ -62,13 +63,10 @@ async function setItemTypeData(data) {
-
+
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index 9d27fc96e..ff8df26d4 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -84,7 +84,7 @@ item:
attenderFk: Atender
clientFk: Client id
warehouseFk: Warehouse
- requesterFk: Salesperson
+ requesterFk: Requester
from: From
to: To
mine: For me
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 935f5160b..7b768d0cb 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -93,7 +93,7 @@ item:
attenderFk: Comprador
clientFk: Id cliente
warehouseFk: Almacén
- requesterFk: Comercial
+ requesterFk: Solicitante
from: Desde
to: Hasta
mine: Para mi
diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
index c1958cdcb..2ba5f4c0b 100644
--- a/src/pages/Monitor/MonitorClients.vue
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -1,19 +1,22 @@
@@ -121,6 +123,8 @@ const columns = computed(() => [
:disable-option="{ card: true }"
dense
class="q-px-none"
+ :row-click="({ id }) => openTab(id)"
+ :row-ctrl-click="(_, { id }) => openTab(id)"
>
@@ -128,13 +132,17 @@ const columns = computed(() => [
-
-
-
+
+
+ {{ row.department }}
+
-
-
+
+ {{ row.clientName }}
+
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
index 873f8abb4..bdfcf3837 100644
--- a/src/pages/Monitor/MonitorOrders.vue
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -1,14 +1,15 @@
}"
default-mode="table"
:row-click="({ id }) => openTab(id)"
+ :row-ctrl-click="(_, { id }) => openTab(id)"
v-model:selected="selectedRows"
:disable-option="{ card: true }"
>
@@ -179,17 +178,16 @@ const openTab = (id) =>
-
-
-
-
+
+ {{ row.clientName }}
+
-
-
-
-
-
-
+
+
+ {{ row.departmentName }}
+
diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
index 48710d696..1cadd4cb4 100644
--- a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
+++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
@@ -9,7 +9,6 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import FetchData from 'src/components/FetchData.vue';
import { dateRange } from 'src/filters';
-import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
defineProps({ dataKey: { type: String, required: true } });
const { t, te } = useI18n();
@@ -78,7 +77,7 @@ const getLocale = (label) => {
@@ -87,7 +86,7 @@ const getLocale = (label) => {
@@ -96,7 +95,7 @@ const getLocale = (label) => {
handleScopeDays(params, val)"
@remove="(val) => handleScopeDays(params, val)"
/>
@@ -107,66 +106,54 @@ const getLocale = (label) => {
-
-
+ filled
+ :label="t('globals.params.departmentFk')"
+ v-model="params.departmentFk"
+ url="Departments"
+ />
-
+
{
{
{
{
-
-
-
-
- [
},
},
{
- label: t('salesClientsTable.salesPerson'),
- name: 'salesPersonFk',
- field: 'userName',
align: 'left',
- columnFilter: {
- component: 'select',
- attrs: {
- url: 'Workers/search?departmentCodes=["VT"]',
- fields: ['id', 'name', 'nickname', 'code'],
- sortBy: 'nickname ASC',
- optionLabel: 'nickname',
- },
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
},
+ create: true,
+ columnField: {
+ component: null,
+ },
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('salesClientsTable.date'),
@@ -437,10 +436,10 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`);
-
-
-
-
+
+
+
+
@@ -450,21 +449,19 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`);
-
-
- {{ row.refFk }}
-
-
-
- {{ row.state }}
-
+
+ {{ row.refFk }}
+
+
+ {{ row.state }}
+
diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml
index c049a5e53..a9ce36ffd 100644
--- a/src/pages/Monitor/locale/en.yml
+++ b/src/pages/Monitor/locale/en.yml
@@ -7,7 +7,6 @@ salesClientsTable:
to: To
date: Date
hour: Hour
- salesPerson: Salesperson
client: Client
salesOrdersTable:
delete: Delete
diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml
index a02d7f36f..6086eda6b 100644
--- a/src/pages/Monitor/locale/es.yml
+++ b/src/pages/Monitor/locale/es.yml
@@ -7,7 +7,6 @@ salesClientsTable:
to: Hasta
date: Fecha
hour: Hora
- salesPerson: Comercial
client: Cliente
salesOrdersTable:
delete: Eliminar
diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue
index d1bd48c9e..10273a254 100644
--- a/src/pages/Order/Card/CatalogFilterValueDialog.vue
+++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue
@@ -57,9 +57,8 @@ const getSelectedTagValues = async (tag) => {
option-value="id"
option-label="name"
dense
- outlined
class="q-mb-md"
- rounded
+ filled
:emit-value="false"
use-input
@update:model-value="getSelectedTagValues"
@@ -79,8 +78,7 @@ const getSelectedTagValues = async (tag) => {
option-value="value"
option-label="value"
dense
- outlined
- rounded
+ filled
emit-value
use-input
:disable="!value || !selectedTag"
@@ -92,16 +90,14 @@ const getSelectedTagValues = async (tag) => {
v-model="value.value"
:label="t('components.itemsFilterPanel.value')"
:disable="!value"
- is-outlined
class="col"
data-cy="catalogFilterValueDialogValueInput"
/>
{
!data.isConfirmed &&
agencyList?.length &&
agencyList.some(
- (agency) => agency.agencyModeFk === data.agency_id
+ (agency) => agency.agencyModeFk === data.agency_id,
)
? data.agencyModeFk
: null
diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue
index ad5c73a87..11dbbe532 100644
--- a/src/pages/Order/Card/OrderCard.vue
+++ b/src/pages/Order/Card/OrderCard.vue
@@ -1,14 +1,16 @@
-
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index d16a92017..cb380c48f 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -221,8 +221,7 @@ function addOrder(value, field, params) {
option-value="id"
option-label="name"
dense
- outlined
- rounded
+ filled
emit-value
use-input
sort-by="name ASC"
@@ -251,8 +250,7 @@ function addOrder(value, field, params) {
v-model="orderBySelected"
:options="orderByList"
dense
- outlined
- rounded
+ filled
@update:model-value="(value) => addOrder(value, 'field', params)"
/>
@@ -264,8 +262,7 @@ function addOrder(value, field, params) {
v-model="orderWaySelected"
:options="orderWayList"
dense
- outlined
- rounded
+ filled
@update:model-value="(value) => addOrder(value, 'way', params)"
/>
@@ -275,8 +272,7 @@ function addOrder(value, field, params) {
onSearchByTag(val, params)"
diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue
index 0d18864dc..ee66bb57e 100644
--- a/src/pages/Order/Card/OrderDescriptor.vue
+++ b/src/pages/Order/Card/OrderDescriptor.vue
@@ -4,11 +4,11 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { toCurrency, toDate } from 'src/filters';
import { useState } from 'src/composables/useState';
-import filter from './OrderFilter.js';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import FetchData from 'components/FetchData.vue';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import OrderCard from './OrderCard.vue';
+import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
const DEFAULT_ITEMS = 0;
@@ -24,11 +24,14 @@ const route = useRoute();
const state = useState();
const { t } = useI18n();
const getTotalRef = ref();
+const total = ref(0);
const entityId = computed(() => {
return $props.id || route.params.id;
});
+const orderTotal = computed(() => state.get('orderTotal') ?? 0);
+
const setData = (entity) => {
if (!entity) return;
getTotalRef.value && getTotalRef.value.fetch();
@@ -38,9 +41,6 @@ const setData = (entity) => {
const getConfirmationValue = (isConfirmed) => {
return t(isConfirmed ? 'globals.confirmed' : 'order.summary.notConfirmed');
};
-
-const orderTotal = computed(() => state.get('orderTotal') ?? 0);
-const total = ref(0);
@@ -54,23 +54,23 @@ const total = ref(0);
"
/>
-
+
- {{ entity?.client?.salesPersonUser?.name || '-' }}
-
+ {{ entity?.client?.department?.name || '-' }}
+
diff --git a/src/pages/Order/Card/OrderDescriptorProxy.vue b/src/pages/Order/Card/OrderDescriptorProxy.vue
index 04ebb054a..1dff1b620 100644
--- a/src/pages/Order/Card/OrderDescriptorProxy.vue
+++ b/src/pages/Order/Card/OrderDescriptorProxy.vue
@@ -12,6 +12,11 @@ const $props = defineProps({
-
+
diff --git a/src/pages/Order/Card/OrderFilter.js b/src/pages/Order/Card/OrderFilter.js
index 3e521b92c..d45578529 100644
--- a/src/pages/Order/Card/OrderFilter.js
+++ b/src/pages/Order/Card/OrderFilter.js
@@ -10,14 +10,14 @@ export default {
relation: 'client',
scope: {
fields: [
- 'salesPersonFk',
+ 'departmentFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
- relation: 'salesPersonUser',
+ relation: 'department',
scope: { fields: ['id', 'name'] },
},
},
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index c387be241..5f91153ac 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -6,7 +6,6 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
-import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
const props = defineProps({
@@ -50,8 +49,7 @@ const sourceList = ref([]);
v-model="params.clientFk"
lazy-rules
dense
- outlined
- rounded
+ filled
/>
-
-
+
-
-
-
- {{ t('order.summary.basket') }} #{{ entity?.id }} -
- {{ entity?.client?.name }} ({{ entity?.clientFk }})
-
-
-
- {{ t('order.summary.confirmLines') }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ dashIfEmpty(entity?.address?.nickname) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ dashIfEmpty(entity?.address?.phone) }}
-
-
-
-
-
-
-
-
-
-
-
- {{ entity?.note }}
-
-
-
-
-
-
- {{ t('globals.subtotal') }}
-
-
- {{
- toCurrency(entity?.subTotal)
- }}
-
-
-
-
- {{ t('globals.vat') }}
-
-
- {{ toCurrency(entity?.VAT) }}
-
-
-
-
- {{ t('order.summary.total') }}
-
-
- {{ toCurrency(entity?.total) }}
-
-
-
-
-
-
-
-
- {{ t('globals.item') }}
- {{ t('globals.description') }}
- {{ t('globals.quantity') }}
- {{ t('globals.price') }}
- {{ t('order.summary.amount') }}
-
-
-
-
-
-
- {{ props.row.item?.id }}
-
-
-
-
-
-
- {{ props.row.item.name }}
-
- {{ props.row.item.subName }}
-
-
+
+
+ {{ t('order.summary.basket') }} #{{ entity?.id }} -
+ {{ entity?.client?.name }} ({{ entity?.clientFk }})
+
+
+
+ {{ t('order.summary.confirmLines') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dashIfEmpty(entity?.address?.nickname) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dashIfEmpty(entity?.address?.phone) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ entity?.note }}
+
+
+
+
+
+
+ {{ t('globals.subtotal') }}
+
+
+ {{ toCurrency(entity?.subTotal) }}
+
+
+
+
+ {{ t('globals.vat') }}
+
+
+ {{ toCurrency(entity?.VAT) }}
+
+
+
+
+ {{ t('order.summary.total') }}
+
+
+ {{ toCurrency(entity?.total) }}
+
+
+
+
+
+
+
+
+ {{ t('globals.item') }}
+ {{ t('globals.description') }}
+ {{ t('globals.quantity') }}
+ {{ t('globals.price') }}
+ {{ t('order.summary.amount') }}
+
+
+
+
+
+
+ {{ props.row.item?.id }}
+
+
+
+
+
+
+ {{ props.row.item.name }}
+
+ {{ props.row.item.subName }}
+
-
-
-
- {{ props.row.quantity }}
-
-
- {{ toCurrency(props.row.price) }}
-
-
- {{
- toCurrency(props.row?.quantity * props.row?.price)
- }}
-
-
-
-
-
-
-
-
+
+
+
+
+ {{ props.row.quantity }}
+
+
+ {{ toCurrency(props.row.price) }}
+
+
+ {{ toCurrency(props.row?.quantity * props.row?.price) }}
+
+
+
+
+
+
+
-
- es:
- isOwn: Tiene propietario
- isAnyVolumeAllowed: Permite cualquier volumen
- en:
- isOwn: Has owner
- isAnyVolumeAllowed: Allows any volume
-
diff --git a/src/pages/Route/Agency/Card/AgencyBasicData.vue b/src/pages/Route/Agency/Card/AgencyBasicData.vue
index 4270b136c..4f8f17163 100644
--- a/src/pages/Route/Agency/Card/AgencyBasicData.vue
+++ b/src/pages/Route/Agency/Card/AgencyBasicData.vue
@@ -21,7 +21,7 @@ const warehouses = ref([]);
@on-fetch="(data) => (warehouses = data)"
auto-load
/>
-
+
diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
index 7dc31f8ba..9fd3fe5e5 100644
--- a/src/pages/Route/Agency/Card/AgencyCard.vue
+++ b/src/pages/Route/Agency/Card/AgencyCard.vue
@@ -1,7 +1,7 @@
-
+
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptor.vue b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
index a0472c6c3..64b33cc06 100644
--- a/src/pages/Route/Agency/Card/AgencyDescriptor.vue
+++ b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
@@ -3,7 +3,7 @@ import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'components/ui/VnLv.vue';
const props = defineProps({
@@ -17,18 +17,19 @@ const props = defineProps({
const { t } = useI18n();
const route = useRoute();
const entityId = computed(() => props.id || route.params.id);
-const { store } = useArrayData('Parking');
+const { store } = useArrayData();
const card = computed(() => store.data);
-
-
+
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue b/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue
new file mode 100644
index 000000000..e5c1249b2
--- /dev/null
+++ b/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/pages/Route/Agency/Card/AgencySummary.vue b/src/pages/Route/Agency/Card/AgencySummary.vue
index 71a6d1066..ab274939a 100644
--- a/src/pages/Route/Agency/Card/AgencySummary.vue
+++ b/src/pages/Route/Agency/Card/AgencySummary.vue
@@ -6,29 +6,31 @@ import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'components/ui/VnLv.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
+import VnCheckbox from 'components/common/VnCheckbox.vue';
+const route = useRoute();
const $props = defineProps({ id: { type: Number, default: 0 } });
const { t } = useI18n();
-const entityId = computed(() => $props.id || useRoute().params.id);
+const entityId = computed(() => $props.id || route.params.id);
-
+
{{ agency.name }}
-
-
diff --git a/src/pages/Route/Agency/locale/en.yml b/src/pages/Route/Agency/locale/en.yml
index 93f8b4aaa..78a687f2e 100644
--- a/src/pages/Route/Agency/locale/en.yml
+++ b/src/pages/Route/Agency/locale/en.yml
@@ -1,11 +1,12 @@
agency:
search: Search agency
- searchInfo: You can search by name
+ searchInfo: You can search by name and by id
isOwn: Own
isAnyVolumeAllowed: Any volume allowed
+ removeItem: Agency removed successfully
notification:
- removeItemError: Error removing agency
- removeItem: WorkCenter removed successfully
+ removeItemError: Error removing work center
+ removeItem: Work center removed successfully
pageTitles:
agency: Agency
searchBar:
diff --git a/src/pages/Route/Agency/locale/es.yml b/src/pages/Route/Agency/locale/es.yml
index 1efed0e9c..b6237a9f7 100644
--- a/src/pages/Route/Agency/locale/es.yml
+++ b/src/pages/Route/Agency/locale/es.yml
@@ -1,15 +1,14 @@
agency:
search: Buscar agencia
- searchInfo: Puedes buscar por nombre
+ searchInfo: Puedes buscar por nombre y por id
isOwn: Propio
isAnyVolumeAllowed: Cualquier volumen
removeItem: Agencia eliminada correctamente
notification:
- removeItemError: Error al eliminar la agencia
+ removeItemError: Error al eliminar la el centro de trabajo
removeItem: Centro de trabajo eliminado correctamente
pageTitles:
agency: Agencia
searchBar:
info: Puedes buscar por nombre o id
label: Buscar agencia...
-
diff --git a/src/pages/Route/Card/RouteAutonomousFilter.vue b/src/pages/Route/Card/RouteAutonomousFilter.vue
index f70f60e1c..fe631a0be 100644
--- a/src/pages/Route/Card/RouteAutonomousFilter.vue
+++ b/src/pages/Route/Card/RouteAutonomousFilter.vue
@@ -71,7 +71,7 @@ const exprBuilder = (param, value) => {
-
+
@@ -83,8 +83,7 @@ const exprBuilder = (param, value) => {
option-value="id"
option-label="name"
dense
- outlined
- rounded
+ filled
emit-value
map-options
use-input
@@ -102,8 +101,7 @@ const exprBuilder = (param, value) => {
option-value="id"
option-label="name"
dense
- outlined
- rounded
+ filled
emit-value
map-options
use-input
@@ -123,8 +121,7 @@ const exprBuilder = (param, value) => {
option-value="name"
option-label="name"
dense
- outlined
- rounded
+ filled
emit-value
map-options
use-input
@@ -135,20 +132,12 @@ const exprBuilder = (param, value) => {
-
+
-
+
@@ -156,7 +145,7 @@ const exprBuilder = (param, value) => {
@@ -166,23 +155,23 @@ const exprBuilder = (param, value) => {
-
+
-
+
-
+
@@ -190,7 +179,7 @@ const exprBuilder = (param, value) => {
diff --git a/src/pages/Route/Card/RouteCard.vue b/src/pages/Route/Card/RouteCard.vue
index c178dc6bf..b71f7d088 100644
--- a/src/pages/Route/Card/RouteCard.vue
+++ b/src/pages/Route/Card/RouteCard.vue
@@ -1,10 +1,10 @@
-
import { ref, computed, onMounted } from 'vue';
import { useRoute } from 'vue-router';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
+import useCardDescription from 'composables/useCardDescription';
import VnLv from 'components/ui/VnLv.vue';
import { dashIfEmpty, toDate } from 'src/filters';
import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
import filter from './RouteFilter.js';
-import useCardDescription from 'src/composables/useCardDescription';
import axios from 'axios';
const $props = defineProps({
@@ -27,23 +27,26 @@ const getZone = async () => {
const filter = {
where: { routeFk: $props.id ? $props.id : route.params.id },
};
- const { data } = await axios.get('Tickets/findOne', {
+ const { data } = await axios.get('Tickets/filter', {
params: {
filter: JSON.stringify(filter),
},
});
- zoneId.value = data.zoneFk;
+
+ if (!data.length) return;
+ const firstRecord = data[0];
+
+ zoneId.value = firstRecord.zoneFk;
const { data: zoneData } = await axios.get(`Zones/${zoneId.value}`);
zone.value = zoneData.name;
};
const data = ref(useCardDescription());
-const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
onMounted(async () => {
getZone();
});
- {
-
+
es:
diff --git a/src/pages/Route/Card/RouteDescriptorProxy.vue b/src/pages/Route/Card/RouteDescriptorProxy.vue
index 1ff39a51e..7553469f3 100644
--- a/src/pages/Route/Card/RouteDescriptorProxy.vue
+++ b/src/pages/Route/Card/RouteDescriptorProxy.vue
@@ -7,6 +7,10 @@ const $props = defineProps({
type: Number,
required: true,
},
+ summary: {
+ type: Object,
+ default: null,
+ },
});
diff --git a/src/pages/Route/Card/RouteFilter.vue b/src/pages/Route/Card/RouteFilter.vue
index 21858102b..f830b83e2 100644
--- a/src/pages/Route/Card/RouteFilter.vue
+++ b/src/pages/Route/Card/RouteFilter.vue
@@ -25,7 +25,7 @@ const emit = defineEmits(['search']);
>
- {{ t(`params.${tag.label}`) }}:
+ {{ t(`route.params.${tag.label}`) }}:
{{ formatFn(tag.value) }}
@@ -33,10 +33,10 @@ const emit = defineEmits(['search']);
@@ -44,15 +44,14 @@ const emit = defineEmits(['search']);
@@ -61,8 +60,8 @@ const emit = defineEmits(['search']);
@@ -72,8 +71,8 @@ const emit = defineEmits(['search']);
@@ -84,8 +83,8 @@ const emit = defineEmits(['search']);
-
+
@@ -136,8 +133,8 @@ const emit = defineEmits(['search']);
@@ -146,7 +143,7 @@ const emit = defineEmits(['search']);
@@ -154,38 +151,3 @@ const emit = defineEmits(['search']);
-
-
-en:
- params:
- warehouseFk: Warehouse
- description: Description
- m3: m³
- scopeDays: Days Onward
- vehicleFk: Vehicle
- agencyModeFk: Agency
- workerFk: Worker
- from: From
- to: To
- Served: Served
-es:
- params:
- warehouseFk: Almacén
- description: Descripción
- m3: m³
- scopeDays: Días en adelante
- vehicleFk: Vehículo
- agencyModeFk: Agencia
- workerFk: Trabajador
- from: Desde
- to: Hasta
- Warehouse: Almacén
- Description: Descripción
- Vehicle: Vehículo
- Agency: Agencia
- Worker: Trabajador
- From: Desde
- To: Hasta
- Served: Servida
- Days Onward: Días en adelante
-
diff --git a/src/pages/Route/Card/RouteSummary.vue b/src/pages/Route/Card/RouteSummary.vue
index 3051972b2..86bdbb5c5 100644
--- a/src/pages/Route/Card/RouteSummary.vue
+++ b/src/pages/Route/Card/RouteSummary.vue
@@ -135,77 +135,82 @@ const ticketColumns = ref([
-
-
-
-
-
-
-
-
-
- {{ dashIfEmpty(entity?.route?.worker?.user?.name) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ {{
+ dashIfEmpty(entity?.route?.worker?.user?.name)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ value }}
@@ -230,7 +235,7 @@ const ticketColumns = ref([
-
+
{{ value }}
@@ -238,7 +243,7 @@ const ticketColumns = ref([
-
+
{{ value }}
diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue
index b3eaf3b48..170f73bc0 100644
--- a/src/pages/Route/Cmr/CmrList.vue
+++ b/src/pages/Route/Cmr/CmrList.vue
@@ -2,28 +2,37 @@
import { onBeforeMount, onMounted, computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
+import { useRoute } from 'vue-router';
import { useSession } from 'src/composables/useSession';
import { toDateHourMin } from 'filters/index';
import { useStateStore } from 'src/stores/useStateStore';
-import axios from 'axios';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
+const route = useRoute();
const { t } = useI18n();
const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia();
const state = useStateStore();
-const warehouses = ref([]);
const selectedRows = ref([]);
+const dataKey = 'CmrList';
+const shipped = Date.vnNew();
+shipped.setHours(0, 0, 0, 0);
+shipped.setDate(shipped.getDate() - 1);
+const userParams = {
+ shipped: null,
+};
+
const columns = computed(() => [
{
align: 'left',
name: 'cmrFk',
- label: t('route.cmr.list.cmrFk'),
+ label: t('route.cmr.params.cmrFk'),
chip: {
condition: () => true,
},
@@ -32,62 +41,67 @@ const columns = computed(() => [
{
align: 'center',
name: 'hasCmrDms',
- label: t('route.cmr.list.hasCmrDms'),
+ label: t('route.cmr.params.hasCmrDms'),
component: 'checkbox',
cardVisible: true,
},
{
align: 'left',
- label: t('route.cmr.list.ticketFk'),
+ label: t('route.cmr.params.ticketFk'),
name: 'ticketFk',
},
{
align: 'left',
- label: t('route.cmr.list.routeFk'),
+ label: t('route.cmr.params.routeFk'),
name: 'routeFk',
},
{
align: 'left',
- label: t('route.cmr.list.clientFk'),
+ label: t('route.cmr.params.clientFk'),
name: 'clientFk',
},
{
align: 'right',
- label: t('route.cmr.list.country'),
+ label: t('route.cmr.params.countryFk'),
name: 'countryFk',
- cardVisible: true,
+ component: 'select',
attrs: {
url: 'countries',
fields: ['id', 'name'],
- optionLabel: 'name',
- optionValue: 'id',
},
columnFilter: {
- inWhere: true,
- component: 'select',
+ name: 'countryFk',
+ attrs: {
+ url: 'countries',
+ fields: ['id', 'name'],
+ },
},
format: ({ countryName }) => countryName,
},
{
align: 'right',
- label: t('route.cmr.list.shipped'),
+ label: t('route.cmr.params.shipped'),
name: 'shipped',
cardVisible: true,
- columnFilter: {
- component: 'date',
- inWhere: true,
- },
+ component: 'date',
format: ({ shipped }) => toDateHourMin(shipped),
},
{
align: 'right',
+ label: t('route.cmr.params.warehouseFk'),
name: 'warehouseFk',
- label: t('globals.warehouse'),
- columnFilter: {
- component: 'select',
- },
+ component: 'select',
attrs: {
- options: warehouses.value,
+ url: 'warehouses',
+ fields: ['id', 'name'],
+ },
+ columnFilter: {
+ inWhere: true,
+ name: 'warehouseFk',
+ attrs: {
+ url: 'warehouses',
+ fields: ['id', 'name'],
+ },
},
format: ({ warehouseName }) => warehouseName,
},
@@ -96,7 +110,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('Ver cmr'),
+ title: t('route.cmr.params.viewCmr'),
icon: 'visibility',
isPrimary: true,
action: (row) => window.open(getCmrUrl(row?.cmrFk), '_blank'),
@@ -105,13 +119,17 @@ const columns = computed(() => [
},
]);
-onBeforeMount(async () => {
- const { data } = await axios.get('Warehouses');
- warehouses.value = data;
+onBeforeMount(() => {
+ initializeFromQuery();
});
onMounted(() => (state.rightDrawer = true));
+const initializeFromQuery = () => {
+ const query = route.query.table ? JSON.parse(route.query.table) : {};
+ shipped.value = query.shipped || shipped.toISOString();
+ Object.assign(userParams, { shipped });
+};
function getApiUrl() {
return new URL(window.location).origin;
}
@@ -133,6 +151,11 @@ function downloadPdfs() {
}
+
- {{ t('route.cmr.list.downloadCmrs') }}
+ {{ t('route.cmr.params.downloadCmrs') }}
{
-import VnCardBeta from 'components/common/VnCardBeta.vue';
+import VnCard from 'components/common/VnCard.vue';
import RoadmapDescriptor from 'pages/Route/Roadmap/RoadmapDescriptor.vue';
-
+
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptor.vue b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
index baa864a15..dfa692feb 100644
--- a/src/pages/Route/Roadmap/RoadmapDescriptor.vue
+++ b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
@@ -2,7 +2,7 @@
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'components/ui/VnLv.vue';
import { dashIfEmpty, toDateHourMin } from 'src/filters';
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
@@ -15,6 +15,10 @@ const $props = defineProps({
required: false,
default: null,
},
+ summary: {
+ type: Object,
+ default: null,
+ },
});
const route = useRoute();
@@ -26,7 +30,13 @@ const entityId = computed(() => {
-
+
@@ -42,7 +52,7 @@ const entityId = computed(() => {
-
+
es:
diff --git a/src/pages/Route/Roadmap/RoadmapFilter.vue b/src/pages/Route/Roadmap/RoadmapFilter.vue
index 982f1efba..9acbfb740 100644
--- a/src/pages/Route/Roadmap/RoadmapFilter.vue
+++ b/src/pages/Route/Roadmap/RoadmapFilter.vue
@@ -31,12 +31,12 @@ const emit = defineEmits(['search']);
-
+
-
+
@@ -44,7 +44,7 @@ const emit = defineEmits(['search']);
@@ -54,7 +54,7 @@ const emit = defineEmits(['search']);
@@ -66,8 +66,7 @@ const emit = defineEmits(['search']);
:fields="['id', 'nickname']"
v-model="params.supplierFk"
dense
- outlined
- rounded
+ filled
emit-value
map-options
use-input
@@ -81,7 +80,7 @@ const emit = defineEmits(['search']);
v-model="params.price"
:label="t('Price')"
type="number"
- is-outlined
+ filled
clearable
/>
@@ -91,7 +90,7 @@ const emit = defineEmits(['search']);
@@ -101,7 +100,7 @@ const emit = defineEmits(['search']);
diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue
index 0c1c2b903..dcd02d98e 100644
--- a/src/pages/Route/Roadmap/RoadmapSummary.vue
+++ b/src/pages/Route/Roadmap/RoadmapSummary.vue
@@ -112,12 +112,9 @@ const filter = {
:label="t('Trailer Plate')"
:value="dashIfEmpty(entity?.trailerPlate)"
/>
-
+
-
- {{ dashIfEmpty(entity?.phone) }}
-
-
+
(stateStore.rightDrawer = false));
selection: 'multiple',
}"
>
-
+
- {{ row.routeFk }}
-
+ {{ row?.agencyModeName }}
+
+
+
+
+
+ {{ row?.agencyAgreement }}
+
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index a7e192765..c69492836 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -38,7 +38,7 @@ const routeFilter = {
};
const columns = computed(() => [
{
- align: 'center',
+ align: 'right',
name: 'id',
label: 'Id',
chip: {
@@ -48,9 +48,8 @@ const columns = computed(() => [
columnFilter: false,
},
{
- align: 'center',
name: 'workerFk',
- label: t('route.Worker'),
+ label: t('globals.worker'),
create: true,
component: 'select',
attrs: {
@@ -71,9 +70,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.workerUserName),
},
{
- align: 'center',
name: 'agencyModeFk',
- label: t('route.Agency'),
+ label: t('globals.agency'),
isTitle: true,
cardVisible: true,
create: true,
@@ -90,9 +88,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.agencyName),
},
{
- align: 'center',
name: 'vehicleFk',
- label: t('route.Vehicle'),
+ label: t('globals.vehicle'),
cardVisible: true,
create: true,
component: 'select',
@@ -111,9 +108,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.vehiclePlateNumber),
},
{
- align: 'center',
name: 'dated',
- label: t('route.Date'),
+ label: t('globals.date'),
columnFilter: false,
cardVisible: true,
create: true,
@@ -122,9 +118,8 @@ const columns = computed(() => [
dated === '0000-00-00' ? dashIfEmpty(null) : toDate(dated),
},
{
- align: 'center',
name: 'from',
- label: t('route.From'),
+ label: t('globals.from'),
visible: false,
cardVisible: true,
create: true,
@@ -132,9 +127,8 @@ const columns = computed(() => [
format: ({ from }) => toDate(from),
},
{
- align: 'center',
name: 'to',
- label: t('route.To'),
+ label: t('globals.to'),
visible: false,
cardVisible: true,
create: true,
@@ -142,14 +136,13 @@ const columns = computed(() => [
format: ({ date }) => toDate(date),
},
{
- align: 'center',
+ align: 'right',
name: 'm3',
label: 'm3',
cardVisible: true,
columnClass: 'shrink',
},
{
- align: 'center',
name: 'started',
label: t('route.hourStarted'),
component: 'time',
@@ -157,7 +150,6 @@ const columns = computed(() => [
format: ({ started }) => toHour(started),
},
{
- align: 'center',
name: 'finished',
label: t('route.hourFinished'),
component: 'time',
@@ -165,7 +157,7 @@ const columns = computed(() => [
format: ({ finished }) => toHour(finished),
},
{
- align: 'center',
+ align: 'right',
name: 'kmStart',
label: t('route.KmStart'),
columnClass: 'shrink',
@@ -173,7 +165,7 @@ const columns = computed(() => [
visible: false,
},
{
- align: 'center',
+ align: 'right',
name: 'kmEnd',
label: t('route.KmEnd'),
columnClass: 'shrink',
@@ -181,16 +173,15 @@ const columns = computed(() => [
visible: false,
},
{
- align: 'center',
+ align: 'left',
name: 'description',
- label: t('route.Description'),
+ label: t('globals.description'),
isTitle: true,
create: true,
component: 'input',
field: 'description',
},
{
- align: 'center',
name: 'isOk',
label: t('route.Served'),
component: 'checkbox',
@@ -202,7 +193,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('route.Add tickets'),
+ title: t('route.addTicket'),
icon: 'vn:ticketAdd',
action: (row) => openTicketsDialog(row?.id),
isPrimary: true,
@@ -214,7 +205,7 @@ const columns = computed(() => [
isPrimary: true,
},
{
- title: t('route.Route summary'),
+ title: t('route.routeSummary'),
icon: 'arrow_forward',
action: (row) => navigate(row?.id),
isPrimary: true,
@@ -276,11 +267,13 @@ const openTicketsDialog = (id) => {
- {{ t('route.Select the starting date') }}
+
+ {{ t('route.extendedList.selectStartingDate') }}
+
@@ -288,7 +281,7 @@ const openTicketsDialog = (id) => {
@@ -335,29 +328,34 @@ const openTicketsDialog = (id) => {
- {{ t('route.Clone Selected Routes') }}
+ {{ t('route.extendedList.cloneSelectedRoutes') }}
- {{ t('route.Download selected routes as PDF') }}
+ {{
+ t('route.extendedList.downloadSelectedRoutes')
+ }}
- {{ t('route.Mark as served') }}
+ {{ t('route.extendedList.markServed') }}
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index 5723e2f0d..810157683 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -3,14 +3,18 @@ import { computed, ref, markRaw } from 'vue';
import { useI18n } from 'vue-i18n';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { toHour } from 'src/filters';
+import { useRouter } from 'vue-router';
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import AgencyDescriptorProxy from 'src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue';
+import VehicleDescriptorProxy from 'src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
+const router = useRouter();
const { viewSummary } = useSummaryDialog();
const tableRef = ref([]);
const dataKey = 'RouteList';
@@ -24,6 +28,14 @@ const routeFilter = {
},
],
};
+
+function redirectToTickets(id) {
+ router.push({
+ name: 'RouteTickets',
+ params: { id },
+ });
+}
+
const columns = computed(() => [
{
align: 'right',
@@ -38,7 +50,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'workerFk',
- label: t('route.Worker'),
+ label: t('globals.worker'),
component: markRaw(VnSelectWorker),
create: true,
cardVisible: true,
@@ -46,13 +58,7 @@ const columns = computed(() => [
columnFilter: false,
},
{
- align: 'left',
- name: 'agencyName',
- label: t('route.Agency'),
- cardVisible: true,
- },
- {
- label: t('route.Agency'),
+ label: t('globals.agency'),
name: 'agencyModeFk',
component: 'select',
attrs: {
@@ -64,19 +70,12 @@ const columns = computed(() => [
},
},
create: true,
- columnFilter: false,
- visible: false,
- },
- {
- align: 'left',
- name: 'vehiclePlateNumber',
- label: t('route.Vehicle'),
+ columnFilter: true,
cardVisible: true,
},
{
name: 'vehicleFk',
- label: t('route.Vehicle'),
- cardVisible: true,
+ label: t('globals.vehicle'),
component: 'select',
attrs: {
url: 'vehicles',
@@ -89,29 +88,29 @@ const columns = computed(() => [
},
},
create: true,
- columnFilter: false,
- visible: false,
+ columnFilter: true,
+ cardVisible: true,
},
{
- align: 'left',
+ align: 'center',
name: 'started',
label: t('route.hourStarted'),
cardVisible: true,
columnFilter: false,
- format: (row) => toHour(row.started),
+ format: ({ started }) => toHour(started),
},
{
- align: 'left',
+ align: 'center',
name: 'finished',
label: t('route.hourFinished'),
cardVisible: true,
columnFilter: false,
- format: (row) => toHour(row.started),
+ format: ({ finished }) => toHour(finished),
},
{
align: 'left',
name: 'description',
- label: t('route.Description'),
+ label: t('globals.description'),
cardVisible: true,
isTitle: true,
create: true,
@@ -119,7 +118,6 @@ const columns = computed(() => [
columnFilter: false,
},
{
- align: 'left',
name: 'isOk',
label: t('route.Served'),
component: 'checkbox',
@@ -130,6 +128,12 @@ const columns = computed(() => [
align: 'right',
name: 'tableActions',
actions: [
+ {
+ title: t('globals.pageTitles.tickets'),
+ icon: 'vn:ticket',
+ action: (row) => redirectToTickets(row?.id),
+ isPrimary: true,
+ },
{
title: t('components.smartCard.viewSummary'),
icon: 'preview',
@@ -155,9 +159,10 @@ const columns = computed(() => [
+
+
+ {{ row?.agencyName }}
+
+
+
+
+
+ {{ row?.vehiclePlateNumber }}
+
+
+
diff --git a/src/pages/Route/RouteRoadmap.vue b/src/pages/Route/RouteRoadmap.vue
index 23b1b1d5b..bdb3d12c4 100644
--- a/src/pages/Route/RouteRoadmap.vue
+++ b/src/pages/Route/RouteRoadmap.vue
@@ -2,13 +2,11 @@
import { useI18n } from 'vue-i18n';
import { computed, ref } from 'vue';
import { dashIfEmpty } from 'src/filters';
-import { toDate, toDateHourMin } from 'filters/index';
+import { toDate, toDateHourMin, toCurrency } from 'filters/index';
import { useQuasar } from 'quasar';
import { useSummaryDialog } from 'composables/useSummaryDialog';
-import toCurrency from 'filters/toCurrency';
import axios from 'axios';
-import VnSearchbar from 'components/ui/VnSearchbar.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import RoadmapSummary from 'pages/Route/Roadmap/RoadmapSummary.vue';
@@ -17,6 +15,8 @@ import VnInputDate from 'components/common/VnInputDate.vue';
import VnInputTime from 'src/components/common/VnInputTime.vue';
import VnSection from 'src/components/common/VnSection.vue';
import RoadmapFilter from './Roadmap/RoadmapFilter.vue';
+import VehicleDescriptorProxy from 'src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue';
+import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
const { viewSummary } = useSummaryDialog();
const { t } = useI18n();
@@ -33,7 +33,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'name',
- label: t('Roadmap'),
+ label: t('route.roadmap.roadmap'),
create: true,
cardVisible: true,
columnFilter: {
@@ -41,9 +41,9 @@ const columns = computed(() => [
},
},
{
- align: 'left',
+ align: 'center',
name: 'etd',
- label: t('ETD'),
+ label: t('route.roadmap.etd'),
component: 'date',
columnFilter: {
inWhere: true,
@@ -54,7 +54,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'supplierFk',
- label: t('Carrier'),
+ label: t('route.roadmap.carrier'),
component: 'select',
attrs: {
url: 'suppliers',
@@ -65,21 +65,21 @@ const columns = computed(() => [
},
{
name: 'tractorPlate',
- label: t('Plate'),
+ label: t('route.roadmap.vehicle'),
field: (row) => row.tractorPlate,
sortable: true,
align: 'left',
},
{
name: 'price',
- label: t('Price'),
- field: (row) => toCurrency(row.price),
+ label: t('route.roadmap.price'),
+ format: ({ price }) => toCurrency(price),
sortable: true,
- align: 'left',
+ align: 'right',
},
{
name: 'observations',
- label: t('Observations'),
+ label: t('route.roadmap.observations'),
field: (row) => dashIfEmpty(row.observations),
sortable: true,
align: 'left',
@@ -89,7 +89,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('Ver cmr'),
+ title: t('route.roadmap.seeCmr'),
icon: 'preview',
isPrimary: true,
action: (row) => viewSummary(row?.id, RoadmapSummary),
@@ -124,8 +124,8 @@ function confirmRemove() {
.dialog({
component: VnConfirm,
componentProps: {
- title: t('Selected roadmaps will be removed'),
- message: t('Are you sure you want to continue?'),
+ title: t('route.roadmap.selectedRoadmapsRemoved'),
+ message: t('route.roadmap.areYouSure'),
promise: removeSelection,
},
})
@@ -157,15 +157,24 @@ function exprBuilder(param, value) {
- {{ t('Select the estimated date of departure (ETD)') }}
+ {{ t('route.roadmap.selectEtd') }}
-
+
-
+
{{ t('globals.clone') }}
@@ -181,7 +190,7 @@ function exprBuilder(param, value) {
:disable="!selectedRows?.length"
@click="isCloneDialogOpen = true"
>
- {{ t('Clone Selected Routes') }}
+ {{ t('route.roadmap.cloneSelected') }}
- {{ t('Delete roadmap(s)') }}
+ {{ t('route.roadmap.deleteRoadmap') }}
@@ -204,7 +213,7 @@ function exprBuilder(param, value) {
}"
>
-
+
- {{ row.supplierFk }}
+
+ {{ row.driverName }}
+
+
@@ -251,21 +263,3 @@ function exprBuilder(param, value) {
gap: 12px;
}
-
-es:
- Create routemap: Crear troncal
- Search roadmaps: Buscar troncales
- You can search by roadmap reference: Puedes buscar por referencia del troncal
- Delete roadmap(s): Eliminar troncal(es)
- Selected roadmaps will be removed: Los troncales seleccionadas serán eliminados
- Are you sure you want to continue?: ¿Seguro que quieres continuar?
- The date can't be empty: La fecha no puede estar vacía
- Clone Selected Routes: Clonar rutas seleccionadas
- Create roadmap: Crear troncal
- Roadmap: Troncal
- Carrier: Transportista
- Plate: Matrícula
- Price: Precio
- Observations: Observaciones
- Select the estimated date of departure (ETD): Selecciona la fecha estimada de salida
-
diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue
index c056a0b3d..5e28bb689 100644
--- a/src/pages/Route/RouteTickets.vue
+++ b/src/pages/Route/RouteTickets.vue
@@ -30,16 +30,16 @@ const columns = computed(() => [
align: 'center',
},
{
- name: 'street',
- label: t('Street'),
- field: (row) => row?.street,
+ name: 'client',
+ label: t('Client'),
+ field: (row) => row?.nickname,
sortable: false,
align: 'left',
},
{
- name: 'city',
- label: t('City'),
- field: (row) => row?.city,
+ name: 'street',
+ label: t('Street'),
+ field: (row) => row?.street,
sortable: false,
align: 'left',
},
@@ -51,9 +51,9 @@ const columns = computed(() => [
align: 'center',
},
{
- name: 'client',
- label: t('Client'),
- field: (row) => row?.nickname,
+ name: 'city',
+ label: t('City'),
+ field: (row) => row?.city,
sortable: false,
align: 'left',
},
@@ -329,7 +329,7 @@ const openSmsDialog = async () => {
selection="multiple"
>
-
+
{
-
+
{{ value }}
{{ t('Open buscaman') }}
@@ -359,7 +359,7 @@ const openSmsDialog = async () => {
-
+
{{ value }}
diff --git a/src/pages/Route/Vehicle/Card/VehicleCard.vue b/src/pages/Route/Vehicle/Card/VehicleCard.vue
index f59420aa2..b6038c24c 100644
--- a/src/pages/Route/Vehicle/Card/VehicleCard.vue
+++ b/src/pages/Route/Vehicle/Card/VehicleCard.vue
@@ -1,10 +1,10 @@
-
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
import VnLv from 'src/components/ui/VnLv.vue';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
const { notify } = useNotify();
+
+const props = defineProps({
+ id: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+});
+
+const route = useRoute();
+const entityId = computed(() => props.id || route.params.id);
-
-
+
es:
diff --git a/src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue b/src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue
new file mode 100644
index 000000000..cc0943cb8
--- /dev/null
+++ b/src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/pages/Route/Vehicle/Card/VehicleNotes.vue b/src/pages/Route/Vehicle/Card/VehicleNotes.vue
new file mode 100644
index 000000000..0afc3c3ed
--- /dev/null
+++ b/src/pages/Route/Vehicle/Card/VehicleNotes.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
diff --git a/src/pages/Route/Vehicle/Card/VehicleSummary.vue b/src/pages/Route/Vehicle/Card/VehicleSummary.vue
index e4b0a9497..13d4bbc9d 100644
--- a/src/pages/Route/Vehicle/Card/VehicleSummary.vue
+++ b/src/pages/Route/Vehicle/Card/VehicleSummary.vue
@@ -13,12 +13,13 @@ const props = defineProps({ id: { type: [Number, String], default: null } });
const route = useRoute();
const entityId = computed(() => props.id || +route.params.id);
+const baseLink = `#/${route.meta.moduleName.toLowerCase()}/vehicle/${entityId.value}`;
const links = {
- 'basic-data': `#/vehicle/${entityId.value}/basic-data`,
- notes: `#/vehicle/${entityId.value}/notes`,
- dms: `#/vehicle/${entityId.value}/dms`,
- 'invoice-in': `#/vehicle/${entityId.value}/invoice-in`,
- events: `#/vehicle/${entityId.value}/events`,
+ 'basic-data': `${baseLink}/basic-data`,
+ notes: `${baseLink}/notes`,
+ dms: `${baseLink}/dms`,
+ 'invoice-in': `${baseLink}/invoice-in`,
+ events: `${baseLink}/events`,
};
@@ -54,7 +55,10 @@ const links = {
{{ entity.supplier?.name }}
-
+
@@ -63,6 +67,7 @@ const links = {
{{ entity.supplierCooler?.name }}
diff --git a/src/pages/Route/Vehicle/VehicleList.vue b/src/pages/Route/Vehicle/VehicleList.vue
index e5b945010..a79cc2e35 100644
--- a/src/pages/Route/Vehicle/VehicleList.vue
+++ b/src/pages/Route/Vehicle/VehicleList.vue
@@ -116,6 +116,7 @@ const columns = computed(() => [
title: t('components.smartCard.openSummary'),
icon: 'preview',
action: (row) => viewSummary(row.id, VehicleSummary),
+ isPrimary: true,
},
],
},
diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml
index cc445f412..e7e2d691e 100644
--- a/src/pages/Route/locale/en.yml
+++ b/src/pages/Route/locale/en.yml
@@ -1,48 +1,79 @@
route:
+ filter:
+ Served: Served
+ extendedList:
+ selectStartingDate: Select the starting date
+ startingDate: Starting date
+ cloneSelectedRoutes: Clone selected routes
+ downloadSelectedRoutes: Download selected routes as PDF
+ markServed: Mark as served
roadmap:
+ roadmap: Roadmap
+ carrier: Carrier
+ vehicle: Vehicle
+ price: Price
+ observations: Observations
+ etd: ETD
+ dateCantEmpty: The date can't be empty
+ createRoadmap: Create roadmap
+ deleteRoadmap: Delete roadmap(s)
+ cloneSelected: Clone selected routes
+ selectedRoadmapsRemoved: Selected roadmaps will be removed
+ areYouSure: Are you sure you want to continue?
+ selectEtd: Select the estimated date of departure (ETD)
search: Search roadmap
searchInfo: You can search by roadmap reference
params:
+ warehouseFk: Warehouse
+ description: Description
+ m3: m³
+ scopeDays: Days Onward
+ vehicleFk: Vehicle
+ agencyModeFk: Agency
+ workerFk: Worker
+ from: From
+ to: To
+ isOk: Served
etd: ETD
tractorPlate: Plate
price: Price
observations: Observations
- id: ID
+ id: Id
name: Name
cmrFk: CMR id
hasCmrDms: Attached in gestdoc
ticketFk: Ticketd id
routeFk: Route id
+ clientFk: Client id
+ countryFk: Country
shipped: Shipped
agencyAgreement: Agency agreement
agencyModeName: Agency route
+ isOwn: Own
+ isAnyVolumeAllowed: Any volume allowed
Worker: Worker
Agency: Agency
Vehicle: Vehicle
Description: Description
hourStarted: H.Start
hourFinished: H.End
- dated: Dated
- From: From
- To: To
+ createRoute: Create route
Date: Date
KmStart: Km start
KmEnd: Km end
Served: Served
- Clone Selected Routes: Clone selected routes
- Select the starting date: Select the starting date
- Stating date: Starting date
- Cancel: Cancel
- Mark as served: Mark as served
- Download selected routes as PDF: Download selected routes as PDF
- Add ticket: Add ticket
- Summary: Summary
+ addTicket: Add ticket
+ routeSummary: Go to summary
Route is closed: Route is closed
Route is not served: Route is not served
search: Search route
searchInfo: You can search by route reference
+ dated: Dated
+ preview: Preview
cmr:
- list:
+ search: Search Cmr
+ searchInfo: You can search Cmr by Id
+ params:
results: results
cmrFk: CMR id
hasCmrDms: Attached in gestdoc
@@ -50,8 +81,10 @@ route:
'false': 'No'
ticketFk: Ticketd id
routeFk: Route id
- country: Country
+ countryFk: Country
clientFk: Client id
+ warehouseFk: Warehouse
shipped: Preparation date
viewCmr: View CMR
- downloadCmrs: Download CMRs
\ No newline at end of file
+ downloadCmrs: Download CMRs
+ search: General search
diff --git a/src/pages/Route/locale/es.yml b/src/pages/Route/locale/es.yml
index 51d43774a..2785ded31 100644
--- a/src/pages/Route/locale/es.yml
+++ b/src/pages/Route/locale/es.yml
@@ -1,21 +1,57 @@
route:
+ filter:
+ Served: Servida
+ extendedList:
+ selectStartingDate: Seleccione la fecha de inicio
+ statingDate: Fecha de inicio
+ cloneSelectedRoutes: Clonar rutas seleccionadas
+ downloadSelectedRoutes: Descargar rutas seleccionadas como PDF
+ markServed: Marcar como servidas
roadmap:
+ roadmap: Troncal
+ carrier: Transportista
+ vehicle: Vehículo
+ price: Precio
+ observations: Observaciones
+ etd: ETD
+ dateCantEmpty: La fecha no puede estar vacía
+ createRoadmap: Crear troncal
+ deleteRoadmap: Eliminar troncal(es)
+ cloneSelected: Clonar rutas seleccionadas
+ selectedRoadmapsRemoved: Los troncales seleccionadas serán eliminados
+ areYouSure: ¿Seguro que quieres continuar?
+ selectEtd: Selecciona la fecha estimada de salida
search: Buscar troncales
searchInfo: Puedes buscar por referencia del troncal
params:
- agencyModeName: Agencia Ruta
- agencyAgreement: Agencia Acuerdo
- id: Id
- name: Troncal
+ warehouseFk: Almacén
+ description: Descripción
+ m3: m³
+ scopeDays: Días adelante
+ vehicleFk: Vehículo
+ agencyModeFk: Agencia
+ workerFk: Trabajador
+ from: Desde
+ to: Hasta
+ isOk: Servida
etd: ETD
tractorPlate: Matrícula
price: Precio
observations: Observaciones
+ id: Id
+ name: Troncal
cmrFk: Id CMR
hasCmrDms: Gestdoc
+ search: Búsqueda general
ticketFk: Id ticket
- routeFK: Id ruta
+ routeFk: Id ruta
+ clientFk: Id cliente
+ countryFk: Pais
shipped: Fecha preparación
+ agencyModeName: Agencia Ruta
+ agencyAgreement: Agencia Acuerdo
+ isOwn: Propio
+ isAnyVolumeAllowed: Cualquier volumen
Worker: Trabajador
Agency: Agencia
Vehicle: Vehículo
@@ -23,25 +59,18 @@ route:
hourStarted: H.Inicio
hourFinished: H.Fin
createRoute: Crear ruta
- From: Desde
- To: Hasta
Date: Fecha
KmStart: Km inicio
KmEnd: Km fin
Served: Servida
- Clone Selected Routes: Clonar rutas seleccionadas
- Select the starting date: Seleccione la fecha de inicio
- Stating date: Fecha de inicio
- Cancel: Cancelar
- Mark as served: Marcar como servidas
- Download selected routes as PDF: Descargar rutas seleccionadas como PDF
- Add ticket: Añadir tickets
- preview: Vista previa
- Summary: Resumen
+ addTicket: Añadir tickets
+ routeSummary: Ir a vista previa
Route is closed: La ruta está cerrada
Route is not served: La ruta no está servida
search: Buscar rutas
searchInfo: Puedes buscar por referencia de la ruta
+ dated: Fecha
+ preview: Vista previa
cmr:
list:
results: resultados
@@ -55,4 +84,4 @@ route:
clientFk: Id cliente
shipped: Fecha preparación
viewCmr: Ver CMR
- downloadCmrs: Descargar CMRs
\ No newline at end of file
+ downloadCmrs: Descargar CMRs
diff --git a/src/pages/Shelving/Card/ShelvingCard.vue b/src/pages/Shelving/Card/ShelvingCard.vue
index 9e0ac8ad2..e2fb79fb0 100644
--- a/src/pages/Shelving/Card/ShelvingCard.vue
+++ b/src/pages/Shelving/Card/ShelvingCard.vue
@@ -1,11 +1,11 @@
- {
});
- {
-
+
diff --git a/src/pages/Shelving/Card/ShelvingFilter.vue b/src/pages/Shelving/Card/ShelvingFilter.vue
index 56cf4f58c..35657a972 100644
--- a/src/pages/Shelving/Card/ShelvingFilter.vue
+++ b/src/pages/Shelving/Card/ShelvingFilter.vue
@@ -2,6 +2,7 @@
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
const props = defineProps({
@@ -38,27 +39,14 @@ const emit = defineEmits(['search']);
option-label="code"
:filter-options="['id', 'code']"
dense
- outlined
- rounded
+ filled
sort-by="code ASC"
/>
-
+
diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue
index f89ff4d78..4a6669624 100644
--- a/src/pages/Shelving/Card/ShelvingSummary.vue
+++ b/src/pages/Shelving/Card/ShelvingSummary.vue
@@ -6,6 +6,7 @@ import VnLv from 'components/ui/VnLv.vue';
import VnUserLink from 'components/ui/VnUserLink.vue';
import filter from './ShelvingFilter.js';
import ShelvingDescriptorMenu from './ShelvingDescriptorMenu.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
const $props = defineProps({
id: {
@@ -38,13 +39,10 @@ const entityId = computed(() => $props.id || route.params.id);
-
+
-import VnCardBeta from 'components/common/VnCardBeta.vue';
+import VnCard from 'components/common/VnCard.vue';
import ParkingDescriptor from 'pages/Shelving/Parking/Card/ParkingDescriptor.vue';
import filter from './ParkingFilter.js';
-
import { computed } from 'vue';
import { useRoute } from 'vue-router';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'components/ui/VnLv.vue';
import filter from './ParkingFilter.js';
const props = defineProps({
@@ -16,17 +16,17 @@ const route = useRoute();
const entityId = computed(() => props.id || route.params.id);
-
-
+
diff --git a/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue
new file mode 100644
index 000000000..e78a2b238
--- /dev/null
+++ b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/src/pages/Shelving/Parking/Card/ParkingSummary.vue b/src/pages/Shelving/Parking/Card/ParkingSummary.vue
index 7188ebeb6..1365c71ca 100644
--- a/src/pages/Shelving/Parking/Card/ParkingSummary.vue
+++ b/src/pages/Shelving/Parking/Card/ParkingSummary.vue
@@ -4,6 +4,7 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'components/ui/VnLv.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
const $props = defineProps({
id: {
@@ -28,13 +29,10 @@ const filter = {
-
+
-
+
@@ -51,8 +47,7 @@ const emit = defineEmits(['search']);
option-label="description"
:label="t('params.sectorFk')"
dense
- outlined
- rounded
+ filled
:options="sectors"
use-input
input-debounce="0"
diff --git a/src/pages/Shelving/ShelvingList.vue b/src/pages/Shelving/ShelvingList.vue
index 4e0c21100..651121de8 100644
--- a/src/pages/Shelving/ShelvingList.vue
+++ b/src/pages/Shelving/ShelvingList.vue
@@ -1,14 +1,17 @@
@@ -37,48 +87,75 @@ function navigate(id) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('shelving.list.newShelving') }}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ es:
+ shelving:
+ list:
+ parking: Estacionamiento
+ priority: Prioridad
+
+ summary:
+ recyclable: Reciclable
+ en:
+ shelving:
+ list:
+ parking: Parking
+ priority: Priority
+
+ summary:
+ recyclable: Recyclable
+
diff --git a/src/pages/Supplier/Card/SupplierBalanceFilter.vue b/src/pages/Supplier/Card/SupplierBalanceFilter.vue
index c4b63d9c8..c727688ad 100644
--- a/src/pages/Supplier/Card/SupplierBalanceFilter.vue
+++ b/src/pages/Supplier/Card/SupplierBalanceFilter.vue
@@ -33,7 +33,7 @@ defineProps({
:label="t('params.from')"
v-model="params.from"
@update:model-value="searchFn()"
- is-outlined
+ filled
/>
@@ -47,8 +47,7 @@ defineProps({
:include="{ relation: 'accountingType' }"
sort-by="id"
dense
- outlined
- rounded
+ filled
>
@@ -74,8 +73,7 @@ defineProps({
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
diff --git a/src/pages/Supplier/Card/SupplierCard.vue b/src/pages/Supplier/Card/SupplierCard.vue
index e30f79f96..74b3520bf 100644
--- a/src/pages/Supplier/Card/SupplierCard.vue
+++ b/src/pages/Supplier/Card/SupplierCard.vue
@@ -1,10 +1,10 @@
- {
- {{ buy.itemName }}
+ {{ buy.itemName }}
diff --git a/src/pages/Supplier/Card/SupplierConsumptionFilter.vue b/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
index 390f7d9ff..e21e37eb3 100644
--- a/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
+++ b/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
@@ -25,20 +25,12 @@ defineProps({
-
+
-
+
@@ -54,8 +46,7 @@ defineProps({
option-label="nickname"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -73,8 +64,7 @@ defineProps({
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
>
@@ -102,8 +92,7 @@ defineProps({
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -113,7 +102,7 @@ defineProps({
:label="t('params.from')"
v-model="params.from"
@update:model-value="searchFn()"
- is-outlined
+ filled
/>
@@ -123,7 +112,7 @@ defineProps({
:label="t('params.to')"
v-model="params.to"
@update:model-value="searchFn()"
- is-outlined
+ filled
/>
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 462bdf853..2511edf11 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -3,7 +3,7 @@ import { ref, computed, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import { toDateString } from 'src/filters';
@@ -61,7 +61,7 @@ const getEntryQueryParams = (supplier) => {
- {
{
-
+
diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue
index d1d437a19..ec89d77e0 100644
--- a/src/pages/Supplier/SupplierList.vue
+++ b/src/pages/Supplier/SupplierList.vue
@@ -172,6 +172,7 @@ const filterColumns = computed(() => {
>
{
};
const { data } = await axios.post(
`tickets/${ticket.value.id}/priceDifference`,
- params
+ params,
);
ticket.value.sale = data;
};
@@ -72,7 +72,7 @@ const submit = async () => {
const { data } = await axios.post(
`tickets/${ticket.value.id}/componentUpdate`,
- params
+ params,
);
if (!data) return;
@@ -99,7 +99,7 @@ const onNextStep = async () => {
openConfirmationModal(
t('basicData.negativesConfirmTitle'),
t('basicData.negativesConfirmMessage'),
- submitWithNegatives
+ submitWithNegatives,
);
else submit();
}
diff --git a/src/pages/Ticket/Card/TicketCard.vue b/src/pages/Ticket/Card/TicketCard.vue
index e22d5799a..19dbd608c 100644
--- a/src/pages/Ticket/Card/TicketCard.vue
+++ b/src/pages/Ticket/Card/TicketCard.vue
@@ -1,10 +1,10 @@
- {
return $props.id || route.params.id;
});
const problems = ref({});
+const originalTicket = ref();
function ticketFilter(ticket) {
return JSON.stringify({ clientFk: ticket.clientFk });
}
+async function getClaims() {
+ const userFilter = { where: { refundTicketFk: entityId.value } };
+ const { data } = await axios.get(`TicketRefunds`, {
+ params: { filter: JSON.stringify(userFilter) },
+ });
+ if (!data) return;
+ originalTicket.value = data[0]?.originalTicketFk;
+}
+async function getProblems() {
+ const { data } = await axios.get(`Tickets/${entityId.value}/getTicketProblems`);
+ if (!data) return;
+ problems.value = data[0];
+}
+function getInfo() {
+ getClaims();
+ getProblems();
+}
- ([problems] = data)"
- />
-
@@ -74,12 +88,12 @@ function ticketFilter(ticket) {
-
+
-
+
+ {{ entity?.client?.department?.name || '-' }}
+
+
{{ t('ticket.card.newOrder') }}
+
+ {{ t('ticket.card.ticketClaimed') }}
+
-
+
diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
index 63e45c8ab..f7389b592 100644
--- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
@@ -32,7 +32,7 @@ onMounted(() => {
watch(
() => props.ticket,
- () => restoreTicket
+ () => restoreTicket,
);
const { push, currentRoute } = useRouter();
@@ -58,7 +58,7 @@ const hasDocuwareFile = ref();
const quasar = useQuasar();
const canRestoreTicket = ref(false);
-const onClientSelected = async(clientId) =>{
+const onClientSelected = async (clientId) => {
client.value = clientId;
await fetchClient();
await fetchAddresses();
@@ -66,10 +66,10 @@ const onClientSelected = async(clientId) =>{
const onAddressSelected = (addressId) => {
address.value = addressId;
-}
+};
const fetchClient = async () => {
- const response = await getClient(client.value)
+ const response = await getClient(client.value);
if (!response) return;
const [retrievedClient] = response.data;
selectedClient.value = retrievedClient;
@@ -151,7 +151,7 @@ function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
recipientId: ticket.value.clientFk,
type: type,
},
- '_blank'
+ '_blank',
);
}
@@ -297,8 +297,8 @@ async function transferClient() {
clientFk: client.value,
addressFk: address.value,
};
-
- await axios.patch( `Tickets/${ticketId.value}/transferClient`, params );
+
+ await axios.patch(`Tickets/${ticketId.value}/transferClient`, params);
window.location.reload();
}
@@ -339,7 +339,7 @@ async function changeShippedHour(time) {
const { data } = await axios.post(
`Tickets/${ticketId.value}/updateEditableTicket`,
- params
+ params,
);
if (data) window.location.reload();
@@ -405,8 +405,7 @@ async function uploadDocuware(force) {
uploadDocuware(true);
});
- const { data } = await axios.post(`Docuwares/upload`, {
- fileCabinet: 'deliveryNote',
+ const { data } = await axios.post(`Docuwares/upload-delivery-note`, {
ticketIds: [parseInt(ticketId.value)],
});
@@ -500,7 +499,7 @@ async function ticketToRestore() {
- {
};
const getMana = async () => {
- const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
+ const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
mana.value = data;
await getUsesMana();
};
diff --git a/src/pages/Ticket/Card/TicketFilter.js b/src/pages/Ticket/Card/TicketFilter.js
index 7846f1658..daa204a7a 100644
--- a/src/pages/Ticket/Card/TicketFilter.js
+++ b/src/pages/Ticket/Card/TicketFilter.js
@@ -12,7 +12,7 @@ export default {
fields: [
'id',
'name',
- 'salesPersonFk',
+ 'departmentFk',
'phone',
'mobile',
'email',
@@ -29,7 +29,7 @@ export default {
fields: ['id', 'lang'],
},
},
- { relation: 'salesPersonUser' },
+ { relation: 'department' },
],
},
},
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index ece871918..a613f905a 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -1,5 +1,5 @@
@@ -405,7 +405,7 @@ watch(
t(`advanceTickets.advanceTitleSubtitle`, {
selectedTickets: selectedTickets.length,
}),
- moveTicketsAdvance
+ moveTicketsAdvance,
)
"
>
@@ -423,7 +423,7 @@ watch(
t(`advanceTickets.advanceWithoutNegativeSubtitle`, {
selectedTickets: selectedTickets.length,
}),
- splitTickets
+ splitTickets,
)
"
>
diff --git a/src/pages/Ticket/TicketAdvanceFilter.vue b/src/pages/Ticket/TicketAdvanceFilter.vue
index 6d5c7726e..f065eaf2e 100644
--- a/src/pages/Ticket/TicketAdvanceFilter.vue
+++ b/src/pages/Ticket/TicketAdvanceFilter.vue
@@ -71,7 +71,7 @@ onMounted(async () => await getItemPackingTypes());
@@ -80,7 +80,7 @@ onMounted(async () => await getItemPackingTypes());
@@ -95,8 +95,7 @@ onMounted(async () => await getItemPackingTypes());
:info="t('iptInfo')"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
:use-like="false"
>
@@ -113,8 +112,7 @@ onMounted(async () => await getItemPackingTypes());
:info="t('iptInfo')"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
:use-like="false"
>
@@ -125,7 +123,7 @@ onMounted(async () => await getItemPackingTypes());
@@ -147,8 +145,7 @@ onMounted(async () => await getItemPackingTypes());
url="Departments"
:fields="['id', 'name']"
dense
- outlined
- rounded
+ filled
/>
@@ -162,8 +159,7 @@ onMounted(async () => await getItemPackingTypes());
option-label="name"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index bdf75c826..d84d1c082 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -22,16 +22,6 @@ const states = ref([]);
const agencies = ref([]);
const warehouses = ref([]);
const groupedStates = ref([]);
-
-const getGroupedStates = (data) => {
- for (const state of data) {
- groupedStates.value.push({
- id: state.id,
- name: t(`${state.code}`),
- code: state.code,
- });
- }
-};
@@ -39,12 +29,11 @@ const getGroupedStates = (data) => {
(states = data)" auto-load />
{
- getGroupedStates(data);
- }
- "
auto-load
+ @on-fetch="
+ (data) =>
+ (groupedStates = data.map((x) => Object.assign(x, { code: t(x.code) })))
+ "
/>
{
-
+
-
+
@@ -82,7 +63,7 @@ const getGroupedStates = (data) => {
@@ -90,22 +71,21 @@ const getGroupedStates = (data) => {
-
@@ -125,8 +105,7 @@ const getGroupedStates = (data) => {
map-options
use-input
dense
- outlined
- rounded
+ filled
/>
@@ -136,29 +115,23 @@ const getGroupedStates = (data) => {
-
+
@@ -166,17 +139,13 @@ const getGroupedStates = (data) => {
-
+
@@ -241,8 +210,7 @@ const getGroupedStates = (data) => {
map-options
use-input
dense
- outlined
- rounded
+ filled
/>
@@ -260,8 +228,7 @@ const getGroupedStates = (data) => {
map-options
use-input
dense
- outlined
- rounded
+ filled
/>
@@ -281,8 +248,7 @@ const getGroupedStates = (data) => {
map-options
use-input
dense
- outlined
- rounded
+ filled
/>
@@ -291,7 +257,7 @@ const getGroupedStates = (data) => {
@@ -308,7 +274,6 @@ en:
from: From
shipped: Shipped
to: To
- salesPersonFk: Salesperson
stateFk: State
groupedStates: Grouped State
refFk: Invoice Ref.
@@ -327,7 +292,7 @@ en:
ON_PREPARATION: On preparation
PACKED: Packed
DELIVERED: Delivered
- ON_PREVIOUS: ON_PREVIOUS
+ ON_PREVIOUS: On previous
es:
params:
search: Contiene
@@ -336,7 +301,6 @@ es:
from: Desde
shipped: F. envío
to: Hasta
- salesPersonFk: Comercial
stateFk: Estado
groupedStates: Estado agrupado
refFk: Ref. Factura
@@ -355,7 +319,6 @@ es:
Order ID: ID Pedido
From: Desde
To: Hasta
- Salesperson: Comercial
State: Estado
Invoice Ref.: Ref. Factura
My team: Mi equipo
@@ -374,7 +337,7 @@ es:
ON_PREPARATION: En preparación
PACKED: Encajado
DELIVERED: Servido
- ON_PREVIOUS: ON_PREVIOUS
+ ON_PREVIOUS: En previa
Collection: Colección
Nickname: Nombre mostrado
diff --git a/src/pages/Ticket/TicketFuture.vue b/src/pages/Ticket/TicketFuture.vue
index 92911cd25..588379ed9 100644
--- a/src/pages/Ticket/TicketFuture.vue
+++ b/src/pages/Ticket/TicketFuture.vue
@@ -160,7 +160,7 @@ const moveTicketsFuture = async () => {
destinationId: ticket.futureId,
originShipped: ticket.shipped,
destinationShipped: ticket.futureShipped,
- salesPersonFk: ticket.salesPersonFk,
+ departmentFk: ticket.departmentFk,
};
});
diff --git a/src/pages/Ticket/TicketFutureFilter.vue b/src/pages/Ticket/TicketFutureFilter.vue
index 64e060a39..033b47f72 100644
--- a/src/pages/Ticket/TicketFutureFilter.vue
+++ b/src/pages/Ticket/TicketFutureFilter.vue
@@ -73,7 +73,7 @@ onMounted(async () => {
@@ -82,7 +82,7 @@ onMounted(async () => {
@@ -91,7 +91,7 @@ onMounted(async () => {
@@ -100,7 +100,7 @@ onMounted(async () => {
@@ -115,8 +115,7 @@ onMounted(async () => {
:info="t('iptInfo')"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
@@ -132,8 +131,7 @@ onMounted(async () => {
:info="t('iptInfo')"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
@@ -148,8 +146,7 @@ onMounted(async () => {
option-label="name"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
@@ -164,8 +161,7 @@ onMounted(async () => {
option-label="name"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
@@ -191,8 +187,7 @@ onMounted(async () => {
option-label="name"
@update:model-value="searchFn()"
dense
- outlined
- rounded
+ filled
>
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index dfaabc848..634b8e50a 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -17,6 +17,7 @@ import TicketFilter from './TicketFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FetchData from 'src/components/FetchData.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import { toTimeFormat } from 'src/filters/date';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
@@ -99,26 +100,20 @@ const columns = computed(() => [
},
{
align: 'left',
- label: t('ticketList.salesPerson'),
- name: 'salesPersonFk',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
component: 'select',
attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- where: { role: 'salesPerson' },
- optionFilter: 'firstName',
- useLike: false,
+ url: 'Departments',
},
columnField: {
component: null,
},
- columnClass: 'expand',
- cardVisible: true,
- format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'left',
- name: 'shipped',
+ name: 'shippedDate',
cardVisible: true,
label: t('ticketList.shipped'),
columnFilter: {
@@ -128,7 +123,7 @@ const columns = computed(() => [
},
{
align: 'left',
- name: 'shipped',
+ name: 'shippedHour',
component: 'time',
columnFilter: false,
label: t('ticketList.hour'),
@@ -253,7 +248,7 @@ const columns = computed(() => [
name: 'TicketCard',
}).href;
window.open(url, '_blank');
- } else viewSummary(row.id, TicketSummary);
+ } else viewSummary(row.id, TicketSummary, 'lg-width');
},
},
],
@@ -345,25 +340,20 @@ async function makeInvoice(ticket) {
});
}
-async function sendDocuware(ticket) {
- try {
- let ticketIds = ticket.map((item) => item.id);
+async function sendDocuware(tickets) {
+ let ticketIds = tickets.map((item) => item.id);
- const { data } = await axios.post(`Docuwares/upload`, {
- fileCabinet: 'deliveryNote',
- ticketIds,
- });
+ const { data } = await axios.post(`Docuwares/upload-delivery-note`, {
+ ticketIds,
+ });
- for (let ticket of ticketIds) {
- ticket.stateFk = data.id;
- ticket.state = data.name;
- ticket.alertLevel = data.alertLevel;
- ticket.alertLevelCode = data.code;
- }
- notify('globals.dataSaved', 'positive');
- } catch (err) {
- console.err('err: ', err);
+ for (let ticket of tickets) {
+ ticket.stateFk = data.id;
+ ticket.state = data.name;
+ ticket.alertLevel = data.alertLevel;
+ ticket.alertLevelCode = data.code;
}
+ notify('globals.dataSaved', 'positive');
}
function openBalanceDialog(ticket) {
@@ -519,10 +509,10 @@ function setReference(data) {
-
+
- {{ dashIfEmpty(row.userName) }}
-
+ {{ dashIfEmpty(row.departmentName) }}
+
diff --git a/src/pages/Ticket/TicketWeekly.vue b/src/pages/Ticket/TicketWeekly.vue
index 0e18fe028..d6493550b 100644
--- a/src/pages/Ticket/TicketWeekly.vue
+++ b/src/pages/Ticket/TicketWeekly.vue
@@ -5,7 +5,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectCache from 'src/components/common/VnSelectCache.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useStateStore } from 'stores/useStateStore';
import { useVnConfirm } from 'composables/useVnConfirm';
@@ -112,23 +112,17 @@ const columns = computed(() => [
},
{
align: 'left',
- name: 'id',
- label: t('weeklyTickets.salesperson'),
- columnFilter: {
- component: 'select',
- alias: 'u',
- attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- where: { role: 'salesperson' },
- },
- inWhere: true,
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
},
+ create: true,
columnField: {
component: null,
},
- cardVisible: true,
- format: (row) => row.userName,
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'right',
@@ -142,9 +136,9 @@ const columns = computed(() => [
openConfirmationModal(
t('You are going to delete this weekly ticket'),
t(
- 'This ticket will be removed from weekly tickets! Continue anyway?'
+ 'This ticket will be removed from weekly tickets! Continue anyway?',
),
- () => deleteWeekly(row.ticketFk)
+ () => deleteWeekly(row.ticketFk),
),
isPrimary: true,
},
@@ -219,10 +213,10 @@ onMounted(async () => {
-
+
- {{ row.userName }}
-
+ {{ row.departmentName }}
+
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index 4370f1ead..808f05f34 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -136,7 +136,6 @@ purchaseRequest:
weeklyTickets:
id: Ticket ID
shipment: Shipment
- salesperson: Salesperson
search: Search weekly tickets
searchInfo: Search weekly tickets by id or client id
ticketSaleTracking:
@@ -172,7 +171,7 @@ tracking:
addState: Add state
package:
package: Package
- added: Added
+ added: D. Added
addPackage: Add package
removePackage: Remove package
ticketList:
@@ -181,7 +180,6 @@ ticketList:
state: State
shipped: Shipped
zone: Zone
- salesPerson: Sales person
totalWithVat: Total with VAT
summary: Summary
client: Customer
@@ -207,6 +205,7 @@ ticketList:
toLines: Go to lines
addressNickname: Address nickname
ref: Reference
+ hour: Hour
rounding: Rounding
noVerifiedData: No verified data
purchaseRequest: Purchase request
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index 8f51e5487..1e5e95eb6 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -58,7 +58,6 @@ basicData:
weeklyTickets:
id: ID Ticket
shipment: Salida
- salesperson: Comercial
search: Buscar por tickets programados
searchInfo: Buscar tickets programados por el identificador o el identificador del cliente
advanceTickets:
@@ -162,7 +161,7 @@ expedition:
removeExpedition: Eliminar expedición
package:
package: Embalaje
- added: Añadido
+ added: F. Creacion
addPackage: Añadir embalaje
removePackage: Quitar embalaje
ticketSaleTracking:
@@ -186,7 +185,6 @@ ticketList:
state: Estado
shipped: F. Envío
zone: Zona
- salesPerson: Comercial
totalWithVat: Total con IVA
summary: Resumen
client: Cliente
diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue
index b1adc8126..a6ef8ad19 100644
--- a/src/pages/Travel/Card/TravelBasicData.vue
+++ b/src/pages/Travel/Card/TravelBasicData.vue
@@ -36,7 +36,7 @@ const warehousesOptionsIn = ref([]);
auto-load
:filter="{ where: { isDestiny: TRUE } }"
/>
-
+
@@ -57,8 +57,8 @@ const warehousesOptionsIn = ref([]);
+ :label="t('travel.summary.availabled')"
+ />
+
diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue
index cb09eafd6..d452f5287 100644
--- a/src/pages/Travel/Card/TravelCard.vue
+++ b/src/pages/Travel/Card/TravelCard.vue
@@ -1,13 +1,13 @@
-
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index 922f89f33..d57046bae 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -3,7 +3,7 @@ import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription';
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
@@ -31,7 +31,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
- (data.value = useCardDescription(entity.ref, entity.
:to="{
name: 'TravelList',
query: {
- params: JSON.stringify({
+ table: JSON.stringify({
agencyModeFk: entity.agencyModeFk,
}),
},
@@ -79,7 +79,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
-
+
diff --git a/src/pages/Travel/Card/TravelFilter.js b/src/pages/Travel/Card/TravelFilter.js
index 05436834f..0799e449c 100644
--- a/src/pages/Travel/Card/TravelFilter.js
+++ b/src/pages/Travel/Card/TravelFilter.js
@@ -12,6 +12,7 @@ export default {
'isRaid',
'daysInForward',
'availabled',
+ 'awbFk',
],
include: [
{
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index 9f9552611..22e2cff86 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -1,5 +1,5 @@
- (warehouses = data)"
- auto-load
- />
`#/travel/${entityId.value}/${param}`;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -376,6 +383,11 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
+
+
+ {{ Math.ceil(value) || 0 }}
+
+
@@ -392,23 +404,24 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
{{ entriesTotals.freight }}
{{ entriesTotals.packageValue }}
{{ entriesTotals.cc }}
+ {{ entriesTotals.roundedCc }}
{{ entriesTotals.pallet }}
{{ entriesTotals.m3 }}
-
-
+ (warehouses = data)"
+ auto-load
+ />
+
[
label: 'id',
field: 'id',
name: 'id',
- align: 'center',
showValue: true,
sortable: true,
},
@@ -165,7 +163,7 @@ const columns = computed(() => [
label: t('globals.amount'),
name: 'invoiceAmount',
field: 'entries',
- align: 'left',
+ align: 'right',
showValue: true,
sortable: true,
format: (value) =>
@@ -184,13 +182,12 @@ const columns = computed(() => [
align: 'left',
showValue: false,
sortable: true,
- style: 'min-width: 170px;',
},
{
label: t('globals.packages'),
field: 'stickers',
name: 'stickers',
- align: 'left',
+ align: 'right',
showValue: true,
sortable: true,
},
@@ -198,7 +195,7 @@ const columns = computed(() => [
label: '%',
field: '',
name: 'percentage',
- align: 'center',
+ align: 'right',
showValue: false,
sortable: true,
},
@@ -214,7 +211,7 @@ const columns = computed(() => [
label: t('extraCommunity.physicKg'),
field: 'loadedKg',
name: 'loadedKg',
- align: 'left',
+ align: 'right',
showValue: true,
sortable: true,
},
@@ -222,7 +219,7 @@ const columns = computed(() => [
label: 'KG Vol.',
field: 'volumeKg',
name: 'volumeKg',
- align: 'left',
+ align: 'right',
showValue: true,
sortable: true,
},
@@ -277,7 +274,6 @@ async function getData() {
const onStoreDataChange = () => {
const newData = JSON.parse(JSON.stringify(arrayData.store.data)) || [];
rows.value = newData;
- // el objetivo de esto es guardar una copia de los valores iniciales de todas las rows para corroborar si la data cambio antes de guardar los cambios
originalRowDataCopy.value = JSON.parse(JSON.stringify(newData));
};
@@ -300,20 +296,17 @@ const openReportPdf = () => {
};
const saveFieldValue = async (val, field, index) => {
- // Evitar la solicitud de guardado si el valor no ha cambiado
if (originalRowDataCopy.value[index][field] == val) return;
const id = rows.value[index].id;
const params = { [field]: val };
await axios.patch(`Travels/${id}`, params);
- // Actualizar la copia de los datos originales con el nuevo valor
originalRowDataCopy.value[index][field] = val;
await arrayData.fetch({ append: false });
};
const stopEventPropagation = (event, col) => {
- // Detener la propagación del evento de los siguientes elementos para evitar el click sobre la row que dispararía la función navigateToTravelId
if (!['ref', 'id', 'cargoSupplierNickname', 'kg'].includes(col.name)) return;
event.preventDefault();
event.stopPropagation();
@@ -335,14 +328,12 @@ onMounted(async () => {
await getData();
});
-// Handler del evento @dragstart (inicio del drag) y guarda información inicial
const handleDragStart = (event, rowIndex, entryIndex) => {
draggedRowIndex.value = rowIndex;
entryRowIndex.value = entryIndex;
event.dataTransfer.effectAllowed = 'move';
};
-// Handler del evento @dragenter (cuando haces drag sobre une elemento y lo arrastras sobre un posible target de drop) y actualiza el targetIndex
const handleDragEnter = (_, targetIndex) => {
targetRowIndex.value = targetIndex;
};
@@ -356,11 +347,8 @@ const saveRowDrop = async (targetRowIndex) => {
const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => {
try {
if (draggedRowIndex === targetRowIndex) return;
- // Remover entry de la row original
draggedEntry.value = rows.value[draggedRowIndex].entries.splice(entryIndex, 1)[0];
- //Si la row de destino por alguna razón no tiene la propiedad entry la creamos
if (!rows.value[targetRowIndex].entries) rows.value[targetRowIndex].entries = [];
- // Añadir entry a la row de destino
rows.value[targetRowIndex].entries.push(draggedEntry.value);
await saveRowDrop(targetRowIndex);
@@ -370,13 +358,11 @@ const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => {
}
};
-// Handler de cuando haces un drop tanto dentro como fuera de la tabla para limpiar acciones y data
const handleDragEnd = () => {
stopScroll();
cleanDragAndDropData();
};
-// Handler del evento @drop (cuando soltas el elemento draggeado sobre un target)
const handleDrop = () => {
if (
!draggedRowIndex.value &&
@@ -399,7 +385,6 @@ const cleanDragAndDropData = () => {
const scrollInterval = ref(null);
const startScroll = (direction) => {
- // Iniciar el scroll en la dirección especificada
if (!scrollInterval.value) {
scrollInterval.value = requestAnimationFrame(() => scroll(direction));
}
@@ -413,14 +398,12 @@ const stopScroll = () => {
};
const scroll = (direction) => {
- // Controlar el desplazamiento en la dirección especificada
const yOffset = direction === 'up' ? -2 : 2;
window.scrollBy(0, yOffset);
const windowHeight = window.innerHeight;
const documentHeight = document.body.offsetHeight;
- // Verificar si se alcanzaron los límites de la ventana para detener el desplazamiento
if (
(direction === 'up' && window.scrollY > 0) ||
(direction === 'down' && windowHeight + window.scrollY < documentHeight)
@@ -431,13 +414,10 @@ const scroll = (direction) => {
}
};
-// Handler del scroll mientras se hace el drag de una row
const handleDragScroll = (event) => {
- // Obtener la posición y dimensiones del cursor
const y = event.clientY;
const windowHeight = window.innerHeight;
- // Verificar si el cursor está cerca del borde superior o inferior de la ventana
const nearTop = y < 150;
const nearBottom = y > windowHeight - 100;
@@ -547,7 +527,7 @@ watch(route, () => {
? `${props.row.percentageKg}%`
: '-'
"
- class="text-left q-py-xs q-px-sm"
+ class="text-right q-py-xs q-px-sm"
:color="getColor(props.row.percentageKg)"
/>
{
]"
v-text="col.value"
/>
-
{
index === props.row.entries.length - 1,
}"
>
-
+
{{ entry.id }}
-
- {{ entry.supplierName }}
-
+
+
+
+ {{ entry.supplierName }}
+
+
+
+
-
-
-
-
-
+
{{ toCurrency(entry.invoiceAmount) }}
{{ entry.reference }}
-
+
{{ entry.stickers }}
-
+
{{ entry.loadedkg }}
-
+
{{ entry.volumeKg }}
-
-
-
-
-
-
-
-
+
+
+ {{ entry.evaNotes }}
+
@@ -662,18 +629,21 @@ watch(route, () => {
}
:deep(.q-table) {
+ table-layout: auto;
+ width: 100%;
border-collapse: collapse;
+ overflow: hidden;
+ text-overflow: ellipsis;
- th {
- padding: 0;
- }
tbody tr td {
&:nth-child(1) {
max-width: 65px;
}
- &:nth-child(4) {
- padding: 0;
- }
+ padding: 0 5px 0;
+ }
+ thead > tr > th {
+ padding: 3px;
+ color: var(--vn-label-color);
}
}
diff --git a/src/pages/Travel/ExtraCommunityFilter.vue b/src/pages/Travel/ExtraCommunityFilter.vue
index ae6e695be..76ffdba20 100644
--- a/src/pages/Travel/ExtraCommunityFilter.vue
+++ b/src/pages/Travel/ExtraCommunityFilter.vue
@@ -87,7 +87,7 @@ warehouses();
-
+
@@ -95,7 +95,7 @@ warehouses();
@@ -106,8 +106,7 @@ warehouses();
type="number"
:label="t('extraCommunity.filter.totalEntries')"
dense
- outlined
- rounded
+ filled
min="0"
class="input-number"
>
@@ -141,8 +140,7 @@ warehouses();
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -152,7 +150,7 @@ warehouses();
:label="t('extraCommunity.filter.shippedFrom')"
v-model="params.shippedFrom"
@update:model-value="searchFn()"
- is-outlined
+ filled
/>
@@ -162,7 +160,7 @@ warehouses();
:label="t('extraCommunity.filter.landedTo')"
v-model="params.landedTo"
@update:model-value="searchFn()"
- is-outlined
+ filled
/>
@@ -176,8 +174,7 @@ warehouses();
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -191,8 +188,7 @@ warehouses();
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -206,8 +202,7 @@ warehouses();
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -218,8 +213,7 @@ warehouses();
v-model="params.cargoSupplierFk"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -229,8 +223,7 @@ warehouses();
v-model="params.entrySupplierFk"
hide-selected
dense
- outlined
- rounded
+ filled
/>
@@ -245,8 +238,7 @@ warehouses();
:filter-options="['code', 'name']"
hide-selected
dense
- outlined
- rounded
+ filled
/>
diff --git a/src/pages/Travel/TravelFilter.vue b/src/pages/Travel/TravelFilter.vue
index 4a9c80952..5498fd269 100644
--- a/src/pages/Travel/TravelFilter.vue
+++ b/src/pages/Travel/TravelFilter.vue
@@ -33,19 +33,14 @@ defineExpose({ states });
-
+
@@ -140,6 +128,7 @@ en:
ref: Reference
agency: Agency
warehouseInFk: Warehouse In
+ warehouseOutFk: Warehouse Out
shipped: Shipped
shipmentHour: Shipment Hour
warehouseOut: Warehouse Out
@@ -153,6 +142,7 @@ es:
ref: Referencia
agency: Agencia
warehouseInFk: Alm.Entrada
+ warehouseOutFk: Alm.Salida
shipped: F.Envío
shipmentHour: Hora de envío
warehouseOut: Alm.Salida
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index b227afcb2..32ddc639a 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -201,7 +201,7 @@ const columns = computed(() => [
{
title: t('components.smartCard.viewSummary'),
icon: 'preview',
- action: (row) => viewSummary(row.id, TravelSummary),
+ action: (row) => viewSummary(row.id, TravelSummary, 'lg-width'),
isPrimary: true,
},
],
diff --git a/src/pages/Wagon/Card/WagonCard.vue b/src/pages/Wagon/Card/WagonCard.vue
index 644a30ffa..19f0a682a 100644
--- a/src/pages/Wagon/Card/WagonCard.vue
+++ b/src/pages/Wagon/Card/WagonCard.vue
@@ -1,6 +1,6 @@
-
+
diff --git a/src/pages/Wagon/WagonList.vue b/src/pages/Wagon/WagonList.vue
index e716686d1..16c5fca63 100644
--- a/src/pages/Wagon/WagonList.vue
+++ b/src/pages/Wagon/WagonList.vue
@@ -8,6 +8,7 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
import { computed, ref } from 'vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
+import VnSection from 'src/components/common/VnSection.vue';
const quasar = useQuasar();
const arrayData = useArrayData('WagonList');
@@ -15,6 +16,7 @@ const store = arrayData.store;
const router = useRouter();
const { t } = useI18n();
const tableRef = ref();
+const dataKey = 'WagonList';
const filter = {
include: {
relation: 'type',
@@ -75,101 +77,110 @@ function navigate(id) {
}
async function remove(row) {
- try {
- await axios.delete(`Wagons/${row.id}`).then(async () => {
- quasar.notify({
- message: t('wagon.list.removeItem'),
- type: 'positive',
- });
- store.data.splice(store.data.indexOf(row), 1);
- window.location.reload();
+ await axios.delete(`Wagons/${row.id}`).then(async () => {
+ quasar.notify({
+ message: t('wagon.list.removeItem'),
+ type: 'positive',
});
- } catch (error) {
- //
- }
+ store.data.splice(store.data.indexOf(row), 1);
+ window.location.reload();
+ });
}
-
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+ {{ t('wagon.warnings.noData') }}
+
+
+
+
-
-
-
- {{ t('wagon.warnings.noData') }}
-
-
-
-
+
-
+
es:
Create new wagon: Crear nuevo vagón
-
\ No newline at end of file
+
diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue
index b807d980b..f2a16b7e1 100644
--- a/src/pages/Worker/Card/WorkerBasicData.vue
+++ b/src/pages/Worker/Card/WorkerBasicData.vue
@@ -96,6 +96,7 @@ onMounted(async () => {
option-label="name"
option-value="code"
v-model="data.maritalStatus"
+ data-cy="MaritalStatus"
/>
@@ -107,6 +108,7 @@ onMounted(async () => {
option-label="name"
option-value="id"
v-model="data.originCountryFk"
+ data-cy="country"
/>
{
-
+
diff --git a/src/pages/Worker/Card/WorkerCalendarFilter.vue b/src/pages/Worker/Card/WorkerCalendarFilter.vue
index 48fc4094b..f0e2d758a 100644
--- a/src/pages/Worker/Card/WorkerCalendarFilter.vue
+++ b/src/pages/Worker/Card/WorkerCalendarFilter.vue
@@ -40,7 +40,7 @@ watch(
(newValue) => {
checkHolidays(newValue);
},
- { deep: true, immediate: true }
+ { deep: true, immediate: true },
);
const emit = defineEmits(['update:businessFk', 'update:year', 'update:absenceType']);
@@ -174,8 +174,7 @@ const yearList = ref(generateYears());
v-model="selectedYear"
:options="yearList"
dense
- outlined
- rounded
+ filled
use-input
:is-clearable="false"
/>
@@ -188,8 +187,7 @@ const yearList = ref(generateYears());
option-value="businessFk"
option-label="businessFk"
dense
- outlined
- rounded
+ filled
use-input
:is-clearable="false"
>
diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue
index 3b7a62025..591dadcd2 100644
--- a/src/pages/Worker/Card/WorkerCard.vue
+++ b/src/pages/Worker/Card/WorkerCard.vue
@@ -1,9 +1,9 @@
- {
};
- {
-
+
-
-
- {{ t('globals.phone') }}
+
+
-
-
- {{ t('worker.summary.sipExtension') }}
+
+
@@ -162,7 +165,7 @@ const handlePhotoUpdated = (evt = false) => {
-
+
@@ -116,6 +118,7 @@ watch(
option-value="code"
v-model="row.itemPackingTypeFk"
:required="true"
+ data-cy="itemPackingType"
/>
@@ -132,6 +136,7 @@ watch(
hide-selected
option-label="description"
v-model="row.sectorFk"
+ data-cy="sector"
/>
@@ -160,11 +166,13 @@ watch(
:label="t('worker.operator.linesLimit')"
v-model="row.linesLimit"
lazy-rules
+ data-cy="linesLimit"
/>
@@ -172,6 +180,7 @@ watch(
:label="t('worker.operator.sizeLimit')"
v-model="row.sizeLimit"
lazy-rules
+ data-cy="sizeLimit"
/>
route.params.id);
-
+const worker = computed(() => useArrayData('Worker').store.data);
const initialData = computed(() => {
return {
userFk: routeId.value,
@@ -31,154 +32,268 @@ const initialData = computed(() => {
};
});
-const deallocatePDA = async (deviceProductionFk) => {
- await axios.post(`Workers/${route.params.id}/deallocatePDA`, {
- pda: deviceProductionFk,
- });
- notify(t('PDA deallocated'), 'positive');
-
- paginate.value.fetch();
-};
+const columns = computed(() => [
+ {
+ align: 'center',
+ label: t('globals.state'),
+ name: 'state',
+ format: (row) => row?.docuware?.state,
+ columnFilter: false,
+ chip: {
+ condition: (_, row) => !!row.docuware,
+ color: (row) => (isSigned(row) ? 'bg-positive' : 'bg-warning'),
+ },
+ visible: false,
+ },
+ {
+ align: 'right',
+ label: t('worker.pda.currentPDA'),
+ name: 'deviceProductionFk',
+ columnClass: 'shrink',
+ cardVisible: true,
+ },
+ {
+ align: 'left',
+ label: t('Model'),
+ name: 'modelFk',
+ format: ({ deviceProduction }) => deviceProduction.modelFk,
+ cardVisible: true,
+ },
+ {
+ align: 'right',
+ label: t('Serial number'),
+ name: 'serialNumber',
+ format: ({ deviceProduction }) => deviceProduction.serialNumber,
+ cardVisible: true,
+ },
+ {
+ align: 'left',
+ label: t('Current SIM'),
+ name: 'simFk',
+ cardVisible: true,
+ },
+ {
+ align: 'right',
+ name: 'actions',
+ columnFilter: false,
+ cardVisible: true,
+ },
+]);
function reloadData() {
initialData.value.deviceProductionFk = null;
initialData.value.simFk = null;
- paginate.value.fetch();
+ tableRef.value.reload();
+}
+
+async function fetchDocuware() {
+ loadingDocuware.value = true;
+
+ const id = `${worker.value?.lastName} ${worker.value?.firstName}`;
+ const rows = tableRef.value.CrudModelRef.formData;
+
+ const promises = rows.map(async (row) => {
+ const { data } = await axios.post(`Docuwares/${id}/checkFile`, {
+ fileCabinet: 'hr',
+ signed: false,
+ mergeFilter: [
+ {
+ DBName: 'TIPO_DOCUMENTO',
+ Value: ['PDA'],
+ },
+ {
+ DBName: 'OBSERVACIONES',
+ Value: [row.deviceProductionFk],
+ },
+ ],
+ });
+ row.docuware = data;
+ });
+
+ await Promise.allSettled(promises);
+ loadingDocuware.value = false;
+}
+
+async function sendToTablet(rows) {
+ const promises = rows.map(async (row) => {
+ await axios.post(`Docuwares/upload-pda-pdf`, {
+ ids: [row.deviceProductionFk],
+ });
+ row.docuware = true;
+ });
+ await Promise.allSettled(promises);
+ notify(t('PDF sended to signed'), 'positive');
+ tableRef.value.reload();
+}
+
+async function deallocatePDA(deviceProductionFk) {
+ await axios.post(`Workers/${route.params.id}/deallocatePDA`, {
+ pda: deviceProductionFk,
+ });
+ const index = tableRef.value.CrudModelRef.formData.findIndex(
+ (data) => data?.deviceProductionFk == deviceProductionFk,
+ );
+ delete tableRef.value.CrudModelRef.formData[index];
+ notify(t('PDA deallocated'), 'positive');
+}
+
+function isSigned(row) {
+ return row.docuware?.state === 'Firmado';
}
-
- (deviceProductions = data)"
- auto-load
- />
-
-
-
-
-
-
-
-
- deallocatePDA(row.deviceProductionFk),
- )
- "
- >
-
- {{ t('worker.pda.removePDA') }}
-
-
-
-
-
-
-
+ (deviceProductions = data)"
+ auto-load
+ />
+
+
+
+
+
+ deallocatePDA(row.deviceProductionFk),
+ )
+ "
+ data-cy="workerPda-remove"
>
-
-
-
-
-
-
-
-
- ID: {{ scope.opt?.id }}
-
- {{ scope.opt?.modelFk }},
- {{ scope.opt?.serialNumber }}
-
-
-
-
-
-
-
-
-
-
+
+ {{ t('worker.pda.removePDA') }}
+
-
- {{ t('globals.new') }}
-
-
-
+ sendToTablet([row]),
+ )
+ "
+ data-cy="workerPda-send"
+ >
+
+ {{ t('worker.pda.sendToTablet') }}
+
+
+
+
+ {{ t('globals.downloadPdf') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ID: {{ scope.opt?.id }}
+
+ {{ scope.opt?.modelFk }},
+ {{ scope.opt?.serialNumber }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('globals.new') }}
+
+
-
es:
Model: Modelo
@@ -190,4 +305,7 @@ es:
Do you want to remove this PDA?: ¿Desea eliminar este PDA?
You can only have one PDA: Solo puedes tener un PDA si no eres autonomo
This PDA is already assigned to another user: Este PDA ya está asignado a otro usuario
+ Are you sure you want to send it?: ¿Seguro que quieres enviarlo?
+ Sign PDA: Firmar PDA
+ PDF sended to signed: PDF enviado para firmar
diff --git a/src/pages/Worker/Card/WorkerPit.vue b/src/pages/Worker/Card/WorkerPit.vue
index 3de60d6a0..cb07c1f1d 100644
--- a/src/pages/Worker/Card/WorkerPit.vue
+++ b/src/pages/Worker/Card/WorkerPit.vue
@@ -68,8 +68,14 @@ const deleteRelative = async (id) => {
:label="t('familySituation')"
clearable
v-model="data.familySituation"
+ data-cy="familySituation"
+ />
+
-
{
clearable
v-model="data.childPension"
:label="t(`childPension`)"
+ data-cy="childPension"
/>
@@ -190,12 +198,14 @@ const deleteRelative = async (id) => {
type="number"
v-model="row.birthed"
:label="t(`birthed`)"
+ data-cy="birthed"
/>
{
url="Workers/summary"
:user-filter="{ where: { id: entityId } }"
data-key="Worker"
+ module-name="Worker"
>
{{ entity.id }} - {{ entity.firstName }} {{ entity.lastName }}
@@ -47,82 +48,91 @@ onBeforeMount(async () => {
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
- {{ t('worker.summary.phoneExtension') }}
-
-
-
-
-
- {{ t('worker.summary.entPhone') }}
-
-
-
-
-
- {{ t('worker.summary.personalPhone') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
{
-
-
- {{ t('worker.summary.sipExtension') }}
+
+
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 7def6e94c..9c0fa6758 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -343,19 +343,29 @@ const updateData = async () => {
const getMailStates = async (date) => {
const url = `WorkerTimeControls/${route.params.id}/getMailStates`;
+ const year = date.getFullYear();
const month = date.getMonth() + 1;
- const prevMonth = month == 1 ? 12 : month - 1;
- const params = {
- month,
- year: date.getFullYear(),
+
+ const getMonthStates = async (month, year) => {
+ return (await axios.get(url, { params: { month, year } })).data;
};
- const curMonthStates = (await axios.get(url, { params })).data;
- const prevMonthStates = (
- await axios.get(url, { params: { ...params, month: prevMonth } })
- ).data;
+ const curMonthStates = await getMonthStates(month, year);
- workerTimeControlMails.value = curMonthStates.concat(prevMonthStates);
+ const prevMonthStates = await getMonthStates(
+ month === 1 ? 12 : month - 1,
+ month === 1 ? year - 1 : year,
+ );
+
+ const postMonthStates = await getMonthStates(
+ month === 12 ? 1 : month + 1,
+ month === 12 ? year + 1 : year,
+ );
+ workerTimeControlMails.value = [
+ ...curMonthStates,
+ ...prevMonthStates,
+ ...postMonthStates,
+ ];
};
const showWorkerTimeForm = (propValue, formType) => {
diff --git a/src/pages/Worker/Card/WorkerTimeForm.vue b/src/pages/Worker/Card/WorkerTimeForm.vue
index 3250e3180..ea9d89144 100644
--- a/src/pages/Worker/Card/WorkerTimeForm.vue
+++ b/src/pages/Worker/Card/WorkerTimeForm.vue
@@ -53,7 +53,7 @@ const title = computed(() => (isEditMode.value ? t('Edit entry') : t('Add time')
const urlCreate = computed(() =>
isEditMode.value
? `WorkerTimeControls/${$props.entryId}/updateTimeEntry`
- : `WorkerTimeControls/${route.params.id}/addTimeEntry`
+ : `WorkerTimeControls/${route.params.id}/addTimeEntry`,
);
onBeforeMount(() => {
@@ -83,6 +83,7 @@ onBeforeMount(() => {
autofocus
:required="true"
:is-clearable="false"
+ data-cy="entryHour"
/>
{
option-value="code"
option-label="description"
hide-selected
+ data-cy="entryType"
/>
diff --git a/src/pages/Worker/Department/Card/DepartmentCard.vue b/src/pages/Worker/Department/Card/DepartmentCard.vue
index 2e3f11521..0fbc90332 100644
--- a/src/pages/Worker/Department/Card/DepartmentCard.vue
+++ b/src/pages/Worker/Department/Card/DepartmentCard.vue
@@ -1,9 +1,9 @@
- {
const { openConfirmationModal } = useVnConfirm();
-
-
+
diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue
index 8210ba0e3..c40afe57e 100644
--- a/src/pages/Worker/WorkerFilter.vue
+++ b/src/pages/Worker/WorkerFilter.vue
@@ -35,7 +35,7 @@ const getLocale = (label) => {
-
@@ -43,29 +43,17 @@ const getLocale = (label) => {
-
+
-
+
-
+
@@ -79,23 +67,18 @@ const getLocale = (label) => {
emit-value
map-options
dense
- outlined
- rounded
+ filled
/>
-
+
-
+
@@ -119,8 +102,11 @@ en:
lastName: Last name
userName: User
extension: Extension
+ departmentFk: Department
es:
+
params:
+ departmentFk: Departamento
search: Contiene
firstName: Nombre
lastName: Apellidos
diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue
index 79eb26881..cb722a139 100644
--- a/src/pages/Worker/WorkerList.vue
+++ b/src/pages/Worker/WorkerList.vue
@@ -105,7 +105,7 @@ const columns = computed(() => [
{
title: t('components.smartCard.viewSummary'),
icon: 'preview',
- action: (row) => viewSummary(row.id, WorkerSummary),
+ action: (row) => viewSummary(row.id, WorkerSummary, 'lg-width'),
isPrimary: true,
},
],
@@ -223,7 +223,7 @@ async function autofillBic(worker) {
:right-search="false"
>
-
+
{
@@ -75,7 +75,6 @@ const setFilteredAddresses = (data) => {
min="0"
/>
-
{
/>
-
{
min="0"
:required="true"
clearable
+ data-cy="ZoneBasicDataPrice"
/>
-import { useRoute } from 'vue-router';
-import { computed } from 'vue';
-
-import VnCard from 'components/common/VnCard.vue';
+import VnCard from 'src/components/common/VnCard.vue';
import ZoneDescriptor from './ZoneDescriptor.vue';
-import ZoneFilterPanel from '../ZoneFilterPanel.vue';
-import filter from './ZoneFilter.js';
-
+import filter from 'src/pages/Zone/Card/ZoneFilter.js';
+import { useRoute } from 'vue-router';
const route = useRoute();
-const routeName = computed(() => route.name);
-
-function notIsLocations(ifIsFalse, ifIsTrue) {
- if (routeName.value != 'ZoneLocations') return ifIsFalse;
- return ifIsTrue;
-}
-
diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue
index 27676212e..f2bcc1247 100644
--- a/src/pages/Zone/Card/ZoneDescriptor.vue
+++ b/src/pages/Zone/Card/ZoneDescriptor.vue
@@ -2,7 +2,7 @@
import { computed } from 'vue';
import { useRoute } from 'vue-router';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import EntityDescriptor from 'components/ui/EntityDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import { toTimeFormat } from 'src/filters/date';
import { toCurrency } from 'filters/index';
@@ -25,7 +25,7 @@ const entityId = computed(() => {
-
+
@@ -36,5 +36,5 @@ const entityId = computed(() => {
-
+
diff --git a/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue b/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
index 3c45700cb..f8683773d 100644
--- a/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
+++ b/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
@@ -36,13 +36,13 @@ function openConfirmDialog(callback) {
}
-
+
{{ t('deleteZone') }}
-
+
diff --git a/src/pages/Zone/Card/ZoneEventExclusionForm.vue b/src/pages/Zone/Card/ZoneEventExclusionForm.vue
index 4b6aa52bd..582a8bbad 100644
--- a/src/pages/Zone/Card/ZoneEventExclusionForm.vue
+++ b/src/pages/Zone/Card/ZoneEventExclusionForm.vue
@@ -1,16 +1,18 @@
-
-
-
+
+
+
+
+
{
await fetchData();
},
- { immediate: true, deep: true }
+ { immediate: true, deep: true },
);
const formatWdays = (event) => {
@@ -178,9 +176,10 @@ onMounted(async () => {
openConfirmationModal(
t('zone.deleteTitle'),
t('zone.deleteSubtitle'),
- () => deleteEvent(event.id)
+ () => deleteEvent(event.id),
)
"
+ data-cy="ZoneEventsPanelDeleteBtn"
>
{{ t('eventsPanel.delete') }}
diff --git a/src/pages/Zone/Card/ZoneLocations.vue b/src/pages/Zone/Card/ZoneLocations.vue
index 08b99df60..add9f6f5b 100644
--- a/src/pages/Zone/Card/ZoneLocations.vue
+++ b/src/pages/Zone/Card/ZoneLocations.vue
@@ -34,9 +34,10 @@ const onSelected = async (val, node) => {
node.selected
? '--checked'
: node.selected == false
- ? '--unchecked'
- : '--indeterminate',
+ ? '--unchecked'
+ : '--indeterminate',
]"
+ data-cy="ZoneLocationTreeCheckbox"
/>
diff --git a/src/pages/Zone/Card/ZoneLocationsTree.vue b/src/pages/Zone/Card/ZoneLocationsTree.vue
index c460143a2..d5d7d52b6 100644
--- a/src/pages/Zone/Card/ZoneLocationsTree.vue
+++ b/src/pages/Zone/Card/ZoneLocationsTree.vue
@@ -1,6 +1,7 @@
+
+
+
{
-
-
+
diff --git a/src/pages/Zone/Card/ZoneSearchbar.vue b/src/pages/Zone/Card/ZoneSearchbar.vue
deleted file mode 100644
index d1188a1e8..000000000
--- a/src/pages/Zone/Card/ZoneSearchbar.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue
index 5b29b495b..5958fe27a 100644
--- a/src/pages/Zone/Card/ZoneSummary.vue
+++ b/src/pages/Zone/Card/ZoneSummary.vue
@@ -60,10 +60,11 @@ onMounted(async () => {
#{{ entity.id }} - {{ entity.name }}
@@ -74,21 +75,30 @@ onMounted(async () => {
-
-
-
+
-
-
-
-
-
-
-
+
{
:class="{
'--today': isToday(timestamp),
}"
+ data-cy="ZoneCalendarDay"
>
{
days.value = {};
if (!data.value) return;
- let day = new Date(firstDay.value.getTime());
+ let day = new Date(firstDay?.value?.getTime());
while (day <= lastDay.value) {
let stamp = day.getTime();
@@ -156,7 +156,7 @@ watch(
(value) => {
data.value = value;
},
- { immediate: true }
+ { immediate: true },
);
const getMonthNameAndYear = (date) => {
diff --git a/src/pages/Zone/ZoneDeliveryDays.vue b/src/pages/Zone/ZoneDeliveryDays.vue
index d95c64d8b..ddde3f6b3 100644
--- a/src/pages/Zone/ZoneDeliveryDays.vue
+++ b/src/pages/Zone/ZoneDeliveryDays.vue
@@ -3,7 +3,6 @@ import { ref } from 'vue';
import ZoneDeliveryPanel from './ZoneDeliveryPanel.vue';
import ZoneCalendarGrid from './ZoneCalendarGrid.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
-import ZoneSearchbar from './Card/ZoneSearchbar.vue';
const firstDay = ref(null);
const lastDay = ref(null);
@@ -11,7 +10,6 @@ const events = ref([]);
-
diff --git a/src/pages/Zone/ZoneDeliveryPanel.vue b/src/pages/Zone/ZoneDeliveryPanel.vue
index 0a535afcb..fc5c04b41 100644
--- a/src/pages/Zone/ZoneDeliveryPanel.vue
+++ b/src/pages/Zone/ZoneDeliveryPanel.vue
@@ -46,7 +46,7 @@ watch(
inq.value = {
deliveryMethodFk: { inq: deliveryMethods.value[deliveryMethodFk.value] },
};
- }
+ },
);
@@ -89,15 +89,15 @@ watch(
v-model="formData.geoFk"
url="Postcodes/location"
:fields="['geoFk', 'code', 'townFk', 'countryFk']"
- :sort-by="['code ASC']"
+ :sort-by="'code ASC'"
option-value="geoFk"
option-label="code"
:filter-options="['code']"
hide-selected
dense
- outlined
- rounded
+ filled
map-key="geoFk"
+ data-cy="ZoneDeliveryDaysPostcodeSelect"
>
@@ -127,8 +127,8 @@ watch(
option-label="name"
hide-selected
dense
- outlined
- rounded
+ filled
+ data-cy="ZoneDeliveryDaysAgencySelect"
/>
diff --git a/src/pages/Zone/ZoneFilterPanel.vue b/src/pages/Zone/ZoneFilterPanel.vue
deleted file mode 100644
index ff65479e4..000000000
--- a/src/pages/Zone/ZoneFilterPanel.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
- (agencies = data)"
- auto-load
- />
-
-
-
- {{ t(`filterPanel.${tag.label}`) }}:
- {{ tag.value }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue
index eb54ec15b..8d7c4a165 100644
--- a/src/pages/Zone/ZoneList.vue
+++ b/src/pages/Zone/ZoneList.vue
@@ -14,9 +14,11 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputTime from 'src/components/common/VnInputTime.vue';
-import RightMenu from 'src/components/common/RightMenu.vue';
-import ZoneFilterPanel from './ZoneFilterPanel.vue';
-import ZoneSearchbar from './Card/ZoneSearchbar.vue';
+
+import VnSection from 'src/components/common/VnSection.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+import ZoneEventInclusionForm from './Card/ZoneEventInclusionForm.vue';
+import ZoneEventExclusionForm from './Card/ZoneEventExclusionForm.vue';
const { t } = useI18n();
const router = useRouter();
@@ -25,7 +27,12 @@ const { viewSummary } = useSummaryDialog();
const { openConfirmationModal } = useVnConfirm();
const tableRef = ref();
const warehouseOptions = ref([]);
-
+const dataKey = 'ZoneList';
+const selectedRows = ref([]);
+const hasSelectedRows = computed(() => selectedRows.value.length > 0);
+const openInclusionForm = ref();
+const showZoneEventForm = ref(false);
+const zoneIds = ref({});
const tableFilter = {
include: [
{
@@ -114,6 +121,7 @@ const columns = computed(() => [
columnFilter: {
inWhere: true,
},
+ columnClass: 'shrink-column',
},
{
align: 'left',
@@ -169,77 +177,180 @@ function formatRow(row) {
return dashIfEmpty(`${row?.address?.nickname},
${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`);
}
+
+const exprBuilder = (param, value) => {
+ switch (param) {
+ case 'name':
+ return {
+ name: { like: `%${value}%` },
+ };
+ case 'code':
+ return {
+ code: { like: `%${value}%` },
+ };
+ case 'agencyModeFk':
+ return {
+ agencyModeFk: value,
+ };
+ case 'search':
+ return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } };
+ case 'price':
+ return {
+ price: value,
+ };
+ }
+};
+
+function openForm(value, rows) {
+ zoneIds.value = rows.map((row) => row.id);
+ openInclusionForm.value = value;
+ showZoneEventForm.value = true;
+}
+
+const closeEventForm = () => {
+ showZoneEventForm.value = false;
+};
-
-
-
-
-
-
-
-
- {{ dashIfEmpty(formatRow(row)) }}
+
+
+
+
+
+ {{ t('list.includeEvent') }}
+
+
+ {{ t('list.excludeEvent') }}
+
+
+
+
+
+
+
+
+ {{ dashIfEmpty(formatRow(row)) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
es:
Search zone: Buscar zona
diff --git a/src/pages/Zone/ZoneUpcoming.vue b/src/pages/Zone/ZoneUpcoming.vue
index adcdfbc04..b8664dc2f 100644
--- a/src/pages/Zone/ZoneUpcoming.vue
+++ b/src/pages/Zone/ZoneUpcoming.vue
@@ -7,7 +7,6 @@ import FetchData from 'components/FetchData.vue';
import { toDateFormat } from 'src/filters/date.js';
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
-import ZoneSearchbar from './Card/ZoneSearchbar.vue';
const { t } = useI18n();
const weekdayStore = useWeekdayStore();
@@ -31,7 +30,7 @@ const columns = computed(() => [
label: t('list.id'),
name: 'id',
field: 'zoneFk',
- align: 'left',
+ align: 'center',
},
]);
@@ -53,7 +52,6 @@ onMounted(() => weekdayStore.initStore());
@on-fetch="(data) => (details = data)"
auto-load
/>
-
diff --git a/src/pages/Zone/locale/en.yml b/src/pages/Zone/locale/en.yml
index e53e7b560..f46a98ee6 100644
--- a/src/pages/Zone/locale/en.yml
+++ b/src/pages/Zone/locale/en.yml
@@ -11,10 +11,13 @@ zone:
m3Max: Max m³
deleteTitle: This item will be deleted
deleteSubtitle: Are you sure you want to continue?
- volumetric: Volumetric
bonus: Bonus
closing: Closing
travelingDays: Traveling days
+ search: Search zone
+ searchInfo: Search zone by id or name
+ searchLocations: Search locations
+ searchLocationsInfo: Search locations by post code
list:
clone: Clone
id: Id
@@ -22,6 +25,7 @@ list:
agency: Agency
close: Close
price: Price
+ priceOptimum: Optimal price
create: Create zone
openSummary: Details
searchZone: Search zones
@@ -30,9 +34,12 @@ list:
confirmCloneTitle: All it's properties will be copied
confirmCloneSubtitle: Do you want to clone this zone?
warehouse: Warehouse
+ isVolumetric: Volumetric
createZone: Create zone
zoneSummary: Summary
addressFk: Address
+ includeEvent: Include event
+ excludeEvent: Exclude event
create:
name: Name
closingHour: Closing hour
diff --git a/src/pages/Zone/locale/es.yml b/src/pages/Zone/locale/es.yml
index bc31e74a9..7a23bdc02 100644
--- a/src/pages/Zone/locale/es.yml
+++ b/src/pages/Zone/locale/es.yml
@@ -15,6 +15,10 @@ zone:
bonus: Bonificación
closing: Cierre
travelingDays: Días de viaje
+ search: Buscar zona
+ searchInfo: Buscar zona por Id o nombre
+ searchLocations: Buscar localización
+ searchLocationsInfo: Buscar localización por código postal
list:
clone: Clonar
id: Id
@@ -35,6 +39,8 @@ list:
createZone: Crear zona
zoneSummary: Resumen
addressFk: Consignatario
+ includeEvent: Incluir evento
+ excludeEvent: Excluir evento
create:
closingHour: Hora de cierre
itemMaxSize: Medida máxima
diff --git a/src/router/__tests__/hooks.spec.js b/src/router/__tests__/hooks.spec.js
new file mode 100644
index 000000000..97f5eacdc
--- /dev/null
+++ b/src/router/__tests__/hooks.spec.js
@@ -0,0 +1,36 @@
+import { describe, it, expect, vi } from 'vitest';
+import { ref, nextTick } from 'vue';
+import { stateQueryGuard } from 'src/router/hooks';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
+
+vi.mock('src/stores/useStateQueryStore', () => {
+ const isLoading = ref(true);
+ return {
+ useStateQueryStore: () => ({
+ isLoading: () => isLoading,
+ setLoading: isLoading,
+ }),
+ };
+});
+
+describe('hooks', () => {
+ describe('stateQueryGuard', () => {
+ const foo = { name: 'foo' };
+ it('should wait until the state query is not loading and then call next()', async () => {
+ const next = vi.fn();
+
+ stateQueryGuard(foo, { name: 'bar' }, next);
+ expect(next).not.toHaveBeenCalled();
+
+ useStateQueryStore().setLoading.value = false;
+ await nextTick();
+ expect(next).toHaveBeenCalled();
+ });
+
+ it('should ignore if both routes are the same', () => {
+ const next = vi.fn();
+ stateQueryGuard(foo, foo, next);
+ expect(next).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/router/hooks.js b/src/router/hooks.js
new file mode 100644
index 000000000..bd9e5334f
--- /dev/null
+++ b/src/router/hooks.js
@@ -0,0 +1,95 @@
+import { useRole } from 'src/composables/useRole';
+import { useUserConfig } from 'src/composables/useUserConfig';
+import { useTokenConfig } from 'src/composables/useTokenConfig';
+import { useAcl } from 'src/composables/useAcl';
+import { isLoggedIn } from 'src/utils/session';
+import { useSession } from 'src/composables/useSession';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
+import { watch } from 'vue';
+import { i18n } from 'src/boot/i18n';
+
+let session = null;
+const { t, te } = i18n.global;
+
+export async function navigationGuard(to, from, next, Router, state) {
+ if (!session) session = useSession();
+ const outLayout = Router.options.routes[0].children.map((r) => r.name);
+ if (!session.isLoggedIn() && !outLayout.includes(to.name)) {
+ return next({ name: 'Login', query: { redirect: to.fullPath } });
+ }
+
+ if (isLoggedIn()) {
+ const stateRoles = state.getRoles().value;
+ if (stateRoles.length === 0) {
+ await useRole().fetch();
+ await useAcl().fetch();
+ await useUserConfig().fetch();
+ await useTokenConfig().fetch();
+ }
+ const matches = to.matched;
+ const hasRequiredAcls = matches.every((route) => {
+ const meta = route.meta;
+ if (!meta?.acls) return true;
+ return useAcl().hasAny(meta.acls);
+ });
+ if (!hasRequiredAcls) return next({ path: '/' });
+ }
+
+ next();
+}
+
+export async function stateQueryGuard(to, from, next) {
+ if (to.name !== from.name) {
+ const stateQuery = useStateQueryStore();
+ await waitUntilFalse(stateQuery.isLoading());
+ }
+
+ next();
+}
+
+export function setPageTitle(to) {
+ let title = t(`login.title`);
+
+ const matches = to.matched;
+ if (matches && matches.length > 1) {
+ const module = matches[1];
+ const moduleTitle = module.meta?.title;
+ if (moduleTitle) {
+ title = t(`globals.pageTitles.${moduleTitle}`);
+ }
+ }
+
+ const childPage = to.meta;
+ const childPageTitle = childPage?.title;
+ if (childPageTitle && matches.length > 2) {
+ if (title != '') title += ': ';
+
+ const moduleLocale = `globals.pageTitles.${childPageTitle}`;
+ const pageTitle = te(moduleLocale)
+ ? t(moduleLocale)
+ : t(`globals.pageTitles.${childPageTitle}`);
+ const idParam = to.params?.id;
+ const idPageTitle = `${idParam} - ${pageTitle}`;
+ const builtTitle = idParam ? idPageTitle : pageTitle;
+
+ title += builtTitle;
+ }
+
+ document.title = title;
+}
+
+function waitUntilFalse(ref) {
+ return new Promise((resolve) => {
+ if (!ref.value) return resolve();
+ const stop = watch(
+ ref,
+ (val) => {
+ if (!val) {
+ stop();
+ resolve();
+ }
+ },
+ { immediate: true },
+ );
+ });
+}
diff --git a/src/router/index.js b/src/router/index.js
index 4403901cb..628a53c8e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -6,101 +6,25 @@ import {
createWebHashHistory,
} from 'vue-router';
import routes from './routes';
-import { i18n } from 'src/boot/i18n';
import { useState } from 'src/composables/useState';
-import { useRole } from 'src/composables/useRole';
-import { useUserConfig } from 'src/composables/useUserConfig';
-import { useTokenConfig } from 'src/composables/useTokenConfig';
-import { useAcl } from 'src/composables/useAcl';
-import { isLoggedIn } from 'src/utils/session';
-import { useSession } from 'src/composables/useSession';
+import { navigationGuard, setPageTitle, stateQueryGuard } from './hooks';
-let session = null;
-const { t, te } = i18n.global;
-
-const createHistory = process.env.SERVER
- ? createMemoryHistory
- : process.env.VUE_ROUTER_MODE === 'history'
- ? createWebHistory
- : createWebHashHistory;
+const webHistory =
+ process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory;
+const createHistory = process.env.SERVER ? createMemoryHistory : webHistory;
const Router = createRouter({
scrollBehavior: () => ({ left: 0, top: 0 }),
routes,
-
- // Leave this as is and make changes in quasar.conf.js instead!
- // quasar.conf.js -> build -> vueRouterMode
- // quasar.conf.js -> build -> publicPath
history: createHistory(process.env.VUE_ROUTER_BASE),
});
-/*
- * If not building with SSR mode, you can
- * directly export the Router instantiation;
- *
- * The function below can be async too; either use
- * async/await or return a Promise which resolves
- * with the Router instance.
- */
export { Router };
-export default defineRouter(function (/* { store, ssrContext } */) {
+export default defineRouter(() => {
const state = useState();
- Router.beforeEach(async (to, from, next) => {
- if (!session) session = useSession();
- const outLayout = Router.options.routes[0].children.map((r) => r.name);
- if (!session.isLoggedIn() && !outLayout.includes(to.name)) {
- return next({ name: 'Login', query: { redirect: to.fullPath } });
- }
-
- if (isLoggedIn()) {
- const stateRoles = state.getRoles().value;
- if (stateRoles.length === 0) {
- await useRole().fetch();
- await useAcl().fetch();
- await useUserConfig().fetch();
- await useTokenConfig().fetch();
- }
- const matches = to.matched;
- const hasRequiredAcls = matches.every((route) => {
- const meta = route.meta;
- if (!meta?.acls) return true;
- return useAcl().hasAny(meta.acls);
- });
- if (!hasRequiredAcls) return next({ path: '/' });
- }
-
- next();
- });
-
- Router.afterEach((to) => {
- let title = t(`login.title`);
-
- const matches = to.matched;
- if (matches && matches.length > 1) {
- const module = matches[1];
- const moduleTitle = module.meta && module.meta.title;
- if (moduleTitle) {
- title = t(`globals.pageTitles.${moduleTitle}`);
- }
- }
-
- const childPage = to.meta;
- const childPageTitle = childPage && childPage.title;
- if (childPageTitle && matches.length > 2) {
- if (title != '') title += ': ';
-
- const moduleLocale = `globals.pageTitles.${childPageTitle}`;
- const pageTitle = te(moduleLocale)
- ? t(moduleLocale)
- : t(`globals.pageTitles.${childPageTitle}`);
- const idParam = to.params && to.params.id;
- const idPageTitle = `${idParam} - ${pageTitle}`;
- const builtTitle = idParam ? idPageTitle : pageTitle;
-
- title += builtTitle;
- }
- document.title = title;
- });
+ Router.beforeEach((to, from, next) => navigationGuard(to, from, next, Router, state));
+ Router.beforeEach(stateQueryGuard);
+ Router.afterEach(setPageTitle);
Router.onError(({ message }) => {
const errorMessages = [
diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js
index 67b00b161..a33ed6be5 100644
--- a/src/router/modules/customer.js
+++ b/src/router/modules/customer.js
@@ -4,8 +4,8 @@ const customerCard = {
name: 'CustomerCard',
path: ':id',
component: () => import('src/pages/Customer/Card/CustomerCard.vue'),
- redirect: { name: 'CustomerSummary' },
- meta: {
+ redirect: { name: 'CustomerSummary' },
+ meta: {
menu: [
'CustomerBasicData',
'CustomerFiscalData',
@@ -40,8 +40,7 @@ const customerCard = {
title: 'basicData',
icon: 'vn:settings',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerBasicData.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerBasicData.vue'),
},
{
path: 'fiscal-data',
@@ -50,8 +49,7 @@ const customerCard = {
title: 'fiscalData',
icon: 'vn:dfiscales',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerFiscalData.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerFiscalData.vue'),
},
{
path: 'billing-data',
@@ -60,8 +58,7 @@ const customerCard = {
title: 'billingData',
icon: 'vn:payment',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerBillingData.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerBillingData.vue'),
},
{
path: 'address',
@@ -85,9 +82,7 @@ const customerCard = {
title: 'address-create',
},
component: () =>
- import(
- 'src/pages/Customer/components/CustomerAddressCreate.vue'
- ),
+ import('src/pages/Customer/components/CustomerAddressCreate.vue'),
},
{
path: ':addressId',
@@ -125,8 +120,7 @@ const customerCard = {
title: 'credits',
icon: 'vn:credit',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerCredits.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerCredits.vue'),
},
{
path: 'greuges',
@@ -135,8 +129,7 @@ const customerCard = {
title: 'greuges',
icon: 'vn:greuge',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerGreuges.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerGreuges.vue'),
},
{
path: 'balance',
@@ -145,8 +138,7 @@ const customerCard = {
title: 'balance',
icon: 'balance',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerBalance.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerBalance.vue'),
},
{
path: 'recoveries',
@@ -155,8 +147,7 @@ const customerCard = {
title: 'recoveries',
icon: 'vn:recovery',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerRecoveries.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerRecoveries.vue'),
},
{
path: 'web-access',
@@ -165,8 +156,7 @@ const customerCard = {
title: 'webAccess',
icon: 'vn:web',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerWebAccess.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerWebAccess.vue'),
},
{
path: 'log',
@@ -247,9 +237,7 @@ const customerCard = {
title: 'creditOpinion',
},
component: () =>
- import(
- 'src/pages/Customer/Card/CustomerCreditOpinion.vue'
- ),
+ import('src/pages/Customer/Card/CustomerCreditOpinion.vue'),
},
],
},
@@ -319,9 +307,7 @@ const customerCard = {
title: 'samples',
},
component: () =>
- import(
- 'src/pages/Customer/Card/CustomerSamples.vue'
- ),
+ import('src/pages/Customer/Card/CustomerSamples.vue'),
},
{
path: 'create',
@@ -376,9 +362,7 @@ const customerCard = {
title: 'fileManagement',
},
component: () =>
- import(
- 'src/pages/Customer/Card/CustomerFileManagement.vue'
- ),
+ import('src/pages/Customer/Card/CustomerFileManagement.vue'),
},
{
path: 'file-management',
@@ -420,8 +404,7 @@ const customerCard = {
meta: {
title: 'unpaid',
},
- component: () =>
- import('src/pages/Customer/Card/CustomerUnpaid.vue'),
+ component: () => import('src/pages/Customer/Card/CustomerUnpaid.vue'),
},
],
},
@@ -429,7 +412,7 @@ const customerCard = {
};
export default {
- name: 'Customer',
+ name: 'Customer',
path: '/customer',
meta: {
title: 'customers',
@@ -469,15 +452,6 @@ export default {
customerCard,
],
},
- {
- path: 'create',
- name: 'CustomerCreate',
- meta: {
- title: 'customerCreate',
- icon: 'add',
- },
- component: () => import('src/pages/Customer/CustomerCreate.vue'),
- },
{
path: 'payments',
name: 'CustomerPayments',
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index b5656dc5f..02eea8c6c 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -81,7 +81,7 @@ export default {
keyBinding: 'e',
menu: [
'EntryList',
- 'MyEntries',
+ 'EntrySupplier',
'EntryLatestBuys',
'EntryStockBought',
'EntryWasteRecalc',
@@ -125,21 +125,12 @@ export default {
},
{
path: 'my',
- name: 'MyEntries',
+ name: 'EntrySupplier',
meta: {
title: 'labeler',
icon: 'sell',
},
- component: () => import('src/pages/Entry/MyEntries.vue'),
- },
- {
- path: 'latest-buys',
- name: 'EntryLatestBuys',
- meta: {
- title: 'latestBuys',
- icon: 'contact_support',
- },
- component: () => import('src/pages/Entry/EntryLatestBuys.vue'),
+ component: () => import('src/pages/Entry/EntrySupplier.vue'),
},
{
path: 'stock-Bought',
diff --git a/src/router/modules/monitor.js b/src/router/modules/monitor.js
index 89ba4078f..3f30ace72 100644
--- a/src/router/modules/monitor.js
+++ b/src/router/modules/monitor.js
@@ -8,13 +8,10 @@ export default {
icon: 'grid_view',
moduleName: 'Monitor',
keyBinding: 'm',
+ menu: ['MonitorTickets', 'MonitorClientsActions'],
},
component: RouterView,
redirect: { name: 'MonitorMain' },
- menus: {
- main: ['MonitorTickets', 'MonitorClientsActions'],
- card: [],
- },
children: [
{
path: '',
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 835324d20..0dd41c86e 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -166,7 +166,7 @@ const vehicleCard = {
component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'),
redirect: { name: 'VehicleSummary' },
meta: {
- menu: ['VehicleBasicData'],
+ menu: ['VehicleBasicData', 'VehicleNotes'],
},
children: [
{
@@ -187,6 +187,15 @@ const vehicleCard = {
},
component: () => import('src/pages/Route/Vehicle/Card/VehicleBasicData.vue'),
},
+ {
+ name: 'VehicleNotes',
+ path: 'notes',
+ meta: {
+ title: 'notes',
+ icon: 'vn:notes',
+ },
+ component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'),
+ }
],
};
@@ -229,6 +238,7 @@ export default {
title: 'list',
icon: 'view_list',
},
+ component: () => import('src/pages/Route/RouteList.vue'),
},
routeCard,
],
@@ -264,11 +274,11 @@ export default {
path: 'roadmap',
name: 'RouteRoadmap',
redirect: { name: 'RoadmapList' },
+ component: () => import('src/pages/Route/RouteRoadmap.vue'),
meta: {
title: 'RouteRoadmap',
icon: 'vn:troncales',
},
- component: () => import('src/pages/Route/RouteRoadmap.vue'),
children: [
{
name: 'RoadmapList',
@@ -277,6 +287,7 @@ export default {
title: 'list',
icon: 'view_list',
},
+ component: () => import('src/pages/Route/RouteRoadmap.vue'),
},
roadmapCard,
],
@@ -294,11 +305,11 @@ export default {
path: 'agency',
name: 'RouteAgency',
redirect: { name: 'AgencyList' },
+ component: () => import('src/pages/Route/Agency/AgencyList.vue'),
meta: {
title: 'agency',
icon: 'garage_home',
},
- component: () => import('src/pages/Route/Agency/AgencyList.vue'),
children: [
{
name: 'AgencyList',
@@ -307,6 +318,8 @@ export default {
title: 'list',
icon: 'view_list',
},
+ component: () =>
+ import('src/pages/Route/Agency/AgencyList.vue'),
},
agencyCard,
],
@@ -315,11 +328,11 @@ export default {
path: 'vehicle',
name: 'RouteVehicle',
redirect: { name: 'VehicleList' },
+ component: () => import('src/pages/Route/Vehicle/VehicleList.vue'),
meta: {
title: 'vehicle',
icon: 'directions_car',
},
- component: () => import('src/pages/Route/Vehicle/VehicleList.vue'),
children: [
{
path: 'list',
@@ -328,6 +341,8 @@ export default {
title: 'vehicleList',
icon: 'directions_car',
},
+ component: () =>
+ import('src/pages/Route/Vehicle/VehicleList.vue'),
},
vehicleCard,
],
diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js
index c085dd8dc..94ff274dc 100644
--- a/src/router/modules/shelving.js
+++ b/src/router/modules/shelving.js
@@ -111,15 +111,6 @@ export default {
shelvingCard,
],
},
- {
- path: 'create',
- name: 'ShelvingCreate',
- meta: {
- title: 'shelvingCreate',
- icon: 'add',
- },
- component: () => import('src/pages/Shelving/Card/ShelvingForm.vue'),
- },
{
path: 'parking',
name: 'ParkingMain',
diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js
index 4a322d305..798c671eb 100644
--- a/src/router/modules/wagon.js
+++ b/src/router/modules/wagon.js
@@ -1,52 +1,60 @@
import { RouterView } from 'vue-router';
+const wagonCard = {
+ name: 'WagonCard',
+ path: ':id',
+ component: () => import('src/pages/Wagon/Card/WagonCard.vue'),
+ redirect: { name: 'WagonEdit' },
+ meta: {
+ menu: ['WagonEdit'],
+ },
+ children: [
+ {
+ path: 'edit',
+ name: 'WagonEdit',
+ meta: {
+ title: 'wagonEdit',
+ icon: 'edit',
+ },
+ component: () => import('src/pages/Wagon/WagonCreate.vue'),
+ },
+ ],
+};
+
export default {
- path: '/wagon',
name: 'Wagon',
+ path: '/wagon',
meta: {
title: 'wagons',
icon: 'vn:trolley',
moduleName: 'Wagon',
+ menu: ['WagonList', 'WagonTypeList', 'WagonCounter'],
},
component: RouterView,
redirect: { name: 'WagonMain' },
- menus: {
- main: ['WagonList', 'WagonTypeList', 'WagonCounter', 'WagonTray'],
- card: [],
- },
children: [
{
- path: '/wagon',
+ path: '',
name: 'WagonMain',
component: () => import('src/components/common/VnModule.vue'),
- redirect: { name: 'WagonList' },
+ redirect: { name: 'WagonIndexMain' },
children: [
{
- path: 'list',
- name: 'WagonList',
- meta: {
- title: 'list',
- icon: 'vn:trolley',
- },
+ path: '',
+ name: 'WagonIndexMain',
+ redirect: { name: 'WagonList' },
component: () => import('src/pages/Wagon/WagonList.vue'),
- },
- {
- path: 'create',
- name: 'WagonCreate',
- meta: {
- title: 'wagonCreate',
- icon: 'create',
- },
- component: () => import('src/pages/Wagon/WagonCreate.vue'),
- },
- {
- path: ':id/edit',
- name: 'WagonEdit',
- meta: {
- title: 'wagonEdit',
- icon: 'edit',
- },
- component: () => import('src/pages/Wagon/WagonCreate.vue'),
+ children: [
+ {
+ name: 'WagonList',
+ path: 'list',
+ meta: {
+ title: 'list',
+ icon: 'view_list',
+ },
+ },
+ wagonCard,
+ ],
},
{
path: 'counter',
@@ -57,40 +65,32 @@ export default {
},
component: () => import('src/pages/Wagon/WagonCounter.vue'),
},
- ],
- },
- {
- path: '/wagon/type',
- name: 'WagonTypeMain',
- component: () => import('src/components/common/VnModule.vue'),
- redirect: { name: 'WagonTypeList' },
- children: [
{
- path: 'list',
- name: 'WagonTypeList',
- meta: {
- title: 'typesList',
- icon: 'view_list',
- },
- component: () => import('src/pages/Wagon/Type/WagonTypeList.vue'),
- },
- {
- path: 'create',
- name: 'WagonTypeCreate',
- meta: {
- title: 'typeCreate',
- icon: 'create',
- },
- component: () => import('src/pages/Wagon/Type/WagonTypeList.vue'),
- },
- {
- path: ':id/edit',
- name: 'WagonTypeEdit',
- meta: {
- title: 'typeEdit',
- icon: 'edit',
- },
- component: () => import('src/pages/Wagon/Type/WagonTypeEdit.vue'),
+ path: 'type',
+ name: 'WagonTypeMain',
+ redirect: { name: 'WagonTypeList' },
+ children: [
+ {
+ path: 'list',
+ name: 'WagonTypeList',
+ meta: {
+ title: 'typesList',
+ icon: 'view_list',
+ },
+ component: () =>
+ import('src/pages/Wagon/Type/WagonTypeList.vue'),
+ },
+ {
+ path: ':id/edit',
+ name: 'WagonTypeEdit',
+ meta: {
+ title: 'typeEdit',
+ icon: 'edit',
+ },
+ component: () =>
+ import('src/pages/Wagon/Type/WagonTypeEdit.vue'),
+ },
+ ],
},
],
},
diff --git a/src/router/modules/zone.js b/src/router/modules/zone.js
index f400a708e..f48a715b9 100644
--- a/src/router/modules/zone.js
+++ b/src/router/modules/zone.js
@@ -1,24 +1,12 @@
import { RouterView } from 'vue-router';
-export default {
- path: '/zone',
- name: 'Zone',
+const zoneCard = {
+ name: 'ZoneCard',
+ path: ':id',
+ component: () => import('src/pages/Zone/Card/ZoneCard.vue'),
+ redirect: { name: 'ZoneSummary' },
meta: {
- title: 'zones',
- icon: 'vn:zone',
- moduleName: 'Zone',
- keyBinding: 'z',
- },
- component: RouterView,
- redirect: { name: 'ZoneMain' },
- menus: {
- main: [
- 'ZoneList',
- 'ZoneDeliveryDays',
- 'ZoneUpcomingList',
- 'ZoneUpcomingDeliveries',
- ],
- card: [
+ menu: [
'ZoneBasicData',
'ZoneWarehouses',
'ZoneHistory',
@@ -28,19 +16,102 @@ export default {
},
children: [
{
- path: '/zone',
+ name: 'ZoneSummary',
+ path: 'summary',
+ meta: {
+ title: 'summary',
+ icon: 'launch',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneSummary.vue'),
+ },
+ {
+ path: 'basic-data',
+ name: 'ZoneBasicData',
+ meta: {
+ title: 'basicData',
+ icon: 'vn:settings',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneBasicData.vue'),
+ },
+ {
+ path: 'location',
+ name: 'ZoneLocations',
+ meta: {
+ title: 'locations',
+ icon: 'my_location',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneLocations.vue'),
+ },
+ {
+ path: 'warehouses',
+ name: 'ZoneWarehouses',
+ meta: {
+ title: 'warehouses',
+ icon: 'home',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneWarehouses.vue'),
+ },
+ {
+ path: 'log',
+ name: 'ZoneHistory',
+ meta: {
+ title: 'log',
+ icon: 'history',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneLog.vue'),
+ },
+ {
+ path: 'events',
+ name: 'ZoneEvents',
+ meta: {
+ title: 'calendar',
+ icon: 'vn:calendar',
+ },
+ component: () => import('src/pages/Zone/Card/ZoneEvents.vue'),
+ },
+ ],
+};
+
+export default {
+ name: 'Zone',
+ path: '/zone',
+ meta: {
+ title: 'zones',
+ icon: 'vn:zone',
+ moduleName: 'Zone',
+ keyBinding: 'z',
+ menu: [
+ 'ZoneList',
+ 'ZoneDeliveryDays',
+ 'ZoneUpcomingList',
+ 'ZoneUpcomingDeliveries',
+ ],
+ },
+ component: RouterView,
+ redirect: { name: 'ZoneMain' },
+ children: [
+ {
name: 'ZoneMain',
+ path: '',
component: () => import('src/components/common/VnModule.vue'),
- redirect: { name: 'ZoneList' },
+ redirect: { name: 'ZoneIndexMain' },
children: [
{
- path: 'list',
- name: 'ZoneList',
- meta: {
- title: 'zonesList',
- icon: 'view_list',
- },
+ path: '',
+ name: 'ZoneIndexMain',
+ redirect: { name: 'ZoneList' },
component: () => import('src/pages/Zone/ZoneList.vue'),
+ children: [
+ {
+ name: 'ZoneList',
+ path: 'list',
+ meta: {
+ title: 'list',
+ icon: 'view_list',
+ },
+ },
+ zoneCard,
+ ],
},
{
path: 'delivery-days',
@@ -62,67 +133,5 @@ export default {
},
],
},
- {
- name: 'ZoneCard',
- path: ':id',
- component: () => import('src/pages/Zone/Card/ZoneCard.vue'),
- redirect: { name: 'ZoneSummary' },
- children: [
- {
- name: 'ZoneSummary',
- path: 'summary',
- meta: {
- title: 'summary',
- icon: 'launch',
- },
- component: () => import('src/pages/Zone/Card/ZoneSummary.vue'),
- },
- {
- name: 'ZoneBasicData',
- path: 'basic-data',
- meta: {
- title: 'basicData',
- icon: 'vn:settings',
- },
- component: () => import('src/pages/Zone/Card/ZoneBasicData.vue'),
- },
- {
- name: 'ZoneLocations',
- path: 'location',
- meta: {
- title: 'locations',
- icon: 'my_location',
- },
- component: () => import('src/pages/Zone/Card/ZoneLocations.vue'),
- },
- {
- name: 'ZoneWarehouses',
- path: 'warehouses',
- meta: {
- title: 'warehouses',
- icon: 'home',
- },
- component: () => import('src/pages/Zone/Card/ZoneWarehouses.vue'),
- },
- {
- name: 'ZoneHistory',
- path: 'log',
- meta: {
- title: 'log',
- icon: 'history',
- },
- component: () => import('src/pages/Zone/Card/ZoneLog.vue'),
- },
- {
- name: 'ZoneEvents',
- path: 'events',
- meta: {
- title: 'calendar',
- icon: 'vn:calendar',
- },
- component: () => import('src/pages/Zone/Card/ZoneEvents.vue'),
- },
- ],
- },
],
};
diff --git a/src/stores/__tests__/useDescriptorStore.spec.js b/src/stores/__tests__/useDescriptorStore.spec.js
new file mode 100644
index 000000000..61aab8d14
--- /dev/null
+++ b/src/stores/__tests__/useDescriptorStore.spec.js
@@ -0,0 +1,28 @@
+import { describe, expect, it, beforeEach } from 'vitest';
+import 'app/test/vitest/helper';
+
+import { useDescriptorStore } from 'src/stores/useDescriptorStore';
+import { useStateStore } from 'stores/useStateStore';
+
+describe('useDescriptorStore', () => {
+ const { get, has } = useDescriptorStore();
+ const stateStore = useStateStore();
+
+ beforeEach(() => {
+ stateStore.setDescriptors({});
+ });
+
+ function getDescriptors() {
+ return stateStore.descriptors;
+ }
+
+ it('should get descriptors in stateStore', async () => {
+ expect(Object.keys(getDescriptors()).length).toBe(0);
+ get();
+ expect(Object.keys(getDescriptors()).length).toBeGreaterThan(0);
+ });
+
+ it('should find ticketDescriptor if search ticketFk', async () => {
+ expect(has('ticketFk')).toBeDefined();
+ });
+});
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
index b3996d1e3..569ff1c7e 100644
--- a/src/stores/useArrayDataStore.js
+++ b/src/stores/useArrayDataStore.js
@@ -18,7 +18,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
navigate: null,
page: 1,
mapKey: 'id',
- keepData: false,
oneRecord: false,
};
diff --git a/src/stores/useDescriptorStore.js b/src/stores/useDescriptorStore.js
new file mode 100644
index 000000000..be342b016
--- /dev/null
+++ b/src/stores/useDescriptorStore.js
@@ -0,0 +1,33 @@
+import { defineAsyncComponent } from 'vue';
+import { defineStore } from 'pinia';
+import { useStateStore } from 'stores/useStateStore';
+
+export const useDescriptorStore = defineStore('descriptorStore', () => {
+ const { descriptors, setDescriptors } = useStateStore();
+ function get() {
+ if (Object.keys(descriptors).length) return descriptors;
+
+ const currentDescriptors = {};
+ const files = import.meta.glob(`/src/**/*DescriptorProxy.vue`);
+ const moduleParser = {
+ account: 'user',
+ customer: 'client',
+ };
+ for (const file in files) {
+ const name = file.split('/').at(-1).slice(0, -19).toLowerCase();
+ const descriptor = moduleParser[name] ?? name;
+ currentDescriptors[descriptor + 'Fk'] = defineAsyncComponent(files[file]);
+ }
+ setDescriptors(currentDescriptors);
+ return currentDescriptors;
+ }
+
+ function has(name) {
+ return get()[name];
+ }
+
+ return {
+ has,
+ get,
+ };
+});
diff --git a/src/stores/useStateStore.js b/src/stores/useStateStore.js
index ca447bc11..44fa133d0 100644
--- a/src/stores/useStateStore.js
+++ b/src/stores/useStateStore.js
@@ -8,6 +8,7 @@ export const useStateStore = defineStore('stateStore', () => {
const rightAdvancedDrawer = ref(false);
const subToolbar = ref(false);
const cardDescriptor = ref(null);
+ const descriptors = ref({});
function cardDescriptorChangeValue(descriptor) {
cardDescriptor.value = descriptor;
@@ -52,6 +53,10 @@ export const useStateStore = defineStore('stateStore', () => {
return subToolbar.value;
}
+ function setDescriptors(value) {
+ descriptors.value = value;
+ }
+
return {
cardDescriptor,
cardDescriptorChangeValue,
@@ -68,5 +73,7 @@ export const useStateStore = defineStore('stateStore', () => {
isSubToolbarShown,
toggleSubToolbar,
rightDrawerChangeValue,
+ descriptors,
+ setDescriptors,
};
});
diff --git a/src/stores/useWeekdayStore.js b/src/stores/useWeekdayStore.js
index 57a302dc1..bf6b2704d 100644
--- a/src/stores/useWeekdayStore.js
+++ b/src/stores/useWeekdayStore.js
@@ -77,14 +77,14 @@ export const useWeekdayStore = defineStore('weekdayStore', () => {
const locales = {};
for (let code of localeOrder.es) {
const weekDay = weekdaysMap[code];
- const locale = t(`weekdays.${weekdaysMap[code].code}`);
+ const locale = t(`weekdays.${weekDay?.code}`);
const obj = {
...weekDay,
locale,
localeChar: locale.substr(0, 1),
localeAbr: locale.substr(0, 3),
};
- locales[weekDay.code] = obj;
+ locales[weekDay?.code] = obj;
}
return locales;
});
diff --git a/test/cypress/.gitignore b/test/cypress/.gitignore
index 3a1fcbf37..52595efbc 100644
--- a/test/cypress/.gitignore
+++ b/test/cypress/.gitignore
@@ -5,3 +5,4 @@ downloads/*
storage/*
reports/*
docker/logs/*
+results/*
diff --git a/test/cypress/cypressParallel.sh b/test/cypress/cypressParallel.sh
new file mode 100644
index 000000000..8ef26bcde
--- /dev/null
+++ b/test/cypress/cypressParallel.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+find 'test/cypress/integration' \
+ -mindepth 1 \
+ -maxdepth 1 \
+ -type d | \
+xargs -P "$1" -I {} sh -c '
+ echo "🔷 {}" &&
+ xvfb-run -a cypress run \
+ --headless \
+ --spec "{}" \
+ --quiet \
+ > /dev/null
+'
+wait
diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/Order/orderCatalog.spec.js
index a106d0e8a..050dd396c 100644
--- a/test/cypress/integration/Order/orderCatalog.spec.js
+++ b/test/cypress/integration/Order/orderCatalog.spec.js
@@ -34,7 +34,7 @@ describe('OrderCatalog', () => {
searchByCustomTagInput('Silver');
});
- it('filters by custom value dialog', () => {
+ it.skip('filters by custom value dialog', () => {
Cypress.on('uncaught:exception', (err) => {
if (err.message.includes('canceled')) {
return false;
@@ -55,9 +55,9 @@ describe('OrderCatalog', () => {
it('removes a secondary tag', () => {
cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
cy.selectOption('[data-cy="catalogFilterType"]', 'Anthurium');
- cy.dataCy('vnFilterPanelChip').should('exist');
+ cy.dataCy('vnFilterPanelChip_typeFk').should('exist');
cy.get('[data-cy="catalogFilterCustomTag"] > .q-chip__icon--remove').click();
- cy.dataCy('vnFilterPanelChip').should('not.exist');
+ cy.dataCy('vnFilterPanelChip_typeFk').should('not.exist');
});
it('Removes category tag', () => {
diff --git a/test/cypress/integration/account/accountDescriptorMenu.spec.js b/test/cypress/integration/account/accountDescriptorMenu.spec.js
index 67a7d8ef6..04fc57040 100644
--- a/test/cypress/integration/account/accountDescriptorMenu.spec.js
+++ b/test/cypress/integration/account/accountDescriptorMenu.spec.js
@@ -1,4 +1,4 @@
-describe('ClaimNotes', () => {
+describe('Account descriptor', () => {
const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list';
const url = '/#/account/1/summary';
@@ -7,6 +7,9 @@ describe('ClaimNotes', () => {
cy.visit(url);
cy.dataCy('descriptor-more-opts').click();
cy.get(descriptorOptions)
+ .should('exist')
+ .should('be.visible')
+
.find('.q-item')
.its('length')
.then((count) => {
diff --git a/test/cypress/integration/claim/claimAction.spec.js b/test/cypress/integration/claim/claimAction.spec.js
index 57b501114..8f406ad2f 100644
--- a/test/cypress/integration/claim/claimAction.spec.js
+++ b/test/cypress/integration/claim/claimAction.spec.js
@@ -15,12 +15,14 @@ describe.skip('ClaimAction', () => {
cy.get('[title="Import claim"]').click();
});
- it('should change destination', () => {
+ // https://redmine.verdnatura.es/issues/8756
+ xit('should change destination', () => {
const rowData = [true, null, null, 'Bueno'];
cy.fillRow(firstRow, rowData);
});
- it('should change destination from other button', () => {
+ // https://redmine.verdnatura.es/issues/8756
+ xit('should change destination from other button', () => {
const rowData = [true];
cy.fillRow(firstRow, rowData);
@@ -33,7 +35,8 @@ describe.skip('ClaimAction', () => {
cy.get('[title="Regularize"]').click();
});
- it('should remove the line', () => {
+ // https://redmine.verdnatura.es/issues/8756
+ xit('should remove the line', () => {
cy.fillRow(firstRow, [true]);
cy.removeCard();
cy.clickConfirm();
diff --git a/test/cypress/integration/claim/claimDevelopment.spec.js b/test/cypress/integration/claim/claimDevelopment.spec.js
index 7ca6472af..097d870df 100755
--- a/test/cypress/integration/claim/claimDevelopment.spec.js
+++ b/test/cypress/integration/claim/claimDevelopment.spec.js
@@ -1,5 +1,5 @@
///
-describe('ClaimDevelopment', () => {
+describe.skip('ClaimDevelopment', () => {
const claimId = 1;
const firstLineReason = 'tbody > :nth-child(1) > :nth-child(2)';
const thirdRow = 'tbody > :nth-child(3)';
@@ -10,8 +10,6 @@ describe('ClaimDevelopment', () => {
cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/claim/${claimId}/development`);
- cy.intercept('GET', /\/api\/Workers\/search/).as('workers');
- cy.intercept('GET', /\/api\/Workers\/search/).as('workers');
cy.waitForElement('tbody');
});
@@ -21,11 +19,10 @@ describe('ClaimDevelopment', () => {
cy.getValue(firstLineReason).should('equal', lastReason);
});
- it('should edit line', () => {
+ it.skip('should edit line', () => {
cy.selectOption(firstLineReason, newReason);
cy.saveCard();
- cy.login('developer');
cy.visit(`/#/claim/${claimId}/development`);
cy.getValue(firstLineReason).should('equal', newReason);
@@ -36,7 +33,6 @@ describe('ClaimDevelopment', () => {
});
it('should add and remove new line', () => {
- cy.wait(['@workers', '@workers']);
cy.addCard();
cy.waitForElement(thirdRow);
@@ -52,12 +48,9 @@ describe('ClaimDevelopment', () => {
cy.fillRow(thirdRow, rowData);
cy.saveCard();
- cy.login('developer');
- cy.visit(`/#/claim/${claimId}/development`);
-
cy.validateRow(thirdRow, rowData);
- cy.reload();
+ cy.visit(`/#/claim/${claimId}/development`);
cy.validateRow(thirdRow, rowData);
//remove row
@@ -66,7 +59,7 @@ describe('ClaimDevelopment', () => {
cy.clickConfirm();
cy.get(thirdRow).should('not.exist');
- cy.reload();
+ cy.visit(`/#/claim/${claimId}/development`);
cy.get(thirdRow).should('not.exist');
});
});
diff --git a/test/cypress/integration/claim/claimNotes.spec.js b/test/cypress/integration/claim/claimNotes.spec.js
index ae8b4186c..576671a38 100644
--- a/test/cypress/integration/claim/claimNotes.spec.js
+++ b/test/cypress/integration/claim/claimNotes.spec.js
@@ -1,4 +1,4 @@
-describe.skip('ClaimNotes', () => {
+describe('ClaimNotes', () => {
const saveBtn = '.q-field__append > .q-btn > .q-btn__content > .q-icon';
const firstNote = '.q-infinite-scroll :nth-child(1) > .q-card__section--vert';
beforeEach(() => {
@@ -8,7 +8,10 @@ describe.skip('ClaimNotes', () => {
it('should add a new note', () => {
const message = 'This is a new message.';
- cy.get('.q-textarea').should('not.be.disabled').type(message);
+ cy.get('.q-textarea')
+ .should('be.visible')
+ .should('not.be.disabled')
+ .type(message);
cy.get(saveBtn).click();
cy.get(firstNote).should('have.text', message);
diff --git a/test/cypress/integration/claim/claimPhoto.spec.js b/test/cypress/integration/claim/claimPhoto.spec.js
index c3522cbfe..ac0460029 100755
--- a/test/cypress/integration/claim/claimPhoto.spec.js
+++ b/test/cypress/integration/claim/claimPhoto.spec.js
@@ -1,6 +1,7 @@
///
-// redmine.verdnatura.es/issues/8417
describe.skip('ClaimPhoto', () => {
+ const carrouselClose =
+ '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon';
beforeEach(() => {
const claimId = 1;
cy.login('developer');
@@ -12,47 +13,38 @@ describe.skip('ClaimPhoto', () => {
cy.get('label > .q-btn input').selectFile('test/cypress/fixtures/image.jpg', {
force: true,
});
- cy.get('.q-notification__message').should('have.text', 'Data saved');
+ cy.checkNotification('Data saved');
});
it('should add new file with drag and drop', () => {
+ cy.get('.container').should('be.visible').and('exist');
cy.get('.container').selectFile('test/cypress/fixtures/image.jpg', {
action: 'drag-drop',
});
- cy.get('.q-notification__message').should('have.text', 'Data saved');
+ cy.checkNotification('Data saved');
});
it('should open first image dialog change to second and close', () => {
- cy.get(':nth-last-child(1) > .q-card').click();
- cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
- 'be.visible',
- );
+ cy.dataCy('file-1').click();
+ cy.get(carrouselClose).click();
- cy.get('.q-carousel__control > button').click();
-
- cy.get(
- '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon',
- ).click();
- cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
- 'not.be.visible',
- );
+ cy.dataCy('file-1').click();
+ cy.get('.q-carousel__control > button').as('nextButton').click();
+ cy.get('.q-carousel__slide > .q-ma-none').should('be.visible');
+ cy.get(carrouselClose).click();
});
it('should remove third and fourth file', () => {
- cy.get(
- '.multimediaParent > :nth-last-child(1) > .q-btn > .q-btn__content > .q-icon',
- ).click();
+ cy.dataCy('delete-button-4').click();
cy.get(
'.q-card__actions > .q-btn--unelevated > .q-btn__content > .block',
).click();
- cy.get('.q-notification__message').should('have.text', 'Data deleted');
+ cy.checkNotification('Data deleted');
- cy.get(
- '.multimediaParent > :nth-last-child(1) > .q-btn > .q-btn__content > .q-icon',
- ).click();
+ cy.dataCy('delete-button-3').click();
cy.get(
'.q-card__actions > .q-btn--unelevated > .q-btn__content > .block',
).click();
- cy.get('.q-notification__message').should('have.text', 'Data deleted');
+ cy.checkNotification('Data deleted');
});
});
diff --git a/test/cypress/integration/client/clientBalance.spec.js b/test/cypress/integration/client/clientBalance.spec.js
index 0d88a9e28..fff6a5e04 100644
--- a/test/cypress/integration/client/clientBalance.spec.js
+++ b/test/cypress/integration/client/clientBalance.spec.js
@@ -5,7 +5,6 @@ describe('Client balance', () => {
cy.visit('#/customer/1101/balance');
});
it('Should create a mandate', () => {
- cy.waitSpinner();
cy.get('.q-page-sticky > div > .q-btn').click();
cy.selectOption('[data-cy="paymentBank"]', 2);
cy.dataCy('paymentAmount_input').clear().type('100');
diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js
index b29ad74af..caf94b8bd 100644
--- a/test/cypress/integration/client/clientList.spec.js
+++ b/test/cypress/integration/client/clientList.spec.js
@@ -1,5 +1,5 @@
///
-describe('Client list', () => {
+describe.skip('Client list', () => {
beforeEach(() => {
cy.login('developer');
cy.visit('/#/customer/list', {
@@ -25,7 +25,7 @@ describe('Client list', () => {
'Web user': { val: `user_test_${randomInt}` },
Street: { val: `C/ STREET ${randomInt}` },
Email: { val: `user.test${randomInt}@cypress.com` },
- 'Sales person': { val: 'salesPerson', type: 'select' },
+ Team: { val: 'Informatica', type: 'select' },
Location: { val: '46000', type: 'select' },
'Business type': { val: 'others', type: 'select' },
};
@@ -53,7 +53,7 @@ describe('Client list', () => {
it('Client founded create ticket', () => {
const search = 'Jessica Jones';
cy.searchByLabel('Name', search);
- cy.openActionDescriptor('Create ticket');
+ cy.selectDescriptorOption();
cy.waitForElement('#formModel');
cy.waitForElement('.q-form');
cy.checkValueForm(1, search);
diff --git a/test/cypress/integration/client/clientWebAccess.spec.js b/test/cypress/integration/client/clientWebAccess.spec.js
index 6803336a3..970aab71c 100644
--- a/test/cypress/integration/client/clientWebAccess.spec.js
+++ b/test/cypress/integration/client/clientWebAccess.spec.js
@@ -12,7 +12,7 @@ describe('Client web-access', () => {
cy.get('.q-btn-group > :nth-child(1)').should('not.be.disabled');
cy.get('.q-checkbox__inner').click();
cy.get('.q-btn-group > .q-btn--standard.q-btn--actionable').should(
- 'not.be.disabled'
+ 'not.be.disabled',
);
cy.get('.q-btn-group > .q-btn--flat').should('not.be.disabled');
cy.get('.q-btn-group > :nth-child(1)').click();
diff --git a/test/cypress/integration/entry/commands.js b/test/cypress/integration/entry/commands.js
new file mode 100644
index 000000000..4d4a8f980
--- /dev/null
+++ b/test/cypress/integration/entry/commands.js
@@ -0,0 +1,20 @@
+Cypress.Commands.add('selectTravel', (warehouse = '1') => {
+ cy.get('i[data-cy="Travel_icon"]').click();
+ cy.selectOption('input[data-cy="Warehouse Out_select"]', warehouse);
+ cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+ cy.get('button[data-cy="save-filter-travel-form"]').click();
+ cy.get('tr').eq(1).click();
+});
+
+Cypress.Commands.add('deleteEntry', () => {
+ cy.get('[data-cy="descriptor-more-opts"]').should('be.visible').click();
+ cy.waitForElement('div[data-cy="delete-entry"]').click();
+});
+
+Cypress.Commands.add('createEntry', () => {
+ cy.get('button[data-cy="vnTableCreateBtn"]').click();
+ cy.selectTravel('one');
+ cy.get('button[data-cy="FormModelPopup_save"]').click();
+ cy.url().should('include', 'summary');
+ cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+});
diff --git a/test/cypress/integration/entry/entryCard/entryBasicData.spec.js b/test/cypress/integration/entry/entryCard/entryBasicData.spec.js
new file mode 100644
index 000000000..ba689b8c7
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryBasicData.spec.js
@@ -0,0 +1,19 @@
+import '../commands.js';
+
+describe('EntryBasicData', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ it('Change Travel', () => {
+ cy.createEntry();
+ cy.waitForElement('[data-cy="entry-buys"]');
+ cy.get('a[data-cy="EntryBasicData-menu-item"]').click();
+ cy.selectTravel('two');
+ cy.saveCard();
+ cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+ cy.deleteEntry();
+ });
+});
diff --git a/test/cypress/integration/entry/entryCard/entryBuys.spec.js b/test/cypress/integration/entry/entryCard/entryBuys.spec.js
new file mode 100644
index 000000000..b5e185a8e
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryBuys.spec.js
@@ -0,0 +1,101 @@
+import '../commands.js';
+describe('EntryBuys', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ it('Edit buys and use toolbar actions', () => {
+ const COLORS = {
+ negative: 'rgb(251, 82, 82)',
+ positive: 'rgb(200, 228, 132)',
+ enabled: 'rgb(255, 255, 255)',
+ disable: 'rgb(168, 168, 168)',
+ };
+
+ const selectCell = (field, row = 0) =>
+ cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
+ const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
+ const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
+ const clickAndType = (field, value, row = 0) => {
+ selectCell(field, row).click().type(`${value}{esc}`);
+ };
+ const checkText = (field, expectedText, row = 0) =>
+ selectCell(field, row).should('have.text', expectedText);
+ const checkColor = (field, expectedColor, row = 0) =>
+ selectSpan(field, row).should('have.css', 'color', expectedColor);
+
+ cy.createEntry();
+ createBuy();
+
+ selectCell('isIgnored').click().click().type('{esc}');
+ checkText('isIgnored', 'close');
+
+ clickAndType('stickers', '1');
+ checkText('stickers', '0/01');
+ checkText('quantity', '1');
+ checkText('amount', '50.00');
+ clickAndType('packing', '2');
+ checkText('packing', '12');
+ checkText('weight', '12.0');
+ checkText('quantity', '12');
+ checkText('amount', '600.00');
+ checkColor('packing', COLORS.enabled);
+
+ selectCell('groupingMode').click().click().click();
+ checkColor('packing', COLORS.disable);
+ checkColor('grouping', COLORS.enabled);
+
+ selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
+ checkText('amount', '12.00');
+ checkColor('minPrice', COLORS.disable);
+
+ selectCell('hasMinPrice').click().click();
+ checkColor('minPrice', COLORS.enabled);
+ selectCell('hasMinPrice').click();
+
+ cy.saveCard();
+ cy.get('span[data-cy="footer-stickers"]').should('have.text', '1');
+ cy.get('.q-notification__message').contains('Data saved');
+
+ selectButton('change-quantity-sign').should('be.disabled');
+ selectButton('check-buy-amount').should('be.disabled');
+ cy.get('tr.cursor-pointer > .q-table--col-auto-width > .q-checkbox').click();
+ selectButton('change-quantity-sign').should('be.enabled');
+ selectButton('check-buy-amount').should('be.enabled');
+
+ selectButton('change-quantity-sign').click();
+ selectButton('set-negative-quantity').click();
+ checkText('quantity', '-12');
+ selectButton('set-positive-quantity').click();
+ checkText('quantity', '12');
+ checkColor('amount', COLORS.disable);
+
+ selectButton('check-buy-amount').click();
+ selectButton('uncheck-amount').click();
+ checkColor('amount', COLORS.disable);
+
+ selectButton('check-amount').click();
+ checkColor('amount', COLORS.positive);
+ cy.saveCard();
+
+ cy.get('tbody > tr [tabindex="0"][role="checkbox"]').click();
+ cy.dataCy('transferBuys').should('be.enabled').click();
+ cy.dataCy('entryDestinyInput').should('be.visible').type('100');
+ cy.dataCy('transferBuysBtn').click();
+
+ cy.deleteEntry();
+ });
+
+ function createBuy() {
+ cy.waitForElement('[data-cy="entry-buys"]');
+ cy.get('a[data-cy="EntryBuys-menu-item"]').click();
+ cy.get('button[data-cy="vnTableCreateBtn"]').click();
+
+ cy.get('input[data-cy="itemFk-create-popup"]').type('1');
+ cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+ cy.get('input[data-cy="Grouping mode_select"]').should('have.value', 'packing');
+ cy.get('button[data-cy="FormModelPopup_save"]').click();
+ }
+});
diff --git a/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js
new file mode 100644
index 000000000..8185866db
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js
@@ -0,0 +1,40 @@
+import '../commands.js';
+describe('EntryDescriptor', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ it('Clone entry and recalculate rates', () => {
+ cy.createEntry();
+
+ cy.waitForElement('[data-cy="entry-buys"]');
+
+ cy.url().then((previousUrl) => {
+ cy.get('[data-cy="descriptor-more-opts"]').click();
+ cy.get('div[data-cy="clone-entry"]').should('be.visible').click();
+
+ cy.get('.q-notification__message').eq(1).should('have.text', 'Entry cloned');
+
+ cy.url()
+ .should('not.eq', previousUrl)
+ .then(() => {
+ cy.waitForElement('[data-cy="entry-buys"]');
+
+ cy.get('[data-cy="descriptor-more-opts"]').click();
+ cy.get('div[data-cy="recalculate-rates"]').click();
+
+ cy.get('.q-notification__message')
+ .eq(2)
+ .should('have.text', 'Entry prices recalculated');
+ cy.deleteEntry();
+
+ cy.visit(previousUrl);
+
+ cy.waitForElement('[data-cy="entry-buys"]');
+ cy.deleteEntry();
+ });
+ });
+ });
+});
diff --git a/test/cypress/integration/entry/entryCard/entryDms.spec.js b/test/cypress/integration/entry/entryCard/entryDms.spec.js
new file mode 100644
index 000000000..f3f0ef20b
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryDms.spec.js
@@ -0,0 +1,22 @@
+import '../commands.js';
+describe('EntryDms', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ it('should create edit and remove new dms', () => {
+ cy.createEntry();
+ cy.waitForElement('[data-cy="entry-buys"]');
+ cy.dataCy('EntryDms-menu-item').click();
+ cy.dataCy('addButton').click();
+ cy.dataCy('attachFile').click();
+ cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
+ force: true,
+ });
+ cy.dataCy('FormModelPopup_save').click();
+ cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+ cy.deleteEntry();
+ });
+});
diff --git a/test/cypress/integration/entry/entryCard/entryLock.spec.js b/test/cypress/integration/entry/entryCard/entryLock.spec.js
new file mode 100644
index 000000000..6ba4392ae
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryLock.spec.js
@@ -0,0 +1,44 @@
+import '../commands.js';
+describe('EntryLock', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ it('Should notify when entry is lock by another user', () => {
+ const checkLockMessage = () => {
+ cy.get('[role="dialog"]').should('be.visible');
+ cy.get('[data-cy="VnConfirm_message"] > span').should(
+ 'contain.text',
+ 'This entry has been locked by buyerNick',
+ );
+ };
+
+ cy.createEntry();
+ goToEntryBuys();
+ cy.get('.q-notification__message')
+ .eq(1)
+ .should('have.text', 'The entry has been locked successfully');
+
+ cy.login('logistic');
+ cy.reload();
+ checkLockMessage();
+ cy.get('[data-cy="VnConfirm_cancel"]').click();
+ cy.url().should('include', 'summary');
+
+ goToEntryBuys();
+ checkLockMessage();
+ cy.get('[data-cy="VnConfirm_confirm"]').click();
+ cy.url().should('include', 'buys');
+
+ cy.deleteEntry();
+
+ function goToEntryBuys() {
+ const entryBuySelector = 'a[data-cy="EntryBuys-menu-item"]';
+ cy.get(entryBuySelector).should('be.visible');
+ cy.waitForElement('[data-cy="entry-buys"]');
+ cy.get(entryBuySelector).click();
+ }
+ });
+});
diff --git a/test/cypress/integration/entry/entryCard/entryNotes.spec.js b/test/cypress/integration/entry/entryCard/entryNotes.spec.js
new file mode 100644
index 000000000..544ac23b0
--- /dev/null
+++ b/test/cypress/integration/entry/entryCard/entryNotes.spec.js
@@ -0,0 +1,50 @@
+import '../commands.js';
+
+describe('EntryNotes', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/list`);
+ });
+
+ const createObservation = (type, description) => {
+ cy.dataCy('vnTableCreateBtn').click();
+ cy.dataCy('Observation type_select').eq(1).should('be.visible').type(type);
+ cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+ cy.dataCy('Description_input').should('be.visible').type(description);
+ cy.dataCy('FormModelPopup_save').should('be.enabled').click();
+ };
+
+ const editObservation = (rowIndex, type, description) => {
+ cy.get(`td[data-col-field="description"][data-row-index="${rowIndex}"]`)
+ .click()
+ .clear()
+ .type(description);
+ cy.get(`td[data-col-field="observationTypeFk"][data-row-index="${rowIndex}"]`)
+ .click()
+ .clear()
+ .type(type);
+ cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+ cy.saveCard();
+ };
+
+ it('Create, delete, and edit observations', () => {
+ cy.createEntry();
+ cy.waitForElement('[data-cy="entry-buys"]');
+
+ cy.dataCy('EntryNotes-menu-item').click();
+
+ createObservation('Packager', 'test');
+ cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+
+ editObservation(0, 'Administrative', 'test2');
+
+ createObservation('Administrative', 'test');
+ cy.get('.q-notification__message')
+ .eq(2)
+ .should('have.text', "The observation type can't be repeated");
+ cy.dataCy('FormModelPopup_cancel').click();
+
+ cy.deleteEntry();
+ });
+});
diff --git a/test/cypress/integration/entry/entryDms.spec.js b/test/cypress/integration/entry/entryDms.spec.js
deleted file mode 100644
index 47dcdba9e..000000000
--- a/test/cypress/integration/entry/entryDms.spec.js
+++ /dev/null
@@ -1,44 +0,0 @@
-describe('EntryDms', () => {
- const entryId = 1;
-
- beforeEach(() => {
- cy.viewport(1920, 1080);
- cy.login('developer');
- cy.visit(`/#/entry/${entryId}/dms`);
- });
-
- it('should create edit and remove new dms', () => {
- cy.addRow();
- cy.get('.icon-attach').click();
- cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
- force: true,
- });
-
- cy.get('tbody > tr').then((value) => {
- const u = undefined;
-
- //Create and check if exist new row
- let newFileTd = Cypress.$(value).length;
- cy.get('.q-btn--standard > .q-btn__content > .block').click();
- expect(value).to.have.length(newFileTd++);
- const newRowSelector = `tbody > :nth-child(${newFileTd})`;
- cy.waitForElement(newRowSelector);
- cy.validateRow(newRowSelector, [u, u, u, u, u, 'ENTRADA ID 1']);
-
- //Edit new dms
- const newDescription = 'entry id 1 modified';
- const textAreaSelector =
- '.q-textarea > .q-field__inner > .q-field__control > .q-field__control-container';
- cy.get(
- `tbody :nth-child(${newFileTd}) > .text-right > .no-wrap > :nth-child(2) > .q-btn > .q-btn__content > .q-icon`
- ).click();
-
- cy.get(textAreaSelector).clear();
- cy.get(textAreaSelector).type(newDescription);
- cy.saveCard();
- cy.reload();
-
- cy.validateRow(newRowSelector, [u, u, u, u, u, newDescription]);
- });
- });
-});
diff --git a/test/cypress/integration/entry/entryList.spec.js b/test/cypress/integration/entry/entryList.spec.js
index d43ec895a..bad47615f 100644
--- a/test/cypress/integration/entry/entryList.spec.js
+++ b/test/cypress/integration/entry/entryList.spec.js
@@ -1,223 +1,55 @@
-describe('Entry', () => {
+import './commands';
+
+describe('EntryList', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('buyer');
cy.visit(`/#/entry/list`);
});
- it('Filter deleted entries and other fields', () => {
- createEntry();
+ it('View popup summary', () => {
+ cy.createEntry();
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
cy.waitForElement('[data-cy="entry-buys"]');
- deleteEntry();
+ cy.deleteEntry();
cy.typeSearchbar('{enter}');
- cy.get('span[title="Date"]').click().click();
- cy.typeSearchbar('{enter}');
- cy.url().should('include', 'order');
- cy.get('td[data-row-index="0"][data-col-field="landed"]').should(
- 'have.text',
- '-',
- );
+ cy.get('button[title="Summary"]').eq(1).should('be.visible').click();
+ cy.dataCy('entry-summary').should('be.visible');
});
- it('Create entry, modify travel and add buys', () => {
- createEntryAndBuy();
- cy.get('a[data-cy="EntryBasicData-menu-item"]').click();
- selectTravel('two');
- cy.saveCard();
- cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
- deleteEntry();
+ it('Show supplierDescriptor on click on supplierDescriptor', () => {
+ cy.typeSearchbar('{enter}');
+ cy.get('td[data-col-field="supplierFk"] > div > span').eq(0).click();
+ cy.get('div[role="menu"] > div[class="descriptor"]').should('be.visible');
});
- it('Clone entry and recalculate rates', () => {
- createEntry();
+ it('Landed badge should display the right color', () => {
+ cy.typeSearchbar('{enter}');
- cy.waitForElement('[data-cy="entry-buys"]');
-
- cy.url().then((previousUrl) => {
- cy.get('[data-cy="descriptor-more-opts"]').click();
- cy.get('div[data-cy="clone-entry"]').should('be.visible').click();
-
- cy.get('.q-notification__message').eq(1).should('have.text', 'Entry cloned');
-
- cy.url()
- .should('not.eq', previousUrl)
- .then(() => {
- cy.waitForElement('[data-cy="entry-buys"]');
-
- cy.get('[data-cy="descriptor-more-opts"]').click();
- cy.get('div[data-cy="recalculate-rates"]').click();
-
- cy.get('.q-notification__message')
- .eq(2)
- .should('have.text', 'Entry prices recalculated');
-
- cy.get('[data-cy="descriptor-more-opts"]').click();
- deleteEntry();
-
- cy.log(previousUrl);
-
- cy.visit(previousUrl);
-
- cy.waitForElement('[data-cy="entry-buys"]');
- deleteEntry();
+ const checkBadgeDate = (selector, comparisonFn) => {
+ cy.get(selector)
+ .should('exist')
+ .each(($badge) => {
+ const badgeText = $badge.text().trim();
+ const badgeDate = new Date(badgeText);
+ const compareDate = new Date('01/01/2001');
+ comparisonFn(badgeDate, compareDate);
});
- });
- });
-
- it('Should notify when entry is lock by another user', () => {
- const checkLockMessage = () => {
- cy.get('[role="dialog"]').should('be.visible');
- cy.get('[data-cy="VnConfirm_message"] > span').should(
- 'contain.text',
- 'This entry has been locked by buyerNick',
- );
};
- createEntry();
- goToEntryBuys();
- cy.get('.q-notification__message')
- .eq(1)
- .should('have.text', 'The entry has been locked successfully');
-
- cy.login('logistic');
- cy.reload();
- checkLockMessage();
- cy.get('[data-cy="VnConfirm_cancel"]').click();
- cy.url().should('include', 'summary');
-
- goToEntryBuys();
- checkLockMessage();
- cy.get('[data-cy="VnConfirm_confirm"]').click();
- cy.url().should('include', 'buys');
-
- deleteEntry();
- });
-
- it('Edit buys and use toolbar actions', () => {
- const COLORS = {
- negative: 'rgb(251, 82, 82)',
- positive: 'rgb(200, 228, 132)',
- enabled: 'rgb(255, 255, 255)',
- disable: 'rgb(168, 168, 168)',
- };
-
- const selectCell = (field, row = 0) =>
- cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
- const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
- const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
- const clickAndType = (field, value, row = 0) => {
- selectCell(field, row).click().type(`${value}{esc}`);
- };
- const checkText = (field, expectedText, row = 0) =>
- selectCell(field, row).should('have.text', expectedText);
- const checkColor = (field, expectedColor, row = 0) =>
- selectSpan(field, row).should('have.css', 'color', expectedColor);
-
- createEntryAndBuy();
-
- selectCell('isIgnored').click().click().type('{esc}');
- checkText('isIgnored', 'close');
-
- clickAndType('stickers', '1');
- checkText('stickers', '0/01');
- checkText('quantity', '1');
- checkText('amount', '50.00');
- clickAndType('packing', '2');
- checkText('packing', '12');
- checkText('weight', '12.0');
- checkText('quantity', '12');
- checkText('amount', '600.00');
- checkColor('packing', COLORS.enabled);
-
- selectCell('groupingMode').click().click().click();
- checkColor('packing', COLORS.disable);
- checkColor('grouping', COLORS.enabled);
-
- selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
- checkText('amount', '12.00');
- checkColor('minPrice', COLORS.disable);
-
- selectCell('hasMinPrice').click().click();
- checkColor('minPrice', COLORS.enabled);
- selectCell('hasMinPrice').click();
-
- cy.saveCard();
- cy.get('span[data-cy="footer-stickers"]').should('have.text', '1');
- cy.get('.q-notification__message').contains('Data saved');
-
- selectButton('change-quantity-sign').should('be.disabled');
- selectButton('check-buy-amount').should('be.disabled');
- cy.get('tr.cursor-pointer > .q-table--col-auto-width > .q-checkbox').click();
- selectButton('change-quantity-sign').should('be.enabled');
- selectButton('check-buy-amount').should('be.enabled');
-
- selectButton('change-quantity-sign').click();
- selectButton('set-negative-quantity').click();
- checkText('quantity', '-12');
- selectButton('set-positive-quantity').click();
- checkText('quantity', '12');
- checkColor('amount', COLORS.disable);
-
- selectButton('check-buy-amount').click();
- selectButton('uncheck-amount').click();
- checkColor('amount', COLORS.disable);
-
- selectButton('check-amount').click();
- checkColor('amount', COLORS.positive);
- cy.saveCard();
-
- cy.get('span[data-cy="footer-amount"]').should(
- 'have.css',
- 'color',
- COLORS.positive,
+ checkBadgeDate(
+ 'td[data-col-field="landed"] > div .bg-warning',
+ (badgeDate, compareDate) => {
+ expect(badgeDate.getTime()).to.be.greaterThan(compareDate.getTime());
+ },
);
- deleteEntry();
+ // fix on task https://redmine.verdnatura.es/issues/8638
+ /* checkBadgeDate(
+ 'td[data-col-field="landed"] > div .bg-info',
+ (badgeDate, compareDate) => {
+ expect(badgeDate.getTime()).to.be.lessThan(compareDate.getTime());
+ },
+ ); */
});
-
- function goToEntryBuys() {
- const entryBuySelector = 'a[data-cy="EntryBuys-menu-item"]';
- cy.get(entryBuySelector).should('be.visible');
- cy.waitForElement('[data-cy="entry-buys"]');
- cy.get(entryBuySelector).click();
- }
-
- function deleteEntry() {
- cy.get('[data-cy="descriptor-more-opts"]').should('be.visible').click();
- cy.waitForElement('div[data-cy="delete-entry"]').click();
- cy.url().should('include', 'list');
- }
-
- function createEntryAndBuy() {
- createEntry();
- createBuy();
- }
-
- function createEntry() {
- cy.get('button[data-cy="vnTableCreateBtn"]').click();
- selectTravel('one');
- cy.get('button[data-cy="FormModelPopup_save"]').click();
- cy.url().should('include', 'summary');
- cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
- }
-
- function selectTravel(warehouse) {
- cy.get('i[data-cy="Travel_icon"]').click();
- cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse);
- cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
- cy.get('button[data-cy="save-filter-travel-form"]').click();
- cy.get('tr').eq(1).click();
- }
-
- function createBuy() {
- cy.get('a[data-cy="EntryBuys-menu-item"]').click();
- cy.get('a[data-cy="EntryBuys-menu-item"]').click();
- cy.get('button[data-cy="vnTableCreateBtn"]').click();
-
- cy.get('input[data-cy="itemFk-create-popup"]').type('1');
- cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
- cy.get('input[data-cy="Grouping mode_select"]').should('have.value', 'packing');
- cy.get('button[data-cy="FormModelPopup_save"]').click();
- }
});
diff --git a/test/cypress/integration/entry/entryStockBought.spec.js b/test/cypress/integration/entry/entryStockBought.spec.js
new file mode 100644
index 000000000..3fad44d91
--- /dev/null
+++ b/test/cypress/integration/entry/entryStockBought.spec.js
@@ -0,0 +1,23 @@
+describe('EntryStockBought', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyer');
+ cy.visit(`/#/entry/stock-Bought`);
+ });
+
+ it('Should edit the reserved space adjust the purchased spaces and check detail', () => {
+ cy.get('[data-cy="edit-travel"]').should('be.visible').click();
+ cy.get('input[aria-label="m3"]').clear().type('60');
+ cy.get('[data-cy="FormModelPopup_save"]').click();
+ cy.get('.vn-row > div > :nth-child(2)').should('have.text', '60');
+
+ cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
+ cy.get('[data-col-field="reserve"][data-row-index="0"]').click();
+ cy.get('input[name="reserve"]').type('10{enter}');
+ cy.get('button[title="Save"]').click();
+ cy.checkNotification('Data saved');
+
+ cy.get('[data-cy="searchBtn"]').eq(0).click();
+ cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
+ });
+});
diff --git a/test/cypress/integration/entry/myEntry.spec.js b/test/cypress/integration/entry/entrySupplier.spec.js
similarity index 71%
rename from test/cypress/integration/entry/myEntry.spec.js
rename to test/cypress/integration/entry/entrySupplier.spec.js
index ed469d9e2..83deecea5 100644
--- a/test/cypress/integration/entry/myEntry.spec.js
+++ b/test/cypress/integration/entry/entrySupplier.spec.js
@@ -1,4 +1,4 @@
-describe('EntryMy when is supplier', () => {
+describe('EntrySupplier when is supplier', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('supplier');
@@ -13,5 +13,7 @@ describe('EntryMy when is supplier', () => {
cy.dataCy('cardBtn').eq(2).click();
cy.dataCy('printLabelsBtn').click();
cy.window().its('open').should('be.called');
+ cy.dataCy('seeLabelBtn').eq(0).should('be.visible').click();
+ cy.window().its('open').should('be.called');
});
});
diff --git a/test/cypress/integration/entry/entryWasteRecalc.spec.js b/test/cypress/integration/entry/entryWasteRecalc.spec.js
new file mode 100644
index 000000000..1b358676c
--- /dev/null
+++ b/test/cypress/integration/entry/entryWasteRecalc.spec.js
@@ -0,0 +1,22 @@
+import './commands';
+describe('EntryDms', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('buyerBoss');
+ cy.visit(`/#/entry/waste-recalc`);
+ });
+
+ it('should recalc waste for today', () => {
+ cy.waitForElement('[data-cy="wasteRecalc"]');
+ cy.dataCy('recalc').should('be.disabled');
+
+ cy.dataCy('dateFrom').should('be.visible').click().type('01-01-2001');
+ cy.dataCy('dateTo').should('be.visible').click().type('01-01-2001');
+
+ cy.dataCy('recalc').should('be.enabled').click();
+ cy.get('.q-notification__message').should(
+ 'have.text',
+ 'The wastes were successfully recalculated',
+ );
+ });
+});
diff --git a/test/cypress/integration/entry/stockBought.spec.js b/test/cypress/integration/entry/stockBought.spec.js
deleted file mode 100644
index 91e0d507e..000000000
--- a/test/cypress/integration/entry/stockBought.spec.js
+++ /dev/null
@@ -1,50 +0,0 @@
-describe('EntryStockBought', () => {
- beforeEach(() => {
- cy.viewport(1920, 1080);
- cy.login('buyer');
- cy.visit(`/#/entry/stock-Bought`);
- });
- it('Should edit the reserved space', () => {
- cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
- cy.get('[data-col-field="reserve"][data-row-index="0"]').click();
- cy.get('input[name="reserve"]').type('10{enter}');
- cy.get('button[title="Save"]').click();
- cy.checkNotification('Data saved');
- });
- it('Should add a new reserved space for buyerBoss', () => {
- cy.addBtnClick();
- cy.get('input[aria-label="Reserve"]').type('1');
- cy.get('input[aria-label="Date"]').eq(1).clear();
- cy.get('input[aria-label="Date"]').eq(1).type('01-01');
- cy.get('input[aria-label="Buyer"]').type('itNick');
- cy.get('div[role="listbox"] > div > div[role="option"]')
- .eq(1)
- .should('be.visible')
- .click();
-
- cy.get('[data-cy="FormModelPopup_save"]').click();
- cy.get('.q-notification__message').should('have.text', 'Data created');
-
- cy.get('[data-col-field="reserve"][data-row-index="1"]').click().clear();
- cy.get('[data-cy="searchBtn"]').eq(1).click();
- cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata')
- .should('have.text', 'warningNo data available')
- .type('{esc}');
- cy.get('[data-col-field="reserve"][data-row-index="1"]')
- .click()
- .type('{backspace}{enter}');
- cy.get('[data-cy="crudModelDefaultSaveBtn"]').should('be.enabled').click();
- cy.get('.q-notification__message').eq(1).should('have.text', 'Data saved');
- });
- it('Should check detail for the buyer', () => {
- cy.get('[data-cy="searchBtn"]').eq(0).click();
- cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
- });
-
- it('Should edit travel m3 and refresh', () => {
- cy.get('[data-cy="edit-travel"]').should('be.visible').click();
- cy.get('input[aria-label="m3"]').clear().type('60');
- cy.get('[data-cy="FormModelPopup_save"]').click();
- cy.get('.vn-row > div > :nth-child(2)').should('have.text', '60');
- });
-});
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 11ca1bb59..ee4d9fb74 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -1,26 +1,40 @@
///
+import moment from 'moment';
describe('InvoiceInBasicData', () => {
- const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select';
const dialogInputs = '.q-dialog input';
- const resetBtn = '.q-btn-group--push > .q-btn--flat';
const getDocumentBtns = (opt) => `[data-cy="dms-buttons"] > :nth-child(${opt})`;
+ const futureDate = moment().add(1, 'days').format('DD-MM-YYYY');
+ const mock = {
+ invoiceInBasicDataSupplier: { val: 'Bros nick', type: 'select' },
+ invoiceInBasicDataSupplierRef_input: 'mockInvoice41',
+ invoiceInBasicDataIssued: { val: futureDate, type: 'date' },
+ invoiceInBasicDataOperated: { val: futureDate, type: 'date' },
+ invoiceInBasicDatabookEntried: { val: futureDate, type: 'date' },
+ invoiceInBasicDataBooked: {
+ val: moment().add(5, 'days').format('DD-MM-YYYY'),
+ type: 'date',
+ },
+ invoiceInBasicDataDeductibleExpenseFk: {
+ val: '4751000000',
+ type: 'select',
+ },
+ invoiceInBasicDataCurrencyFk: { val: 'USD', type: 'select' },
+ invoiceInBasicDataCompanyFk: { val: 'CCs', type: 'select' },
+ invoiceInBasicDataWithholdingSageFk: {
+ val: 'Arrendamiento y subarrendamiento',
+ type: 'select',
+ },
+ };
beforeEach(() => {
- cy.login('developer');
+ cy.login('administrative');
cy.visit(`/#/invoice-in/1/basic-data`);
});
- it('should edit the provideer and supplier ref', () => {
- cy.dataCy('UnDeductibleVatSelect').type('4751000000');
- cy.get('.q-menu .q-item').contains('4751000000').click();
- cy.get(resetBtn).click();
-
- cy.waitForElement('#formModel').within(() => {
- cy.dataCy('vnSupplierSelect').type('Bros nick');
- })
- cy.get('.q-menu .q-item').contains('Bros nick').click();
+ it('should edit every field', () => {
+ cy.fillInForm(mock, { attr: 'data-cy' });
cy.saveCard();
- cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Bros nick');
+ cy.validateForm(mock, { attr: 'data-cy' });
});
it('should edit, remove and create the dms data', () => {
@@ -44,7 +58,7 @@ describe('InvoiceInBasicData', () => {
cy.checkNotification('Data saved');
//create
- cy.get('[data-cy="dms-create"]').eq(0).click();
+ cy.get('[data-cy="invoiceInBasicDataDmsAdd"]').eq(0).click();
cy.get('[data-cy="VnDms_inputFile"').selectFile(
'test/cypress/fixtures/image.jpg',
{
diff --git a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
index 731174040..275fa1358 100644
--- a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
@@ -1,22 +1,59 @@
-///
-describe('InvoiceInCorrective', () => {
- const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';
+describe('invoiceInCorrective', () => {
+ beforeEach(() => cy.login('administrative'));
- it('should create a correcting invoice', () => {
- cy.viewport(1280, 720);
- cy.login('developer');
- cy.visit(`/#/invoice-in/1/summary`);
+ it('should modify the invoice', () => {
+ cy.visit('/#/invoice-in/1/summary');
cy.intercept('POST', '/api/InvoiceIns/corrective').as('corrective');
+ cy.intercept('POST', '/api/InvoiceInCorrections/crud').as('crud');
+ cy.intercept('GET', /InvoiceInCorrections\?filter=.+/).as('getCorrective');
- cy.openActionsDescriptor();
+ cy.selectDescriptorOption(4);
+ cy.dataCy('saveCorrectiveInvoice').click();
- cy.dataCy('createCorrectiveItem').click();
- cy.get(saveDialog).click();
- cy.wait('@corrective').then((interception) => {
- const correctingId = interception.response.body;
- cy.url().should('include', `/invoice-in/${correctingId}/summary`);
- cy.visit(`/#/invoice-in/${correctingId}/corrective`);
+ cy.wait('@corrective').then(({ response }) => {
+ const correctingFk = response.body;
+ cy.url().should('include', `/invoice-in/${correctingFk}/summary`);
+ cy.visit(`/#/invoice-in/${correctingFk}/corrective`);
+ cy.selectOption('[data-cy="invoiceInCorrective_class"]', 'r4');
+ cy.selectOption('[data-cy="invoiceInCorrective_type"]', 'sustitución');
+ cy.selectOption('[data-cy="invoiceInCorrective_reason"]', 'vat');
+ cy.dataCy('crudModelDefaultSaveBtn').click();
+
+ cy.wait('@crud');
+ cy.reload();
+ cy.wait('@getCorrective');
+ cy.validateRow('tbody > :nth-of-type(1)', [
+ ,
+ 'S – Por sustitución',
+ 'R4',
+ 'Error in VAT calculation',
+ ]);
});
- cy.get('tbody > tr:visible').should('have.length', 1);
+ });
+
+ it('should not be able to modify the invoice if the original invoice is booked', () => {
+ cy.intercept('POST', '/api/InvoiceIns/corrective').as('corrective');
+ cy.visit('/#/invoice-in/4/summary');
+ cy.selectDescriptorOption();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.selectDescriptorOption(4);
+ cy.dataCy('saveCorrectiveInvoice').click();
+
+ cy.wait('@corrective').then(({ response }) => {
+ const correctingFk = response.body;
+ cy.url().should('include', `/invoice-in/${correctingFk}/summary`);
+ cy.visit(`/#/invoice-in/${correctingFk}/corrective`);
+
+ cy.dataCy('invoiceInCorrective_class').should('be.disabled');
+ cy.dataCy('invoiceInCorrective_type').should('be.disabled');
+ cy.dataCy('invoiceInCorrective_reason').should('be.disabled');
+ });
+ });
+
+ it('should show/hide the section if it is a corrective invoice', () => {
+ cy.visit('/#/invoice-in/1/summary');
+ cy.get('[data-cy="InvoiceInCorrective-menu-item"]').should('not.exist');
+ cy.clicDescriptorAction(4);
+ cy.get('[data-cy="InvoiceInCorrective-menu-item"]').should('exist');
});
});
diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
index 97a9fe976..9744486e0 100644
--- a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
@@ -1,21 +1,147 @@
describe('InvoiceInDescriptor', () => {
- const book = '.summaryHeader > .no-wrap > .q-btn';
- const firstDescritorOpt = '.q-menu > .q-list > :nth-child(5) > .q-item__section';
- const checkbox = ':nth-child(5) > .q-checkbox';
+ beforeEach(() => cy.login('administrative'));
- it('should booking and unbooking the invoice properly', () => {
- cy.viewport(1280, 720);
- cy.login('developer');
- cy.visit('/#/invoice-in/1/summary');
- cy.waitForElement('.q-page');
+ describe('more options', () => {
+ it('should booking and unbooking the invoice properly', () => {
+ const checkbox = '[data-cy="vnLvIs booked"] > .q-checkbox';
+ cy.visit('/#/invoice-in/2/summary');
+ cy.selectDescriptorOption();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.validateCheckbox(checkbox);
+ cy.selectDescriptorOption();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.validateCheckbox(checkbox, false);
+ });
- cy.get(book).click();
- cy.dataCy('VnConfirm_confirm').click();
- cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'true');
+ it('should delete the invoice properly', () => {
+ cy.visit('/#/invoice-in/2/summary');
+ cy.selectDescriptorOption(2);
+ cy.clickConfirm();
+ cy.checkNotification('invoice deleted');
+ });
- cy.dataCy('descriptor-more-opts').first().click();
- cy.get(firstDescritorOpt).click();
- cy.dataCy('VnConfirm_confirm').click();
- cy.get(checkbox).invoke('attr', 'aria-checked').should('eq', 'false');
+ it('should clone the invoice properly', () => {
+ cy.visit('/#/invoice-in/3/summary');
+ cy.selectDescriptorOption(3);
+ cy.clickConfirm();
+ cy.checkNotification('Invoice cloned');
+ });
+
+ it('should show the agricultural PDF properly', () => {
+ cy.visit('/#/invoice-in/6/summary');
+ cy.validatePdfDownload(
+ /api\/InvoiceIns\/6\/invoice-in-pdf\?access_token=.*/,
+ () => cy.selectDescriptorOption(4),
+ );
+ });
+
+ it('should send the agricultural PDF properly', () => {
+ cy.intercept('POST', 'api/InvoiceIns/6/invoice-in-email').as('sendEmail');
+ cy.visit('/#/invoice-in/6/summary');
+ cy.selectDescriptorOption(5);
+
+ cy.dataCy('SendEmailNotificationDialogInput_input').type(
+ '{selectall}jorgito@gmail.mx',
+ );
+ cy.clickConfirm();
+ cy.checkNotification('Notification sent');
+ cy.wait('@sendEmail').then(({ request, response }) => {
+ expect(request.body).to.deep.equal({
+ recipientId: 2,
+ recipient: 'jorgito@gmail.mx',
+ });
+ expect(response.statusCode).to.equal(200);
+ });
+ });
+ // https://redmine.verdnatura.es/issues/8767
+ it.skip('should download the file properly', () => {
+ cy.visit('/#/invoice-in/1/summary');
+ cy.validateDownload(() => cy.selectDescriptorOption(5));
+ });
+ });
+
+ describe('buttons', () => {
+ beforeEach(() => cy.visit('/#/invoice-in/1/summary'));
+
+ it('should navigate to the supplier summary', () => {
+ cy.clicDescriptorAction(1);
+ cy.url().should('to.match', /supplier\/\d+\/summary/);
+ });
+
+ it('should navigate to the entry summary', () => {
+ cy.clicDescriptorAction(2);
+ cy.url().should('to.match', /entry\/\d+\/summary/);
+ });
+
+ it('should navigate to the invoiceIn list', () => {
+ cy.clicDescriptorAction(3);
+ cy.url().should('to.match', /invoice-in\/list\?table=\{.*supplierFk.+\}/);
+ });
+ });
+
+ describe('corrective', () => {
+ const originalId = 4;
+
+ beforeEach(() => cy.visit(`/#/invoice-in/${originalId}/summary`));
+
+ it('should create a correcting invoice and redirect to original invoice', () => {
+ createCorrective();
+ redirect(originalId);
+ });
+
+ it('should create a correcting invoice and navigate to list filtered by corrective', () => {
+ createCorrective();
+ redirect(originalId);
+
+ cy.clicDescriptorAction(4);
+ cy.validateVnTableRows({
+ cols: [
+ {
+ name: 'supplierRef',
+ val: '1237',
+ operation: 'include',
+ },
+ ],
+ });
+ });
+ });
+
+ describe('link', () => {
+ it('should open the supplier descriptor popup', () => {
+ cy.visit('/#/invoice-in/1/summary');
+ cy.intercept('GET', /Suppliers\/\d+/).as('getSupplier');
+
+ cy.dataCy('invoiceInDescriptor_supplier').then(($el) => {
+ const alias = $el.text().trim();
+ $el.click();
+ cy.wait('@getSupplier').then(() =>
+ cy.validateDescriptor({ listbox: { 1: alias }, popup: true }),
+ );
+ });
+ });
});
});
+
+function createCorrective() {
+ cy.intercept('POST', '/api/InvoiceIns/corrective').as('corrective');
+
+ cy.selectDescriptorOption(4);
+ cy.dataCy('saveCorrectiveInvoice').click();
+
+ cy.wait('@corrective').then(({ response }) => {
+ const correctingId = response.body;
+ cy.url().should('include', `/invoice-in/${correctingId}/summary`);
+ cy.visit(`/#/invoice-in/${correctingId}/corrective`);
+ cy.dataCy('invoiceInCorrective_class').should('contain.value', 'R2');
+ cy.dataCy('invoiceInCorrective_type').should('contain.value', 'diferencias');
+ cy.dataCy('invoiceInCorrective_reason').should('contain.value', 'sales details');
+ });
+}
+
+function redirect(subtitle) {
+ const regex = new RegExp(`InvoiceIns/${subtitle}\\?filter=.*`);
+ cy.intercept('GET', regex).as('getOriginal');
+ cy.clicDescriptorAction(4);
+ cy.wait('@getOriginal');
+ cy.validateDescriptor({ subtitle });
+}
diff --git a/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js b/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js
index 5a5becd22..2fc34a7ae 100644
--- a/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js
@@ -4,7 +4,7 @@ describe('InvoiceInDueDay', () => {
const addBtn = '.q-page-sticky > div > .q-btn > .q-btn__content';
beforeEach(() => {
- cy.login('developer');
+ cy.login('administrative');
cy.visit(`/#/invoice-in/6/due-day`);
});
diff --git a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
index 4c2550548..6a1c18785 100644
--- a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
@@ -6,7 +6,7 @@ describe('InvoiceInIntrastat', () => {
const firstRowAmount = `${firstRow} > :nth-child(3)`;
beforeEach(() => {
- cy.login('developer');
+ cy.login('administrative');
cy.visit(`/#/invoice-in/1/intrastat`);
});
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index d9ab3f7e7..7254e8909 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -1,13 +1,21 @@
///
+
describe('InvoiceInList', () => {
const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)';
const firstId = `${firstRow} > td:nth-child(2) span`;
const firstDetailBtn = `${firstRow} .q-btn:nth-child(1)`;
- const summaryHeaders = '.summaryBody .header-link';
+ const summaryHeaders = (opt) => `.summaryBody > .${opt} > .q-pb-lg > .header-link`;
+ const mockInvoiceRef = `createMockInvoice${Math.floor(Math.random() * 100)}`;
+ const mock = {
+ vnSupplierSelect: { val: 'farmer king', type: 'select' },
+ 'Invoice nº_input': mockInvoiceRef,
+ Company_select: { val: 'orn', type: 'select' },
+ 'Expedition date_inputDate': '16-11-2001',
+ };
beforeEach(() => {
cy.viewport(1920, 1080);
- cy.login('developer');
+ cy.login('administrative');
cy.visit(`/#/invoice-in/list`);
cy.get('#searchbar input').type('{enter}');
});
@@ -24,7 +32,21 @@ describe('InvoiceInList', () => {
it('should open the details', () => {
cy.get(firstDetailBtn).click();
- cy.get(summaryHeaders).eq(1).contains('Basic data');
- cy.get(summaryHeaders).eq(4).contains('Vat');
+ cy.get(summaryHeaders('max-width')).contains('Basic data');
+ cy.get(summaryHeaders('vat')).contains('Vat');
+ });
+
+ it('should create a new Invoice', () => {
+ cy.dataCy('vnTableCreateBtn').click();
+ cy.fillInForm({ ...mock }, { attr: 'data-cy' });
+ cy.dataCy('FormModelPopup_save').click();
+ cy.intercept('GET', /\/api\/InvoiceIns\/\d+\/getTotals$/).as('invoice');
+ cy.wait('@invoice').then(() => {
+ cy.validateDescriptor({
+ title: mockInvoiceRef,
+ listBox: { 0: '11/16/2001', 3: 'The farmer' },
+ });
+ cy.dataCy('invoiceInBasicDataCompanyFk').should('have.value', 'ORN');
+ });
});
});
diff --git a/test/cypress/integration/invoiceIn/invoiceInSerial.spec.js b/test/cypress/integration/invoiceIn/invoiceInSerial.spec.js
new file mode 100644
index 000000000..3750f8f06
--- /dev/null
+++ b/test/cypress/integration/invoiceIn/invoiceInSerial.spec.js
@@ -0,0 +1,25 @@
+describe('InvoiceInSerial', () => {
+ beforeEach(() => {
+ cy.login('administrative');
+ cy.visit('#/invoice-in/serial');
+ });
+
+ it('should filter by serial number', () => {
+ cy.dataCy('serial_input').type('R{enter}');
+ cy.validateVnTableRows({ cols: [{ name: 'serial', val: 'r' }] });
+ });
+
+ it('should filter by last days ', () => {
+ cy.dataCy('vnTableCell_total')
+ .invoke('text')
+ .then((before) => {
+ cy.dataCy('Last days_input')
+ .type('{selectall}1{enter}')
+ .then(() => {
+ cy.dataCy('vnTableCell_total')
+ .invoke('text')
+ .then((after) => expect(+after).to.be.lessThan(+before));
+ });
+ });
+ });
+});
diff --git a/test/cypress/integration/invoiceIn/invoiceInSummary.spec.js b/test/cypress/integration/invoiceIn/invoiceInSummary.spec.js
new file mode 100644
index 000000000..72dbdd9a8
--- /dev/null
+++ b/test/cypress/integration/invoiceIn/invoiceInSummary.spec.js
@@ -0,0 +1,24 @@
+describe('InvoiceInSummary', () => {
+ beforeEach(() => {
+ cy.login('administrative');
+ cy.visit('/#/invoice-in/3/summary');
+ });
+
+ it('should booking and unbooking the invoice properly', () => {
+ const checkbox = '[data-cy="vnLvIs booked"] > .q-checkbox';
+ cy.dataCy('invoiceInSummary_book').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.validateCheckbox(checkbox);
+ });
+
+ it('should open the supplier descriptor popup', () => {
+ cy.intercept('GET', /Suppliers\/\d+/).as('getSupplier');
+ cy.dataCy('invoiceInSummary_supplier').then(($el) => {
+ const description = $el.text().trim();
+ $el.click();
+ cy.wait('@getSupplier').then(() =>
+ cy.validateDescriptor({ description, popup: true }),
+ );
+ });
+ });
+});
diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
index 1e7ce1003..ff7d639e6 100644
--- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
@@ -1,17 +1,15 @@
///
describe('InvoiceInVat', () => {
const thirdRow = 'tbody > :nth-child(3)';
- const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)';
+ const firstLineVat = 'tbody > :nth-child(1) ';
const vats = '[data-cy="vat-sageiva"]';
const dialogInputs = '.q-dialog label input';
const addBtn = 'tbody tr:nth-child(1) td:nth-child(2) .--add-icon';
const randomInt = Math.floor(Math.random() * 100);
beforeEach(() => {
- cy.login('developer');
+ cy.login('administrative');
cy.visit(`/#/invoice-in/1/vat`);
- cy.intercept('GET', '/api/InvoiceIns/1/getTotals').as('lastCall');
- cy.wait('@lastCall');
});
it('should edit the sage iva', () => {
@@ -20,6 +18,17 @@ describe('InvoiceInVat', () => {
cy.get(vats).eq(0).should('have.value', '8: H.P. IVA 21% CEE');
});
+ it('should mark the line as deductible VAT', () => {
+ cy.get(`${firstLineVat} [data-cy="isDeductible_checkbox"]`).click();
+
+ cy.saveCard();
+
+ cy.get(`${firstLineVat} [data-cy="isDeductible_checkbox"]`)
+
+ .click();
+ cy.saveCard();
+ });
+
it('should add a new row', () => {
cy.addRow();
cy.fillRow(thirdRow, [true, 2000000001, 30, 'H.P. IVA 10']);
diff --git a/test/cypress/integration/invoiceOut/invoiceOutList.spec.js b/test/cypress/integration/invoiceOut/invoiceOutList.spec.js
index d3a84d226..b8b42fa4b 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutList.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutList.spec.js
@@ -13,7 +13,6 @@ describe('InvoiceOut list', () => {
':nth-child(1) > .text-right > [data-cy="tableAction-0"] > .q-btn__content > .q-icon';
beforeEach(() => {
- cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/invoice-out/list`);
cy.typeSearchbar('{enter}');
@@ -41,7 +40,7 @@ describe('InvoiceOut list', () => {
});
it('should filter the results by client ID, then check the first result is correct', () => {
- cy.dataCy('Customer ID_input').type('1103');
+ cy.dataCy('Client id_input').type('1103');
cy.get(filterBtn).click();
cy.get(firstRowDescriptor).click();
cy.get('.q-item > .q-item__label').should('include.text', '1103');
diff --git a/test/cypress/integration/invoiceOut/invoiceOutMakeInvoice.spec.js b/test/cypress/integration/invoiceOut/invoiceOutMakeInvoice.spec.js
index 145f492a1..e93326f1d 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutMakeInvoice.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutMakeInvoice.spec.js
@@ -1,5 +1,5 @@
///
-describe('InvoiceOut manual invoice', () => {
+describe.skip('InvoiceOut manual invoice', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
@@ -10,12 +10,17 @@ describe('InvoiceOut manual invoice', () => {
it('should create an invoice from a ticket and go to that invoice', () => {
cy.searchByLabel('Customer ID', '1101');
cy.get(
- '[data-q-vs-anchor=""] > :nth-child(1) > .q-checkbox > .q-checkbox__inner'
+ '[data-q-vs-anchor=""] > :nth-child(1) > .q-checkbox > .q-checkbox__inner',
).click();
cy.dataCy('ticketListMakeInvoiceBtn').click();
cy.checkNotification('Data saved');
cy.get('.q-virtual-scroll__content > :nth-child(1) > :nth-child(3)').click();
cy.get(':nth-child(8) > .value > .link').click();
- cy.get('.header > :nth-child(3) > .q-btn__content').click();
+ cy.get('.q-menu > .descriptor > .header').should('be.visible');
+ cy.get(
+ '.q-menu > .descriptor > .header > [data-cy="descriptor-more-opts"] > .q-btn__content',
+ ).click();
+ cy.get('[data-cy="descriptor-more-opts-menu"] > .q-list > :nth-child(4)').click();
+ cy.dataCy('VnConfirm_confirm').click();
});
});
diff --git a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
index 4d530de05..9c6eef2ed 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
@@ -9,16 +9,16 @@ describe('InvoiceOut negative bases', () => {
cy.visit(`/#/invoice-out/negative-bases`);
});
- it('should open the posible descriptors', () => {
+ it.skip('should open the posible descriptors', () => {
cy.get(getDescriptors('clientId')).click();
cy.get('.descriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('include.text', '1101');
cy.get(getDescriptors('ticketFk')).click();
cy.get('.descriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('include.text', '23');
- cy.get(getDescriptors('workerName')).click();
+ cy.get(getDescriptors('departmentFk')).click();
cy.get('.descriptor').should('be.visible');
- cy.get('.q-item > .q-item__label').should('include.text', '18');
+ cy.get('.q-item > .q-item__label').should('include.text', '155');
});
it('should filter and download as CSV', () => {
diff --git a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
index 29d841acc..49eed32c7 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
@@ -7,17 +7,14 @@ describe('InvoiceOut summary', () => {
const firstRowDescriptors = (opt) =>
`tbody > :nth-child(1) > :nth-child(${opt}) > .q-btn`;
- const toCustomerSummary = '[href="#/customer/1101"]';
const toTicketList = '[href="#/ticket/list?table={%22refFk%22:%22T1111111%22}"]';
const selectMenuOption = (opt) => `.q-menu > .q-list > :nth-child(${opt})`;
const confirmSend = '.q-btn--unelevated';
beforeEach(() => {
- cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/invoice-out/1/summary`);
});
-
it('open the descriptors', () => {
cy.get(firstRowDescriptors(1)).click();
cy.get('.descriptor').should('be.visible');
@@ -27,19 +24,20 @@ describe('InvoiceOut summary', () => {
cy.get('.q-item > .q-item__label').should('include.text', '1101');
});
- it('should open the client summary and the ticket list', () => {
- cy.get(toCustomerSummary).click();
+ it('should open the client summary', () => {
+ cy.dataCy('invoiceOutDescriptorCustomerCard').click();
cy.get('.descriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('include.text', '1101');
});
- it.skip('should open the ticket list', () => {
+ it('should open the ticket list', () => {
cy.get(toTicketList).click();
- cy.get('.descriptor').should('be.visible');
- cy.dataCy('vnFilterPanelChip').should('include.text', 'T1111111');
+ cy.get('[data-col-field="stateFk"]').each(($el) => {
+ cy.wrap($el).contains('T1111111');
+ });
});
- it('should transfer the invoice ', () => {
+ it.skip('should transfer the invoice ', () => {
cy.typeSearchbar('T1111111{enter}');
cy.dataCy('descriptor-more-opts').click();
cy.get(selectMenuOption(1)).click();
@@ -52,6 +50,7 @@ describe('InvoiceOut summary', () => {
cy.dataCy('descriptor-more-opts').click();
cy.get(selectMenuOption(3)).click();
cy.dataCy('InvoiceOutDescriptorMenuSendPdfOption').click();
+ cy.dataCy('SendEmailNotificationDialogInput').should('be.visible');
cy.get(confirmSend).click();
cy.checkNotification('Notification sent');
});
@@ -60,18 +59,11 @@ describe('InvoiceOut summary', () => {
cy.dataCy('descriptor-more-opts').click();
cy.get(selectMenuOption(3)).click();
cy.dataCy('InvoiceOutDescriptorMenuSendCsvOption').click();
+ cy.dataCy('SendEmailNotificationDialogInput').should('be.visible');
cy.get(confirmSend).click();
cy.checkNotification('Notification sent');
});
- it('should delete an invoice ', () => {
- cy.typeSearchbar('T2222222{enter}');
- cy.dataCy('descriptor-more-opts').click();
- cy.get(selectMenuOption(4)).click();
- cy.dataCy('VnConfirm_confirm').click();
- cy.checkNotification('InvoiceOut deleted');
- });
-
it('should book the invoice', () => {
cy.dataCy('descriptor-more-opts').click();
cy.get(selectMenuOption(5)).click();
diff --git a/test/cypress/integration/item/ItemFixedPrice.spec.js b/test/cypress/integration/item/ItemFixedPrice.spec.js
index 2cf9c2caf..404e8e365 100644
--- a/test/cypress/integration/item/ItemFixedPrice.spec.js
+++ b/test/cypress/integration/item/ItemFixedPrice.spec.js
@@ -3,7 +3,6 @@ function goTo(n = 1) {
return `.q-virtual-scroll__content > :nth-child(${n})`;
}
const firstRow = goTo();
-`.q-virtual-scroll__content > :nth-child(2)`;
describe('Handle Items FixedPrice', () => {
beforeEach(() => {
cy.viewport(1280, 720);
diff --git a/test/cypress/integration/item/itemBotanical.spec.js b/test/cypress/integration/item/itemBotanical.spec.js
index 08886d9a8..6105ef179 100644
--- a/test/cypress/integration/item/itemBotanical.spec.js
+++ b/test/cypress/integration/item/itemBotanical.spec.js
@@ -7,11 +7,9 @@ describe('Item botanical', () => {
});
it('should modify the botanical', () => {
- cy.dataCy('AddGenusSelectDialog').type('Abies');
- cy.get('.q-menu .q-item').contains('Abies').click();
- cy.dataCy('AddSpeciesSelectDialog').type('dealbata');
- cy.get('.q-menu .q-item').contains('dealbata').click();
- cy.get('.q-btn-group > .q-btn--standard').click();
+ cy.selectOption('[data-cy="AddGenusSelectDialog"]', 'Abies');
+ cy.selectOption('[data-cy="AddSpeciesSelectDialog"]', 'dealbata');
+ cy.saveCard();
cy.checkNotification('Data saved');
});
diff --git a/test/cypress/integration/item/itemList.spec.js b/test/cypress/integration/item/itemList.spec.js
index f0c744f21..10e388580 100644
--- a/test/cypress/integration/item/itemList.spec.js
+++ b/test/cypress/integration/item/itemList.spec.js
@@ -1,6 +1,6 @@
///
-describe('Item list', () => {
+describe.skip('Item list', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
@@ -16,8 +16,7 @@ describe('Item list', () => {
cy.get('.q-virtual-scroll__content > :nth-child(4) > :nth-child(4)').click();
});
- // https://redmine.verdnatura.es/issues/8421
- it.skip('should create an item', () => {
+ it('should create an item', () => {
const data = {
Description: { val: `Test item` },
Type: { val: `Crisantemo`, type: 'select' },
diff --git a/test/cypress/integration/order/orderList.spec.js b/test/cypress/integration/order/orderList.spec.js
index e7b49c9d0..e08c6aaff 100644
--- a/test/cypress/integration/order/orderList.spec.js
+++ b/test/cypress/integration/order/orderList.spec.js
@@ -1,5 +1,9 @@
///
describe('OrderList', () => {
+ const clientCreateSelect = '#formModel [data-cy="Client_select"]';
+ const addressCreateSelect = '#formModel [data-cy="Address_select"]';
+ const agencyCreateSelect = '#formModel [data-cy="Agency_select"]';
+
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
@@ -7,14 +11,15 @@ describe('OrderList', () => {
});
it('create order', () => {
- cy.dataCy('vnTableCreateBtn').click();
+ cy.get('[data-cy="vnTableCreateBtn"]').click();
+ cy.selectOption(clientCreateSelect, 1101);
+ cy.get(addressCreateSelect).click();
+ cy.get(
+ '.q-menu > div> div.q-item:nth-child(1) >div.q-item__section--avatar > i',
+ ).should('have.text', 'star');
+ cy.dataCy('landedDate').find('input').type('06/01/2001');
+ cy.selectOption(agencyCreateSelect, 1);
- const data = {
- Client: { val: 'salesPerson', type: 'select' },
- Address: { val: 'salesPerson', type: 'select' },
- Landed: { val: '01-01-2024', type: 'date' },
- Agency: { val: 'Other agency', type: 'select' },
- };
cy.intercept('GET', /\/api\/Orders\/\d/).as('orderSale');
cy.fillInForm(data);
@@ -29,10 +34,12 @@ describe('OrderList', () => {
it('filter list and create order', () => {
cy.dataCy('Customer ID_input').type('1101{enter}');
+ cy.intercept('GET', /\/api\/Clients/).as('clientFilter');
cy.dataCy('vnTableCreateBtn').click();
+ cy.wait('@clientFilter');
cy.dataCy('landedDate').find('input').type('06/01/2001');
- cy.get('.q-card [data-cy="Agency_select"]').click();
- cy.get('.q-menu > div> .q-item:nth-child(1)').click();
+ cy.selectOption(agencyCreateSelect, 1);
+
cy.intercept('GET', /\/api\/Orders\/\d/).as('orderSale');
cy.get('[data-cy="FormModelPopup_save"] > .q-btn__content > .block').click();
cy.wait('@orderSale');
@@ -53,11 +60,12 @@ describe('OrderList', () => {
`[href="#/order/list?createForm={%22clientFk%22:${clientId},%22addressId%22:1}"] > .q-btn__content > .q-icon`,
).click();
cy.dataCy('vnTableCreateBtn').click();
- cy.get('[data-cy="Client_select"]').should('have.value', 'Bruce Wayne');
- cy.get('[data-cy="Address_select"]').should('have.value', 'Bruce Wayne');
+
+ cy.get(clientCreateSelect).should('have.value', 'Bruce Wayne');
+ cy.get(addressCreateSelect).should('have.value', 'Bruce Wayne');
cy.dataCy('landedDate').find('input').type('06/01/2001');
- cy.get('.q-card [data-cy="Agency_select"]').click();
- cy.get('.q-menu > div> .q-item:nth-child(1)').click();
+ cy.selectOption(agencyCreateSelect, 1);
+
cy.intercept('GET', /\/api\/Orders\/\d/).as('orderSale');
cy.get('[data-cy="FormModelPopup_save"] > .q-btn__content > .block').click();
cy.wait('@orderSale');
diff --git a/test/cypress/integration/outLogin/login.spec.js b/test/cypress/integration/outLogin/login.spec.js
index 2bd5a8c3b..22e30dd8e 100755
--- a/test/cypress/integration/outLogin/login.spec.js
+++ b/test/cypress/integration/outLogin/login.spec.js
@@ -12,7 +12,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
- 'Invalid username or password'
+ 'Invalid username or password',
);
});
@@ -23,7 +23,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
- 'Invalid username or password'
+ 'Invalid username or password',
);
});
@@ -33,7 +33,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
- 'You have successfully logged in'
+ 'You have successfully logged in',
);
cy.url().should('contain', '/dashboard');
});
@@ -44,7 +44,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
- 'You have successfully logged in'
+ 'You have successfully logged in',
);
cy.url().should('contain', '/dashboard');
cy.get('#user').click();
@@ -61,14 +61,4 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.url().should('contain', '/dashboard');
});
-
- // ticket creation is not yet implemented, use this test once it is
- // it(`should get redirected to ticket creation after login since salesPerson can do it`, () => {
- // cy.visit('/#/ticket/create', { failOnStatusCode: false });
- // cy.url().should('contain', '/#/login?redirect=/ticket/create');
- // cy.get('input[aria-label="Username"]').type('salesPerson');
- // cy.get('input[aria-label="Password"]').type('nightmare');
- // cy.get('button[type="submit"]').click();
- // cy.url().should('contain', '/#/ticket/create');
- // })
});
diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/outLogin/logout.spec.js
index bcdacec78..9f022617d 100644
--- a/test/cypress/integration/outLogin/logout.spec.js
+++ b/test/cypress/integration/outLogin/logout.spec.js
@@ -1,5 +1,5 @@
///
-describe('Logout', () => {
+describe.skip('Logout', () => {
beforeEach(() => {
cy.login('developer');
cy.visit(`/#/dashboard`);
@@ -24,11 +24,13 @@ describe('Logout', () => {
},
},
statusMessage: 'AUTHORIZATION_REQUIRED',
- });
+ }).as('badRequest');
});
it('when token not exists', () => {
- cy.get('.q-list').first().should('be.visible').click();
+ cy.get('.q-list').should('be.visible').first().should('be.visible').click();
+ cy.wait('@badRequest');
+
cy.checkNotification('Authorization Required');
});
});
diff --git a/test/cypress/integration/route/agency/agencyModes.spec.js b/test/cypress/integration/route/agency/agencyModes.spec.js
new file mode 100644
index 000000000..3f5784997
--- /dev/null
+++ b/test/cypress/integration/route/agency/agencyModes.spec.js
@@ -0,0 +1,15 @@
+describe('Agency modes', () => {
+ const name = 'inhouse pickup';
+
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit(`/#/route/agency/1/modes`);
+ });
+
+ it('should display the agency modes page', () => {
+ cy.get('.flex > .title').should('have.text', name);
+ cy.get('.flex > .q-chip > .q-chip__content').should('have.text', 'ID: 1');
+ cy.get('.list-items > :nth-child(1) > .value').should('have.text', name);
+ });
+});
diff --git a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
index 5679ceba1..79dcd6f70 100644
--- a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
+++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
@@ -1,27 +1,34 @@
-describe.skip('AgencyWorkCenter', () => {
+describe('AgencyWorkCenter', () => {
+ const selectors = {
+ workCenter: 'workCenter_select',
+ popupSave: 'FormModelPopup_save',
+ popupCancel: 'FormModelPopup_cancel',
+ remove: 'removeWorkCenterBtn',
+ };
+
+ const messages = {
+ dataCreated: 'Data created',
+ alreadyAssigned: 'This workCenter is already assigned to this agency',
+ removed: 'Work center removed successfully',
+ };
+
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/route/agency/11/workCenter`);
});
- const createButton = '.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon';
- const workCenterCombobox = 'input[role="combobox"]';
- it('check workCenter crud', () => {
- // create
- cy.get(createButton).click();
- cy.get(workCenterCombobox).type('workCenterOne{enter}');
+ it('Should add work center, check already assigned and remove work center', () => {
+ cy.addBtnClick();
+ cy.selectOption('[data-cy="workCenter_select"]', 'workCenterOne');
+ cy.dataCy(selectors.popupSave).click();
cy.checkNotification('Data created');
-
- // expect error when duplicate
- cy.get(createButton).click();
- cy.selectOption(workCenterCombobox, 'workCenterOne');
- cy.get('[data-cy="FormModelPopup_save"]').click();
- cy.checkNotification('This workCenter is already assigned to this agency');
- cy.get('[data-cy="FormModelPopup_cancel"]').click();
-
- // delete
- cy.get('.q-item__section--side > .q-btn > .q-btn__content > .q-icon').click();
- cy.checkNotification('WorkCenter removed successfully');
+ cy.addBtnClick();
+ cy.selectOption('[data-cy="workCenter_select"]', 'workCenterOne');
+ cy.dataCy(selectors.popupSave).click();
+ cy.checkNotification(messages.alreadyAssigned);
+ cy.dataCy(selectors.popupCancel).click();
+ cy.dataCy(selectors.remove).click();
+ cy.checkNotification(messages.removed);
});
});
diff --git a/test/cypress/integration/route/cmr/cmrList.spec.js b/test/cypress/integration/route/cmr/cmrList.spec.js
new file mode 100644
index 000000000..d33508e3a
--- /dev/null
+++ b/test/cypress/integration/route/cmr/cmrList.spec.js
@@ -0,0 +1,91 @@
+describe('Cmr list', () => {
+ const getLinkSelector = (colField) =>
+ `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;
+
+ const selectors = {
+ ticket: getLinkSelector('ticketFk'),
+ client: getLinkSelector('clientFk'),
+ lastRowSelectCheckBox:
+ '.q-virtual-scroll__content > tr:last-child > :nth-child(1) > .q-checkbox',
+ downloadBtn: '#subToolbar > .q-btn',
+ viewCmr: 'tableAction-0',
+ descriptorOpenSummaryBtn: '.descriptor [data-cy="openSummaryBtn"]',
+ summaryTitle: '.summaryHeader',
+ descriptorId: '.descriptor .subtitle',
+ descriptorTitle: '.descriptor .title',
+ summaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]',
+ descriptorGoToSummaryBtn: '.descriptor [data-cy="goToSummaryBtn"]',
+ removeFilter: '.q-chip__icon--remove',
+ };
+
+ const data = {
+ ticket: '1',
+ client: 'Bruce Wayne',
+ };
+
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit('/#/route/cmr');
+ cy.typeSearchbar('{enter}');
+ cy.get(selectors.removeFilter).click();
+ });
+
+ it('Should download selected cmr', () => {
+ const downloadsFolder = Cypress.config('downloadsFolder');
+ cy.get(selectors.lastRowSelectCheckBox).should('be.visible').click();
+ cy.get(selectors.downloadBtn).should('be.visible').click();
+ cy.wait(3000);
+
+ const fileName = 'cmrs.zip';
+ cy.readFile(`${downloadsFolder}/${fileName}`).should('exist');
+ });
+
+ it('Should open selected cmr pdf', () => {
+ cy.window().then((win) => {
+ cy.stub(win, 'open').as('windowOpen');
+ });
+ cy.dataCy(selectors.viewCmr).last().click();
+ cy.get('@windowOpen').should('be.calledWithMatch', '\/api\/Cmrs\/3');
+ });
+
+ describe('Ticket pop-ups', () => {
+ it('Should redirect to the ticket summary from the ticket descriptor pop-up', () => {
+ cy.get(selectors.ticket).should('be.visible').click();
+ cy.containContent(selectors.descriptorId, data.ticket);
+ cy.get(selectors.descriptorGoToSummaryBtn).should('be.visible').click();
+ cy.url().should('include', '/ticket/1/summary');
+ cy.containContent(selectors.summaryTitle, data.client);
+ });
+
+ it('Should redirect to the ticket summary from summary pop-up from the ticket descriptor pop-up', () => {
+ cy.get(selectors.ticket).should('be.visible').click();
+ cy.containContent(selectors.descriptorId, data.ticket);
+ cy.get(selectors.descriptorOpenSummaryBtn).should('be.visible').click();
+ cy.containContent(selectors.summaryTitle, data.client);
+ cy.get(selectors.summaryGoToSummaryBtn).should('be.visible').click();
+ cy.url().should('include', '/ticket/1/summary');
+ cy.containContent(selectors.summaryTitle, data.client);
+ });
+ });
+
+ describe('Client pop-ups', () => {
+ it('Should redirect to the client summary from the client descriptor pop-up', () => {
+ cy.get(selectors.client).should('be.visible').click();
+ cy.containContent(selectors.descriptorTitle, data.client);
+ cy.get(selectors.descriptorGoToSummaryBtn).should('be.visible').click();
+ cy.url().should('include', '/customer/1101/summary');
+ cy.containContent(selectors.summaryTitle, data.client);
+ });
+
+ it('Should redirect to the client summary from summary pop-up from the client descriptor pop-up', () => {
+ cy.get(selectors.client).should('be.visible').click();
+ cy.containContent(selectors.descriptorTitle, data.client);
+ cy.get(selectors.descriptorOpenSummaryBtn).should('be.visible').click();
+ cy.containContent(selectors.summaryTitle, data.client);
+ cy.get(selectors.summaryGoToSummaryBtn).should('be.visible').click();
+ cy.url().should('include', '/customer/1101/summary');
+ cy.containContent(selectors.summaryTitle, data.client);
+ });
+ });
+});
diff --git a/test/cypress/integration/route/roadMap/roadmapList.spec.js b/test/cypress/integration/route/roadMap/roadmapList.spec.js
index 6d46b2cf6..35c0c2b02 100644
--- a/test/cypress/integration/route/roadMap/roadmapList.spec.js
+++ b/test/cypress/integration/route/roadMap/roadmapList.spec.js
@@ -1,12 +1,74 @@
describe('RoadMap', () => {
+ const getSelector = (colField) =>
+ `tr:last-child > [data-col-field="${colField}"] > .no-padding`;
+
+ const selectors = {
+ roadmap: getSelector('name'),
+ id: getSelector('id'),
+ etd: getSelector('etd'),
+ summaryHeader: '.summaryHeader > :nth-child(2)',
+ summaryGoToSummaryBtn: '.summaryHeader > a > .q-icon',
+ summaryBtn: 'tableAction-0',
+ inputRoadmap: 'Roadmap_input',
+ checkbox: '.q-virtual-scroll__content tr:last-child .q-checkbox',
+ cloneFormBtn: '.q-card__actions > .q-btn--standard',
+ cloneBtn: '#subToolbar > :nth-child(3)',
+ deleteBtn: ':nth-child(4) > .q-btn__content',
+ confirmBtn: 'VnConfirm_confirm',
+ inputEtd: 'ETD_inputDate',
+ };
+
+ const data = {
+ roadmap: 'TEST-ROADMAP',
+ etd: '01/01/2025',
+ };
+
+ const dataCreated = 'Data created';
+ const summaryUrl = '/summary';
+
beforeEach(() => {
+ cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/route/roadmap`);
+ cy.typeSearchbar('{enter}');
});
+
+ it('Should list roadmaps', () => {
+ cy.get('.q-table')
+ .children()
+ .should('be.visible')
+ .should('have.length.greaterThan', 0);
+ });
+
it('Route list create roadmap and redirect', () => {
cy.addBtnClick();
- cy.get('input[name="name"]').type('roadMapTestOne{enter}');
- cy.get('.q-notification__message').should('have.text', 'Data created');
- cy.url().should('include', '/summary');
+ cy.dataCy(selectors.inputRoadmap).type(`${data.roadmap}{enter}`);
+ cy.checkNotification(dataCreated);
+ cy.url().should('include', summaryUrl);
+ });
+
+ it('open summary', () => {
+ cy.dataCy(selectors.summaryBtn).last().click();
+ cy.get(selectors.summaryHeader).should('contain', data.roadmap);
+ cy.get(selectors.summaryGoToSummaryBtn).click();
+ cy.get(selectors.summaryHeader).should('contain', data.roadmap);
+ });
+
+ it('Should clone selected roadmap with new ETD', () => {
+ cy.get(selectors.checkbox).click();
+ cy.get(selectors.cloneBtn).click();
+ cy.dataCy(selectors.inputEtd).click().type(`${data.etd}{enter}`);
+ cy.get(selectors.cloneFormBtn).click();
+ cy.get(selectors.etd).should('contain', data.etd);
+ });
+
+ it('Should delete selected roadmap', () => {
+ cy.get(selectors.id).then(($el) => {
+ cy.get(selectors.checkbox).click();
+ cy.get(selectors.deleteBtn).click();
+ cy.dataCy(selectors.confirmBtn).click();
+ cy.typeSearchbar('{enter}');
+ cy.get(selectors.id).should('not.have.text', $el.text);
+ });
});
});
diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js
index acf82bd95..d77584c04 100644
--- a/test/cypress/integration/route/routeAutonomous.spec.js
+++ b/test/cypress/integration/route/routeAutonomous.spec.js
@@ -1,4 +1,4 @@
-describe('RouteAutonomous', () => {
+describe.skip('RouteAutonomous', () => {
const getLinkSelector = (colField) =>
`tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;
@@ -49,12 +49,12 @@ describe('RouteAutonomous', () => {
cy.get(selectors.firstRowCheckbox).click();
cy.get(selectors.createInvoiceBtn).click();
cy.dataCy(selectors.reference).type(data.reference);
+ cy.dataCy('attachFile').click();
cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
force: true,
});
- cy.dataCy(selectors.saveFormBtn).click();
+ cy.dataCy(selectors.saveFormBtn).should('be.visible').click();
cy.checkNotification(dataSaved);
- cy.typeSearchbar('{enter}');
});
it('Should display the total price of the selected rows', () => {
diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js
index e3505ad60..e6c873d5e 100644
--- a/test/cypress/integration/route/routeExtendedList.spec.js
+++ b/test/cypress/integration/route/routeExtendedList.spec.js
@@ -1,4 +1,4 @@
-describe.skip('Route extended list', () => {
+describe('Route extended list', () => {
const getSelector = (colField) => `tr:last-child > [data-col-field="${colField}"]`;
const selectors = {
@@ -8,6 +8,8 @@ describe.skip('Route extended list', () => {
date: getSelector('dated'),
description: getSelector('description'),
served: getSelector('isOk'),
+ firstRowSelectCheckBox:
+ 'tbody > tr:first-child > :nth-child(1) .q-checkbox__inner',
lastRowSelectCheckBox: 'tbody > tr:last-child > :nth-child(1) .q-checkbox__inner',
removeBtn: '[title="Remove"]',
resetBtn: '[title="Reset"]',
@@ -19,7 +21,7 @@ describe.skip('Route extended list', () => {
markServedBtn: '#st-actions > .q-btn-group > :nth-child(3)',
searchbar: 'searchbar',
firstTicketsRowSelectCheckBox:
- '.q-card > :nth-child(2) > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(1) > .q-table--col-auto-width > .q-checkbox > .q-checkbox__inner > .q-checkbox__bg > .q-checkbox__svg',
+ '.q-card .q-table > tbody > :nth-child(1) .q-checkbox',
};
const checkboxState = {
@@ -32,18 +34,18 @@ describe.skip('Route extended list', () => {
const originalFields = [
{ selector: selectors.worker, type: 'select', value: 'logistic' },
- { selector: selectors.agency, type: 'select', value: 'Super-Man delivery' },
+ { selector: selectors.agency, type: 'select', value: 'inhouse pickup' },
{ selector: selectors.vehicle, type: 'select', value: '3333-IMK' },
- { selector: selectors.date, type: 'date', value: '01/02/2024' },
+ { selector: selectors.date, type: 'date', value: '01/01/2001' },
{ selector: selectors.description, type: 'input', value: 'Test route' },
{ selector: selectors.served, type: 'checkbox', value: checkboxState.uncheck },
];
const updateFields = [
{ selector: selectors.worker, type: 'select', value: 'salesperson' },
- { selector: selectors.agency, type: 'select', value: 'inhouse pickup' },
+ { selector: selectors.agency, type: 'select', value: 'Super-Man delivery' },
{ selector: selectors.vehicle, type: 'select', value: '1111-IMK' },
- { selector: selectors.date, type: 'date', value: '01/01/2001' },
+ { selector: selectors.date, type: 'date', value: '11/01/2001' },
{ selector: selectors.description, type: 'input', value: 'Description updated' },
{ selector: selectors.served, type: 'checkbox', value: checkboxState.check },
];
@@ -51,17 +53,20 @@ describe.skip('Route extended list', () => {
function fillField(selector, type, value) {
switch (type) {
case 'select':
- cy.get(selector).should('be.visible').click();
- cy.dataCy('null_select').clear().type(value);
+ cy.get(selector).should('be.visible').click().clear().type(value);
cy.get('.q-item').contains(value).click();
break;
case 'input':
- cy.get(selector).should('be.visible').click();
- cy.dataCy('null_input').clear().type(`${value}{enter}`);
+ cy.get(selector)
+ .should('be.visible')
+ .click()
+ .type(`{selectall}{backspace}${value}`);
break;
case 'date':
- cy.get(selector).should('be.visible').click();
- cy.dataCy('null_inputDate').clear().type(`${value}{enter}`);
+ cy.get(selector)
+ .should('be.visible')
+ .click()
+ .type(`{selectall}{backspace}${value}`);
break;
case 'checkbox':
cy.get(selector).should('be.visible').click().click();
@@ -76,15 +81,6 @@ describe.skip('Route extended list', () => {
cy.typeSearchbar('{enter}');
});
- after(() => {
- cy.visit(url);
- cy.typeSearchbar('{enter}');
- cy.get(selectors.lastRowSelectCheckBox).click();
-
- cy.get(selectors.removeBtn).click();
- cy.dataCy(selectors.confirmBtn).click();
- });
-
it('Should list routes', () => {
cy.get('.q-table')
.children()
@@ -97,9 +93,9 @@ describe.skip('Route extended list', () => {
const data = {
Worker: { val: 'logistic', type: 'select' },
- Agency: { val: 'Super-Man delivery', type: 'select' },
+ Agency: { val: 'inhouse pickup', type: 'select' },
Vehicle: { val: '3333-IMK', type: 'select' },
- Date: { val: '02-01-2024', type: 'date' },
+ Date: { val: '01-01-2001', type: 'date' },
From: { val: '01-01-2024', type: 'date' },
To: { val: '10-01-2024', type: 'date' },
'Km start': { val: 1000 },
@@ -110,8 +106,8 @@ describe.skip('Route extended list', () => {
cy.fillInForm(data);
cy.dataCy(selectors.saveFormBtn).click();
- cy.checkNotification(dataCreated);
cy.url().should('include', '/summary');
+ cy.checkNotification(dataCreated);
});
it('Should reset changed values when click reset button', () => {
@@ -126,26 +122,31 @@ describe.skip('Route extended list', () => {
});
});
- it('Should clone selected route', () => {
- cy.get(selectors.lastRowSelectCheckBox).click();
+ it('Should clone selected route and add ticket', () => {
+ cy.get(selectors.firstRowSelectCheckBox).click();
cy.get(selectors.cloneBtn).click();
- cy.dataCy('route.Starting date_inputDate').type('10-05-2001{enter}');
+ cy.dataCy('Starting date_inputDate').type('01-01-2001');
cy.get('.q-card__actions > .q-btn--standard > .q-btn__content').click();
- cy.validateContent(selectors.date, '05/10/2001');
+ cy.validateContent(selectors.date, '01/01/2001');
+
+ cy.dataCy('tableAction-0').last().click();
+ cy.get(selectors.firstTicketsRowSelectCheckBox).click();
+ cy.get('.q-card__actions > .q-btn--standard > .q-btn__content').click();
+ cy.checkNotification(dataSaved);
+
+ cy.get(selectors.lastRowSelectCheckBox).click();
+ cy.get(selectors.removeBtn).click();
+ cy.dataCy(selectors.confirmBtn).click();
});
it('Should download selected route', () => {
const downloadsFolder = Cypress.config('downloadsFolder');
cy.get(selectors.lastRowSelectCheckBox).click();
cy.get(selectors.downloadBtn).click();
- cy.wait(5000);
+ cy.wait(3000);
const fileName = 'download.zip';
cy.readFile(`${downloadsFolder}/${fileName}`).should('exist');
-
- cy.task('deleteFile', `${downloadsFolder}/${fileName}`).then((deleted) => {
- expect(deleted).to.be.true;
- });
});
it('Should mark as served the selected route', () => {
@@ -158,7 +159,6 @@ describe.skip('Route extended list', () => {
it('Should delete the selected route', () => {
cy.get(selectors.lastRowSelectCheckBox).click();
-
cy.get(selectors.removeBtn).click();
cy.dataCy(selectors.confirmBtn).click();
@@ -175,18 +175,15 @@ describe.skip('Route extended list', () => {
cy.typeSearchbar('{enter}');
- updateFields.forEach(({ selector, value }) => {
- cy.validateContent(selector, value);
+ updateFields.forEach(({ selector, value, type }) => {
+ if (type === 'date') {
+ const [month, day, year] = value.split('/');
+ value = `${day}/${month}/${year}`;
+ }
+ cy.get(selector).should('contain', value);
});
});
- it('Should add ticket to route', () => {
- cy.dataCy('tableAction-0').last().click();
- cy.get(selectors.firstTicketsRowSelectCheckBox).click();
- cy.get('.q-card__actions > .q-btn--standard > .q-btn__content').click();
- cy.checkNotification(dataSaved);
- });
-
it('Should open summary pop-up when click summuary icon', () => {
cy.dataCy('tableAction-1').last().click();
cy.get('.summaryHeader > :nth-child(2').should('contain', updateFields[4].value);
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index 04278cfc5..f08c267a4 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -1,37 +1,205 @@
describe('Route', () => {
+ const getSelector = (colField) =>
+ `tr:last-child > [data-col-field="${colField}"] > .no-padding > .link`;
+
+ const selectors = {
+ lastRow: 'tr:last-child > [data-col-field="workerFk"]',
+ workerLink: getSelector('workerFk'),
+ agencyLink: getSelector('agencyModeFk'),
+ vehicleLink: getSelector('vehicleFk'),
+ assignedTicketsBtn: 'tableAction-0',
+ rowSummaryBtn: 'tableAction-1',
+ summaryTitle: '.summaryHeader',
+ descriptorTitle: '.descriptor .title',
+ descriptorOpenSummaryBtn: '.descriptor [data-cy="openSummaryBtn"]',
+ descriptorGoToSummaryBtn: '.descriptor [data-cy="goToSummaryBtn"]',
+ SummaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]',
+ };
+
+ const data = {
+ Worker: { val: 'logistic', type: 'select' },
+ Agency: { val: 'Walking', type: 'select' },
+ Vehicle: { val: '3333-BAT', type: 'select' },
+ Description: { val: 'routeTest' },
+ };
+
+ const summaryUrl = '/summary';
+
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
- cy.visit(`/#/route/extended-list`);
+ cy.visit(`/#/route/list`);
+ cy.typeSearchbar('{enter}');
});
- it('Route list create route', () => {
+ it('Should list routes', () => {
+ cy.get('.q-table')
+ .children()
+ .should('be.visible')
+ .should('have.length.greaterThan', 0);
+ });
+
+ it('Should create new route', () => {
cy.addBtnClick();
- cy.get('.q-card input[name="description"]').type('routeTestOne{enter}');
- cy.get('.q-notification__message').should('have.text', 'Data created');
- cy.url().should('include', '/summary');
+
+ cy.fillInForm(data);
+
+ cy.dataCy('FormModelPopup_save').should('be.visible').click();
+
+ cy.checkNotification('Data created');
+ cy.url().should('include', summaryUrl);
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Description.val);
+ });
});
- it('Route list search and edit', () => {
- cy.get('#searchbar input').type('{enter}');
- cy.get('[data-col-field="description"][data-row-index="0"]')
- .click()
- .type('routeTestOne{enter}');
- cy.get('.q-table tr')
- .its('length')
- .then((rowCount) => {
- expect(rowCount).to.be.greaterThan(0);
+ it('Should open route summary by clicking a route', () => {
+ cy.get(selectors.lastRow).should('be.visible').click();
+ cy.url().should('include', summaryUrl);
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Description.val);
});
- cy.get('[data-col-field="workerFk"][data-row-index="0"]')
- .click()
- .type('{downArrow}{enter}');
- cy.get('[data-col-field="agencyModeFk"][data-row-index="0"]')
- .click()
- .type('{downArrow}{enter}');
- cy.get('[data-col-field="vehicleFk"][data-row-index="0"]')
- .click()
- .type('{downArrow}{enter}');
- cy.get('button[title="Save"]').click();
- cy.get('.q-notification__message').should('have.text', 'Data saved');
+ });
+
+ it('Should redirect to the summary from the route pop-up summary', () => {
+ cy.dataCy(selectors.rowSummaryBtn).last().should('be.visible').click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Description.val);
+ });
+ cy.get(selectors.SummaryGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Description.val);
+ });
+ });
+
+ it('Should redirect to the route assigned tickets from the row assignedTicketsBtn', () => {
+ cy.dataCy(selectors.assignedTicketsBtn).first().should('be.visible').click();
+ cy.url().should('include', '1/tickets');
+ cy.get('.q-table')
+ .children()
+ .should('be.visible')
+ .should('have.length.greaterThan', 0);
+ });
+
+ describe('Worker pop-ups', () => {
+ it('Should redirect to summary from the worker pop-up descriptor', () => {
+ cy.get(selectors.workerLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Worker.val);
+ });
+ cy.get(selectors.descriptorGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Worker.val);
+ });
+ });
+
+ it('Should redirect to the summary from the worker pop-up summary', () => {
+ cy.get(selectors.workerLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Worker.val);
+ });
+ cy.get(selectors.descriptorOpenSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Worker.val);
+ });
+ cy.get(selectors.SummaryGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Worker.val);
+ });
+ });
+ });
+
+ describe('Agency pop-ups', () => {
+ it('Should redirect to summary from the agency pop-up descriptor', () => {
+ cy.get(selectors.agencyLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Agency.val);
+ });
+ cy.get(selectors.descriptorGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Agency.val);
+ });
+ });
+
+ it('Should redirect to the summary from the agency pop-up summary', () => {
+ cy.get(selectors.agencyLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Agency.val);
+ });
+ cy.get(selectors.descriptorOpenSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Agency.val);
+ });
+ cy.get(selectors.SummaryGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Agency.val);
+ });
+ });
+ });
+
+ describe('Vehicle pop-ups', () => {
+ it('Should redirect to summary from the vehicle pop-up descriptor', () => {
+ cy.get(selectors.vehicleLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Vehicle.val);
+ });
+ cy.get(selectors.descriptorGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Vehicle.val);
+ });
+ });
+
+ it('Should redirect to the summary from the vehicle pop-up summary', () => {
+ cy.get(selectors.vehicleLink).click();
+ cy.get(selectors.descriptorTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Vehicle.val);
+ });
+ cy.get(selectors.descriptorOpenSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Vehicle.val);
+ });
+ cy.get(selectors.SummaryGoToSummaryBtn).click();
+ cy.get(selectors.summaryTitle)
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(data.Vehicle.val);
+ });
+ });
});
});
diff --git a/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js b/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
index 64b9ca0a0..3e9c816c4 100644
--- a/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
+++ b/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
@@ -2,11 +2,11 @@ describe('Vehicle', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('deliveryAssistant');
- cy.visit(`/#/route/vehicle/7`);
+ cy.visit(`/#/route/vehicle/7/summary`);
});
it('should delete a vehicle', () => {
- cy.openActionsDescriptor();
+ cy.dataCy('descriptor-more-opts').click();
cy.get('[data-cy="delete"]').click();
cy.checkNotification('Vehicle removed');
});
diff --git a/test/cypress/integration/route/vehicle/vehicleNotes.spec.js b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js
new file mode 100644
index 000000000..cd92cc4af
--- /dev/null
+++ b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js
@@ -0,0 +1,28 @@
+describe('Vehicle Notes', () => {
+ const selectors = {
+ addNoteInput: 'Add note here..._input',
+ saveNoteBtn: 'saveNote',
+ deleteNoteBtn: 'notesRemoveNoteBtn',
+ noteCard: '.column.full-width > :nth-child(1) > .q-card__section--vert',
+ };
+
+ const noteText = 'Golpe parachoques trasero';
+ const newNoteText = 'probando';
+
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit(`/#/route/vehicle/1/notes`);
+ });
+
+ it('Should add new note', () => {
+ cy.dataCy(selectors.addNoteInput).should('be.visible').type(newNoteText);
+ cy.dataCy(selectors.saveNoteBtn).click();
+ cy.validateContent(selectors.noteCard, newNoteText);
+ });
+
+ it('Should delete note', () => {
+ cy.dataCy(selectors.deleteNoteBtn).first().should('be.visible').click();
+ cy.get(selectors.noteCard).first().should('have.text', noteText);
+ });
+});
diff --git a/test/cypress/integration/shelving/parking/parkingBasicData.spec.js b/test/cypress/integration/shelving/parking/parkingBasicData.spec.js
index e28d7eeca..81c158684 100644
--- a/test/cypress/integration/shelving/parking/parkingBasicData.spec.js
+++ b/test/cypress/integration/shelving/parking/parkingBasicData.spec.js
@@ -6,13 +6,16 @@ describe('ParkingBasicData', () => {
beforeEach(() => {
cy.login('developer');
cy.visit(`/#/shelving/parking/1/basic-data`);
+ cy.get('[data-cy="loading-spinner"]', { timeout: 10000 }).should(
+ 'not.be.visible',
+ );
});
it('should give an error if the code aldready exists', () => {
cy.get(codeInput).eq(0).should('have.value', '700-01').clear();
cy.get(codeInput).eq(0).type('700-02');
cy.saveCard();
- cy.get('.q-notification__message').should('have.text', 'The code already exists');
+ cy.checkNotification('The code already exists');
});
it('should edit the code and sector', () => {
@@ -24,7 +27,8 @@ describe('ParkingBasicData', () => {
cy.dataCy('Picking order_input').clear().type(80230);
cy.saveCard();
- cy.get('.q-notification__message').should('have.text', 'Data saved');
+ cy.checkNotification('Data saved');
+
cy.get(sectorSelect).should('have.value', 'First sector');
cy.get(codeInput).should('have.value', '700-01');
cy.dataCy('Picking order_input').should('have.value', 80230);
diff --git a/test/cypress/integration/shelving/parking/parkingList.spec.js b/test/cypress/integration/shelving/parking/parkingList.spec.js
index ecee8aab7..7372da164 100644
--- a/test/cypress/integration/shelving/parking/parkingList.spec.js
+++ b/test/cypress/integration/shelving/parking/parkingList.spec.js
@@ -1,8 +1,8 @@
///
describe('ParkingList', () => {
const searchbar = '#searchbar input';
- const firstCard = ':nth-child(1) > .q-card > .no-margin > .q-py-none';
- const summaryHeader = '.summaryBody .header';
+ const firstCard = ':nth-child(1) > .q-card > .no-margin > .q-py-none';
+ const summaryHeader = '.header-link';
beforeEach(() => {
cy.viewport(1920, 1080);
diff --git a/test/cypress/integration/shelving/shelvingBasicData.spec.js b/test/cypress/integration/shelving/shelvingBasicData.spec.js
new file mode 100644
index 000000000..d7b0dc692
--- /dev/null
+++ b/test/cypress/integration/shelving/shelvingBasicData.spec.js
@@ -0,0 +1,24 @@
+///
+describe('ShelvingList', () => {
+ const parking =
+ '.q-card > :nth-child(1) > .q-select > .q-field__inner > .q-field__control > .q-field__control-container';
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit(`/#/shelving/1/basic-data`);
+ });
+
+ it('should give an error if the code aldready exists', () => {
+ cy.dataCy('Code_input').should('exist').clear().type('AA7');
+ cy.saveCard();
+ cy.get('.q-notification__message').should('have.text', 'The code already exists');
+ });
+ it('should edit the data and save', () => {
+ cy.selectOption(parking, 'P-01-1');
+ cy.dataCy('Code_input').clear().type('AA1');
+ cy.dataCy('Priority_input').clear().type('10');
+ cy.get(':nth-child(2) > .q-checkbox > .q-checkbox__inner').click();
+ cy.saveCard();
+ cy.get('.q-notification__message').should('have.text', 'Data saved');
+ });
+});
diff --git a/test/cypress/integration/shelving/shelvingList.spec.js b/test/cypress/integration/shelving/shelvingList.spec.js
new file mode 100644
index 000000000..20b72e419
--- /dev/null
+++ b/test/cypress/integration/shelving/shelvingList.spec.js
@@ -0,0 +1,41 @@
+///
+describe('ShelvingList', () => {
+ beforeEach(() => {
+ cy.viewport(1920, 1080);
+ cy.login('developer');
+ cy.visit(`/#/shelving/list`);
+ });
+
+ it('should redirect on clicking a shelving', () => {
+ cy.typeSearchbar('{enter}');
+ cy.dataCy('cardBtn').eq(0).click();
+ cy.get('.summaryHeader > .header > .q-icon').click();
+ cy.url().should('include', '/shelving/1/summary');
+ });
+
+ it('should redirect from preview to basic-data', () => {
+ cy.typeSearchbar('{enter}');
+ cy.dataCy('cardBtn').eq(0).click();
+ cy.get('.summaryHeader > .header > .q-icon').click();
+ cy.url().should('include', '/shelving/1/summary');
+ });
+
+ it('should filter and redirect if only one result', () => {
+ cy.selectOption('[data-cy="Parking_select"]', 'P-02-2');
+ cy.dataCy('Parking_select').type('{enter}');
+ cy.url().should('match', /\/shelving\/\d+\/summary/);
+ });
+
+ it('should create a new shelving', () => {
+ cy.dataCy('vnTableCreateBtn').click();
+ cy.dataCy('code-create-popup').type('Test');
+ cy.dataCy('Priority_input').type('10');
+ cy.selectOption(
+ '.grid-create > .q-select > .q-field__inner > .q-field__control > .q-field__control-container',
+ '100-01',
+ );
+ cy.dataCy('FormModelPopup_save').click();
+ cy.checkNotification('Data created');
+ cy.url().should('match', /\/shelving\/\d+\/basic-data/);
+ });
+});
diff --git a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
index be9749c65..b4997fa69 100644
--- a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
+++ b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
@@ -1,5 +1,5 @@
///
-describe('Ticket Lack detail', () => {
+describe.skip('Ticket Lack detail', () => {
beforeEach(() => {
cy.login('developer');
cy.intercept('GET', /\/api\/Tickets\/itemLack\/5.*$/, {
@@ -37,11 +37,11 @@ describe('Ticket Lack detail', () => {
],
}).as('getItemLack');
- cy.visit('/#/ticket/negative/5');
+ cy.visit('/#/ticket/negative/5', false);
cy.wait('@getItemLack');
});
describe('Table actions', () => {
- it.skip('should display only one row in the lack list', () => {
+ it('should display only one row in the lack list', () => {
cy.location('href').should('contain', '#/ticket/negative/5');
cy.get('[data-cy="changeItem"]').should('be.disabled');
diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js
index 3fc2842d3..b5c95c463 100644
--- a/test/cypress/integration/ticket/ticketDescriptor.spec.js
+++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js
@@ -3,10 +3,10 @@ describe('Ticket descriptor', () => {
const listItem = '[role="menu"] .q-list .q-item';
const toCloneOpt = 'To clone ticket';
const setWeightOpt = 'Set weight';
- const warehouseValue = ':nth-child(1) > :nth-child(6) > .value > span';
+ const warehouseValue = ':nth-child(1) > [data-cy="vnLvWarehouse"]';
const summaryHeader = '.summaryHeader > div';
const weight = 25;
- const weightValue = '.summaryBody.row :nth-child(1) > :nth-child(9) > .value > span';
+ const weightValue = '[data-cy="vnLvWeight"]';
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
@@ -14,8 +14,6 @@ describe('Ticket descriptor', () => {
it('should clone the ticket without warehouse', () => {
cy.visit('/#/ticket/1/summary');
- cy.intercept('GET', /\/api\/Tickets\/\d/).as('ticket');
- cy.wait('@ticket');
cy.openActionsDescriptor();
cy.contains(listItem, toCloneOpt).click();
cy.clickConfirm();
diff --git a/test/cypress/integration/ticket/ticketExpedition.spec.js b/test/cypress/integration/ticket/ticketExpedition.spec.js
index 6d7dc6721..95ec330dc 100644
--- a/test/cypress/integration/ticket/ticketExpedition.spec.js
+++ b/test/cypress/integration/ticket/ticketExpedition.spec.js
@@ -10,10 +10,8 @@ describe('Ticket expedtion', () => {
it('should change the state', () => {
cy.visit('#/ticket/1/expedition');
- cy.intercept('GET', /\/api\/Expeditions\/filter/).as('show');
cy.intercept('POST', /\/api\/ExpeditionStates\/addExpeditionState/).as('add');
- cy.wait('@show');
cy.selectRows([1, 2]);
cy.dataCy('change-state').click();
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
index 8a459a6bf..5613a5854 100644
--- a/test/cypress/integration/ticket/ticketList.spec.js
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -5,7 +5,7 @@ describe('TicketList', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
- cy.visit('/#/ticket/list');
+ cy.visit('/#/ticket/list', false);
});
const searchResults = (search) => {
@@ -38,12 +38,13 @@ describe('TicketList', () => {
it('filter client and create ticket', () => {
cy.intercept('GET', /\/api\/Tickets\/filter/).as('ticketSearchbar');
searchResults();
+ cy.wait('@ticketSearchbar');
- cy.intercept('GET', /\/api\/Tickets\/filter/).as('ticketFilter');
cy.dataCy('Customer ID_input').clear('1');
cy.dataCy('Customer ID_input').type('1101{enter}');
cy.get('[data-cy="vnTableCreateBtn"] > .q-btn__content > .q-icon').click();
+ cy.waitSpinner();
cy.dataCy('Customer_select').should('have.value', 'Bruce Wayne');
cy.dataCy('Address_select').click();
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
index 61ba9fe4f..6d84f214c 100644
--- a/test/cypress/integration/ticket/ticketSale.spec.js
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -23,7 +23,7 @@ describe('TicketSale', () => {
cy.get('[data-col-field="price"]')
.find('.q-btn > .q-btn__content')
- .should('have.text', `€${price}`);
+ .should('contain.text', `€${price}`);
});
it('update discount', () => {
const discount = Math.floor(Math.random() * 100) + 1;
@@ -152,22 +152,6 @@ describe('TicketSale', () => {
cy.checkNotification('Future ticket date not allowed');
});
- 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();
diff --git a/test/cypress/integration/vnComponent/UserPanel.spec.js b/test/cypress/integration/vnComponent/UserPanel.spec.js
index 25724e873..8722fe37e 100644
--- a/test/cypress/integration/vnComponent/UserPanel.spec.js
+++ b/test/cypress/integration/vnComponent/UserPanel.spec.js
@@ -39,11 +39,11 @@ describe('UserPanel', () => {
cy.get(userCompany).should('have.value', 'Warehouse One').click();
//Actualizo la opción
- cy.getOption(2);
+ cy.getOption(3);
//Compruebo la notificación
cy.get('.q-notification').should('be.visible');
- cy.get(userCompany).should('have.value', 'Warehouse Two');
+ cy.get(userCompany).should('have.value', 'TestingWarehouse');
//Restauro el valor
cy.get(userCompany).click();
diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
deleted file mode 100644
index 053902f35..000000000
--- a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-describe('VnAccountNumber', () => {
- const accountInput = 'input[data-cy="supplierFiscalDataAccount_input"]';
- beforeEach(() => {
- cy.login('developer');
- cy.viewport(1920, 1080);
- cy.visit('/#/supplier/1/fiscal-data');
- });
-
- describe('VnInput handleInsertMode()', () => {
- it('should replace character at cursor position in insert mode', () => {
- cy.get(accountInput).type('{selectall}4100000001');
- cy.get(accountInput).type('{movetostart}');
- cy.get(accountInput).type('999');
- cy.get(accountInput).should('have.value', '9990000001');
- });
-
- it('should replace character at cursor position in insert mode', () => {
- cy.get(accountInput).clear();
- cy.get(accountInput).type('4100000001');
- cy.get(accountInput).type('{movetostart}');
- cy.get(accountInput).type('999');
- cy.get(accountInput).should('have.value', '9990000001');
- });
-
- it('should respect maxlength prop', () => {
- cy.get(accountInput).clear();
- cy.get(accountInput).type('123456789012345');
- cy.get(accountInput).should('have.value', '1234567890');
- });
- });
-
- it('should convert short account number to standard format', () => {
- cy.get(accountInput).clear();
- cy.get(accountInput).type('123.');
- cy.get(accountInput).should('have.value', '1230000000');
- });
-});
diff --git a/test/cypress/integration/vnComponent/VnLog.spec.js b/test/cypress/integration/vnComponent/VnLog.spec.js
index 80b9d07df..57faeac85 100644
--- a/test/cypress/integration/vnComponent/VnLog.spec.js
+++ b/test/cypress/integration/vnComponent/VnLog.spec.js
@@ -1,25 +1,28 @@
///
describe('VnLog', () => {
- const chips = [
- ':nth-child(1) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content',
- ':nth-child(2) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content',
- ];
beforeEach(() => {
cy.login('developer');
cy.visit(`/#/claim/${1}/log`);
- cy.openRightMenu();
});
it('should filter by insert actions', () => {
- cy.checkOption(':nth-child(7) > .q-checkbox');
- cy.get('.q-page').click();
- cy.validateContent(chips[0], 'Document');
- cy.validateContent(chips[1], 'Beginning');
+ cy.get('[data-cy="vnLog-checkbox"]').eq(0).click();
+ cy.get('[data-cy="vnLog-action-icon"]').each(($el) => {
+ cy.wrap($el).should('have.attr', 'title', 'Creates');
+ });
});
it('should filter by entity', () => {
- cy.selectOption('.q-drawer--right .q-item > .q-select', 'Claim');
- cy.get('.q-page').click();
- cy.validateContent(chips[0], 'Claim');
+ const entity = 'Document';
+ cy.selectOption('[data-cy="vnLog-entity"]', entity);
+ cy.get('[data-cy="vnLog-model-chip"]').each(($el) => {
+ cy.wrap($el).should('have.text', entity);
+ });
+ });
+
+ it('should show claimDescriptor', () => {
+ cy.dataCy('iconLaunch-claimFk').first().click();
+ cy.dataCy('vnDescriptor_subtitle').contains('1');
+ cy.dataCy('iconLaunch-claimFk').first().click();
});
});
diff --git a/test/cypress/integration/vnComponent/VnSearchBar.spec.js b/test/cypress/integration/vnComponent/VnSearchBar.spec.js
index 11d9bbe6a..8fed23643 100644
--- a/test/cypress/integration/vnComponent/VnSearchBar.spec.js
+++ b/test/cypress/integration/vnComponent/VnSearchBar.spec.js
@@ -27,7 +27,7 @@ describe('VnSearchBar', () => {
const searchAndCheck = (searchTerm, expectedText) => {
cy.clearSearchbar();
cy.typeSearchbar(`${searchTerm}{enter}`);
- cy.get(idGap).should('have.text', expectedText);
+ cy.get(idGap).should('include.text', expectedText);
};
const checkTableLength = (expectedLength) => {
diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
index e08c44635..cc5cacbe4 100644
--- a/test/cypress/integration/vnComponent/VnShortcut.spec.js
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -1,6 +1,6 @@
///
-
-describe('VnShortcuts', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('VnShortcuts', () => {
const modules = {
item: 'a',
customer: 'c',
@@ -27,12 +27,15 @@ describe('VnShortcuts', () => {
code: `Key${shortcut.toUpperCase()}`,
});
+ cy.waitSpinner();
cy.url().should('include', module);
if (['monitor', 'claim'].includes(module)) {
return;
}
cy.waitForElement('.q-page').should('exist');
cy.dataCy('vnTableCreateBtn').should('exist');
+ cy.waitSpinner();
+
cy.get('.q-page').trigger('keydown', {
ctrlKey: true,
altKey: true,
diff --git a/test/cypress/integration/wagon/wagonCreate.spec.js b/test/cypress/integration/wagon/wagonCreate.spec.js
index 4e78e57de..88855fdf9 100644
--- a/test/cypress/integration/wagon/wagonCreate.spec.js
+++ b/test/cypress/integration/wagon/wagonCreate.spec.js
@@ -16,8 +16,8 @@ describe('WagonCreate', () => {
cy.get(
'.grid-create > [label="Volume"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="Volume_input"]',
).type('100');
- cy.dataCy('Type_select').type('{downarrow}{enter}');
-
+ cy.selectOption('[data-cy="Type_select"]', '1');
+ cy.dataCy('FormModelPopup_save').click();
cy.get('[title="Remove"] > .q-btn__content > .q-icon').first().click();
});
});
diff --git a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
index 49d7d9f01..915927a6d 100644
--- a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
+++ b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
@@ -2,7 +2,7 @@ describe('WagonTypeCreate', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
- cy.visit('/#/wagon/type/create');
+ cy.visit('/#/wagon/type/list');
cy.waitForElement('.q-page', 6000);
});
diff --git a/test/cypress/integration/worker/workerBasicData.spec.js b/test/cypress/integration/worker/workerBasicData.spec.js
new file mode 100644
index 000000000..cf452a044
--- /dev/null
+++ b/test/cypress/integration/worker/workerBasicData.spec.js
@@ -0,0 +1,15 @@
+describe('WorkerBasicData', () => {
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('developer');
+ cy.visit('/#/worker/1107/basic-data');
+ });
+
+ it('should modify worker summary', () => {
+ cy.dataCy('MaritalStatus').type('Married');
+ cy.dataCy('fi').type('42572374H');
+ cy.dataCy('country').type('Alemania');
+ cy.saveCard();
+ cy.checkNotification('Data saved');
+ });
+});
diff --git a/test/cypress/integration/worker/workerBusiness.spec.js b/test/cypress/integration/worker/workerBusiness.spec.js
new file mode 100644
index 000000000..46da28cd6
--- /dev/null
+++ b/test/cypress/integration/worker/workerBusiness.spec.js
@@ -0,0 +1,34 @@
+describe.skip('WorkerBusiness', () => {
+ const saveBtn = '.q-mt-lg > .q-btn--standard';
+ const contributionCode = `Representantes de comercio`;
+ const contractType = `INDEFINIDO A TIEMPO COMPLETO`;
+
+ const Business = {
+ 'Start Date': { val: '26-12-2002', type: 'date' },
+ Company: { val: `VNL`, type: 'select' },
+ Department: { val: `RECICLAJE`, type: 'select' },
+ 'Professional Category': { val: `employee`, type: 'select' },
+ 'Work Calendar': { val: `General schedule`, type: 'select' },
+ 'Work Center': { val: `Silla`, type: 'select' },
+ 'Contract Category': { val: `INFORMATICA`, type: 'select' },
+ 'Contribution Code': { val: contributionCode, type: 'select' },
+ Rate: { val: `5` },
+ 'Contract Type': { val: contractType, type: 'select' },
+ 'Transport Workers Salary': { val: `1000` },
+ };
+
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('hr');
+ cy.visit('/#/worker/1107/business');
+ cy.addCard();
+ });
+
+ it('should create a business', () => {
+ cy.fillInForm({
+ ...Business,
+ });
+ cy.get(saveBtn).click();
+ cy.checkNotification('Data created');
+ });
+});
diff --git a/test/cypress/integration/worker/workerCreate.spec.js b/test/cypress/integration/worker/workerCreate.spec.js
index 6349f04a0..71fd6b347 100644
--- a/test/cypress/integration/worker/workerCreate.spec.js
+++ b/test/cypress/integration/worker/workerCreate.spec.js
@@ -1,4 +1,4 @@
-describe.skip('WorkerCreate', () => {
+describe('WorkerCreate', () => {
const externalRadio = '.q-radio:nth-child(2)';
const developerBossId = 120;
const payMethodCross =
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index 0a45441c1..d964c3dc8 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -1,4 +1,5 @@
-describe('WorkerList', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('WorkerList', () => {
const inputName = '.q-drawer .q-form input[aria-label="First Name"]';
const searchBtn = '.q-drawer button:nth-child(3)';
const descriptorTitle = '.descriptor .title span';
@@ -13,7 +14,7 @@ describe('WorkerList', () => {
cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker');
cy.get(searchBtn).click();
cy.wait('@worker').then(() =>
- cy.get(descriptorTitle).should('include.text', 'Jessica')
+ cy.get(descriptorTitle).should('include.text', 'Jessica'),
);
});
});
diff --git a/test/cypress/integration/worker/workerMutual.spec.js b/test/cypress/integration/worker/workerMutual.spec.js
new file mode 100644
index 000000000..a6d2c5f4f
--- /dev/null
+++ b/test/cypress/integration/worker/workerMutual.spec.js
@@ -0,0 +1,23 @@
+///
+describe('WorkerMutual', () => {
+ const userId = 1106;
+ const saveBtn = '.q-mt-lg > .q-btn--standard';
+ const medicalReview = {
+ Date: { val: '01-01-2001', type: 'date' },
+ 'Formation Center': { val: '1', type: 'select' },
+ Invoice: { val: '24532' },
+ Amount: { val: '540' },
+ };
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('developer');
+ cy.visit(`/#/worker/${userId}/medical`);
+ cy.addCard();
+ });
+
+ it('should create a medical Review', () => {
+ cy.fillInForm(medicalReview);
+ cy.get(saveBtn).click();
+ cy.checkNotification('Data created');
+ });
+});
diff --git a/test/cypress/integration/worker/workerNotes.spec.js b/test/cypress/integration/worker/workerNotes.spec.js
new file mode 100644
index 000000000..661314ac9
--- /dev/null
+++ b/test/cypress/integration/worker/workerNotes.spec.js
@@ -0,0 +1,13 @@
+///
+describe('WorkerNotes', () => {
+ const userId = 1106;
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('developer');
+ cy.visit(`/#/worker/${userId}/notes`);
+ });
+
+ it('Should load layout', () => {
+ cy.get('.q-card').should('be.visible');
+ });
+});
diff --git a/test/cypress/integration/worker/workerNotificationsManager.spec.js b/test/cypress/integration/worker/workerNotificationsManager.spec.js
index 0907cc4ad..ad48d8a6c 100644
--- a/test/cypress/integration/worker/workerNotificationsManager.spec.js
+++ b/test/cypress/integration/worker/workerNotificationsManager.spec.js
@@ -22,7 +22,7 @@ describe('WorkerNotificationsManager', () => {
);
});
- it.skip('should active a notification that is yours', () => {
+ it('should active a notification that is yours', () => {
cy.login('developer');
cy.visit(`/#/worker/${developerId}/notifications`);
cy.waitForElement(activeList);
diff --git a/test/cypress/integration/worker/workerOperator.spec.js b/test/cypress/integration/worker/workerOperator.spec.js
new file mode 100644
index 000000000..95839aeba
--- /dev/null
+++ b/test/cypress/integration/worker/workerOperator.spec.js
@@ -0,0 +1,19 @@
+///
+describe('WorkerOperator', () => {
+ const userId = 1106;
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('hr');
+ cy.visit(`/#/worker/${userId}/operator`);
+ });
+
+ it('should fill the operator form', () => {
+ cy.dataCy('numberOfWagons').type('4');
+ cy.dataCy('linesLimit').type('6');
+ cy.dataCy('volumeLimit').type('3');
+ cy.dataCy('sizeLimit').type('3');
+ cy.saveCard();
+
+ cy.checkNotification('Data saved');
+ });
+});
diff --git a/test/cypress/integration/worker/workerPda.spec.js b/test/cypress/integration/worker/workerPda.spec.js
index 31ec19eda..2623e81cf 100644
--- a/test/cypress/integration/worker/workerPda.spec.js
+++ b/test/cypress/integration/worker/workerPda.spec.js
@@ -1,23 +1,80 @@
describe('WorkerPda', () => {
- const select = '[data-cy="pda-dialog-select"]';
+ const deviceId = 4;
beforeEach(() => {
- cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/worker/1110/pda`);
});
- it('assign pda', () => {
- cy.addBtnClick();
- cy.get(select).click();
- cy.get(select).type('{downArrow}{enter}');
- cy.get('.q-notification__message').should('have.text', 'Data created');
+ it('assign and delete pda', () => {
+ creatNewPDA();
+ cy.checkNotification('Data created');
+ cy.visit(`/#/worker/1110/pda`);
+ removeNewPDA();
+ cy.checkNotification('PDA deallocated');
});
- it('delete pda', () => {
- cy.get('.btn-delete').click();
- cy.get(
- '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block'
- ).click();
- cy.get('.q-notification__message').should('have.text', 'PDA deallocated');
+ it('send and download pdf to docuware', () => {
+ //Send
+ cy.intercept('POST', '/api/Docuwares/upload-pda-pdf', (req) => {
+ req.reply({
+ statusCode: 200,
+ body: {},
+ });
+ });
+
+ creatNewPDA();
+
+ cy.dataCy('workerPda-send').click();
+ cy.clickConfirm();
+ cy.checkNotification('PDF sended to signed');
+
+ //Download
+ cy.intercept('POST', /\/api\/Docuwares\/Jones%20Jessica\/checkFile/, (req) => {
+ req.reply({
+ statusCode: 200,
+ body: {
+ id: deviceId,
+ state: 'Firmado',
+ },
+ });
+ });
+ cy.get('#st-actions').contains('refresh').click();
+ cy.intercept('GET', '/api/Docuwares/download-pda-pdf**', (req) => {
+ req.reply({
+ statusCode: 200,
+ body: {},
+ });
+ });
+
+ cy.dataCy('workerPda-download').click();
+ removeNewPDA();
});
+
+ it('send 2 pdfs to docuware', () => {
+ cy.intercept('POST', '/api/Docuwares/upload-pda-pdf', (req) => {
+ req.reply({
+ statusCode: 200,
+ body: {},
+ });
+ });
+
+ creatNewPDA();
+ creatNewPDA(2);
+ cy.selectRows([1, 2]);
+ cy.get('#st-actions').contains('Send').click();
+ cy.checkNotification('PDF sended to signed');
+
+ removeNewPDA();
+ });
+
+ function creatNewPDA(id = deviceId) {
+ cy.addBtnClick();
+ cy.selectOption('[data-cy="pda-dialog-select"]', id);
+ cy.saveCard();
+ }
+
+ function removeNewPDA() {
+ cy.dataCy('workerPda-remove').first().click();
+ cy.clickConfirm();
+ }
});
diff --git a/test/cypress/integration/worker/workerPit.spec.js b/test/cypress/integration/worker/workerPit.spec.js
index 19cbebc20..04f232648 100644
--- a/test/cypress/integration/worker/workerPit.spec.js
+++ b/test/cypress/integration/worker/workerPit.spec.js
@@ -1,19 +1,5 @@
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"]';
- const Descendant = 'Descendiente';
- 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';
@@ -24,15 +10,15 @@ describe('WorkerPit', () => {
});
it('complete PIT', () => {
- cy.get(familySituationInput).type(familySituation);
- cy.get(childPensionInput).type(childPension);
- cy.get(spouseNifInput).type(spouseNif);
- cy.get(spousePensionInput).type(spousePension);
+ cy.dataCy('familySituation').type('1');
+ cy.dataCy('childPension').type('120');
+ cy.dataCy('spouseNif').type('65117125P');
+ cy.dataCy('spousePension').type('120');
cy.get(savePIT).click();
cy.get(addRelative).click();
- cy.get(isDescendantSelect).type(Descendant);
- cy.get(birthedInput).type(birthed);
- cy.get(adoptionYearInput).type(adoptionYear);
+ cy.dataCy('Descendant/Ascendant').type('Descendiente');
+ cy.dataCy('birthed').type('2002');
+ cy.dataCy('adoptionYear').type('2004');
cy.get(saveRelative).click();
});
});
diff --git a/test/cypress/integration/worker/workerSummary.spec.js b/test/cypress/integration/worker/workerSummary.spec.js
index 3d70fdf96..6071c4cdf 100644
--- a/test/cypress/integration/worker/workerSummary.spec.js
+++ b/test/cypress/integration/worker/workerSummary.spec.js
@@ -1,16 +1,26 @@
describe('WorkerSummary', () => {
+ const department = ':nth-child(1) > [data-cy="vnLvDepartment"] > .value';
+ const role = '[data-cy="vnLvRole"] > .value';
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('developer');
cy.visit('/#/worker/19/summary');
});
- it('should load worker summary', () => {
+ it('should load worker summary and show the department', () => {
cy.waitForElement('.summaryHeader');
cy.get('.summaryHeader > div').should('have.text', '19 - salesboss salesboss');
- cy.get(':nth-child(1) > :nth-child(2) > .value > span').should(
- 'have.text',
- 'salesBossNick'
- );
+ cy.get(department).should('have.text', 'VENTAS');
+ });
+
+ it('should try descriptors', () => {
+ cy.waitForElement('.summaryHeader');
+ cy.get(department).click();
+ cy.get('.descriptor').should('be.visible');
+ cy.get('.q-item > .q-item__label').should('include.text', '43');
+ cy.get('.summaryBody').click();
+ cy.get(role).click();
+ cy.get('.descriptor').should('be.visible');
+ cy.get('.q-item > .q-item__label').should('include.text', '19');
});
});
diff --git a/test/cypress/integration/zone/zoneBasicData.spec.js b/test/cypress/integration/zone/zoneBasicData.spec.js
index 6db39b072..2d255d959 100644
--- a/test/cypress/integration/zone/zoneBasicData.spec.js
+++ b/test/cypress/integration/zone/zoneBasicData.spec.js
@@ -1,5 +1,5 @@
describe('ZoneBasicData', () => {
- const priceBasicData = '[data-cy="Price_input"]';
+ const priceBasicData = '[data-cy="ZoneBasicDataPrice"]';
const saveBtn = '.q-btn-group > .q-btn--standard';
beforeEach(() => {
@@ -8,20 +8,13 @@ describe('ZoneBasicData', () => {
cy.visit('/#/zone/4/basic-data');
});
- it('should throw an error if the name is empty', () => {
- cy.get('[data-cy="zone-basic-data-name"] input').type('{selectall}{backspace}');
-
- cy.get(saveBtn).click();
- cy.checkNotification("can't be blank");
- });
-
it('should throw an error if the price is empty', () => {
cy.get(priceBasicData).clear();
cy.get(saveBtn).click();
- cy.checkNotification('cannot be blank');
+ cy.get('.q-field__messages > div').should('have.text', 'Field required');
});
- it("should edit the basicData's zone", () => {
+ it("should edit the basicData's zone name", () => {
cy.get('.q-card > :nth-child(1)').type(' modified');
cy.get(saveBtn).click();
cy.checkNotification('Data saved');
diff --git a/test/cypress/integration/zone/zoneCalendar.spec.js b/test/cypress/integration/zone/zoneCalendar.spec.js
new file mode 100644
index 000000000..68b85d1d2
--- /dev/null
+++ b/test/cypress/integration/zone/zoneCalendar.spec.js
@@ -0,0 +1,50 @@
+describe('ZoneCalendar', () => {
+ const addEventBtn = '.q-page-sticky > div > .q-btn';
+ const submitBtn = '.q-mt-lg > .q-btn--standard';
+ const deleteBtn = 'ZoneEventsPanelDeleteBtn';
+
+ beforeEach(() => {
+ cy.login('developer');
+ cy.visit(`/#/zone/13/events`);
+ });
+
+ it('should include a one day event, then delete it', () => {
+ cy.get(addEventBtn).click();
+ cy.dataCy('ZoneEventInclusionDayRadio').click();
+ cy.get('.q-card > :nth-child(5)').type('01/01/2001');
+ cy.get(submitBtn).click();
+ cy.dataCy(deleteBtn).click();
+ cy.dataCy('VnConfirm_confirm').click();
+ });
+
+ it('should include an indefinitely event for monday and tuesday', () => {
+ cy.get(addEventBtn).click();
+ cy.get('.flex > .q-gutter-x-sm > :nth-child(1)').click();
+ cy.get('.flex > .q-gutter-x-sm > :nth-child(2)').click();
+ cy.get(submitBtn).click();
+ cy.dataCy(deleteBtn).click();
+ cy.dataCy('VnConfirm_confirm').click();
+ });
+
+ it('should include a range of dates event', () => {
+ cy.get(addEventBtn).click();
+ cy.dataCy('ZoneEventInclusionRangeRadio').click();
+ cy.get('.flex > .q-gutter-x-sm > :nth-child(1)').click();
+ cy.dataCy('From_inputDate').type('01/01/2001');
+ cy.dataCy('To_inputDate').type('31/01/2001');
+ cy.get(submitBtn).click();
+ cy.dataCy(deleteBtn).click();
+ cy.dataCy('VnConfirm_confirm').click();
+ });
+
+ it('should exclude an event', () => {
+ cy.get('.q-mb-sm > .q-radio__inner').click();
+ cy.get('.q-current-day > .q-calendar-month__day--label__wrapper').click();
+ cy.get('.q-mt-lg > .q-btn--standard').click();
+ cy.get(
+ '.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]',
+ ).click();
+ cy.dataCy('ZoneEventExclusionDeleteBtn').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ });
+});
diff --git a/test/cypress/integration/zone/zoneCreate.spec.js b/test/cypress/integration/zone/zoneCreate.spec.js
index 0f630db5d..fadf5b07f 100644
--- a/test/cypress/integration/zone/zoneCreate.spec.js
+++ b/test/cypress/integration/zone/zoneCreate.spec.js
@@ -9,7 +9,6 @@ describe('ZoneCreate', () => {
};
beforeEach(() => {
- cy.viewport(1280, 720);
cy.login('developer');
cy.visit('/#/zone/list');
cy.get('.q-page-sticky > div > .q-btn').click();
diff --git a/test/cypress/integration/zone/zoneDeliveryDays.spec.js b/test/cypress/integration/zone/zoneDeliveryDays.spec.js
index 1e1fc8ff5..a89def12d 100644
--- a/test/cypress/integration/zone/zoneDeliveryDays.spec.js
+++ b/test/cypress/integration/zone/zoneDeliveryDays.spec.js
@@ -1,15 +1,59 @@
describe('ZoneDeliveryDays', () => {
+ const postcode = '46680';
+ const agency = 'Gotham247Expensive';
+ const submitForm = '.q-form > .q-btn > .q-btn__content';
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit(`/#/zone/delivery-days`);
});
- it('should query for the day', () => {
+ it('should return no data when querying without params', () => {
cy.get('.q-form > .q-btn > .q-btn__content').click();
cy.get('.q-notification__message').should(
'have.text',
- 'No service for the specified zone'
+ 'No service for the specified zone',
);
});
+
+ it('should query for delivery', () => {
+ cy.intercept('GET', /\/api\/Zones\/getEvents/, (req) => {
+ req.headers['cache-control'] = 'no-cache';
+ req.headers['pragma'] = 'no-cache';
+ req.headers['expires'] = '0';
+ req.on('response', (res) => {
+ delete res.headers['if-none-match'];
+ delete res.headers['if-modified-since'];
+ });
+ }).as('events');
+
+ cy.dataCy('ZoneDeliveryDaysPostcodeSelect').type(postcode);
+ cy.get('.q-menu .q-item').contains(postcode).click();
+ cy.get('.q-menu').then(($menu) => {
+ if ($menu.is(':visible')) {
+ cy.get('[data-cy="ZoneDeliveryDaysPostcodeSelect"]')
+ .as('focusedElement')
+ .focus();
+ cy.get('@focusedElement').blur();
+ }
+ });
+
+ cy.dataCy('ZoneDeliveryDaysAgencySelect').type(agency);
+ cy.get('.q-menu .q-item').contains(agency).click();
+ cy.get('.q-menu').then(($menu) => {
+ if ($menu.is(':visible')) {
+ cy.get('[data-cy="ZoneDeliveryDaysAgencySelect"]')
+ .as('focusedElement')
+ .focus();
+ cy.get('@focusedElement').blur();
+ }
+ });
+
+ cy.get(submitForm).click();
+ cy.wait('@events').then((interception) => {
+ cy.log('interception: ', interception);
+ const data = interception.response.body.events;
+ expect(data.length).to.be.greaterThan(0);
+ });
+ });
});
diff --git a/test/cypress/integration/zone/zoneList.spec.js b/test/cypress/integration/zone/zoneList.spec.js
index 68e924635..c84b1b017 100644
--- a/test/cypress/integration/zone/zoneList.spec.js
+++ b/test/cypress/integration/zone/zoneList.spec.js
@@ -1,21 +1,25 @@
describe('ZoneList', () => {
const agency = 'inhouse pickup';
+ const firstSummaryIcon =
+ ':nth-child(1) > .q-table--col-auto-width > [data-cy="tableAction-0"]';
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('developer');
cy.visit('/#/zone/list');
- });
-
- it('should filter by agency', () => {
- cy.dataCy('zoneFilterPanelNameInput').type('{downArrow}{enter}');
+ cy.typeSearchbar('{enter}');
});
it('should open the zone summary', () => {
- cy.dataCy('zoneFilterPanelAgencySelect').type(agency);
- cy.get('.q-menu .q-item').contains(agency).click();
- cy.get(':nth-child(1) > [data-col-field="agencyModeFk"]').should(
- 'include.text',
- agency,
- );
+ cy.get(firstSummaryIcon).click();
+ cy.get('.header > .q-icon').click();
+ cy.url().should('include', 'zone/1/summary');
+ });
+
+ it('should clone the zone', () => {
+ cy.get('.router-link-active > .q-icon').click();
+ cy.dataCy('tableAction-1').eq(1).click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.url().should('not.include', 'zone/2/');
+ cy.url().should('match', /zone\/\d+\/basic-data/);
});
});
diff --git a/test/cypress/integration/zone/zoneLocations.spec.js b/test/cypress/integration/zone/zoneLocations.spec.js
new file mode 100644
index 000000000..dabd3eb2b
--- /dev/null
+++ b/test/cypress/integration/zone/zoneLocations.spec.js
@@ -0,0 +1,59 @@
+describe('ZoneLocations', () => {
+ const cp = 46680;
+ const searchIcon = '.router-link-active > .q-icon';
+ beforeEach(() => {
+ cy.login('developer');
+ cy.visit(`/#/zone/2/location`);
+ });
+
+ it('should be able to search by postal code', () => {
+ cy.get('.q-tree > :nth-child(1) > :nth-child(2) > :nth-child(1)')
+ .should('exist')
+ .should('be.visible');
+
+ cy.intercept('GET', '**/api/Zones/2/getLeaves*', (req) => {
+ req.headers['cache-control'] = 'no-cache';
+ req.headers['pragma'] = 'no-cache';
+ req.headers['expires'] = '0';
+
+ req.on('response', (res) => {
+ delete res.headers['if-none-match'];
+ delete res.headers['if-modified-since'];
+ });
+ }).as('location');
+ cy.get('#searchbarForm').type(cp);
+ cy.get(searchIcon).click();
+ cy.wait('@location').then((interception) => {
+ const data = interception.response.body;
+ expect(data).to.include(cp);
+ });
+ });
+
+ it('should check, uncheck, and set a location to mixed state', () => {
+ cy.get('#searchbarForm').type(cp);
+ cy.get(searchIcon).click();
+
+ cy.get('.q-tree > :nth-child(1) > :nth-child(2) > :nth-child(1)')
+ .as('tree')
+ .within(() => {
+ cy.get('[data-cy="ZoneLocationTreeCheckbox"] > .q-checkbox__inner')
+ .last()
+ .as('lastCheckbox');
+
+ const verifyCheckboxState = (state) => {
+ cy.get('@lastCheckbox')
+ .parents('.q-checkbox')
+ .should('have.attr', 'aria-checked', state);
+ };
+
+ cy.get('@lastCheckbox').click();
+ verifyCheckboxState('true');
+
+ cy.get('@lastCheckbox').click();
+ verifyCheckboxState('false');
+
+ cy.get('@lastCheckbox').click();
+ verifyCheckboxState('mixed');
+ });
+ });
+});
diff --git a/test/cypress/integration/zone/zoneSummary.spec.js b/test/cypress/integration/zone/zoneSummary.spec.js
new file mode 100644
index 000000000..fa9c5353c
--- /dev/null
+++ b/test/cypress/integration/zone/zoneSummary.spec.js
@@ -0,0 +1,22 @@
+describe('ZoneSummary', () => {
+ const agency = 'inhouse pickup';
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('developer');
+ cy.visit('/#/zone/2/summary');
+ });
+
+ it('should clone the zone, then delete it', () => {
+ cy.dataCy('descriptor-more-opts').click();
+ cy.dataCy('Clone_button').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ cy.url().should('not.include', 'zone/2/');
+ cy.url().should('match', /zone\/\d+\/basic-data/);
+ cy.get('.list-box > :nth-child(1)').should('include.text', agency);
+ cy.get('.title > span').should('include.text', 'Zone pickup B');
+ cy.get('.q-page').should('exist');
+ cy.dataCy('descriptor-more-opts').click();
+ cy.dataCy('Delete_button').click();
+ cy.dataCy('VnConfirm_confirm').click();
+ });
+});
diff --git a/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js b/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js
index 28e2222d4..576b2ea70 100644
--- a/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js
+++ b/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js
@@ -1,9 +1,17 @@
describe('ZoneUpcomingDeliveries', () => {
+ const tableFields = (opt) =>
+ `:nth-child(1) > .q-table__container > .q-table__middle > .q-table > thead > tr > :nth-child(${opt})`;
+
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit(`/#/zone/upcoming-deliveries`);
});
- it('should show the page', () => {});
+ it('should show the page', () => {
+ cy.get('.q-card').should('be.visible');
+ cy.get(tableFields(1)).should('be.visible').should('have.text', 'Province');
+ cy.get(tableFields(2)).should('be.visible').should('have.text', 'Closing');
+ cy.get(tableFields(3)).should('be.visible').should('have.text', 'Id');
+ });
});
diff --git a/test/cypress/integration/zone/zoneWarehouse.spec.js b/test/cypress/integration/zone/zoneWarehouse.spec.js
index 0f646f33a..d7a9854bb 100644
--- a/test/cypress/integration/zone/zoneWarehouse.spec.js
+++ b/test/cypress/integration/zone/zoneWarehouse.spec.js
@@ -1,32 +1,29 @@
describe('ZoneWarehouse', () => {
const data = {
- Warehouse: { val: 'Warehouse One', type: 'select' },
+ Warehouse: { val: 'Warehouse Two', type: 'select' },
};
-
const dataError = 'The introduced warehouse already exists';
const saveBtn = '.q-btn--standard > .q-btn__content > .block';
beforeEach(() => {
cy.viewport(1280, 720);
cy.login('developer');
- cy.visit(`/#/zone/2/warehouses`);
+ cy.visit(`/#/zone/1/warehouses`);
});
it('should throw an error if the warehouse chosen is already put in the zone', () => {
cy.addBtnClick();
- cy.dataCy('Warehouse_select').type('Warehouse Two{enter}');
+ cy.dataCy('Warehouse_select').type('Warehouse One{enter}');
cy.get(saveBtn).click();
cy.checkNotification(dataError);
});
- it('should create & remove a warehouse', () => {
+ it.skip('should create & remove a warehouse', () => {
cy.addBtnClick();
cy.fillInForm(data);
cy.get(saveBtn).click();
cy.get('.q-mt-lg > .q-btn--standard').click();
cy.get('tbody > :nth-child(2) > :nth-child(2) > .q-icon').click();
cy.get('[title="Confirm"]').click();
-
- cy.reload();
});
});
diff --git a/test/cypress/run.sh b/test/cypress/run.sh
new file mode 100755
index 000000000..0f8c59902
--- /dev/null
+++ b/test/cypress/run.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+salix_dir="${1:-$HOME/Projects/salix}"
+salix_dir=$(eval echo "$salix_dir")
+
+echo "$salix_dir"
+
+current_dir=$(pwd)
+
+cleanup() {
+ docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml down -v
+}
+
+trap cleanup SIGINT
+
+# CLEAN
+rm -rf test/cypress/screenshots
+rm -f test/cypress/results/*
+rm -f test/cypress/reports/*
+rm -f junit/e2e-*.xml
+
+# RUN
+export CI=true
+export TZ=Europe/Madrid
+
+# IMAGES
+docker build -t registry.verdnatura.es/salix-back:dev -f "$salix_dir/back/Dockerfile" "$salix_dir"
+cd "$salix_dir" && npx myt run -t
+docker exec vn-database sh -c "rm -rf /mysql-template"
+docker exec vn-database sh -c "cp -a /var/lib/mysql /mysql-template"
+docker commit vn-database registry.verdnatura.es/salix-db:dev
+docker rm -f vn-database
+cd "$current_dir"
+docker build -f ./docs/Dockerfile.dev -t lilium-dev .
+# END IMAGES
+
+docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml up -d
+
+docker run -it --rm \
+ -v "$(pwd)":/app \
+ --network e2e_default \
+ -e CI \
+ -e TZ \
+ lilium-dev \
+ bash -c 'sh test/cypress/cypressParallel.sh 2'
+
+cleanup
diff --git a/test/cypress/summary.sh b/test/cypress/summary.sh
new file mode 100644
index 000000000..4bca3255d
--- /dev/null
+++ b/test/cypress/summary.sh
@@ -0,0 +1,3 @@
+pnpm exec junit-merge --dir junit --out junit/junit-final.xml
+pnpm exec xunit-viewer -r junit/junit-final.xml -o junit/report.html
+xdg-open junit/report.html
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index c2dd1579f..7f5203547 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -27,7 +27,9 @@
// DO NOT REMOVE
// Imports Quasar Cypress AE predefined commands
// import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress';
+import moment from 'moment';
import waitUntil from './waitUntil';
+
Cypress.Commands.add('waitUntil', { prevSubject: 'optional' }, waitUntil);
Cypress.Commands.add('resetDB', () => {
@@ -57,14 +59,15 @@ Cypress.Commands.add('login', (user = 'developer') => {
});
});
-Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
+Cypress.Commands.overwrite('visit', (originalFn, url, options, waitRequest = true) => {
originalFn(url, options);
cy.waitUntil(() => cy.document().then((doc) => doc.readyState === 'complete'));
cy.waitUntil(() => cy.get('main').should('exist'));
+ if (waitRequest) cy.waitSpinner();
});
-Cypress.Commands.add('waitForElement', (element, timeout = 10000) => {
- cy.get(element, { timeout }).should('be.visible').and('not.be.disabled');
+Cypress.Commands.add('waitForElement', (element) => {
+ cy.get(element).should('be.visible').and('not.be.disabled');
});
Cypress.Commands.add('getValue', (selector) => {
@@ -120,9 +123,10 @@ function selectItem(selector, option, ariaControl, hasWrite = true) {
cy.waitSpinner();
getItems(ariaControl).then((items) => {
- const matchingItem = items
- .toArray()
- .find((item) => item.innerText.includes(option));
+ const matchingItem = items.toArray().find((item) => {
+ const val = typeof option == 'string' ? option.toLowerCase() : option;
+ return item.innerText.toLowerCase().includes(val);
+ });
if (matchingItem) return cy.wrap(matchingItem).click();
if (hasWrite) cy.get(selector).clear().type(option);
@@ -158,14 +162,20 @@ Cypress.Commands.add('countSelectOptions', (selector, option) => {
cy.get('.q-menu .q-item').should('have.length', option);
});
-Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
+Cypress.Commands.add('fillInForm', (obj, opts = {}) => {
+ cy.waitSpinner();
+ const { form = '.q-form > .q-card', attr = 'aria-label' } = opts;
cy.waitForElement(form);
cy.get(`${form} input`).each(([el]) => {
cy.wrap(el)
- .invoke('attr', 'aria-label')
- .then((ariaLabel) => {
- const field = obj[ariaLabel];
+ .invoke('attr', attr)
+ .then((key) => {
+ const field = obj[key];
if (!field) return;
+ if (typeof field == 'string')
+ return cy
+ .wrap(el)
+ .type(`{selectall}{backspace}${field}`, { delay: 0 });
const { type, val } = field;
switch (type) {
@@ -173,7 +183,9 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
cy.selectOption(el, val);
break;
case 'date':
- cy.get(el).type(val.split('-').join(''));
+ cy.get(el).type(
+ `{selectall}{backspace}${val.split('-').join('')}`,
+ );
break;
case 'time':
cy.get(el).click();
@@ -182,13 +194,47 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
cy.get('.q-time .q-time__link').contains(val.x).click();
break;
default:
- cy.wrap(el).type(val);
+ cy.wrap(el).type(`{selectall}${val}`, { delay: 0 });
break;
}
});
});
});
+Cypress.Commands.add('validateForm', (obj, opts = {}) => {
+ const { form = '.q-form > .q-card', attr = 'data-cy' } = opts;
+ cy.waitForElement(form);
+ cy.get(`${form} input`).each(([el]) => {
+ cy.wrap(el)
+ .invoke('attr', attr)
+ .then((key) => {
+ const field = obj[key];
+ if (!field) return;
+
+ const { type, val } = field;
+ cy.get(el)
+ .invoke('val')
+ .then((elVal) => {
+ if (typeof field == 'string')
+ expect(elVal.toLowerCase()).to.equal(field.toLowerCase());
+ else
+ switch (type) {
+ case 'date':
+ const elDate = moment(elVal, 'DD-MM-YYYY');
+ const mockDate = moment(val, 'DD-MM-YYYY');
+ expect(elDate.isSame(mockDate, 'day')).to.be.true;
+ break;
+ default:
+ expect(elVal.toLowerCase()).to.equal(
+ val.toLowerCase(),
+ );
+ break;
+ }
+ });
+ });
+ });
+});
+
Cypress.Commands.add('checkOption', (selector) => {
cy.get(selector).find('.q-checkbox__inner').click();
});
@@ -205,14 +251,17 @@ Cypress.Commands.add('saveCard', () => {
Cypress.Commands.add('resetCard', () => {
cy.get('[title="Reset"]').click();
});
+
Cypress.Commands.add('removeCard', () => {
cy.get('[title="Remove"]').click();
});
+
Cypress.Commands.add('addCard', () => {
cy.waitForElement('tbody');
cy.waitForElement('.q-page-sticky > div > .q-btn');
cy.get('.q-page-sticky > div > .q-btn').click();
});
+
Cypress.Commands.add('clickConfirm', () => {
cy.waitForElement('.q-dialog__inner > .q-card');
cy.get('.q-card__actions > .q-btn--unelevated > .q-btn__content > .block').click();
@@ -293,6 +342,7 @@ Cypress.Commands.add('removeRow', (rowIndex) => {
});
});
});
+
Cypress.Commands.add('openListSummary', (row) => {
cy.get('.card-list-body .actions .q-btn:nth-child(2)').eq(row).click();
});
@@ -320,6 +370,15 @@ Cypress.Commands.add('validateContent', (selector, expectedValue) => {
cy.get(selector).should('have.text', expectedValue);
});
+Cypress.Commands.add('containContent', (selector, expectedValue) => {
+ cy.get(selector)
+ .should('be.visible')
+ .invoke('text')
+ .then((text) => {
+ expect(text).to.include(expectedValue);
+ });
+});
+
Cypress.Commands.add('openActionDescriptor', (opt) => {
cy.openActionsDescriptor();
const listItem = '[role="menu"] .q-list .q-item';
@@ -327,13 +386,7 @@ Cypress.Commands.add('openActionDescriptor', (opt) => {
});
Cypress.Commands.add('openActionsDescriptor', () => {
- cy.get('[data-cy="descriptor-more-opts"]').click();
-});
-
-Cypress.Commands.add('clickButtonDescriptor', (id) => {
- cy.get(`.actions > .q-card__actions> .q-btn:nth-child(${id})`)
- .invoke('removeAttr', 'target')
- .click();
+ cy.get('[data-cy="vnDescriptor"] [data-cy="descriptor-more-opts"]').click();
});
Cypress.Commands.add('openUserPanel', () => {
@@ -341,7 +394,7 @@ Cypress.Commands.add('openUserPanel', () => {
});
Cypress.Commands.add('checkNotification', (text) => {
- cy.get('.q-notification', { timeout: 10000 })
+ cy.get('.q-notification')
.should('be.visible')
.should('have.length.greaterThan', 0)
.should(($elements) => {
@@ -351,7 +404,6 @@ Cypress.Commands.add('checkNotification', (text) => {
expect(found).to.be.true;
});
});
-
Cypress.Commands.add('openActions', (row) => {
cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click();
});
@@ -394,6 +446,7 @@ Cypress.Commands.add('clickButtonWith', (type, value) => {
break;
}
});
+
Cypress.Commands.add('clickButtonWithIcon', (iconClass) => {
cy.waitForElement('[data-cy="descriptor_actions"]');
cy.get('[data-cy="loading-spinner"]', { timeout: 10000 }).should('not.be.visible');
@@ -422,3 +475,137 @@ Cypress.Commands.add('searchBtnFilterPanel', () => {
Cypress.Commands.add('waitRequest', (alias, cb) => {
cy.wait(alias).then(cb);
});
+
+Cypress.Commands.add('validateDescriptor', (toCheck = {}) => {
+ const { title, description, subtitle, listbox = {}, popup = false } = toCheck;
+
+ const popupSelector = popup ? '[role="menu"] ' : '';
+
+ if (title) cy.get(`${popupSelector}[data-cy="vnDescriptor_title"]`).contains(title);
+ if (description)
+ cy.get(`${popupSelector}[data-cy="vnDescriptor_description"]`).contains(
+ description,
+ );
+ if (subtitle)
+ cy.get(`${popupSelector}[data-cy="vnDescriptor_subtitle"]`).contains(subtitle);
+
+ for (const index in listbox)
+ cy.get(`${popupSelector}[data-cy="vnDescriptor_listbox"] > *`)
+ .eq(index)
+ .should('contain.text', listbox[index]);
+});
+
+Cypress.Commands.add('validateVnTableRows', (opts = {}) => {
+ let { cols = [], rows = [] } = opts;
+ if (!Array.isArray(cols)) cols = [cols];
+ const rowSelector = rows.length
+ ? rows.map((row) => `> :nth-child(${row})`).join(', ')
+ : '> *';
+ cy.get(`[data-cy="vnTable"] .q-virtual-scroll__content`).within(() => {
+ cy.get(`${rowSelector}`).each(($el) => {
+ for (const { name, type = 'string', val, operation = 'equal' } of cols) {
+ cy.wrap($el)
+ .find(`[data-cy="vnTableCell_${name}"]`)
+ .invoke('text')
+ .then((text) => {
+ if (type === 'string')
+ expect(text.trim().toLowerCase()).to[operation](
+ val.toLowerCase(),
+ );
+ if (type === 'number') cy.checkNumber(text, val, operation);
+ if (type === 'date') cy.checkDate(text, val, operation);
+ });
+ }
+ });
+ });
+});
+
+Cypress.Commands.add('checkDate', (rawDate, expectedVal, operation) => {
+ const date = moment(rawDate.trim(), 'MM/DD/YYYY');
+ const compareDate = moment(expectedVal, 'DD/MM/YYYY');
+
+ switch (operation) {
+ case 'equal':
+ expect(text.trim()).to.equal(compareDate);
+ break;
+ case 'before':
+ expect(date.isBefore(compareDate)).to.be.true;
+ break;
+ case 'after':
+ expect(date.isAfter(compareDate)).to.be.true;
+ }
+});
+
+Cypress.Commands.add('selectDescriptorOption', (opt = 1) => {
+ const listItem = '[data-cy="descriptor-more-opts_list"]';
+ cy.get('body').then(($body) => {
+ if (!$body.find(listItem).length) cy.openActionsDescriptor();
+ });
+
+ cy.waitForElement(listItem);
+ cy.get(`${listItem} > :not(template):nth-of-type(${opt})`).click();
+});
+
+Cypress.Commands.add('validateCheckbox', (selector, expectedVal = 'true') => {
+ cy.get(selector).should('have.attr', 'aria-checked', expectedVal.toString());
+});
+
+Cypress.Commands.add('validateDownload', (trigger, opts = {}) => {
+ const {
+ url = /api\/dms\/\d+\/downloadFile\?access_token=.+/,
+ types = ['text/plain', 'image/jpeg'],
+ alias = 'download',
+ } = opts;
+ cy.intercept('GET', url).as(alias);
+ trigger().then(() => {
+ cy.wait(`@${alias}`).then(({ response }) => {
+ expect(response.statusCode).to.equal(200);
+ const isValidType = types.some((type) =>
+ response.headers['content-type'].includes(type),
+ );
+ expect(isValidType).to.be.true;
+ });
+ });
+});
+
+Cypress.Commands.add('validatePdfDownload', (match, trigger) => {
+ cy.window().then((win) => {
+ cy.stub(win, 'open')
+ .callsFake(() => null)
+ .as('pdf');
+ });
+ trigger();
+ cy.get('@pdf')
+ .should('be.calledOnce')
+ .then((stub) => {
+ const [url] = stub.getCall(0).args;
+ expect(url).to.match(match);
+ cy.request(url).then((response) =>
+ expect(response.headers['content-type']).to.include('application/pdf'),
+ );
+ });
+});
+
+Cypress.Commands.add('clicDescriptorAction', (index = 1) => {
+ cy.get(`[data-cy="descriptor_actions"] .q-btn:nth-of-type(${index})`).click();
+});
+
+Cypress.Commands.add('checkQueryParams', (expectedParams = {}) => {
+ cy.url().then((url) => {
+ const urlParams = new URLSearchParams(url.split('?')[1]);
+
+ for (const key in expectedParams) {
+ const expected = expectedParams[key];
+ const param = JSON.parse(decodeURIComponent(urlParams.get(key)));
+
+ if (typeof expected === 'object') {
+ const { subkey, val } = expected;
+ expect(param[subkey]).to.equal(val);
+ } else expect(param).to.equal(expected);
+ }
+ });
+});
+
+Cypress.Commands.add('waitTableScrollLoad', () =>
+ cy.waitForElement('[data-q-vs-anchor]'),
+);
diff --git a/test/cypress/support/index.js b/test/cypress/support/index.js
index 075e0c8eb..b0f0fb3b1 100644
--- a/test/cypress/support/index.js
+++ b/test/cypress/support/index.js
@@ -40,4 +40,35 @@ style.innerHTML = `
`;
document.head.appendChild(style);
+// FIXME: https://redmine.verdnatura.es/issues/8771
+Cypress.on('uncaught:exception', (err) => {
+ if (err.code === 'ERR_CANCELED') return false;
+});
+
+const waitForApiReady = (url, maxRetries = 20, delay = 1000) => {
+ let retries = 0;
+
+ function checkApi() {
+ return cy
+ .request({
+ url,
+ failOnStatusCode: false,
+ })
+ .then((response) => {
+ if (response.status !== 200 && retries < maxRetries) {
+ retries++;
+ cy.wait(delay);
+ return checkApi();
+ }
+ expect(response.status).to.eq(200);
+ });
+ }
+
+ return checkApi();
+};
+
+before(() => {
+ waitForApiReady('/api/Applications/status');
+});
+
export { randomString, randomNumber, randomizeValue };