diff --git a/src/pages/Customer/composables/__tests__/getAddresses.spec.js b/src/pages/Customer/composables/__tests__/getAddresses.spec.js new file mode 100644 index 000000000..9e04a83cc --- /dev/null +++ b/src/pages/Customer/composables/__tests__/getAddresses.spec.js @@ -0,0 +1,33 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; +import axios from 'axios'; +import { getAddresses } from 'src/pages/Customer/composables/getAddresses'; + +vi.mock('axios'); + +describe('getAddresses', () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should fetch addresses with correct parameters for a valid clientId', async () => { + const clientId = '12345'; + + await getAddresses(clientId); + + expect(axios.get).toHaveBeenCalledWith(`Clients/${clientId}/addresses`, { + params: { + filter: JSON.stringify({ + fields: ['nickname', 'street', 'city', 'id'], + where: { isActive: true }, + order: 'nickname ASC', + }), + }, + }); + }); + + it('should return undefined when clientId is not provided', async () => { + await getAddresses(undefined); + + expect(axios.get).not.toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/pages/Customer/composables/__tests__/getClient.spec.js b/src/pages/Customer/composables/__tests__/getClient.spec.js new file mode 100644 index 000000000..a83d3d89f --- /dev/null +++ b/src/pages/Customer/composables/__tests__/getClient.spec.js @@ -0,0 +1,41 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; +import axios from 'axios'; +import { getClient } from 'src/pages/Customer/composables/getClient'; + +vi.mock('axios'); + +describe('getClient', () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + const generateParams = (clientId) => ({ + params: { + filter: JSON.stringify({ + include: { + relation: 'defaultAddress', + scope: { + fields: ['id', 'agencyModeFk'], + }, + }, + where: { id: clientId }, + }), + }, + }); + + it('should fetch client data with correct parameters for a valid clientId', async () => { + const clientId = '12345'; + + await getClient(clientId); + + expect(axios.get).toHaveBeenCalledWith('Clients', generateParams(clientId)); + }); + + it('should return undefined when clientId is not provided', async () => { + const clientId = undefined; + + await getClient(clientId); + + expect(axios.get).toHaveBeenCalledWith('Clients', generateParams(clientId)); + }); +}); diff --git a/src/pages/Customer/composables/getAddresses.js b/src/pages/Customer/composables/getAddresses.js new file mode 100644 index 000000000..eecc0150b --- /dev/null +++ b/src/pages/Customer/composables/getAddresses.js @@ -0,0 +1,14 @@ +import axios from 'axios'; + +export async function getAddresses(clientId) { + if (!clientId) return; + const filter = { + fields: ['nickname', 'street', 'city', 'id'], + where: { isActive: true }, + order: 'nickname ASC', + }; + const params = { filter: JSON.stringify(filter) }; + return await axios.get(`Clients/${clientId}/addresses`, { + params, + }); +}; \ No newline at end of file diff --git a/src/pages/Customer/composables/getClient.js b/src/pages/Customer/composables/getClient.js new file mode 100644 index 000000000..ecacc67c0 --- /dev/null +++ b/src/pages/Customer/composables/getClient.js @@ -0,0 +1,15 @@ +import axios from 'axios'; + +export async function getClient(clientId) { + const filter = { + include: { + relation: 'defaultAddress', + scope: { + fields: ['id', 'agencyModeFk'], + }, + }, + where: { id: clientId }, + }; + const params = { filter: JSON.stringify(filter) }; + return await axios.get('Clients', { params }); +}; \ No newline at end of file diff --git a/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js b/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js new file mode 100644 index 000000000..9897173f1 --- /dev/null +++ b/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js @@ -0,0 +1,55 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; +import axios from 'axios'; +import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies'; + +vi.mock('axios'); + +describe('getAgencies', () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + const generateParams = (formData) => ({ + params: { + warehouseFk: formData.warehouseId, + addressFk: formData.addressId, + landed: formData.landed, + }, + }); + + it('should fetch agencies data with correct parameters for valid formData', async () => { + const formData = { + warehouseId: '123', + addressId: '456', + landed: 'true', + }; + + await getAgencies(formData); + + expect(axios.get).toHaveBeenCalledWith('Agencies/getAgenciesWithWarehouse', generateParams(formData)); + }); + + it('should not call API when formData is missing required landed field', async () => { + const formData = { warehouseId: '123', addressId: '456' }; + + await getAgencies(formData); + + expect(axios.get).not.toHaveBeenCalled(); + }); + + it('should not call API when formData is missing required addressId field', async () => { + const formData = { warehouseId: '123', landed: 'true' }; + + await getAgencies(formData); + + expect(axios.get).not.toHaveBeenCalled(); + }); + + it('should not call API when formData is missing required warehouseId field', async () => { + const formData = { addressId: '456', landed: 'true' }; + + await getAgencies(formData); + + expect(axios.get).not.toHaveBeenCalled(); + }); +}); diff --git a/src/pages/Route/Agency/composables/getAgencies.js b/src/pages/Route/Agency/composables/getAgencies.js new file mode 100644 index 000000000..7299d7e23 --- /dev/null +++ b/src/pages/Route/Agency/composables/getAgencies.js @@ -0,0 +1,12 @@ +import axios from 'axios'; + +export async function getAgencies(formData) { + if (!formData.warehouseId || !formData.addressId || !formData.landed) return; + let params = { + warehouseFk: formData.warehouseId, + addressFk: formData.addressId, + landed: formData.landed, + }; + + return await axios.get('Agencies/getAgenciesWithWarehouse', { params }); +} diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue index 38e2af612..89f7015d7 100644 --- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue +++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue @@ -16,6 +16,8 @@ import VnInputTime from 'src/components/common/VnInputTime.vue'; import { useAcl } from 'src/composables/useAcl'; import VnInputNumber from 'src/components/common/VnInputNumber.vue'; import { useArrayData } from 'src/composables/useArrayData'; +import { getAddresses } from 'src/pages/Customer/composables/getAddresses'; +import { getClient } from 'src/pages/Customer/composables/getClient'; const props = defineProps({ ticket: { @@ -40,7 +42,10 @@ const { openReport, sendEmail } = usePrintService(); const ticketSummary = useArrayData('TicketSummary'); const { ticket } = toRefs(props); const ticketId = computed(() => props.ticket.id ?? currentRoute.value.params.id); -const client = ref(); +const client = ref(null); +const address = ref(null); +const addressesOptions = ref([]); +const selectedClient = ref(); const showTransferDialog = ref(false); const showTurnDialog = ref(false); const showChangeTimeDialog = ref(false); @@ -52,6 +57,31 @@ const weight = ref(); const hasDocuwareFile = ref(); const quasar = useQuasar(); const canRestoreTicket = ref(false); + +const onClientSelected = async(clientId) =>{ + client.value = clientId; + await fetchClient(); + await fetchAddresses(); +}; + +const onAddressSelected = (addressId) => { + address.value = addressId; +} + +const fetchClient = async () => { + const { data } = await getClient(client.value) + const [retrievedClient] = data; + selectedClient.value = retrievedClient; +}; + +const fetchAddresses = async () => { + const { data } = await getAddresses(client.value); + addressesOptions.value = data; + + const { defaultAddress } = selectedClient.value; + address.value = defaultAddress.id; +}; + const actions = { clone: async () => { const opts = { message: t('Ticket cloned'), type: 'positive' }; @@ -260,17 +290,14 @@ async function makeInvoice() { window.location.reload(); } -async function transferClient(client) { +async function transferClient() { const params = { - clientFk: client, + clientFk: client.value, + addressFk: address.value, }; - - const { data } = await axios.patch( - `Tickets/${ticketId.value}/transferClient`, - params - ); - - if (data) window.location.reload(); + + await axios.patch( `Tickets/${ticketId.value}/transferClient`, params ); + window.location.reload(); } async function addTurn(day) { @@ -446,7 +473,7 @@ async function ticketToRestore() { + + + @@ -762,7 +813,7 @@ async function ticketToRestore() { en: addTurn: Add turn invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}" - + es: Show Delivery Note...: Ver albarán... Send Delivery Note...: Enviar albarán... @@ -814,4 +865,5 @@ es: Are you sure you want to restore the ticket?: ¿Seguro que quieres restaurar el ticket? You are going to restore this ticket: Vas a restaurar este ticket Ticket restored: Ticket restaurado + Select a client to enable: Selecciona un cliente para habilitar diff --git a/src/pages/Ticket/TicketCreate.vue b/src/pages/Ticket/TicketCreate.vue index a369b1248..4c32448e4 100644 --- a/src/pages/Ticket/TicketCreate.vue +++ b/src/pages/Ticket/TicketCreate.vue @@ -9,9 +9,11 @@ import VnRow from 'components/ui/VnRow.vue'; import VnSelect from 'components/common/VnSelect.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; +import { getClient } from 'src/pages/Customer/composables/getClient'; +import { getAddresses } from 'src/pages/Customer/composables/getAddresses'; +import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies'; import { useState } from 'composables/useState'; -import axios from 'axios'; const { t } = useI18n(); const route = useRoute(); @@ -37,33 +39,13 @@ onBeforeMount(async () => { }); const fetchClient = async (formData) => { - const filter = { - include: { - relation: 'defaultAddress', - scope: { - fields: ['id', 'agencyModeFk'], - }, - }, - where: { id: formData.clientId }, - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get('Clients', { params }); + const { data } = await getClient(formData.clientId); const [client] = data; selectedClient.value = client; }; const fetchAddresses = async (formData) => { - if (!formData.clientId) return; - - const filter = { - fields: ['nickname', 'street', 'city', 'id'], - where: { isActive: true }, - order: 'nickname ASC', - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, { - params, - }); + const { data } = await getAddresses(formData.clientId); addressesOptions.value = data; const { defaultAddress } = selectedClient.value; @@ -76,15 +58,7 @@ const onClientSelected = async (formData) => { }; const fetchAvailableAgencies = async (formData) => { - if (!formData.warehouseId || !formData.addressId || !formData.landed) return; - let params = { - warehouseFk: formData.warehouseId, - addressFk: formData.addressId, - landed: formData.landed, - }; - - const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params }); - + const { data } = await getAgencies(formData); agenciesOptions.value = data; const defaultAgency = agenciesOptions.value.find( diff --git a/src/pages/Ticket/TicketCreateDialog.vue b/src/pages/Ticket/TicketCreateDialog.vue index 06565733e..c8b126d7d 100644 --- a/src/pages/Ticket/TicketCreateDialog.vue +++ b/src/pages/Ticket/TicketCreateDialog.vue @@ -9,9 +9,11 @@ import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnSelect from 'components/common/VnSelect.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; +import { getClient } from 'src/pages/Customer/composables/getClient'; +import { getAddresses } from 'src/pages/Customer/composables/getAddresses'; +import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies'; import { useState } from 'composables/useState'; -import axios from 'axios'; const { t } = useI18n(); const route = useRoute(); @@ -37,33 +39,13 @@ onBeforeMount(async () => { }); const fetchClient = async (formData) => { - const filter = { - include: { - relation: 'defaultAddress', - scope: { - fields: ['id', 'agencyModeFk'], - }, - }, - where: { id: formData.clientId }, - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get('Clients', { params }); + const { data } = await getClient(formData.clientId); const [client] = data; selectedClient.value = client; }; const fetchAddresses = async (formData) => { - if (!formData.clientId) return; - - const filter = { - fields: ['nickname', 'street', 'city', 'id'], - where: { isActive: true }, - order: 'nickname ASC', - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, { - params, - }); + const { data } = await getAddresses(formData.clientId); addressesOptions.value = data; const { defaultAddress } = selectedClient.value; @@ -76,15 +58,7 @@ const onClientSelected = async (formData) => { }; const fetchAvailableAgencies = async (formData) => { - if (!formData.warehouseId || !formData.addressId || !formData.landed) return; - let params = { - warehouseFk: formData.warehouseId, - addressFk: formData.addressId, - landed: formData.landed, - }; - - const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params }); - + const { data } = await getAgencies(formData); agenciesOptions.value = data; const defaultAgency = agenciesOptions.value.find( diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index 7c117beb4..8cf1184eb 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -22,6 +22,9 @@ import { toTimeFormat } from 'src/filters/date'; import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; import TicketProblems from 'src/components/TicketProblems.vue'; import VnSection from 'src/components/common/VnSection.vue'; +import { getClient } from 'src/pages/Customer/composables/getClient'; +import { getAddresses } from 'src/pages/Customer/composables/getAddresses'; +import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies'; const route = useRoute(); const router = useRouter(); @@ -237,15 +240,7 @@ const onClientSelected = async (formData) => { }; const fetchAvailableAgencies = async (formData) => { - if (!formData.warehouseId || !formData.addressId || !formData.landed) return; - let params = { - warehouseFk: formData.warehouseId, - addressFk: formData.addressId, - landed: formData.landed, - }; - - const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params }); - + const { data } = await getAgencies(formData); agenciesOptions.value = data; const defaultAgency = agenciesOptions.value.find( @@ -257,34 +252,13 @@ const fetchAvailableAgencies = async (formData) => { }; const fetchClient = async (formData) => { - const filter = { - include: { - relation: 'defaultAddress', - scope: { - fields: ['id', 'agencyModeFk'], - }, - }, - where: { id: formData.clientId }, - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get('Clients', { params }); + const { data } = await getClient(formData.clientId); const [client] = data; selectedClient.value = client; }; const fetchAddresses = async (formData) => { - if (!formData.clientId) return; - - const filter = { - fields: ['nickname', 'street', 'city', 'id', 'isActive'], - order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'], - }; - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, { - params, - }); - addressesOptions.value = data; - + const { data } = await getAddresses(formData.clientId); addressesOptions.value = data; const { defaultAddress } = selectedClient.value;