From bb6fae5d087575a84418549cc75ed22ca8e01a23 Mon Sep 17 00:00:00 2001 From: provira Date: Fri, 10 Jan 2025 14:08:25 +0100 Subject: [PATCH 1/6] feat: refs #7087 created CardSummary test --- .../ui/__tests__/CardSummary.spec.js | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/components/ui/__tests__/CardSummary.spec.js diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js new file mode 100644 index 000000000..4a32e92e5 --- /dev/null +++ b/src/components/ui/__tests__/CardSummary.spec.js @@ -0,0 +1,48 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import CardSummary from 'src/components/ui/CardSummary.vue'; + +describe('CardSummary', () => { + let vm; + let wrapper; + + beforeAll(() => { + const mockApiResponse = { + data: { + data: [], + total: 0, + } + }; + + vi.spyOn(axios, 'get').mockResolvedValue(mockApiResponse); + + wrapper = createWrapper(CardSummary, { + global: { + stubs: [ + 'arrayData', + 'useArrayData', + ], + mocks: { + validate: vi.fn(), + }, + }, + propsData: { + dataKey: 'cardSummaryKey', + url: 'cardSummaryUrl', + }, + }); + + vm = wrapper.vm; + wrapper = wrapper.wrapper; + + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should fetch data', async () => { + expect(wrapper.emitted('fetch')); + }); + +}); \ No newline at end of file From 1295f394f393a6a842f39f94fd0adc034f66b603 Mon Sep 17 00:00:00 2001 From: provira Date: Mon, 13 Jan 2025 08:11:41 +0100 Subject: [PATCH 2/6] feat: refs #7087 added more test cases --- .../ui/__tests__/CardSummary.spec.js | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js index 4a32e92e5..7a979c2ea 100644 --- a/src/components/ui/__tests__/CardSummary.spec.js +++ b/src/components/ui/__tests__/CardSummary.spec.js @@ -1,48 +1,63 @@ -import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; import { createWrapper, axios } from 'app/test/vitest/helper'; import CardSummary from 'src/components/ui/CardSummary.vue'; describe('CardSummary', () => { let vm; let wrapper; - + beforeAll(() => { - const mockApiResponse = { - data: { - data: [], - total: 0, - } - }; - - vi.spyOn(axios, 'get').mockResolvedValue(mockApiResponse); + vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); + }); + beforeEach(() => { wrapper = createWrapper(CardSummary, { - global: { - stubs: [ - 'arrayData', - 'useArrayData', - ], - mocks: { - validate: vi.fn(), - }, - }, propsData: { dataKey: 'cardSummaryKey', url: 'cardSummaryUrl', + filter: 'cardFilter', }, }); - vm = wrapper.vm; wrapper = wrapper.wrapper; - }); - + afterEach(() => { vi.clearAllMocks(); }); - it('should fetch data', async () => { - expect(wrapper.emitted('fetch')); + it('should fetch data correctly', async () => { + const fetchSpy = vi + .spyOn(vm.arrayData, 'fetch') + .mockResolvedValue({ data: [{ id: 1, name: 'Test Entity' }] }); + await vm.fetch(); + + expect(fetchSpy).toHaveBeenCalledWith({ append: false, updateRouter: false }); + expect(wrapper.emitted('onFetch')).toBeTruthy(); + expect(vm.isLoading).toBe(false); + }); + + it('should set correct props to the store', () => { + expect(vm.store.url).toEqual('cardSummaryUrl'); + expect(vm.store.filter).toEqual('cardFilter'); + }); + + it('should compute entity correctly from store data', () => { + vm.store.data = [{ id: 1, name: 'Entity 1' }]; + expect(vm.entity).toEqual({ id: 1, name: 'Entity 1' }); + }); + + it('should handle empty data gracefully', () => { + vm.store.data = []; + expect(vm.entity).toBeUndefined(); + }); + + it('should respond to prop changes and refetch data', async () => { + const fetchSpy = vi.spyOn(vm.arrayData, 'fetch'); + await wrapper.setProps({ url: 'newUrl', filter: { key: 'newValue' } }); + + expect(fetchSpy).toHaveBeenCalled(); + expect(vm.store.url).toBe('newUrl'); + expect(vm.store.filter).toEqual({ key: 'newValue' }); }); - }); \ No newline at end of file From 54867597aaec1f9a7ae3a9e7937eb6dd3f7a32d2 Mon Sep 17 00:00:00 2001 From: provira Date: Wed, 15 Jan 2025 08:52:43 +0100 Subject: [PATCH 3/6] feat: refs #7087 added new test --- src/components/ui/__tests__/CardSummary.spec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js index 7a979c2ea..b114797ef 100644 --- a/src/components/ui/__tests__/CardSummary.spec.js +++ b/src/components/ui/__tests__/CardSummary.spec.js @@ -1,6 +1,7 @@ import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; import { createWrapper, axios } from 'app/test/vitest/helper'; import CardSummary from 'src/components/ui/CardSummary.vue'; +import * as vueRouter from 'vue-router'; describe('CardSummary', () => { let vm; @@ -10,6 +11,14 @@ describe('CardSummary', () => { vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); }); + vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ + query: {}, + params: {}, + meta: { moduleName: 'mockName' }, + path: 'mockName/1/summary', + name: 'CardSummary', + }); + beforeEach(() => { wrapper = createWrapper(CardSummary, { propsData: { @@ -60,4 +69,8 @@ describe('CardSummary', () => { expect(vm.store.url).toBe('newUrl'); expect(vm.store.filter).toEqual({ key: 'newValue' }); }); + + it('should return true if route path ends with /summary' , () => { + expect(vm.isSummary).toBe(true); + }); }); \ No newline at end of file From 6ecbaf1a0412538a3eaa06ef269385231adecbe1 Mon Sep 17 00:00:00 2001 From: provira Date: Wed, 15 Jan 2025 08:55:16 +0100 Subject: [PATCH 4/6] Merge branch '7087-testCardSummary' of https: refs #7087//gitea.verdnatura.es/verdnatura/salix-front into 7087-testCardSummary --- src/components/RegularizeStockForm.vue | 2 +- src/components/ui/CardDescriptor.vue | 32 +- src/components/ui/CardSummary.vue | 24 +- src/components/ui/VnMoreOptions.vue | 20 ++ src/composables/useHasAccount.js | 6 + src/pages/Account/Card/AccountDescriptor.vue | 25 +- .../Account/Card/AccountDescriptorMenu.vue | 29 +- src/pages/Account/Card/AccountMailAlias.vue | 13 +- .../Account/Card/AccountMailForwarding.vue | 21 +- src/pages/Account/Card/AccountSummary.vue | 5 +- src/pages/Claim/Card/ClaimCard.vue | 18 +- src/pages/Claim/Card/ClaimSummary.vue | 4 + src/pages/Claim/ClaimList.vue | 76 ++--- src/pages/Claim/locale/en.yml | 2 + src/pages/Claim/locale/es.yml | 4 +- src/pages/Customer/Card/CustomerSummary.vue | 9 +- .../components/CustomerAddressEdit.vue | 8 +- src/pages/Entry/Card/EntryDescriptor.vue | 16 +- src/pages/Entry/Card/EntryDescriptorMenu.vue | 22 ++ src/pages/Entry/Card/EntrySummary.vue | 9 +- src/pages/Entry/EntryList.vue | 1 - src/pages/Entry/locale/en.yml | 1 + src/pages/Entry/locale/es.yml | 1 + .../InvoiceIn/Card/InvoiceInBasicData.vue | 2 +- .../InvoiceIn/Card/InvoiceInDescriptor.vue | 274 ++---------------- .../Card/InvoiceInDescriptorMenu.vue | 206 +++++++++++++ src/pages/InvoiceIn/Card/InvoiceInSummary.vue | 72 ++--- src/pages/InvoiceIn/InvoiceInCreate.vue | 6 +- src/pages/InvoiceIn/InvoiceInFilter.vue | 2 +- src/pages/InvoiceIn/InvoiceInList.vue | 20 +- src/pages/InvoiceIn/locale/en.yml | 24 +- src/pages/InvoiceIn/locale/es.yml | 26 +- .../InvoiceOut/Card/InvoiceOutSummary.vue | 4 + src/pages/InvoiceOut/InvoiceOutList.vue | 2 +- src/pages/Item/Card/ItemDescriptor.vue | 42 +-- src/pages/Item/Card/ItemDescriptorImage.vue | 1 - src/pages/Item/Card/ItemDescriptorMenu.vue | 44 +++ src/pages/Item/Card/ItemSummary.vue | 8 +- src/pages/Item/ItemList.vue | 3 +- src/pages/Item/ItemRequest.vue | 26 +- src/pages/Item/locale/en.yml | 1 + src/pages/Item/locale/es.yml | 1 + src/pages/Order/Card/OrderDescriptor.vue | 4 - src/pages/Order/Card/OrderSummary.vue | 4 + src/pages/Route/Card/RouteDescriptorMenu.vue | 2 +- src/pages/Route/Card/RouteSummary.vue | 4 + src/pages/Route/Roadmap/RoadmapSummary.vue | 4 + .../Shelving/Card/ShelvingDescriptorMenu.vue | 7 +- src/pages/Shelving/Card/ShelvingSummary.vue | 13 +- src/pages/Ticket/Card/TicketSummary.vue | 18 +- src/pages/Travel/Card/TravelSummary.vue | 5 +- src/pages/Worker/Card/WorkerDescriptor.vue | 55 +--- .../Worker/Card/WorkerDescriptorMenu.vue | 65 +++++ src/pages/Worker/Card/WorkerSummary.vue | 4 + src/pages/Zone/Card/ZoneBasicData.vue | 13 +- .../Zone/Card/ZoneEventInclusionForm.vue | 10 +- src/pages/Zone/Card/ZoneSummary.vue | 4 + src/pages/Zone/locale/es.yml | 1 + src/router/modules/claim.js | 223 +++++++------- src/stores/invoiceOutGlobal.js | 44 ++- .../invoiceIn/invoiceInCorrective.spec.js | 4 +- 61 files changed, 873 insertions(+), 723 deletions(-) create mode 100644 src/components/ui/VnMoreOptions.vue create mode 100644 src/composables/useHasAccount.js create mode 100644 src/pages/Entry/Card/EntryDescriptorMenu.vue create mode 100644 src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue create mode 100644 src/pages/Item/Card/ItemDescriptorMenu.vue create mode 100644 src/pages/Worker/Card/WorkerDescriptorMenu.vue diff --git a/src/components/RegularizeStockForm.vue b/src/components/RegularizeStockForm.vue index 3cd18d1c8..91a2e5d39 100644 --- a/src/components/RegularizeStockForm.vue +++ b/src/components/RegularizeStockForm.vue @@ -44,7 +44,7 @@ const onDataSaved = (data) => { diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue index f4c0091d2..cf217555a 100644 --- a/src/components/ui/CardDescriptor.vue +++ b/src/components/ui/CardDescriptor.vue @@ -6,6 +6,7 @@ import { useArrayData } from 'composables/useArrayData'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useState } from 'src/composables/useState'; import { useRoute } from 'vue-router'; +import VnMoreOptions from './VnMoreOptions.vue'; const $props = defineProps({ url: { @@ -47,7 +48,6 @@ let store; let entity; const isLoading = ref(false); const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName); -const menuRef = ref(); defineExpose({ getData }); onBeforeMount(async () => { @@ -159,25 +159,11 @@ const toModule = computed(() => - - - {{ t('components.cardDescriptor.moreOptions') }} - - - - - - - + + +
@@ -222,8 +208,8 @@ const toModule = computed(() => /> - + - -en: - isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries - isLinked: The entry {bookEntry} has been linked to Sage. Please contact administration for further information - assertAction: Are you sure you want to {action} this invoice? -es: - book: asentar - unbook: desasentar - delete: eliminar - clone: clonar - To book: Contabilizar - To unbook: Descontabilizar - Delete invoice: Eliminar factura - Invoice deleted: Factura eliminada - Clone invoice: Clonar factura - Invoice cloned: Factura clonada - Show agricultural receipt as PDF: Ver recibo agrícola como PDF - Send agricultural receipt as PDF: Enviar recibo agrícola como PDF - Are you sure you want to send it?: Estás seguro que quieres enviarlo? - Send PDF invoice: Enviar factura a PDF - Create rectificative invoice: Crear factura rectificativa - Rectificative invoice: Factura rectificativa - Original invoice: Factura origen - Entry: entrada - isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes - isLinked: El asiento {bookEntry} fue enlazado a Sage, por favor contacta con administración - assertAction: Estas seguro de querer {action} esta factura? - diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue new file mode 100644 index 000000000..647b68f88 --- /dev/null +++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue @@ -0,0 +1,206 @@ + + + + + +en: + isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries + isLinked: The entry has been linked to Sage. Please contact administration for further information + assertAction: Are you sure you want to {action} this invoice? +es: + isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes + isLinked: El asiento fue enlazado a Sage, por favor contacta con administración + assertAction: Estas seguro de querer {action} esta factura? + diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue index 115a33208..eca0c7af1 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue @@ -10,6 +10,7 @@ import VnLv from 'src/components/ui/VnLv.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import InvoiceIntoBook from '../InvoiceInToBook.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; +import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue'; const props = defineProps({ id: { type: [Number, String], default: 0 } }); const { t } = useI18n(); @@ -26,14 +27,14 @@ const intrastatTotals = ref({ amount: 0, net: 0, stems: 0 }); const vatColumns = ref([ { name: 'expense', - label: 'InvoiceIn.summary.expense', + label: 'invoicein.summary.expense', field: (row) => row.expenseFk, sortable: true, align: 'left', }, { name: 'landed', - label: 'InvoiceIn.summary.taxableBase', + label: 'invoicein.summary.taxableBase', field: (row) => row.taxableBase, format: (value) => toCurrency(value), sortable: true, @@ -41,7 +42,7 @@ const vatColumns = ref([ }, { name: 'vat', - label: 'InvoiceIn.summary.sageVat', + label: 'invoicein.summary.sageVat', field: (row) => { if (row.taxTypeSage) return `#${row.taxTypeSage.id} : ${row.taxTypeSage.vat}`; }, @@ -51,7 +52,7 @@ const vatColumns = ref([ }, { name: 'transaction', - label: 'InvoiceIn.summary.sageTransaction', + label: 'invoicein.summary.sageTransaction', field: (row) => { if (row.transactionTypeSage) return `#${row.transactionTypeSage.id} : ${row.transactionTypeSage?.transaction}`; @@ -62,7 +63,7 @@ const vatColumns = ref([ }, { name: 'rate', - label: 'InvoiceIn.summary.rate', + label: 'invoicein.summary.rate', field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate), format: (value) => toCurrency(value), sortable: true, @@ -70,7 +71,7 @@ const vatColumns = ref([ }, { name: 'currency', - label: 'InvoiceIn.summary.currency', + label: 'invoicein.summary.currency', field: (row) => row.foreignValue, format: (val) => val && toCurrency(val, currency.value), sortable: true, @@ -81,21 +82,21 @@ const vatColumns = ref([ const dueDayColumns = ref([ { name: 'date', - label: 'InvoiceIn.summary.dueDay', + label: 'invoicein.summary.dueDay', field: (row) => toDate(row.dueDated), sortable: true, align: 'left', }, { name: 'bank', - label: 'InvoiceIn.summary.bank', + label: 'invoicein.summary.bank', field: (row) => row.bank.bank, sortable: true, align: 'left', }, { name: 'amount', - label: 'InvoiceIn.list.amount', + label: 'invoicein.list.amount', field: (row) => row.amount, format: (value) => toCurrency(value), sortable: true, @@ -103,7 +104,7 @@ const dueDayColumns = ref([ }, { name: 'landed', - label: 'InvoiceIn.summary.foreignValue', + label: 'invoicein.summary.foreignValue', field: (row) => row.foreignValue, format: (val) => val && toCurrency(val, currency.value), sortable: true, @@ -114,7 +115,7 @@ const dueDayColumns = ref([ const intrastatColumns = ref([ { name: 'code', - label: 'InvoiceIn.summary.code', + label: 'invoicein.summary.code', field: (row) => { return `${row.intrastat.id}: ${row.intrastat?.description}`; }, @@ -123,21 +124,21 @@ const intrastatColumns = ref([ }, { name: 'amount', - label: 'InvoiceIn.list.amount', + label: 'invoicein.list.amount', field: (row) => toCurrency(row.amount), sortable: true, align: 'left', }, { name: 'net', - label: 'InvoiceIn.summary.net', + label: 'invoicein.summary.net', field: (row) => row.net, sortable: true, align: 'left', }, { name: 'stems', - label: 'InvoiceIn.summary.stems', + label: 'invoicein.summary.stems', field: (row) => row.stems, format: (value) => value, sortable: true, @@ -145,7 +146,7 @@ const intrastatColumns = ref([ }, { name: 'landed', - label: 'InvoiceIn.summary.country', + label: 'invoicein.summary.country', field: (row) => row.country?.code, format: (value) => value, sortable: true, @@ -200,6 +201,9 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; + diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml index 3723a0f05..94db50066 100644 --- a/src/pages/InvoiceIn/locale/en.yml +++ b/src/pages/InvoiceIn/locale/en.yml @@ -1,4 +1,4 @@ -InvoiceIn: +invoicein: serial: Serial isBooked: Is booked list: @@ -12,6 +12,26 @@ InvoiceIn: amount: Amount descriptor: ticketList: Ticket list + descriptorMenu: + book: Book + unbook: Unbook + delete: Delete + clone: Clone + toBook: To book + toUnbook: To unbook + deleteInvoice: Delete invoice + invoiceDeleted: invoice deleted + cloneInvoice: Clone invoice + invoiceCloned: Invoice cloned + showAgriculturalPdf: Show agricultural receipt as PDF + sendAgriculturalPdf: Send agricultural receipt as PDF + checkSendInvoice: Are you sure you want to send it? + sendPdfInvoice: Send PDF invoice + createCorrective: Create rectificative invoice + correctiveInvoice: Rectificative invoice + originalInvoice: Original invoice + entry: Entry + emailEmpty: The email can't be empty card: client: Client company: Company @@ -46,8 +66,6 @@ InvoiceIn: search: Id or supplier name correctedFk: Corrected isBooked: Is booked -invoicein: - params: account: Ledger account correctingFk: Rectificative \ No newline at end of file diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml index 5637605f6..bcb9c0551 100644 --- a/src/pages/InvoiceIn/locale/es.yml +++ b/src/pages/InvoiceIn/locale/es.yml @@ -1,4 +1,4 @@ -InvoiceIn: +invoicein: serial: Serie isBooked: Contabilizada list: @@ -12,6 +12,26 @@ InvoiceIn: amount: Importe descriptor: ticketList: Listado de tickets + descriptorMenu: + book: Asentar + unbook: Desasentar + delete: Eliminar + clone: Clonar + toBook: Contabilizar + toUnbook: Descontabilizar + deleteInvoice: Eliminar factura + invoiceDeleted: Factura eliminada + cloneInvoice: Clonar factura + invoiceCloned: Factura clonada + showAgriculturalPdf: Ver recibo agrícola como PDF + sendAgriculturalPdf: Enviar recibo agrícola como PDF + checkSendInvoice: ¿Estás seguro que quieres enviarlo? + sendPdfInvoice: Enviar factura a PDF + createCorrective: Crear factura rectificativa + correctiveInvoice: Factura rectificativa + originalInvoice: Factura origen + entry: Entrada + emailEmpty: El email no puede estar vacío card: client: Cliente company: Empresa @@ -43,8 +63,6 @@ InvoiceIn: params: search: Id o nombre proveedor correctedFk: Rectificada -invoicein: - params: account: Cuenta contable correctingFk: Rectificativa - + diff --git a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue index 81b3e7c41..3ceb447dd 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue @@ -10,6 +10,7 @@ import { getUrl } from 'src/composables/getUrl'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; +import InvoiceOutDescriptorMenu from './InvoiceOutDescriptorMenu.vue'; onMounted(async () => { fetch(); @@ -113,6 +114,9 @@ const ticketsColumns = ref([ +