diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue
index 4c045968f..4068498cd 100644
--- a/src/components/ui/VnLinkPhone.vue
+++ b/src/components/ui/VnLinkPhone.vue
@@ -1,6 +1,7 @@
diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index f3f6d64f1..3649ba8f5 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -133,7 +133,7 @@ const addFilter = async (filter, params) => {
async function fetch(params) {
useArrayData(props.dataKey, params);
arrayData.reset(['filter.skip', 'skip', 'page']);
- await arrayData.fetch({ append: false });
+ await arrayData.fetch({ append: false, updateRouter: mounted.value });
return emitStoreData();
}
diff --git a/src/filters/index.js b/src/filters/index.js
index ce5c44706..1f7ac77dd 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -12,10 +12,12 @@ import dateRange from './dateRange';
import toHour from './toHour';
import dashOrCurrency from './dashOrCurrency';
import getParamWhere from './getParamWhere';
+import parsePhone from './parsePhone';
import isDialogOpened from './isDialogOpened';
export {
isDialogOpened,
+ parsePhone,
toLowerCase,
toLowerCamel,
toDate,
diff --git a/src/filters/parsePhone.js b/src/filters/parsePhone.js
new file mode 100644
index 000000000..696f55007
--- /dev/null
+++ b/src/filters/parsePhone.js
@@ -0,0 +1,12 @@
+export default function (phone, prefix = 34) {
+ if (phone.startsWith('+')) {
+ return `${phone.slice(1)}`;
+ }
+ if (phone.startsWith('00')) {
+ return `${phone.slice(2)}`;
+ }
+ if (phone.startsWith(prefix) && phone.length === prefix.length + 9) {
+ return `${prefix}${phone.slice(prefix.length)}`;
+ }
+ return `${prefix}${phone}`;
+}
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index a823a57d4..98e443b6a 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -864,7 +864,6 @@ components:
cardDescriptor:
mainList: Main list
summary: Summary
- moreOptions: More options
leftMenu:
addToPinned: Add to pinned
removeFromPinned: Remove from pinned
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 79d48a667..cd567d415 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -101,8 +101,8 @@ const exprBuilder = (param, value) => {
-
+ {
/>
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
outlined
rounded
auto-load
+ />
+
+
+
+
-
-
-
-
-
-
-
+
+
@@ -203,7 +201,6 @@ es:
Salesperson: Comercial
Province: Provincia
City: Ciudad
- More options: Más opciones
Phone: Teléfono
Email: Email
Zone: Zona
diff --git a/src/pages/Entry/EntryBuysTableDialog.vue b/src/pages/Entry/EntryBuysTableDialog.vue
index c885c2485..3975bff19 100644
--- a/src/pages/Entry/EntryBuysTableDialog.vue
+++ b/src/pages/Entry/EntryBuysTableDialog.vue
@@ -82,11 +82,11 @@ const entriesTableColumns = computed(() => [
@@ -126,7 +126,9 @@ const entriesTableColumns = computed(() => [
"
unelevated
>
- {{ t('viewLabel') }}
+ {{
+ t('myEntries.viewLabel')
+ }}
diff --git a/src/pages/Entry/MyEntries.vue b/src/pages/Entry/MyEntries.vue
index 2c37c2c42..91a29b190 100644
--- a/src/pages/Entry/MyEntries.vue
+++ b/src/pages/Entry/MyEntries.vue
@@ -101,7 +101,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('printLabels'),
+ title: t('myEntries.printLabels'),
icon: 'print',
isPrimary: true,
action: (row) => printBuys(row.id),
diff --git a/src/pages/InvoiceIn/InvoiceInFilter.vue b/src/pages/InvoiceIn/InvoiceInFilter.vue
index d1c0856b5..130a77960 100644
--- a/src/pages/InvoiceIn/InvoiceInFilter.vue
+++ b/src/pages/InvoiceIn/InvoiceInFilter.vue
@@ -184,5 +184,4 @@ es:
Amount: Importe
Issued: Fecha factura
Id or supplier: Id o proveedor
- More options: Más opciones
diff --git a/src/pages/InvoiceOut/InvoiceOutFilter.vue b/src/pages/InvoiceOut/InvoiceOutFilter.vue
index 9ce8cc254..dc1d833a2 100644
--- a/src/pages/InvoiceOut/InvoiceOutFilter.vue
+++ b/src/pages/InvoiceOut/InvoiceOutFilter.vue
@@ -83,36 +83,29 @@ const states = ref();
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -149,5 +142,4 @@ es:
Issued: Fecha emisión
Created: Fecha creación
Dued: Fecha vencimiento
- More options: Más opciones
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index 8edb78732..c8fffb0ef 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -60,8 +60,15 @@ const columns = computed(() => [
label: t('globals.reference'),
isTitle: true,
component: 'select',
- attrs: { url: MODEL, optionLabel: 'ref', optionValue: 'id' },
+ attrs: {
+ url: MODEL,
+ optionLabel: 'ref',
+ optionValue: 'ref',
+ },
columnField: { component: null },
+ columnFilter: {
+ inWhere: true,
+ },
},
{
align: 'left',
@@ -139,25 +146,22 @@ function openPdf(id) {
}
function downloadPdf() {
- if (selectedRows.value.size === 0) return;
- const selectedCardsArray = Array.from(selectedRows.value.values());
+ if (selectedRows.value.size === 0) return;
+ const selectedCardsArray = Array.from(selectedRows.value.values());
- if (selectedRows.value.size === 1) {
- const [invoiceOut] = selectedCardsArray;
- openPdf(invoiceOut.id);
- } else {
- const invoiceOutIdsArray = selectedCardsArray.map(
- (invoiceOut) => invoiceOut.id
- );
- const invoiceOutIds = invoiceOutIdsArray.join(',');
+ if (selectedRows.value.size === 1) {
+ const [invoiceOut] = selectedCardsArray;
+ openPdf(invoiceOut.id);
+ } else {
+ const invoiceOutIdsArray = selectedCardsArray.map((invoiceOut) => invoiceOut.id);
+ const invoiceOutIds = invoiceOutIdsArray.join(',');
- const params = {
- ids: invoiceOutIds,
- };
-
- openReport(`${MODEL}/downloadZip`, params);
- }
+ const params = {
+ ids: invoiceOutIds,
+ };
+ openReport(`${MODEL}/downloadZip`, params);
+ }
}
watchEffect(selectedRows);
diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue
index 53bb87f8d..b91e7d229 100644
--- a/src/pages/Order/Card/CatalogFilterValueDialog.vue
+++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue
@@ -49,7 +49,7 @@ const getSelectedTagValues = async (tag) => {
-
+
{
:emit-value="false"
use-input
@update:model-value="getSelectedTagValues"
+ data-cy="catalogFilterValueDialogTagSelect"
/>
{
:disable="!value"
is-outlined
class="col"
+ data-cy="catalogFilterValueDialogValueInput"
/>
-
+
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 6202a6f90..1dd569fb5 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -178,6 +178,7 @@ function addOrder(value, field, params) {
? resetCategory(params, searchFn)
: removeTagGroupParam(params, searchFn, valIndex)
"
+ data-cy="catalogFilterCustomTag"
>
{{
@@ -211,6 +212,7 @@ function addOrder(value, field, params) {
:name="category.icon"
class="category-icon"
@click="selectCategory(params, category, searchFn)"
+ data-cy="catalogFilterCategory"
>
{{ t(category.name) }}
@@ -234,6 +236,7 @@ function addOrder(value, field, params) {
sort-by="name ASC"
:disable="!params.categoryFk"
@update:model-value="searchFn()"
+ data-cy="catalogFilterType"
>
@@ -285,6 +288,7 @@ function addOrder(value, field, params) {
:is-clearable="false"
v-model="searchByTag"
@keyup.enter="(val) => onSearchByTag(val, params)"
+ data-cy="catalogFilterValueInput"
>
@@ -297,6 +301,7 @@ function addOrder(value, field, params) {
color="primary"
size="md"
dense
+ data-cy="catalogFilterValueDialogBtn"
/>
{
});
async function fetchClientAddress(id, formData = {}) {
const { data } = await axios.get(`Clients/${id}`, {
- params: { filter: { include: { relation: 'addresses' } } },
+ params: {
+ filter: {
+ order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'],
+ include: { relation: 'addresses' },
+ },
+ },
});
addressesList.value = data.addresses;
formData.addressId = data.defaultAddressFk;
@@ -162,7 +168,7 @@ async function fetchAgencies({ landed, addressId }) {
const { data } = await axios.get('Agencies/landsThatDay', {
params: { addressFk: addressId, landed },
});
- agencyList.value = data;
+ agencyList.value = dataByOrder(data, 'agencyMode ASC');
}
const getDateColor = (date) => {
@@ -191,7 +197,7 @@ const getDateColor = (date) => {
urlCreate: 'Orders/new',
title: t('module.cerateOrder'),
onDataSaved: (url) => {
- tableRef.redirect(`${url}/catalog`);
+ tableRef.redirect(`${url}/catalog`);
},
formInitialData: {
active: true,
@@ -253,22 +259,27 @@ const getDateColor = (date) => {
@update:model-value="() => fetchAgencies(data)"
>
-
+
+
+
+
-
- {{
- `${
- !scope.opt?.isActive
- ? t('basicData.inactive')
- : ''
- } `
- }}
- {{ scope.opt?.nickname }}: {{ scope.opt?.street }},
- {{ scope.opt?.city }}
+
+ {{ scope.opt.nickname }}
+
+
+ {{ `${scope.opt.street}, ${scope.opt.city}` }}
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index 6f1cac83b..bde27f30e 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -212,81 +212,78 @@ const getGroupedStates = (data) => {
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -340,7 +337,6 @@ es:
With problems: Con problemas
Invoiced: Facturado
Routed: Enrutado
- More options: Más opciones
Province: Provincia
Agency: Agencia
Warehouse: Almacén
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 149a794a9..2fe4fcddc 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -274,7 +274,7 @@ const fetchAddresses = async (formData) => {
const filter = {
fields: ['nickname', 'street', 'city', 'id', 'isActive'],
- order: 'nickname ASC',
+ order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'],
};
const params = { filter: JSON.stringify(filter) };
const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, {
@@ -590,7 +590,22 @@ function setReference(data) {
@update:model-value="() => fetchAvailableAgencies(data)"
>
-
+
+
+
+
+describe('OrderCatalog', () => {
+ beforeEach(() => {
+ cy.login('developer');
+ cy.viewport(1920, 720);
+ cy.visit('/#/order/8/catalog');
+ });
+
+ const checkCustomFilterTag = (filterName = 'Plant') => {
+ cy.dataCy('catalogFilterCustomTag').should('exist');
+ cy.dataCy('catalogFilterCustomTag').contains(filterName);
+ };
+
+ const checkFilterTag = (filterName = 'Plant') => {
+ cy.dataCy('vnFilterPanelChip').should('exist');
+ cy.dataCy('vnFilterPanelChip').contains(filterName);
+ };
+
+ const selectCategory = (categoryIndex = 1, categoryName = 'Plant') => {
+ cy.get(
+ `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+ ).should('exist');
+ cy.get(
+ `div.q-page-container div:nth-of-type(${categoryIndex}) > [data-cy='catalogFilterCategory']`
+ ).click();
+ checkCustomFilterTag(categoryName);
+ };
+
+ const searchByCustomTagInput = (option) => {
+ cy.dataCy('catalogFilterValueInput').find('input').last().focus();
+ cy.dataCy('catalogFilterValueInput').find('input').last().type(option);
+ cy.dataCy('catalogFilterValueInput').find('input').last().type('{enter}');
+ checkCustomFilterTag(option);
+ };
+
+ const selectTypeFilter = (option) => {
+ cy.selectOption(
+ 'div.q-page-container div.list > div:nth-of-type(2) div:nth-of-type(3)',
+ option
+ );
+ checkFilterTag(option);
+ };
+
+ it('Shows empty state', () => {
+ cy.dataCy('orderCatalogPage').should('exist');
+ cy.dataCy('orderCatalogPage').contains('No data to display');
+ });
+
+ it('filter by category', () => {
+ selectCategory();
+ cy.dataCy('orderCatalogItem').should('exist');
+ });
+
+ it('filters by type', () => {
+ selectCategory();
+ selectTypeFilter('Anthurium');
+ });
+
+ it('filters by custom value select', () => {
+ selectCategory();
+ searchByCustomTagInput('Silver');
+ });
+
+ it('filters by custom value dialog', () => {
+ Cypress.on('uncaught:exception', (err) => {
+ if (err.message.includes('canceled')) {
+ return false;
+ }
+ });
+ selectCategory();
+ cy.dataCy('catalogFilterValueDialogBtn').should('exist');
+ cy.dataCy('catalogFilterValueDialogBtn').last().click();
+ cy.dataCy('catalogFilterValueDialogTagSelect').should('exist');
+ cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
+ cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('{enter}');
+ checkCustomFilterTag('2');
+ });
+
+ it('removes a secondary tag', () => {
+ selectCategory();
+ selectTypeFilter('Anthurium');
+ cy.dataCy('vnFilterPanelChip').should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='vnFilterPanelChip'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .click();
+ cy.dataCy('vnFilterPanelChip').should('not.exist');
+ });
+
+ it('Removes category tag', () => {
+ selectCategory();
+ cy.get(
+ "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .should('exist');
+ cy.get(
+ "div.q-page-container [data-cy='catalogFilterCustomTag'] > i.q-chip__icon--remove"
+ )
+ .contains('cancel')
+ .click();
+ cy.dataCy('catalogFilterCustomTag').should('not.exist');
+ });
+});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 53f9d1d73..dbaa7871c 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -86,9 +86,10 @@ Cypress.Commands.add('getValue', (selector) => {
});
// Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option) => {
+Cypress.Commands.add('selectOption', (selector, option, timeout) => {
cy.waitForElement(selector);
cy.get(selector).click();
+ cy.wait(timeout || 1000);
cy.get('.q-menu .q-item').contains(option).click();
});
Cypress.Commands.add('countSelectOptions', (selector, option) => {
diff --git a/test/vitest/__tests__/components/common/VnLinkPhone.spec.js b/test/vitest/__tests__/components/common/VnLinkPhone.spec.js
new file mode 100644
index 000000000..e460ab2fc
--- /dev/null
+++ b/test/vitest/__tests__/components/common/VnLinkPhone.spec.js
@@ -0,0 +1,29 @@
+import { describe, it, expect } from 'vitest';
+import parsePhone from 'src/filters/parsePhone';
+
+describe('parsePhone filter', () => {
+ it("adds prefix +34 if it doesn't have one", () => {
+ const resultado = parsePhone('123456789', '34');
+ expect(resultado).toBe('34123456789');
+ });
+
+ it('maintains prefix +34 if it is already correct', () => {
+ const resultado = parsePhone('+34123456789', '34');
+ expect(resultado).toBe('34123456789');
+ });
+
+ it('converts prefix 0034 to +34', () => {
+ const resultado = parsePhone('0034123456789', '34');
+ expect(resultado).toBe('34123456789');
+ });
+
+ it('converts prefix 34 without symbol to +34', () => {
+ const resultado = parsePhone('34123456789', '34');
+ expect(resultado).toBe('34123456789');
+ });
+
+ it('replaces incorrect prefix with the correct one', () => {
+ const resultado = parsePhone('+44123456789', '34');
+ expect(resultado).toBe('44123456789');
+ });
+});