{{ t(`filterPanel.${tag.label}`) }}:
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index 332494aa887..cc8d86ea8a1 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -19,7 +19,7 @@ export const useInvoiceOutGlobalStore = defineStore({
maxShipped: null,
clientId: null,
printer: null,
- serialType: null,
+ serialType: 'global',
},
addresses: [],
minInvoicingDate: null,
@@ -41,7 +41,6 @@ export const useInvoiceOutGlobalStore = defineStore({
async fetchAllData() {
try {
- const userInfo = await useUserConfig().fetch();
const date = Date.vnNew();
this.formInitialData.maxShipped = new Date(
date.getFullYear(),
@@ -53,7 +52,7 @@ export const useInvoiceOutGlobalStore = defineStore({
await Promise.all([
this.fetchParallelism(),
- this.fetchInvoiceOutConfig(userInfo.companyFk),
+ this.fetchInvoiceOutConfig(),
]);
this.initialDataLoading = false;
@@ -62,21 +61,23 @@ export const useInvoiceOutGlobalStore = defineStore({
}
},
- async fetchInvoiceOutConfig(companyFk) {
+ async fetchInvoiceOutConfig(formData = this.formInitialData) {
try {
- this.formInitialData.companyFk = companyFk;
- const params = { companyFk: companyFk };
+ const userInfo = await useUserConfig().fetch();
+ const params = {
+ companyFk: userInfo.companyFk,
+ serialType: formData.serialType,
+ };
const { data } = await axios.get('InvoiceOuts/getInvoiceDate', {
params,
});
- const stringDate = data.issued.substring(0, 10);
- this.minInvoicingDate = stringDate;
- this.formInitialData.invoiceDate = stringDate;
-
- this.minInvoicingDate = new Date(data.issued);
+ this.minInvoicingDate = data?.issued
+ ? new Date(data.issued)
+ : Date.vnNew();
this.formInitialData.invoiceDate = this.minInvoicingDate;
+ formData.invoiceDate = this.minInvoicingDate;
} catch (err) {
console.error('Error fetching invoice out global initial data');
throw new Error();
diff --git a/test/cypress/integration/claim/claimDevelopment.spec.js b/test/cypress/integration/claim/claimDevelopment.spec.js
index eb39f340a7d..df9d09a49db 100755
--- a/test/cypress/integration/claim/claimDevelopment.spec.js
+++ b/test/cypress/integration/claim/claimDevelopment.spec.js
@@ -3,6 +3,8 @@ describe('ClaimDevelopment', () => {
const claimId = 1;
const firstLineReason = 'tbody > :nth-child(1) > :nth-child(2)';
const thirdRow = 'tbody > :nth-child(3)';
+ const lastReason = 'Incompetencia';
+ const newReason = 'Calor';
beforeEach(() => {
cy.viewport(1920, 1080);
@@ -14,22 +16,22 @@ describe('ClaimDevelopment', () => {
});
it('should reset line', () => {
- cy.selectOption(firstLineReason, 'Novato');
+ cy.selectOption(firstLineReason, newReason);
cy.resetCard();
- cy.getValue(firstLineReason).should('equal', 'Prisas');
+ cy.getValue(firstLineReason).should('equal', lastReason);
});
it('should edit line', () => {
- cy.selectOption(firstLineReason, 'Novato');
+ cy.selectOption(firstLineReason, newReason);
cy.saveCard();
cy.login('developer');
cy.visit(`/#/claim/${claimId}/development`);
- cy.getValue(firstLineReason).should('equal', 'Novato');
+ cy.getValue(firstLineReason).should('equal', newReason);
//Restart data
- cy.selectOption(firstLineReason, 'Prisas');
+ cy.selectOption(firstLineReason, lastReason);
cy.saveCard();
});
@@ -42,7 +44,7 @@ describe('ClaimDevelopment', () => {
const rowData = [
false,
- 'Novato',
+ newReason,
'Roces',
'Compradores',
'administrativeNick',
diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js
index ce07deb1619..dcded63b0fe 100644
--- a/test/cypress/integration/client/clientList.spec.js
+++ b/test/cypress/integration/client/clientList.spec.js
@@ -16,7 +16,7 @@ describe('Client list', () => {
});
it('Client list create new client', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ cy.addBtnClick();
const randomInt = Math.floor(Math.random() * 90) + 10;
const data = {
@@ -26,8 +26,8 @@ describe('Client list', () => {
'Web user': { val: `user_test_${randomInt}` },
Street: { val: `C/ STREET ${randomInt}` },
Email: { val: `user.test${randomInt}@cypress.com` },
- 'Sales person': { val: 'employee', type: 'select' },
- Location: { val: '46000, Valencia(Province one), España', type: 'select' },
+ 'Sales person': { val: 'salesPerson', type: 'select' },
+ Location: { val: '46000', type: 'select' },
'Business type': { val: 'Otros', type: 'select' },
};
cy.fillInForm(data);
diff --git a/test/cypress/integration/entry/stockBought.spec.js b/test/cypress/integration/entry/stockBought.spec.js
index 66e06b79ee3..078ad19cc28 100644
--- a/test/cypress/integration/entry/stockBought.spec.js
+++ b/test/cypress/integration/entry/stockBought.spec.js
@@ -11,7 +11,7 @@ describe('EntryStockBought', () => {
cy.get('.q-notification__message').should('have.text', 'Data saved');
});
it('Should add a new reserved space for buyerBoss', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ 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');
diff --git a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
index f6dac4c733f..4c255054843 100644
--- a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js
@@ -2,7 +2,7 @@
describe('InvoiceInIntrastat', () => {
const firstRow = 'tbody > :nth-child(1)';
const thirdRow = 'tbody > :nth-child(3)';
- const firstRowCode = `${firstRow} > :nth-child(2)`;
+ const codes = `[data-cy="intrastat-code"]`;
const firstRowAmount = `${firstRow} > :nth-child(3)`;
beforeEach(() => {
@@ -11,13 +11,12 @@ describe('InvoiceInIntrastat', () => {
});
it('should edit the first line', () => {
- cy.selectOption(firstRowCode, 'Plantas vivas: Esqueje/injerto, Vid');
+ cy.selectOption(`${firstRow} ${codes}`, 'Plantas vivas: Esqueje/injerto, Vid');
cy.get(firstRowAmount).clear();
cy.saveCard();
- cy.get(`${firstRowCode} span`).should(
- 'have.text',
- '6021010:Plantas vivas: Esqueje/injerto, Vid'
- );
+ cy.get(codes)
+ .eq(0)
+ .should('have.value', '6021010: Plantas vivas: Esqueje/injerto, Vid');
});
it('should add a new row', () => {
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index fa0d1c5e462..d9ab3f7e790 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -1,7 +1,7 @@
///
describe('InvoiceInList', () => {
const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)';
- const firstId = `${firstRow} > td:nth-child(1) span`;
+ const firstId = `${firstRow} > td:nth-child(2) span`;
const firstDetailBtn = `${firstRow} .q-btn:nth-child(1)`;
const summaryHeaders = '.summaryBody .header-link';
diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
index b84d743d11b..f8b403a458f 100644
--- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
@@ -2,6 +2,7 @@
describe('InvoiceInVat', () => {
const thirdRow = 'tbody > :nth-child(3)';
const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)';
+ 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);
@@ -14,9 +15,9 @@ describe('InvoiceInVat', () => {
});
it('should edit the sage iva', () => {
- cy.selectOption(firstLineVat, 'H.P. IVA 21% CEE');
+ cy.selectOption(`${firstLineVat} ${vats}`, 'H.P. IVA 21% CEE');
cy.saveCard();
- cy.get(`${firstLineVat} span`).should('have.text', '8:H.P. IVA 21% CEE');
+ cy.get(vats).eq(0).should('have.value', '8: H.P. IVA 21% CEE');
});
it('should add a new row', () => {
diff --git a/test/cypress/integration/item/ItemFixedPrice.spec.js b/test/cypress/integration/item/ItemFixedPrice.spec.js
index 824ecf7a065..92dc27fda7a 100644
--- a/test/cypress/integration/item/ItemFixedPrice.spec.js
+++ b/test/cypress/integration/item/ItemFixedPrice.spec.js
@@ -19,7 +19,7 @@ describe('Handle Items FixedPrice', () => {
cy.selectOption('.list > :nth-child(2)', 'Alstroemeria');
cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ cy.addBtnClick();
cy.selectOption(`${firstRow} > :nth-child(2)`, '#13');
cy.get(`${firstRow} > :nth-child(4)`).find('input').type(1);
cy.get(`${firstRow} > :nth-child(5)`).find('input').type('2');
@@ -29,7 +29,7 @@ describe('Handle Items FixedPrice', () => {
});
it('Create and delete ', function () {
cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ cy.addBtnClick();
cy.selectOption(`${firstRow} > :nth-child(2)`, '#11');
cy.get(`${firstRow} > :nth-child(4)`).type('1');
cy.get(`${firstRow} > :nth-child(5)`).type('2');
diff --git a/test/cypress/integration/item/itemLastEntries.spec.js b/test/cypress/integration/item/itemLastEntries.spec.js
new file mode 100644
index 00000000000..c94cfa4800f
--- /dev/null
+++ b/test/cypress/integration/item/itemLastEntries.spec.js
@@ -0,0 +1,20 @@
+describe('ItemLastEntries', () => {
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.login('buyer');
+ cy.visit('/#/item/1/last-entries');
+ cy.intercept('GET', /.*lastEntriesFilter/).as('item');
+ cy.waitForElement('tbody');
+ });
+
+ it('should filter by agency', () => {
+ cy.get('tbody > tr')
+ .its('length')
+ .then((rowCount) => {
+ cy.get('[data-cy="hideInventory"]').click();
+ cy.wait('@item');
+ cy.waitForElement('tbody');
+ cy.get('tbody > tr').should('have.length.greaterThan', rowCount);
+ });
+ });
+});
diff --git a/test/cypress/integration/route/roadMap/roadmapList.spec.js b/test/cypress/integration/route/roadMap/roadmapList.spec.js
index ba602fdf67f..2f5e5672f46 100644
--- a/test/cypress/integration/route/roadMap/roadmapList.spec.js
+++ b/test/cypress/integration/route/roadMap/roadmapList.spec.js
@@ -5,7 +5,7 @@ describe('RoadMap', () => {
cy.visit(`/#/route/roadmap`);
});
it('Route list create roadmap and redirect', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ cy.addBtnClick();
cy.get('input[name="name"]').eq(1).type('roadMapTestOne{enter}');
cy.get('.q-notification__message').should('have.text', 'Data created');
cy.url().should('include', '/summary');
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index 8020d3ea9f2..4da43ce8e63 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -9,7 +9,7 @@ describe('Route', () => {
const getRowColumn = (row, column) => `:nth-child(${row}) > :nth-child(${column})`;
it('Route list create route', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+ cy.addBtnClick();
cy.get('input[name="description"]').type('routeTestOne{enter}');
cy.get('.q-notification__message').should('have.text', 'Data created');
cy.url().should('include', '/summary');
diff --git a/test/cypress/integration/worker/workerPda.spec.js b/test/cypress/integration/worker/workerPda.spec.js
index fe8efa834cc..31ec19eda0e 100644
--- a/test/cypress/integration/worker/workerPda.spec.js
+++ b/test/cypress/integration/worker/workerPda.spec.js
@@ -1,6 +1,5 @@
describe('WorkerPda', () => {
- const deviceProductionField =
- '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
+ const select = '[data-cy="pda-dialog-select"]';
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
@@ -8,8 +7,9 @@ describe('WorkerPda', () => {
});
it('assign pda', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
- cy.get(deviceProductionField).type('{downArrow}{enter}');
+ cy.addBtnClick();
+ cy.get(select).click();
+ cy.get(select).type('{downArrow}{enter}');
cy.get('.q-notification__message').should('have.text', 'Data created');
});
diff --git a/test/cypress/integration/zone/zoneBasicData.spec.js b/test/cypress/integration/zone/zoneBasicData.spec.js
index c6151a49b65..6229039b7c3 100644
--- a/test/cypress/integration/zone/zoneBasicData.spec.js
+++ b/test/cypress/integration/zone/zoneBasicData.spec.js
@@ -1,5 +1,6 @@
describe('ZoneBasicData', () => {
const notification = '.q-notification__message';
+ const priceBasicData = '[data-cy="Price_input"]';
beforeEach(() => {
cy.viewport(1280, 720);
@@ -8,14 +9,20 @@ describe('ZoneBasicData', () => {
});
it('should throw an error if the name is empty', () => {
- cy.get('.q-card > :nth-child(1)').clear();
+ cy.get('[data-cy="zone-basic-data-name"] input').type('{selectall}{backspace}');
cy.get('.q-btn-group > .q-btn--standard').click();
cy.get(notification).should('contains.text', "can't be blank");
});
+ it('should throw an error if the price is empty', () => {
+ cy.get(priceBasicData).clear();
+ cy.get('.q-btn-group > .q-btn--standard').click();
+ cy.get(notification).should('contains.text', 'cannot be blank');
+ });
+
it("should edit the basicData's zone", () => {
cy.get('.q-card > :nth-child(1)').type(' modified');
cy.get('.q-btn-group > .q-btn--standard').click();
- cy.get(notification).should('contains.text', 'Data saved');
+ cy.checkNotification('Data saved');
});
});
diff --git a/test/cypress/integration/zone/zoneWarehouse.spec.js b/test/cypress/integration/zone/zoneWarehouse.spec.js
index 3ffa3f69d70..817e26312d5 100644
--- a/test/cypress/integration/zone/zoneWarehouse.spec.js
+++ b/test/cypress/integration/zone/zoneWarehouse.spec.js
@@ -1,10 +1,10 @@
describe('ZoneWarehouse', () => {
const data = {
- Warehouse: { val: 'Algemesi', type: 'select' },
+ Warehouse: { val: 'Warehouse One', type: 'select' },
};
- const deviceProductionField =
- '.vn-row > :nth-child(1) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
- const dataError = "ER_DUP_ENTRY: Duplicate entry '2-2' for key 'zoneFk'";
+
+ const dataError = 'ER_DUP_ENTRY: Duplicate entry';
+ const saveBtn = '.q-btn--standard > .q-btn__content > .block';
beforeEach(() => {
cy.viewport(1280, 720);
@@ -13,22 +13,21 @@ describe('ZoneWarehouse', () => {
});
it('should throw an error if the warehouse chosen is already put in the zone', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
- cy.get(deviceProductionField).click();
- cy.get(deviceProductionField).type('{upArrow}{enter}');
- cy.get('.q-notification__message').should('have.text', dataError);
+ cy.addBtnClick();
+ cy.selectOption('[data-cy="Warehouse_select"]', 'Warehouse Two');
+ cy.get(saveBtn).click();
+ cy.checkNotification(dataError);
});
- it('should create a warehouse', () => {
- cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
- cy.get(deviceProductionField).click();
+ it('should create & remove a warehouse', () => {
+ cy.addBtnClick();
cy.fillInForm(data);
+ cy.get(saveBtn).click();
cy.get('.q-mt-lg > .q-btn--standard').click();
- });
- it('should delete a warehouse', () => {
cy.get('tbody > :nth-child(2) > :nth-child(2) > .q-icon').click();
- cy.get('.q-card__actions > .q-btn--flat > .q-btn__content').click();
+ cy.get('[title="Confirm"]').click();
+
cy.reload();
});
});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 2b13a714445..df2c00e03dd 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -58,8 +58,9 @@ Cypress.Commands.add('domContentLoad', (element, timeout = 5000) => {
cy.waitUntil(() => cy.document().then((doc) => doc.readyState === 'complete'));
});
Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
- cy.waitUntil(() => cy.get(element).then(($el) => $el.is(':visible')));
+ cy.get(element, { timeout }).should('be.visible').and('not.be.disabled');
});
+
Cypress.Commands.add('getValue', (selector) => {
cy.get(selector).then(($el) => {
if ($el.find('.q-checkbox__inner').length > 0) {
@@ -86,15 +87,40 @@ Cypress.Commands.add('getValue', (selector) => {
});
// Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option, timeout) => {
- cy.waitForElement(selector);
+Cypress.Commands.add('selectOption', (selector, option, timeout = 5000) => {
+ cy.waitForElement(selector, timeout);
cy.get(selector).click();
- cy.wait(timeout || 1000);
- cy.get('.q-menu .q-item').contains(option).click();
+ cy.get(selector).invoke('data', 'url').as('dataUrl');
+ cy.get(selector)
+ .clear()
+ .type(option)
+ .then(() => {
+ cy.get('.q-menu', { timeout })
+ .should('be.visible') // Asegurarse de que el menú está visible
+ .and('exist') // Verificar que el menú existe
+ .then(() => {
+ cy.get('@dataUrl').then((url) => {
+ if (url) {
+ cy.log('url: ', url);
+ // Esperar a que el menú no esté visible (desaparezca)
+ cy.get('.q-menu').should('not.be.visible');
+ // Ahora esperar a que el menú vuelva a aparecer
+ cy.get('.q-menu').should('be.visible').and('exist');
+ }
+ });
+ });
+ });
+
+ // Finalmente, seleccionar la opción deseada
+ cy.get('.q-menu:visible') // Asegurarse de que estamos dentro del menú visible
+ .find('.q-item') // Encontrar los elementos de las opciones
+ .contains(option) // Verificar que existe una opción que contenga el texto deseado
+ .click(); // Hacer clic en la opción
});
+
Cypress.Commands.add('countSelectOptions', (selector, option) => {
cy.waitForElement(selector);
- cy.get(selector).click();
+ cy.get(selector).click({ force: true });
cy.get('.q-menu .q-item').should('have.length', option);
});
@@ -110,8 +136,7 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
const { type, val } = field;
switch (type) {
case 'select':
- cy.get(el).click();
- cy.get('.q-menu .q-item').contains(val).click();
+ cy.selectOption(el, val);
break;
case 'date':
cy.get(el).type(val.split('-').join(''));
@@ -347,3 +372,10 @@ Cypress.Commands.add('searchByLabel', (label, value) => {
Cypress.Commands.add('dataCy', (tag, attr = 'data-cy') => {
return cy.get(`[${attr}="${tag}"]`);
});
+
+Cypress.Commands.add('addBtnClick', () => {
+ cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon')
+ .should('exist')
+ .and('be.visible')
+ .click();
+});
diff --git a/test/vitest/__tests__/components/common/VnDiscount.spec.js b/test/vitest/__tests__/components/common/VnDiscount.spec.js
new file mode 100644
index 00000000000..5d5be61ac7e
--- /dev/null
+++ b/test/vitest/__tests__/components/common/VnDiscount.spec.js
@@ -0,0 +1,28 @@
+import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import VnDiscount from 'components/common/vnDiscount.vue';
+
+describe('VnDiscount', () => {
+ let vm;
+
+ beforeAll(() => {
+ vm = createWrapper(VnDiscount, {
+ props: {
+ data: {},
+ price: 100,
+ quantity: 2,
+ discount: 10,
+ }
+ }).vm;
+ });
+
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
+
+ describe('total', () => {
+ it('should calculate total correctly', () => {
+ expect(vm.total).toBe(180);
+ });
+ });
+});
\ No newline at end of file
diff --git a/test/vitest/__tests__/composables/getExchange.spec.js b/test/vitest/__tests__/composables/getExchange.spec.js
new file mode 100644
index 00000000000..dba31458ee1
--- /dev/null
+++ b/test/vitest/__tests__/composables/getExchange.spec.js
@@ -0,0 +1,45 @@
+import { describe, expect, it, vi } from 'vitest';
+import axios from 'axios';
+import { getExchange } from 'src/composables/getExchange';
+
+vi.mock('axios');
+
+describe('getExchange()', () => {
+ it('should return the correct exchange rate', async () => {
+ axios.get.mockResolvedValue({
+ data: { value: 1.2 },
+ });
+
+ const amount = 100;
+ const currencyFk = 1;
+ const dated = '2023-01-01';
+ const result = await getExchange(amount, currencyFk, dated);
+
+ expect(result).toBe('83.33');
+ });
+
+ it('should return the correct exchange rate with custom decimal places', async () => {
+ axios.get.mockResolvedValue({
+ data: { value: 1.2 },
+ });
+
+ const amount = 100;
+ const currencyFk = 1;
+ const dated = '2023-01-01';
+ const decimalPlaces = 3;
+ const result = await getExchange(amount, currencyFk, dated, decimalPlaces);
+
+ expect(result).toBe('83.333');
+ });
+
+ it('should return null if the API call fails', async () => {
+ axios.get.mockRejectedValue(new Error('Network error'));
+
+ const amount = 100;
+ const currencyFk = 1;
+ const dated = '2023-01-01';
+ const result = await getExchange(amount, currencyFk, dated);
+
+ expect(result).toBeNull();
+ });
+});
diff --git a/test/vitest/__tests__/composables/getTotal.spec.js b/test/vitest/__tests__/composables/getTotal.spec.js
new file mode 100644
index 00000000000..789e3fbcfe0
--- /dev/null
+++ b/test/vitest/__tests__/composables/getTotal.spec.js
@@ -0,0 +1,55 @@
+import { vi, describe, expect, it } from 'vitest';
+import { getTotal } from 'src/composables/getTotal';
+
+vi.mock('src/filters', () => ({
+ toCurrency: vi.fn((value, currency) => `${currency} ${value.toFixed(2)}`),
+}));
+
+describe('getTotal()', () => {
+ const rows = [
+ { amount: 10.5, tax: 2.1 },
+ { amount: 20.75, tax: 3.25 },
+ { amount: 30.25, tax: 4.75 },
+ ];
+
+ it('should calculate the total for a given key', () => {
+ const total = getTotal(rows, 'amount');
+ expect(total).toBe('61.50');
+ });
+
+ it('should calculate the total with a callback function', () => {
+ const total = getTotal(rows, null, { cb: (row) => row.amount + row.tax });
+ expect(total).toBe('71.60');
+ });
+
+ it('should format the total as currency', () => {
+ const total = getTotal(rows, 'amount', { currency: 'USD' });
+ expect(total).toBe('USD 61.50');
+ });
+
+ it('should format the total as currency with default currency', () => {
+ const total = getTotal(rows, 'amount', { currency: 'default' });
+ expect(total).toBe('undefined 61.50');
+ });
+
+ it('should calculate the total with integer formatting', () => {
+ const total = getTotal(rows, 'amount', { decimalPlaces: 0 });
+ expect(total).toBe('62');
+ });
+
+ it('should calculate the total with custom decimal places', () => {
+ const total = getTotal(rows, 'amount', { decimalPlaces: 1 });
+ expect(total).toBe('61.5');
+ });
+
+ it('should handle rows with missing keys', () => {
+ const rowsWithMissingKeys = [{ amount: 10.5 }, { amount: 20.75 }, {}];
+ const total = getTotal(rowsWithMissingKeys, 'amount');
+ expect(total).toBe('31.25');
+ });
+
+ it('should handle empty rows', () => {
+ const total = getTotal([], 'amount');
+ expect(total).toBe('0.00');
+ });
+});
diff --git a/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js b/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js
new file mode 100644
index 00000000000..d2458581210
--- /dev/null
+++ b/test/vitest/__tests__/composables/useAccountShortToStandard.spec.js
@@ -0,0 +1,9 @@
+import { describe, expect, it } from 'vitest';
+import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard';
+
+describe('useAccountShortToStandard()', () => {
+ it('should pad the decimal part with zeros for short numbers', () => {
+ expect(useAccountShortToStandard('123.45')).toBe('1230000045');
+ expect(useAccountShortToStandard('123.')).toBe('1230000000');
+ });
+});
diff --git a/test/vitest/__tests__/pages/InvoiceIn/InvoiceInIntrastat.spec.js b/test/vitest/__tests__/pages/InvoiceIn/InvoiceInIntrastat.spec.js
deleted file mode 100644
index adfb054c658..00000000000
--- a/test/vitest/__tests__/pages/InvoiceIn/InvoiceInIntrastat.spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { vi, describe, expect, it, beforeAll } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
-import InvoiceInIntrastat from 'src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue';
-
-describe('InvoiceInIntrastat', () => {
- let vm;
-
- beforeAll(() => {
- vm = createWrapper(InvoiceInIntrastat, {
- global: {
- stubs: ['vnPaginate'],
- mocks: {
- fetch: vi.fn(),
- },
- },
- }).vm;
- vi.spyOn(axios, 'get').mockResolvedValue({ data: [{}] });
- });
-
- describe('getTotal()', () => {
- it('should correctly handle the sum', () => {
- const invoceInIntrastat = [
- { amount: 10, stems: 162 },
- { amount: 20, stems: 21 },
- ];
-
- const totalAmount = vm.getTotal(invoceInIntrastat, 'amount');
- const totalStems = vm.getTotal(invoceInIntrastat, 'stems');
-
- expect(totalAmount).toBe(10 + 20);
- expect(totalStems).toBe(162 + 21);
- });
- });
-});
diff --git a/test/vitest/__tests__/pages/InvoiceIn/InvoiceInVat.spec.js b/test/vitest/__tests__/pages/InvoiceIn/InvoiceInVat.spec.js
deleted file mode 100644
index 76453f65aa6..00000000000
--- a/test/vitest/__tests__/pages/InvoiceIn/InvoiceInVat.spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { vi, describe, expect, it, beforeAll } from 'vitest';
-import { createWrapper } from 'app/test/vitest/helper';
-import InvoiceInVat from 'src/pages/InvoiceIn/Card/InvoiceInVat.vue';
-
-describe('InvoiceInVat', () => {
- let vm;
-
- beforeAll(() => {
- vm = createWrapper(InvoiceInVat, {
- global: {
- stubs: [],
- mocks: {
- fetch: vi.fn(),
- },
- },
- }).vm;
- });
-
- describe('taxRate()', () => {
- it('should correctly compute the tax rate', () => {
- const invoiceInTax = { taxableBase: 100, taxTypeSageFk: 1 };
- vm.sageTaxTypes = [
- { id: 1, rate: 10 },
- { id: 2, rate: 20 },
- ];
- const result = vm.taxRate(invoiceInTax);
- expect(result).toBe((10 / 100) * 100);
- });
-
- it('should return 0 if there is not tax rate', () => {
- const invoiceInTax = { taxableBase: 100, taxTypeSageFk: 1 };
- vm.sageTaxTypes = [];
-
- const result = vm.taxRate(invoiceInTax);
- expect(result).toBe(0);
- });
- });
-});