diff --git a/CHANGELOG.md b/CHANGELOG.md index e34523545..b72bc2c8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- (Worker) => Se crea la sección Taquilla +- (General) => Se mantiene el filtro lateral en cualquier parte de la seccíon. + ### Fixed - (General) => Se vuelven a mostrar los parámetros en la url al aplicar un filtro diff --git a/quasar.config.js b/quasar.config.js index dd7a91002..b59c62eeb 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -29,7 +29,7 @@ module.exports = configure(function (/* ctx */) { // app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli/boot-files - boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar.defaults'], + boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar', 'quasar.defaults'], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css css: ['app.scss'], diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue index 068646c9a..b2c5226e6 100644 --- a/src/components/CreateBankEntityForm.vue +++ b/src/components/CreateBankEntityForm.vue @@ -8,12 +8,7 @@ import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import FormModelPopup from './FormModelPopup.vue'; -const props = defineProps({ - showEntityField: { - type: Boolean, - default: true, - }, -}); +defineProps({ showEntityField: { type: Boolean, default: true } }); const emit = defineEmits(['onDataSaved']); const { t } = useI18n(); @@ -26,7 +21,7 @@ const bankEntityFormData = reactive({ }); const countriesFilter = { - fields: ['id', 'country', 'code'], + fields: ['id', 'name', 'code'], }; const countriesOptions = ref([]); @@ -79,7 +74,7 @@ onMounted(async () => { v-model="data.countryFk" :options="countriesOptions" option-value="id" - option-label="country" + option-label="name" hide-selected :required="true" :rules="validate('bankEntity.countryFk')" diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue index fd8570176..25a61a0ca 100644 --- a/src/components/CreateNewPostcodeForm.vue +++ b/src/components/CreateNewPostcodeForm.vue @@ -127,13 +127,14 @@ const onProvinceCreated = async ({ name }, formData) => { - - - + { async function fetch() { try { - const { data } = await axios.get($props.url, { + let { data } = await axios.get($props.url, { params: { filter: JSON.stringify($props.filter) }, }); + + if (Array.isArray(data)) data = data[0] ?? {}; + state.set($props.model, data); originalData.value = data && JSON.parse(JSON.stringify(data)); diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue index c5caf9778..25213a8b7 100644 --- a/src/components/FormModelPopup.vue +++ b/src/components/FormModelPopup.vue @@ -6,7 +6,7 @@ import FormModel from 'components/FormModel.vue'; const emit = defineEmits(['onDataSaved']); -const $props = defineProps({ +defineProps({ title: { type: String, default: '', diff --git a/src/components/FormPopup.vue b/src/components/FormPopup.vue index e203a7c75..2da986006 100644 --- a/src/components/FormPopup.vue +++ b/src/components/FormPopup.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'; const emit = defineEmits(['onSubmit']); -const $props = defineProps({ +defineProps({ title: { type: String, default: '', diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue index c2011639f..3ae05a268 100644 --- a/src/components/UserPanel.vue +++ b/src/components/UserPanel.vue @@ -178,6 +178,8 @@ function copyUserToken() { :options="warehousesData" option-label="name" option-value="id" + input-debounce="0" + hide-selected /> @@ -201,10 +205,11 @@ function copyUserToken() { @@ -224,6 +230,8 @@ function copyUserToken() { option-label="code" option-value="id" style="flex: 0" + dense + input-debounce="0" /> diff --git a/src/components/common/RightMenu.vue b/src/components/common/RightMenu.vue new file mode 100644 index 000000000..e288fbc87 --- /dev/null +++ b/src/components/common/RightMenu.vue @@ -0,0 +1,55 @@ + + + + + + + {{ t('globals.collapseMenu') }} + + + + + + + + + + + diff --git a/src/components/common/SendEmailDialog.vue b/src/components/common/SendEmailDialog.vue index 501c48a4d..d73133921 100644 --- a/src/components/common/SendEmailDialog.vue +++ b/src/components/common/SendEmailDialog.vue @@ -29,10 +29,12 @@ async function confirm() { const response = { address: address.value }; if (props.promise) { isLoading.value = true; - const { address: _address, ...restData } = props.data; try { - Object.assign(response, restData); + const dataCopy = JSON.parse(JSON.stringify({ ...props.data })); + delete dataCopy.address; + + Object.assign(response, dataCopy); await props.promise(response); } finally { isLoading.value = false; diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue index 6d0badffb..58cb12708 100644 --- a/src/components/common/VnCard.vue +++ b/src/components/common/VnCard.vue @@ -1,13 +1,13 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 684770e9c..8358cd6e6 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -37,14 +37,6 @@ const styleAttrs = computed(() => { : {}; }); -const onEnterPress = () => { - emit('keyup.enter'); -}; - -const handleValue = (val = null) => { - value.value = val; -}; - const focus = () => { vnInputRef.value.focus(); }; @@ -73,7 +65,7 @@ const inputRules = [ v-bind="{ ...$attrs, ...styleAttrs }" :type="$attrs.type" :class="{ required: $attrs.required }" - @keyup.enter="onEnterPress()" + @keyup.enter="emit('keyup.enter')" :clearable="false" :rules="inputRules" :lazy-rules="true" @@ -82,14 +74,14 @@ const inputRules = [ - + - + diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index e8083dec2..493f094ce 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -22,6 +22,10 @@ const $props = defineProps({ type: String, default: '', }, + optionFilter: { + type: String, + default: null, + }, url: { type: String, default: '', @@ -59,7 +63,7 @@ const $props = defineProps({ const { t } = useI18n(); const requiredFieldRule = (val) => val ?? t('globals.fieldRequired'); -const { optionLabel, optionValue, options, modelValue } = toRefs($props); +const { optionLabel, optionValue, optionFilter, options, modelValue } = toRefs($props); const myOptions = ref([]); const myOptionsOriginal = ref([]); const vnSelectRef = ref(); @@ -109,9 +113,9 @@ async function fetchFilter(val) { const { fields, sortBy, limit } = $props; let key = optionLabel.value; - if (new RegExp(/\d/g).test(val)) key = optionValue.value; + if (new RegExp(/\d/g).test(val)) key = optionFilter.value ?? optionValue.value; - const where = { [key]: { like: `%${val}%` } }; + const where = { ...{ [key]: { like: `%${val}%` } }, ...$props.where }; return dataRef.value.fetch({ fields, where, order: sortBy, limit }); } diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue index 1a4514ef5..57d1cb19a 100644 --- a/src/components/ui/CardSummary.vue +++ b/src/components/ui/CardSummary.vue @@ -54,6 +54,13 @@ async function fetch() { emit('onFetch', Array.isArray(data) ? data[0] : data); isLoading.value = false; } + +const showRedirectToSummaryIcon = computed(() => { + const routeExists = route.matched.some( + (route) => route.name === `${route.meta.moduleName}Summary` + ); + return !isSummary.value && route.meta.moduleName && routeExists; +}); @@ -64,7 +71,7 @@ async function fetch() { - diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue index c00849512..190393d2f 100644 --- a/src/components/ui/VnPaginate.vue +++ b/src/components/ui/VnPaginate.vue @@ -42,6 +42,10 @@ const props = defineProps({ type: Object, default: null, }, + keepOpts: { + type: Array, + default: () => [], + }, offset: { type: Number, default: 0, @@ -76,6 +80,7 @@ const arrayData = useArrayData(props.dataKey, { order: props.order, userParams: props.userParams, exprBuilder: props.exprBuilder, + keepOpts: props.keepOpts, }); const store = arrayData.store; diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index 344267ef7..38dcf97d1 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -1,11 +1,13 @@ @@ -120,7 +105,7 @@ async function search() { - {{ props.info }} + {{ t(props.info) }} diff --git a/src/components/ui/VnTree.vue b/src/components/ui/VnTree.vue index 13aa05635..928d045e9 100644 --- a/src/components/ui/VnTree.vue +++ b/src/components/ui/VnTree.vue @@ -90,7 +90,7 @@ const onNodeCreated = async () => { await fetchNodeLeaves(creationNodeSelectedId.value); }; -onMounted(async (n) => { +onMounted(async () => { const tree = [...state.get('Tree'), 1]; const lastStateTree = state.get('TreeState'); if (tree) { diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 525cf6e6b..e2465f5ba 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -47,7 +47,10 @@ export function useArrayData(key, userOptions) { if (isEmpty || !allowedOptions.includes(option)) continue; if (Object.prototype.hasOwnProperty.call(store, option)) { - store[option] = userOptions[option]; + const defaultOpts = userOptions[option]; + store[option] = userOptions.keepOpts?.includes(option) + ? Object.assign(defaultOpts, store[option]) + : defaultOpts; } } } @@ -127,7 +130,8 @@ export function useArrayData(key, userOptions) { store.filter = {}; if (params) store.userParams = Object.assign({}, params); - await fetch({ append: false }); + const response = await fetch({ append: false }); + return response; } async function addFilter({ filter, params }) { diff --git a/src/composables/useRedirect.js b/src/composables/useRedirect.js new file mode 100644 index 000000000..c1470718b --- /dev/null +++ b/src/composables/useRedirect.js @@ -0,0 +1,25 @@ +import { useRouter } from 'vue-router'; + +export default function useRedirect() { + const router = useRouter(); + + const navigate = (data, { customRouteRedirectName, searchText }) => { + if (customRouteRedirectName) + return router.push({ + name: customRouteRedirectName, + params: { id: searchText }, + }); + + const { matched: matches } = router.currentRoute.value; + const { path } = matches.at(-1); + + const to = + data.length === 1 + ? path.replace(/\/(list|:id)|-list/, `/${data[0].id}`) + : path.replace(/:id.*/, ''); + + router.push({ path: to }); + }; + + return { navigate }; +} diff --git a/src/composables/useState.js b/src/composables/useState.js index e671d41bd..9b9c9d642 100644 --- a/src/composables/useState.js +++ b/src/composables/useState.js @@ -20,28 +20,12 @@ const headerMounted = ref(false); export function useState() { function getUser() { return computed(() => { - return { - id: user.value.id, - name: user.value.name, - nickname: user.value.nickname, - lang: user.value.lang, - darkMode: user.value.darkMode, - companyFk: user.value.companyFk, - warehouseFk: user.value.warehouseFk, - }; + return user.value; }); } function setUser(data) { - user.value = { - id: data.id, - name: data.name, - nickname: data.nickname, - lang: data.lang, - darkMode: data.darkMode, - companyFk: data.companyFk, - warehouseFk: data.warehouseFk, - }; + user.value = data; } function getRoles() { diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index d8fb231f0..7d680c681 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -32,6 +32,7 @@ globals: confirm: Confirm assign: Assign back: Back + downloadPdf: Download PDF yes: 'Yes' no: 'No' noChanges: No changes to save @@ -271,6 +272,7 @@ customer: tableVisibleColumns: id: Identifier name: Name + socialName: Social name fi: Tax number salesPersonFk: Salesperson credit: Credit @@ -430,6 +432,7 @@ ticket: boxing: Boxing sms: Sms notes: Notes + sale: Sale list: nickname: Nickname state: State @@ -826,6 +829,7 @@ worker: log: Log calendar: Calendar timeControl: Time control + locker: Locker list: name: Name email: Email @@ -1234,12 +1238,10 @@ item/itemType: itemType: Item type basicData: Basic data summary: Summary -zone: +monitor: pageTitles: - zones: Zone - zonesList: Zones - deliveryList: Delivery days - upcomingList: Upcoming deliveries + monitors: Monitors + list: List components: topbar: {} itemsFilterPanel: diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 67e075935..d78e1762c 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -59,6 +59,7 @@ globals: amount: Importe packages: Bultos download: Descargar + downloadPdf: Descargar PDF selectRows: 'Seleccionar las { numberRows } filas(s)' allRows: 'Todo { numberRows } filas(s)' markAll: Marcar todo @@ -269,6 +270,7 @@ customer: tableVisibleColumns: id: Identificador name: Nombre + socialName: Razón social fi: NIF / CIF salesPersonFk: Comercial credit: Crédito @@ -428,6 +430,7 @@ ticket: boxing: Encajado sms: Sms notes: Notas + sale: Lineas del pedido list: nickname: Alias state: Estado @@ -824,6 +827,7 @@ worker: log: Historial calendar: Calendario timeControl: Control de horario + locker: Taquilla list: name: Nombre email: Email @@ -1239,6 +1243,10 @@ zone: zonesList: Zonas deliveryList: Días de entrega upcomingList: Próximos repartos +monitor: + pageTitles: + monitors: Monitores + list: Listado components: topbar: {} itemsFilterPanel: diff --git a/src/pages/Agency/Card/AgencyCard.vue b/src/pages/Agency/Card/AgencyCard.vue index e78d1cc55..6b2296df3 100644 --- a/src/pages/Agency/Card/AgencyCard.vue +++ b/src/pages/Agency/Card/AgencyCard.vue @@ -1,34 +1,14 @@ diff --git a/src/pages/Agency/Card/AgencyDescriptor.vue b/src/pages/Agency/Card/AgencyDescriptor.vue index 0fa89d07d..b9772037c 100644 --- a/src/pages/Agency/Card/AgencyDescriptor.vue +++ b/src/pages/Agency/Card/AgencyDescriptor.vue @@ -15,8 +15,8 @@ const props = defineProps({ }); const { t } = useI18n(); -const { params } = useRoute(); -const entityId = computed(() => props.id || params.id); +const route = useRoute(); +const entityId = computed(() => props.id || route.params.id); const { store } = useArrayData('Parking'); const card = computed(() => store.data); diff --git a/src/pages/Agency/Card/AgencySummary.vue b/src/pages/Agency/Card/AgencySummary.vue index a4a6a2a18..839d88200 100644 --- a/src/pages/Agency/Card/AgencySummary.vue +++ b/src/pages/Agency/Card/AgencySummary.vue @@ -3,26 +3,13 @@ import { computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import FetchData from 'src/components/FetchData.vue'; import CardSummary from 'components/ui/CardSummary.vue'; import VnLv from 'components/ui/VnLv.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -const $props = defineProps({ - id: { - type: Number, - default: 0, - }, -}); -const { params } = useRoute(); +const $props = defineProps({ id: { type: Number, default: 0 } }); const { t } = useI18n(); -const entityId = computed(() => $props.id || params.id); - -const filter = { - fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'], - include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }], -}; +const entityId = computed(() => $props.id || useRoute().params.id); diff --git a/src/pages/Claim/Card/ClaimAction.vue b/src/pages/Claim/Card/ClaimAction.vue index b0650b610..a24a2a15e 100644 --- a/src/pages/Claim/Card/ClaimAction.vue +++ b/src/pages/Claim/Card/ClaimAction.vue @@ -201,30 +201,7 @@ async function post(query, params) { auto-load @on-fetch="(data) => (destinationTypes = data)" /> - - - - - - {{ t('globals.collapseMenu') }} - - - - - - + {{ `${t('Total claimed')}: ${toCurrency(totalClaimed)}` }} @@ -274,7 +251,7 @@ async function post(query, params) { v-model="multiplicatorValue" /> - + import VnCard from 'components/common/VnCard.vue'; import ClaimDescriptor from './ClaimDescriptor.vue'; +import ClaimFilter from '../ClaimFilter.vue'; diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue index 6e0a08f2c..c3c5f5b7b 100644 --- a/src/pages/Claim/ClaimList.vue +++ b/src/pages/Claim/ClaimList.vue @@ -12,7 +12,6 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP import VnUserLink from 'src/components/ui/VnUserLink.vue'; import ClaimSummary from './Card/ClaimSummary.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; -import { getUrl } from 'src/composables/getUrl'; const stateStore = useStateStore(); const router = useRouter(); diff --git a/src/pages/Customer/Card/CustomerAddress.vue b/src/pages/Customer/Card/CustomerAddress.vue index cd5ef1483..6c8279d84 100644 --- a/src/pages/Customer/Card/CustomerAddress.vue +++ b/src/pages/Customer/Card/CustomerAddress.vue @@ -202,9 +202,9 @@ const toCustomerAddressEdit = (addressId) => { {{ observation.observationType.description }}: diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue index 2c1d6eccc..0886383de 100644 --- a/src/pages/Customer/Card/CustomerBalance.vue +++ b/src/pages/Customer/Card/CustomerBalance.vue @@ -11,6 +11,7 @@ import { useState } from 'src/composables/useState'; import { useStateStore } from 'stores/useStateStore'; import { useValidator } from 'src/composables/useValidator'; import { usePrintService } from 'src/composables/usePrintService'; +import { useSession } from 'src/composables/useSession'; import VnPaginate from 'src/components/ui/VnPaginate.vue'; import FetchData from 'components/FetchData.vue'; @@ -19,6 +20,9 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; +const session = useSession(); + +const tokenMultimedia = session.getTokenMultimedia(); const { sendEmail } = usePrintService(); const { t } = useI18n(); @@ -188,6 +192,11 @@ const saveFieldValue = async (row) => { const sendEmailAction = () => { sendEmail(`Suppliers/${route.params.id}/campaign-metrics-email`); }; + +const showBalancePdf = (balance) => { + const url = `api/InvoiceOuts/${balance.id}/download?access_token=${tokenMultimedia}`; + window.open(url, '_blank'); +}; @@ -257,17 +266,28 @@ const sendEmailAction = () => { {{ t('Send compensation') }} + + + {{ t('globals.downloadPdf') }} + + diff --git a/src/pages/Customer/Card/CustomerCard.vue b/src/pages/Customer/Card/CustomerCard.vue index 872bd7da7..98842a0c7 100644 --- a/src/pages/Customer/Card/CustomerCard.vue +++ b/src/pages/Customer/Card/CustomerCard.vue @@ -1,14 +1,16 @@ diff --git a/src/pages/Customer/Card/CustomerCreditContracts.vue b/src/pages/Customer/Card/CustomerCreditContracts.vue index 1729ac076..568adcf0b 100644 --- a/src/pages/Customer/Card/CustomerCreditContracts.vue +++ b/src/pages/Customer/Card/CustomerCreditContracts.vue @@ -105,7 +105,7 @@ const updateData = () => { color="primary" name="lock" size="md" - style="font-variation-settings: 'FILL' 1" + class="fill-icon" > {{ t('Close contract') }} diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue index 50fbec25d..deaaefc50 100644 --- a/src/pages/Customer/Card/CustomerFiscalData.vue +++ b/src/pages/Customer/Card/CustomerFiscalData.vue @@ -102,22 +102,24 @@ function handleLocation(data, location) { - + - + - - - - {{ t('whenActivatingIt') }} - - + + + + + {{ t('whenActivatingIt') }} + + + - + - - - - - {{ t('inOrderToInvoice') }} - - + + + + + + {{ t('inOrderToInvoice') }} + + + - + import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - +import { useRoute } from 'vue-router'; import { QBtn } from 'quasar'; - +import { useStateStore } from 'src/stores/useStateStore'; import { toCurrency } from 'src/filters'; import { toDateTimeFormat } from 'src/filters/date'; - import FetchData from 'components/FetchData.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; const { t } = useI18n(); const route = useRoute(); -const router = useRouter(); - +const stateStore = computed(() => useStateStore()); const rows = ref([]); const totalAmount = ref(0); @@ -105,28 +102,40 @@ const columns = computed(() => [ const setRows = (data) => { rows.value = data; - totalAmount.value = data.reduce((accumulator, currentValue) => { - return accumulator + currentValue.amount; - }, 0); -}; - -const toCustomerGreugeCreate = () => { - router.push({ name: 'CustomerGreugeCreate' }); + totalAmount.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0); }; - + + + + + + {{ t('globals.collapseMenu') }} + + + + + + + + + {{ t('Total') }}: + {{ toCurrency(totalAmount) }} + + + + - - - {{ t('Total') }}: - {{ toCurrency(totalAmount) }} - - - { - + {{ t('New greuge') }} diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index f447c5256..9e534235c 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -11,7 +11,6 @@ import useNotify from 'src/composables/useNotify'; import { useStateStore } from 'stores/useStateStore'; import FetchData from 'components/FetchData.vue'; -import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; diff --git a/src/pages/Customer/Card/CustomerWebPayment.vue b/src/pages/Customer/Card/CustomerWebPayment.vue index b1c45aa6c..13ec6b128 100644 --- a/src/pages/Customer/Card/CustomerWebPayment.vue +++ b/src/pages/Customer/Card/CustomerWebPayment.vue @@ -7,7 +7,6 @@ import axios from 'axios'; import { toCurrency, toDateHourMinSec } from 'src/filters'; -import FetchData from 'components/FetchData.vue'; import CustomerCloseIconTooltip from '../components/CustomerCloseIconTooltip.vue'; import CustomerCheckIconTooltip from '../components/CustomerCheckIconTooltip.vue'; diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue index 5816eb1ec..c1e537c0a 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue @@ -3,10 +3,10 @@ import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { QBtn, QCheckbox, useQuasar } from 'quasar'; +import { useStateStore } from 'stores/useStateStore'; -import { toCurrency, toDate } from 'filters/index'; - -import FetchData from 'components/FetchData.vue'; +import { toCurrency, toDate, dateRange } from 'filters/index'; +import VnPaginate from 'src/components/ui/VnPaginate.vue'; import CustomerNotificationsFilter from './CustomerDefaulterFilter.vue'; import CustomerBalanceDueTotal from './CustomerBalanceDueTotal.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -14,13 +14,14 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue'; +const stateStore = useStateStore(); -const { t } = useI18n(); +const { t, locale } = useI18n(); const quasar = useQuasar(); +const dataRef = ref(null); const balanceDueTotal = ref(0); const selected = ref([]); -const rows = ref([]); const tableColumnComponents = { client: { @@ -167,39 +168,61 @@ const columns = computed(() => [ }, ]); -const setRows = (data) => { - rows.value = data; - balanceDueTotal.value = data.reduce((accumulator, currentValue) => { - return accumulator + (currentValue['amount'] || 0); - }, 0); -}; - const viewAddObservation = (rowsSelected) => { quasar.dialog({ component: CustomerDefaulterAddObservation, componentProps: { clients: rowsSelected, - promise: refreshData, + promise: async () => await dataRef.value.fetch(), }, }); }; -const refreshData = () => { - setRows(); +const onFetch = (data) => { + for (const element of data) element.isWorker = element.businessTypeFk === 'worker'; + + balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0); }; -const onFetch = (data) => { - for (const element of data) { - element.isWorker = element.businessTypeFk === 'worker'; +function exprBuilder(param, value) { + switch (param) { + case 'clientFk': + return { [`d.${param}`]: value?.id }; + case 'creditInsurance': + case 'amount': + case 'workerFk': + case 'countryFk': + case 'payMethod': + case 'salesPersonFk': + return { [`d.${param}`]: value }; + case 'date': + return { 'd.created': { between: dateRange(value) } }; + case 'defaulterSinced': + return { 'd.defaulterSinced': { between: dateRange(value) } }; } - rows.value = data; -}; +} - + + + + + + {{ t('globals.collapseMenu') }} + + + + + - + @@ -214,69 +237,107 @@ const onFetch = (data) => { icon="vn:notes" :disabled="!selected.length" @click.stop="viewAddObservation(selected)" - /> + > + {{ t('Add observation') }} + - - - - - - - - {{ t(col.label) }} - {{ col.tooltip }} - - - + + + + + + + + + + {{ t(col.label) }} + {{ + col.tooltip + }} + + + - - - - - - - - - {{ props.value }} - + + + + + + + + + {{ props.value }} + - - - - - - + + + + + + + + + - + @@ -289,6 +350,7 @@ const onFetch = (data) => { es: + Add observation: Añadir observación Client: Cliente Is worker: Es trabajador Salesperson: Comercial diff --git a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue index 9d173087b..26a6743d5 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue @@ -57,7 +57,7 @@ const authors = ref(); hide-selected map-options option-label="name" - option-value="clientTypeFk" + option-value="id" outlined rounded use-input @@ -162,7 +162,7 @@ const authors = ref(); - { allColumnNames.value = filteredColumns.map((col) => col.name); }); -const rows = computed(() => arrayData.value.store.data); - const selectedCustomerId = ref(0); const selectedSalesPersonId = ref(0); const allColumnNames = ref([]); @@ -70,6 +68,11 @@ const tableColumnComponents = { props: () => {}, event: () => {}, }, + socialName: { + component: 'span', + props: () => {}, + event: () => {}, + }, fi: { component: 'span', props: () => {}, @@ -283,6 +286,12 @@ const columns = computed(() => [ label: t('customer.extendedList.tableVisibleColumns.name'), name: 'name', }, + { + align: 'left', + field: 'socialName', + label: t('customer.extendedList.tableVisibleColumns.socialName'), + name: 'socialName', + }, { align: 'left', field: 'fi', @@ -485,6 +494,23 @@ const selectSalesPersonId = (id) => (selectedSalesPersonId.value = id); + + + + + + {{ t('globals.collapseMenu') }} + + + + (selectedSalesPersonId.value = id); - + (selectedSalesPersonId.value = id); - navigateToTravelId(row.id)" + - - - {{ value }} - - - - - + + navigateToTravelId(row.id)" > - - {{ props.row.id }} - - + + + {{ value }} + + + + + + + + + + + + + {{ props.row.id }} + + + + + + + + {{ props.row.salesPerson }} + + - + + + + + + + + + - - - - - {{ props.row.salesPerson }} - - - - - - - - - - - + diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue index 52ea4cc27..9ff6b2301 100644 --- a/src/pages/Customer/Notifications/CustomerNotifications.vue +++ b/src/pages/Customer/Notifications/CustomerNotifications.vue @@ -1,17 +1,16 @@ - (rows = data)" - auto-load - url="Clients" - /> + + + + + + {{ t('globals.collapseMenu') }} + + + + + - + - - - + + + + + - - - - - - {{ props.value }} - - - - + + + + + + + + + {{ props.value }} + + + + + + + - + @@ -140,4 +175,5 @@ es: Phone: Teléfono City: Población Email: Email + Campaign consumption: Consumo campaña diff --git a/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue new file mode 100644 index 000000000..6d8e00966 --- /dev/null +++ b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue @@ -0,0 +1,152 @@ + + + + (campaignsOptions = data)" + :filter="{ fields: ['id', 'code', 'dated'], order: 'code ASC', limit: 30 }" + auto-load + /> + (upcomingOptions = data)" + auto-load + /> + + + + {{ t('Campaign consumption') }} + + + + + + + + + + + + + + {{ t('Campaign consumption') }} + + + + + en: + params: + valentinesDay: Valentine's Day + mothersDay: Mother's Day + allSaints: All Saints' Day + es: + params: + valentinesDay: Día de San Valentín + mothersDay: Día de la Madre + allSaints: Día de Todos los Santos + Campaign consumption: Consumo campaña + Campaign: Campaña + From: Desde + To: Hasta + diff --git a/src/pages/Customer/Payments/CustomerPayments.vue b/src/pages/Customer/Payments/CustomerPayments.vue index 623d610ef..e53da84a3 100644 --- a/src/pages/Customer/Payments/CustomerPayments.vue +++ b/src/pages/Customer/Payments/CustomerPayments.vue @@ -110,13 +110,7 @@ function stateColor(row) { - + diff --git a/src/pages/Customer/components/CustomerAddressCreate.vue b/src/pages/Customer/components/CustomerAddressCreate.vue index d92377f54..57997fb01 100644 --- a/src/pages/Customer/components/CustomerAddressCreate.vue +++ b/src/pages/Customer/components/CustomerAddressCreate.vue @@ -11,7 +11,6 @@ import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelectDialog from 'src/components/common/VnSelectDialog.vue'; -import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue'; const { t } = useI18n(); diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue index 734924993..2d14b571e 100644 --- a/src/pages/Customer/components/CustomerAddressEdit.vue +++ b/src/pages/Customer/components/CustomerAddressEdit.vue @@ -11,7 +11,6 @@ import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelectDialog from 'src/components/common/VnSelectDialog.vue'; -import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import CustomsNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue'; const { t } = useI18n(); diff --git a/src/pages/Customer/components/CustomerNewCustomsAgent.vue b/src/pages/Customer/components/CustomerNewCustomsAgent.vue index b6aa7a173..3c95dcae6 100644 --- a/src/pages/Customer/components/CustomerNewCustomsAgent.vue +++ b/src/pages/Customer/components/CustomerNewCustomsAgent.vue @@ -1,5 +1,4 @@ diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue index 1f9aaea28..766587bde 100644 --- a/src/pages/Entry/Card/EntrySummary.vue +++ b/src/pages/Entry/Card/EntrySummary.vue @@ -6,7 +6,6 @@ import { useI18n } from 'vue-i18n'; import CardSummary from 'components/ui/CardSummary.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue'; -import VnTitle from 'src/components/common/VnTitle.vue'; import { toDate, toCurrency } from 'src/filters'; import { getUrl } from 'src/composables/getUrl'; diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue index c3e83c96f..da4190a04 100644 --- a/src/pages/Entry/EntryLatestBuys.vue +++ b/src/pages/Entry/EntryLatestBuys.vue @@ -12,6 +12,7 @@ import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import EntryLatestBuysFilter from './EntryLatestBuysFilter.vue'; import ItemDescriptorProxy from '../Item/Card/ItemDescriptorProxy.vue'; +import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDate, toCurrency } from 'src/filters'; @@ -636,18 +637,18 @@ onUnmounted(() => (stateStore.rightDrawer = false)); auto-load @on-fetch="(data) => (intrastatOptions = data)" /> - - + + - + - + diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue index bdba33500..a963f1792 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue @@ -3,14 +3,13 @@ import { ref, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; +import axios from 'axios'; import { useArrayData } from 'src/composables/useArrayData'; import { downloadFile } from 'src/composables/downloadFile'; - import FormModel from 'components/FormModel.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import FetchData from 'src/components/FetchData.vue'; - -import axios from 'axios'; +import VnRow from 'src/components/ui/VnRow.vue'; const quasar = useQuasar(); const route = useRoute(); @@ -181,7 +180,7 @@ async function upsert() { :auto-load="true" > - + - - + + - - + + - - + + - - + + - - - - + + diff --git a/src/pages/InvoiceIn/Card/InvoiceInCard.vue b/src/pages/InvoiceIn/Card/InvoiceInCard.vue index ceec5042d..912713f23 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInCard.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInCard.vue @@ -1,6 +1,7 @@ diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue index c77502af5..a969c2c4b 100644 --- a/src/pages/InvoiceOut/InvoiceOutList.vue +++ b/src/pages/InvoiceOut/InvoiceOutList.vue @@ -139,7 +139,7 @@ const openCreateInvoiceModal = () => { icon="cloud_download" :disable="selectedCards.size === 0" > - {{ t('downloadPdf') }} + {{ t('globals.downloadPdf') }} diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue index 4eca6137c..66d46f576 100644 --- a/src/pages/Item/Card/ItemCard.vue +++ b/src/pages/Item/Card/ItemCard.vue @@ -1,7 +1,17 @@ - + diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 2a753a3a5..e74f7f828 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -309,9 +309,9 @@ const addRow = () => { const lastItemCopy = JSON.parse( JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1]) ); - const { id, ...restOfItem } = lastItemCopy; - fixedPricesOriginalData.value.push(restOfItem); - fixedPrices.value.push(restOfItem); + delete lastItemCopy.id; + fixedPricesOriginalData.value.push(lastItemCopy); + fixedPrices.value.push(lastItemCopy); }; const openEditTableCellDialog = () => { diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 39e190147..27acf3fdd 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -457,6 +457,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); :limit="12" :expr-builder="exprBuilder" :user-params="params" + :keep-opts="['userParams']" :offset="50" auto-load > diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 9d826655f..dd023f94b 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -7,8 +7,7 @@ import VnLv from 'src/components/ui/VnLv.vue'; import CardList from 'src/components/ui/CardList.vue'; import ItemTypeSummary from 'src/pages/ItemType/Card/ItemTypeSummary.vue'; import ItemTypeFilter from 'src/pages/ItemType/ItemTypeFilter.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; - +import ItemTypeSearchbar from '../ItemType/ItemTypeSearchbar.vue'; import { useStateStore } from 'stores/useStateStore'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; @@ -63,13 +62,7 @@ const exprBuilder = (param, value) => { - + @@ -132,11 +125,3 @@ const exprBuilder = (param, value) => { - - -es: - New item type: Nueva familia - Name: Nombre - Search item type: Buscar familia - Search itemType by id, name or code: Buscar familia por id, nombre o código - diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index c08c71f48..99dbeb9fd 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -78,3 +78,6 @@ itemTags: tag: Tag value: Value relevancy: Relevancy +searchbar: + label: Search item + info: Search by item id diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index 9b6a51b8a..60e589932 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -78,3 +78,6 @@ itemTags: tag: Etiqueta value: Valor relevancy: Relevancia +searchbar: + label: Buscar artículo + info: Buscar por id de artículo diff --git a/src/pages/ItemType/Card/ItemTypeCard.vue b/src/pages/ItemType/Card/ItemTypeCard.vue index cb8adf7f6..9daec7921 100644 --- a/src/pages/ItemType/Card/ItemTypeCard.vue +++ b/src/pages/ItemType/Card/ItemTypeCard.vue @@ -1,12 +1,20 @@ + :filter-panel="ItemTypeFilter" + search-data-key="ItemTypeList" + search-url="ItemTypes" + > + + + + diff --git a/src/pages/ItemType/ItemTypeSearchbar.vue b/src/pages/ItemType/ItemTypeSearchbar.vue new file mode 100644 index 000000000..749033d43 --- /dev/null +++ b/src/pages/ItemType/ItemTypeSearchbar.vue @@ -0,0 +1,19 @@ + + + + + + +es: + Search item type: Buscar familia + Search itemType by id, name or code: Buscar familia por id, nombre o código + diff --git a/src/pages/Monitor/MonitorList.vue b/src/pages/Monitor/MonitorList.vue new file mode 100644 index 000000000..1b1ccb5b3 --- /dev/null +++ b/src/pages/Monitor/MonitorList.vue @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + {{ t('salesMonitor.clientsOnWebsite') }} + + + {{ t('salesMonitor.recentOrderActions') }} + + + + + + + + {{ t('salesMonitor.clientsOnWebsite') }} + + + + + + {{ t('salesMonitor.recentOrderActions') }} + + + + + + + + + + + {{ t('salesMonitor.ticketsMonitor') }} + + + + + + + + + diff --git a/src/pages/Monitor/MonitorMain.vue b/src/pages/Monitor/MonitorMain.vue new file mode 100644 index 000000000..c1f2a31db --- /dev/null +++ b/src/pages/Monitor/MonitorMain.vue @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/src/pages/Monitor/SalesClientsTable.vue b/src/pages/Monitor/SalesClientsTable.vue new file mode 100644 index 000000000..3f2389471 --- /dev/null +++ b/src/pages/Monitor/SalesClientsTable.vue @@ -0,0 +1,219 @@ + + + + (workersActiveOptions = data)" + /> + (clientsOptions = data)" + /> + + + + + + + + + + + + + + + + + + {{ row.salesPerson }} + + + + + + {{ row.clientName }} + + + + + + + + diff --git a/src/pages/Monitor/SalesOrdersTable.vue b/src/pages/Monitor/SalesOrdersTable.vue new file mode 100644 index 000000000..0ba900393 --- /dev/null +++ b/src/pages/Monitor/SalesOrdersTable.vue @@ -0,0 +1,201 @@ + + + + (workersActiveOptions = data)" + /> + (clientsOptions = data)" + /> + + + + + redirectToOrderSummary(row.id)" + > + + + {{ t('salesOrdersTable.delete') }} + + + + + + {{ toDateFormat(row.date_send) }} + + {{ toDateTimeFormat(row.date_make) }} + + + + + + {{ row.clientName }} + + + {{ row.agencyName }} + + + + + + {{ row.salesPerson }} + + + {{ toCurrency(row.import) }} + + + + + + + + diff --git a/src/pages/Monitor/SalesTicketsTable.vue b/src/pages/Monitor/SalesTicketsTable.vue new file mode 100644 index 000000000..222ccb9d0 --- /dev/null +++ b/src/pages/Monitor/SalesTicketsTable.vue @@ -0,0 +1,623 @@ + + + + (workersActiveOptions = data)" + /> + (provincesOptions = data)" + /> + (statesOptions = data)" + /> + (zonesOptions = data)" + /> + + + redirectToTicketSummary(row.id)" + > + + + + + + + + + + + + + + + {{ + t('salesTicketsTable.noVerifiedData') + }} + + + {{ + t('salesTicketsTable.purchaseRequest') + }} + + + {{ t('salesTicketsTable.notVisible') }} + + + {{ t('salesTicketsTable.clientFrozen') }} + + + {{ t('salesTicketsTable.risk') }}: + {{ row.risk }} + + + {{ + t('salesTicketsTable.componentLack') + }} + + + {{ t('salesTicketsTable.tooLittle') }} + + + + + + {{ row.id }} + + + + + + {{ row.nickname }} + + + + + + {{ row.userName }} + + + + + + + {{ formatShippedDate(row.shippedDate) }} + + + + + + + {{ row.refFk }} + + + + {{ row.state }} + + + + + + + {{ t('salesTicketsTable.isFragile') }} + + + + + + {{ row.zoneName }} + + + + + + + {{ toCurrency(row.totalWithVat) }} + + + + + + + {{ t('salesTicketsTable.goToLines') }} + + + {{ t('salesTicketsTable.preview') }} + + + + + + + diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml new file mode 100644 index 000000000..f58db7854 --- /dev/null +++ b/src/pages/Monitor/locale/en.yml @@ -0,0 +1,45 @@ +salesMonitor: + clientsOnWebsite: Clients on website + recentOrderActions: Recent order actions + ticketsMonitor: Tickets monitor +salesClientsTable: + from: From + to: To + date: Date + hour: Hour + salesPerson: Salesperson + client: Client +salesOrdersTable: + delete: Delete + date: Date + client: Client + salesPerson: Salesperson + deleteConfirmTitle: Delete selected elements + deleteConfirmMessage: All the selected elements will be deleted. Are you sure you want to continue? +salesTicketsTable: + autoRefresh: Auto-refresh + problems: Problems + noVerifiedData: No verified data + notVisible: Not visible + purchaseRequest: Purchase request + clientFrozen: Client frozen + risk: Risk + componentLack: Component lack + tooLittle: Ticket too little + identifier: Identifier + client: Client + salesPerson: Salesperson + date: Date + theoretical: Theoretical + practical: Practical + province: Province + state: State + isFragile: Is fragile + zone: Zone + goToLines: Go to lines + preview: Preview + total: Total + preparation: Preparation +searchBar: + label: Search tickets + info: Search tickets by id or alias diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml new file mode 100644 index 000000000..918b51813 --- /dev/null +++ b/src/pages/Monitor/locale/es.yml @@ -0,0 +1,45 @@ +salesMonitor: + clientsOnWebsite: Clientes activos en la web + recentOrderActions: Acciones recientes en pedidos + ticketsMonitor: Monitor de tickets +salesClientsTable: + from: Desde + to: Hasta + date: Fecha + hour: Hora + salesPerson: Comercial + client: Cliente +salesOrdersTable: + delete: Eliminar + date: Fecha + client: Cliente + salesPerson: Comercial + deleteConfirmTitle: Eliminar los elementos seleccionados + deleteConfirmMessage: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar? +salesTicketsTable: + autoRefresh: Auto-refresco + problems: Problemas + noVerifiedData: Sin datos comprobados + notVisible: No visible + purchaseRequest: Petición de compra + clientFrozen: Cliente congelado + risk: Riesgo + componentLack: Faltan componentes + tooLittle: Ticket demasiado pequeño + identifier: Identificador + client: Cliente + salesPerson: Comercial + date: Fecha + theoretical: Teórica + practical: Práctica + province: Provincia + state: Estado + isFragile: Es frágil + zone: Zona + goToLines: Ir a líneas + preview: Vista previa + total: Total + preparation: Preparación +searchBar: + label: Buscar tickets + info: Buscar tickets por identificador o alias diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue index ef7b30d86..5b6896656 100644 --- a/src/pages/Order/Card/OrderCard.vue +++ b/src/pages/Order/Card/OrderCard.vue @@ -1,7 +1,19 @@ - + + + + + diff --git a/src/pages/Order/Card/OrderForm.vue b/src/pages/Order/Card/OrderForm.vue index 08ed074e5..378073897 100644 --- a/src/pages/Order/Card/OrderForm.vue +++ b/src/pages/Order/Card/OrderForm.vue @@ -1,6 +1,6 @@ - - - - @@ -158,11 +151,7 @@ const detailsColumns = ref([ {{ t('order.summary.details') }} - + {{ t('order.summary.item') }} diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue index 203eaccd1..6d36d8b31 100644 --- a/src/pages/Order/OrderList.vue +++ b/src/pages/Order/OrderList.vue @@ -61,6 +61,7 @@ function navigate(id) { :limit="20" :order="['landed DESC', 'clientFk', 'id DESC']" :user-params="{ showEmpty: false }" + :keep-opts="['userParams']" auto-load > diff --git a/src/pages/Parking/Card/ParkingBasicData.vue b/src/pages/Parking/Card/ParkingBasicData.vue index c1a9dcee8..8e3433a5b 100644 --- a/src/pages/Parking/Card/ParkingBasicData.vue +++ b/src/pages/Parking/Card/ParkingBasicData.vue @@ -1,5 +1,5 @@ - + + + + + diff --git a/src/pages/Route/Card/RouteSearchbar.vue b/src/pages/Route/Card/RouteSearchbar.vue index e3833d13c..924280580 100644 --- a/src/pages/Route/Card/RouteSearchbar.vue +++ b/src/pages/Route/Card/RouteSearchbar.vue @@ -1,6 +1,6 @@ diff --git a/src/pages/Route/Card/RouteSummary.vue b/src/pages/Route/Card/RouteSummary.vue index 220f93f30..ac03a8231 100644 --- a/src/pages/Route/Card/RouteSummary.vue +++ b/src/pages/Route/Card/RouteSummary.vue @@ -10,7 +10,6 @@ import { dashIfEmpty, toCurrency, toDate, toHour } from 'src/filters'; import WorkerDescriptorProxy from 'pages/Worker/Card/WorkerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue'; -import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue'; import { openBuscaman } from 'src/utils/buscaman'; const $props = defineProps({ @@ -118,11 +117,6 @@ const ticketColumns = ref([ - - - - - import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; +import { useRouter } from 'vue-router'; import VnRow from 'components/ui/VnRow.vue'; import FormModel from 'components/FormModel.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; @@ -9,7 +9,6 @@ import VnInput from 'components/common/VnInput.vue'; import VnInputTime from 'components/common/VnInputTime.vue'; const { t } = useI18n(); -const route = useRoute(); const router = useRouter(); const defaultInitialData = { etd: Date.vnNew().toISOString(), @@ -31,11 +30,7 @@ const onSave = (data, response) => { > - + diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue index 1fed6aa78..9aa8f40d7 100644 --- a/src/pages/Route/Roadmap/RoadmapSummary.vue +++ b/src/pages/Route/Roadmap/RoadmapSummary.vue @@ -72,7 +72,12 @@ const openAddStopDialog = () => { - + diff --git a/src/pages/Route/RouteAutonomous.vue b/src/pages/Route/RouteAutonomous.vue index 0ecf0a971..238dce070 100644 --- a/src/pages/Route/RouteAutonomous.vue +++ b/src/pages/Route/RouteAutonomous.vue @@ -280,7 +280,7 @@ function navigateToRouteSummary(event, row) { { { { @@ -295,7 +295,7 @@ const openSmsDialog = async () => { @@ -425,10 +425,6 @@ const openSmsDialog = async () => { .table-actions { gap: 12px; } - -.filled-icon { - font-variation-settings: 'FILL' 1; -} es: diff --git a/src/pages/Shelving/Card/ShelvingCard.vue b/src/pages/Shelving/Card/ShelvingCard.vue index f4a2fcf60..a501a7a99 100644 --- a/src/pages/Shelving/Card/ShelvingCard.vue +++ b/src/pages/Shelving/Card/ShelvingCard.vue @@ -1,7 +1,19 @@ - + + + + + diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue index 649799b00..168552832 100644 --- a/src/pages/Shelving/Card/ShelvingSummary.vue +++ b/src/pages/Shelving/Card/ShelvingSummary.vue @@ -1,11 +1,9 @@ diff --git a/src/pages/Supplier/Card/SupplierConsumption.vue b/src/pages/Supplier/Card/SupplierConsumption.vue index 8dbb87529..4eac24469 100644 --- a/src/pages/Supplier/Card/SupplierConsumption.vue +++ b/src/pages/Supplier/Card/SupplierConsumption.vue @@ -1,6 +1,6 @@ diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue new file mode 100644 index 000000000..02cccaff2 --- /dev/null +++ b/src/pages/Ticket/Card/TicketSale.vue @@ -0,0 +1 @@ +Ticket sale diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index af501240b..f55669619 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -13,6 +13,7 @@ import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import { getUrl } from 'src/composables/getUrl'; import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; +import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; const route = useRoute(); const router = useRouter(); @@ -262,9 +263,12 @@ async function changeState(value) { :url="ticketUrl + 'sale'" :text="t('ticket.summary.saleLines')" /> - + + + {{ value }} + - + {{ t('ticket.summary.item') }} {{ t('ticket.summary.visible') }} @@ -360,23 +364,29 @@ async function changeState(value) { - {{ props.row.itemFk }} + + + {{ props.row.itemFk }} + + + {{ props.row.visible }} {{ props.row.available }} {{ props.row.quantity }} - - - {{ props.row.item.name }} - {{ - props.row.item.subName - }} + + + {{ props.row.item.name }} + + {{ props.row.item.subName.toUpperCase() }} + - + > - {{ props.row.price }} + {{ props.row.price }} € {{ props.row.discount }} % {{ @@ -453,4 +463,28 @@ async function changeState(value) { padding: 1%; } } +.q-table { + tr, + th, + .q-td { + border-bottom: 1px solid black; + } +} + +.subName { + margin-left: 10%; +} + +.tr-header, +.subName { + color: var(--vn-label-color); +} + +.description-cell { + width: 25%; +} + +.fetched-tags { + max-width: 70%; +} diff --git a/src/pages/Travel/TravelFilter.vue b/src/pages/Travel/TravelFilter.vue index 43e0db3eb..77f7ec112 100644 --- a/src/pages/Travel/TravelFilter.vue +++ b/src/pages/Travel/TravelFilter.vue @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; -import VnInput from 'src/components/common/VnInput.vue'; import FetchData from 'components/FetchData.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; diff --git a/src/pages/Wagon/Type/WagonTypeList.vue b/src/pages/Wagon/Type/WagonTypeList.vue index 23f56e4c3..3ecca1ea3 100644 --- a/src/pages/Wagon/Type/WagonTypeList.vue +++ b/src/pages/Wagon/Type/WagonTypeList.vue @@ -6,7 +6,6 @@ import { useArrayData } from 'src/composables/useArrayData'; import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; import CardList from 'components/ui/CardList.vue'; -import VnLv from 'components/ui/VnLv.vue'; const quasar = useQuasar(); const arrayData = useArrayData('WagonTypeList'); diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue index 4f1786a67..d1c27beda 100644 --- a/src/pages/Worker/Card/WorkerBasicData.vue +++ b/src/pages/Worker/Card/WorkerBasicData.vue @@ -35,8 +35,8 @@ const workersFilter = { limit: 30, }; const countriesFilter = { - fields: ['id', 'country', 'code'], - order: 'country ASC', + fields: ['id', 'name', 'code'], + order: 'name ASC', limit: 30, }; const educationLevelsFilter = { fields: ['id', 'name'], order: 'name ASC', limit: 30 }; @@ -124,7 +124,7 @@ const maritalStatus = [ :label="t('Origin country')" :options="countriesOptions" hide-selected - option-label="country" + option-label="name" option-value="id" v-model="data.originCountryFk" /> diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue index d76ef6f59..fb9ab9666 100644 --- a/src/pages/Worker/Card/WorkerCard.vue +++ b/src/pages/Worker/Card/WorkerCard.vue @@ -1,14 +1,16 @@ diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue new file mode 100644 index 000000000..171074b20 --- /dev/null +++ b/src/pages/Worker/Card/WorkerLocker.vue @@ -0,0 +1,64 @@ + + + (lockers = data)" + /> + + + + + + diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue index 85259c043..9d962e450 100644 --- a/src/pages/Worker/WorkerCreate.vue +++ b/src/pages/Worker/WorkerCreate.vue @@ -9,7 +9,6 @@ import VnInputDate from 'components/common/VnInputDate.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelectDialog from 'src/components/common/VnSelectDialog.vue'; import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue'; -import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import VnLocation from 'src/components/common/VnLocation.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; @@ -57,7 +56,7 @@ const onBankEntityCreated = (data) => { }; function handleLocation(data, location) { - const { town, postcode: code, provinceFk, countryFk } = location ?? {}; + const { town, code, provinceFk, countryFk } = location ?? {}; data.postcode = code; data.city = town; data.provinceFk = provinceFk; diff --git a/src/pages/Worker/locale/es.yml b/src/pages/Worker/locale/es.yml index 86dd9d0d9..a960dffe6 100644 --- a/src/pages/Worker/locale/es.yml +++ b/src/pages/Worker/locale/es.yml @@ -1,2 +1,3 @@ Search worker: Buscar trabajador You can search by worker id or name: Puedes buscar por id o nombre del trabajador +Locker: Taquilla diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue index 5d57b920e..7a2c505fa 100644 --- a/src/pages/Zone/Card/ZoneBasicData.vue +++ b/src/pages/Zone/Card/ZoneBasicData.vue @@ -1,34 +1,24 @@ @@ -36,58 +26,90 @@ const agencyFilter = { :filter="agencyFilter" @on-fetch="(data) => (agencyOptions = data)" auto-load - url="agencies" - /> - (zoneOptions = data)" - auto-load - url="zones" + url="AgencyModes/isActive" /> - - + + - + - - - + + + - - - - - - + - + + + + + + - + es: Name: Nombre diff --git a/src/pages/Zone/Card/ZoneCard.vue b/src/pages/Zone/Card/ZoneCard.vue index 948636c55..9d6895f36 100644 --- a/src/pages/Zone/Card/ZoneCard.vue +++ b/src/pages/Zone/Card/ZoneCard.vue @@ -1,6 +1,15 @@ - + diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue index 93e951801..b3a55bbe0 100644 --- a/src/pages/Zone/Card/ZoneDescriptor.vue +++ b/src/pages/Zone/Card/ZoneDescriptor.vue @@ -6,8 +6,10 @@ import { useI18n } from 'vue-i18n'; import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import { toTimeFormat } from 'src/filters/date'; +import { toCurrency } from 'filters/index'; import useCardDescription from 'src/composables/useCardDescription'; +import ZoneDescriptorMenuItems from './ZoneDescriptorMenuItems.vue'; const $props = defineProps({ id: { @@ -58,7 +60,7 @@ const setData = (entity) => { flat dense size="md" - icon="preview" + icon="vn:zone" color="white" class="link" :to="{ name: 'ZoneList' }" @@ -68,29 +70,15 @@ const setData = (entity) => { - + - {{ console.log('entity', entity) }} - - - - - + + + + + - - -es: - Summary: Detalles - The zone will be deleted: El envío será eliminado - Do you want to delete this zone?: ¿Quieres eliminar este envío? - All zones with current agency: Todos los envíos con la agencia actual - Agency: Agencia - Closing hour: Hora de cierre - zoneing days: Días de viaje - Price: Precio - Bonus: Bonificación - diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue index 00df03cb0..d46282c10 100644 --- a/src/pages/Zone/Card/ZoneSummary.vue +++ b/src/pages/Zone/Card/ZoneSummary.vue @@ -2,14 +2,16 @@ import { ref, onMounted, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import { dashIfEmpty } from 'src/filters'; -import { getUrl } from 'src/composables/getUrl'; + import VnLv from 'src/components/ui/VnLv.vue'; -import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import CardSummary from 'components/ui/CardSummary.vue'; -import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; +import { getUrl } from 'src/composables/getUrl'; +import { toCurrency } from 'filters/index'; +import { toTimeFormat } from 'src/filters/date'; +import axios from 'axios'; + const route = useRoute(); const { t } = useI18n(); @@ -23,71 +25,84 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const zoneUrl = ref(); -onMounted(async () => { - zoneUrl.value = (await getUrl('')) + `zone/${entityId.value}/`; +const filter = computed(() => { + const filter = { + include: { + relation: 'agencyMode', + fields: ['name'], + }, + where: { + id: entityId, + }, + }; + return filter; }); -const filter = computed(() => { - return { where: { id: entityId.value } }; +const columns = computed(() => [ + { + label: t('summary.name'), + name: 'name', + field: 'warehouse', + align: 'left', + format: (val) => val.name, + }, +]); +const warehouses = ref([]); + +const getWarehouses = async () => { + const params = { + filter: { + include: { + relation: 'warehouse', + fields: ['name'], + }, + }, + }; + + const { data } = await axios.get(`Zones/${entityId.value}/warehouses`, { params }); + warehouses.value = data; +}; + +onMounted(async () => { + zoneUrl.value = (await getUrl('')) + `zone/${entityId.value}/`; + await getWarehouses(); }); - {{ entity.id }} - {{ entity.firstName }} {{ entity.lastName }} + #{{ entity.id }} - {{ entity.name }} - - - - - - - - - - - - {{ t('zone.summary.phoneExtension') }} - - - - - - {{ t('zone.summary.entPhone') }} - - - - + + + + - - - - - - - {{ t('zone.summary.sipExtension') }} - - - + + + + + + + + diff --git a/src/pages/Zone/Delivery/ZoneDeliveryList.vue b/src/pages/Zone/Delivery/ZoneDeliveryList.vue index 695388a9b..ca87dbd84 100644 --- a/src/pages/Zone/Delivery/ZoneDeliveryList.vue +++ b/src/pages/Zone/Delivery/ZoneDeliveryList.vue @@ -63,7 +63,7 @@ async function remove(row) { outline /> +import { useI18n } from 'vue-i18n'; +import { useRouter } from 'vue-router'; +import { computed } from 'vue'; +import { toCurrency } from 'src/filters'; + +import ZoneSummary from 'src/pages/Zone/Card/ZoneSummary.vue'; + +import { useSummaryDialog } from 'src/composables/useSummaryDialog'; +import { toTimeFormat } from 'filters/date.js'; + +const { t } = useI18n(); +const router = useRouter(); +const { viewSummary } = useSummaryDialog(); + +defineProps({ + rows: { + type: Array, + required: true, + default: () => [], + }, +}); + +const columns = computed(() => [ + { + label: t('zoneClosingTable.id'), + name: 'id', + field: 'id', + sortable: true, + align: 'left', + }, + { + label: t('zoneClosingTable.name'), + name: 'name', + field: 'name', + sortable: true, + align: 'left', + }, + { + label: t('zoneClosingTable.agency'), + name: 'agency', + field: 'agencyModeName', + sortable: true, + align: 'left', + }, + { + label: t('zoneClosingTable.closing'), + name: 'close', + field: 'hour', + sortable: true, + align: 'left', + format: (val) => toTimeFormat(val), + }, + { + label: t('zoneClosingTable.price'), + name: 'price', + field: 'price', + sortable: true, + align: 'left', + format: (val) => toCurrency(val), + }, + { + name: 'actions', + align: 'left', + }, +]); + +const redirectToZoneSummary = (id) => { + router.push({ name: 'ZoneSummary', params: { id } }); +}; + + + + + + {{ t('zoneClosingTable.zones') }} + + redirectToZoneSummary(row.id)" + style="max-height: 400px" + > + + + + + {{ t('zoneClosingTable.preview') }} + + + + + + + + + diff --git a/src/pages/Zone/ZoneCreate.vue b/src/pages/Zone/ZoneCreate.vue index 93ea9589b..e25ccae3a 100644 --- a/src/pages/Zone/ZoneCreate.vue +++ b/src/pages/Zone/ZoneCreate.vue @@ -1,184 +1,114 @@ - - - - - - - - - - - - - - - - - - - - - - - - {{ t('zone.warnings.noData') }} - - - - - - - - - - - - + (warehousesOptions = data)" + auto-load + /> + (agencyOptions = data)" + auto-load + /> + + + + + + + + + + + + + + + + + + + + + + + + + - - diff --git a/src/pages/Zone/ZoneDeliveryCalendar.vue b/src/pages/Zone/ZoneDeliveryCalendar.vue new file mode 100644 index 000000000..96a62086e --- /dev/null +++ b/src/pages/Zone/ZoneDeliveryCalendar.vue @@ -0,0 +1,192 @@ + + + + + + {{ + calendarHeaderTitle + }} + + + + + + + + + + + + + + + + + diff --git a/src/pages/Zone/ZoneDeliveryDays.vue b/src/pages/Zone/ZoneDeliveryDays.vue index 485500dba..d6ce70f6d 100644 --- a/src/pages/Zone/ZoneDeliveryDays.vue +++ b/src/pages/Zone/ZoneDeliveryDays.vue @@ -1 +1,257 @@ -Zone Delivery days + + + + + + + + + {{ t('globals.collapseMenu') }} + + + + + + + + + + + + + + + {{ headerTitle }} + + + + + + + + + + diff --git a/src/pages/Zone/ZoneDeliveryPanel.vue b/src/pages/Zone/ZoneDeliveryPanel.vue new file mode 100644 index 000000000..c754d484f --- /dev/null +++ b/src/pages/Zone/ZoneDeliveryPanel.vue @@ -0,0 +1,149 @@ + + + + + + + + + + + + {{ opt.code }} + {{ opt.town?.province?.name }}, + {{ opt.town?.province?.country?.country }} + + + + + + + + + diff --git a/src/pages/Zone/ZoneFilterPanel.vue b/src/pages/Zone/ZoneFilterPanel.vue index 94765919d..c84355eb0 100644 --- a/src/pages/Zone/ZoneFilterPanel.vue +++ b/src/pages/Zone/ZoneFilterPanel.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'; import VnInput from 'components/common/VnInput.vue'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; -import VnSelectFilter from 'components/common/VnSelectFilter.vue'; +import VnSelect from 'components/common/VnSelect.vue'; const { t } = useI18n(); const props = defineProps({ @@ -17,37 +17,47 @@ const props = defineProps({ default: null, }, }); + const agencies = ref([]); - (agencies = data)" - auto-load - /> - - + (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 f260eb134..5a7d07d71 100644 --- a/src/pages/Zone/ZoneList.vue +++ b/src/pages/Zone/ZoneList.vue @@ -1,111 +1,212 @@ - (agencyOptions = data)" - :filter="{ fields: ['id', 'name'] }" - auto-load - /> + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + {{ t(col.label) }} + {{ + col.tooltip + }} + + + + + + + + {{ props.value }} + + + + + + + {{ t('globals.clone') }} + + + {{ t('Preview') }} + + + + + - - {{ t('zone.list.create') }} + + {{ t('list.create') }} diff --git a/src/pages/Zone/locale/en.yml b/src/pages/Zone/locale/en.yml index e62111d57..cda2daca7 100644 --- a/src/pages/Zone/locale/en.yml +++ b/src/pages/Zone/locale/en.yml @@ -1,19 +1,58 @@ zone: - list: - volume: Volume - clone: Clone - id: Id - name: Name - agency: Agency - close: Close - price: Price - create: Create zone - openSummary: Details - create: - name: Name - agency: Agency - close: Close - price: Price - type: - submit: Save - reset: Reset + pageTitles: + zones: Zone + zonesList: Zones + zoneCreate: Create zone + deliveryDays: Delivery days + upcomingList: Upcoming deliveries +list: + clone: Clone + id: Id + name: Name + agency: Agency + close: Close + price: Price + create: Create zone + openSummary: Details + searchZone: Search zones + searchInfo: Search zone by id or name + confirmCloneTitle: All it's properties will be copied + confirmCloneSubtitle: Do you want to clone this zone? +create: + name: Name + warehouse: Warehouse + agency: Agency + travelingDays: Traveling days + closingHour: Closing hour + price: Price + bonus: Bonus + volumetric: Volumetric +summary: + agency: Agency + price: Price + basicData: Basic data + bonus: Bonus + closeHour: Close hour + travelingDays: Traveling days + volumetric: Volumetric + warehouse: Warehouse + name: Name +filterPanel: + name: Name + agencyModeFk: Agency +deliveryPanel: + pickup: Pick up + delivery: Delivery + postcode: Postcode + agency: Agency + warehouse: Warehouse + query: Query + noEventsWarning: No service for the specified zone +zoneClosingTable: + id: Id + name: Name + agency: Agency + closing: Closing + price: Price + preview: Preview + zones: Zones diff --git a/src/pages/Zone/locale/es.yml b/src/pages/Zone/locale/es.yml index 5d7a265bf..3b658ab02 100644 --- a/src/pages/Zone/locale/es.yml +++ b/src/pages/Zone/locale/es.yml @@ -1,19 +1,60 @@ zone: - list: - volume: Volumen - clone: Clonar - id: Id - name: Nombre - agency: Agencia - close: Cierre - price: Precio - create: Crear zona - openSummary: Detalles - create: - name: Nombre - agency: Agencia - close: Cierre - price: Precio - type: - submit: Guardar - reset: Reiniciar + pageTitles: + zones: Zonas + zonesList: Zonas + zoneCreate: Nueva zona + deliveryDays: Días de entrega + upcomingList: Próximos repartos +list: + clone: Clonar + id: Id + name: Nombre + agency: Agencia + close: Cierre + price: Precio + create: Crear zona + openSummary: Detalles + searchZone: Buscar zonas + searchInfo: Buscar zonas por identificador o nombre + confirmCloneTitle: Todas sus propiedades serán copiadas + confirmCloneSubtitle: ¿Seguro que quieres clonar esta zona? +create: + name: Nombre + warehouse: Almacén + agency: Agencia + travelingDays: Días de viaje + closingHour: Hora de cierre + price: Precio + bonus: Bonificación + volumetric: Volumétrico +summary: + agency: Agencia + price: Precio + basicData: Datos básicos + bonus: Bonificación + closeHour: Hora de cierre + travelingDays: Días de viaje + volumetric: Volumétrico + warehouse: Almacén + name: Nombre +filterPanel: + name: Nombre + agencyModeFk: Agencia +deliveryPanel: + pickup: Recogida + delivery: Entrega + postcode: Código postal + agency: Agencia + warehouse: Almacén + query: Consultar + noEventsWarning: No hay servicio para la zona especificada +zoneClosingTable: + id: Id + name: Nombre + agency: Agencia + closing: Cierre + preview: Vista previa + price: Precio + zones: Zonas +Search zones: Buscar zonas +You can search by zone reference: Puedes buscar por referencia de la zona diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js index 5ef5945f3..092d60639 100644 --- a/src/router/modules/customer.js +++ b/src/router/modules/customer.js @@ -87,7 +87,7 @@ export default { name: 'CustomerNotifications', meta: { title: 'notifications', - icon: 'notifications', + icon: 'campaign', }, component: () => import( @@ -99,7 +99,7 @@ export default { name: 'CustomerDefaulter', meta: { title: 'defaulter', - icon: 'vn:risk', + icon: 'vn:defaulter', }, component: () => import('src/pages/Customer/Defaulter/CustomerDefaulter.vue'), diff --git a/src/router/modules/index.js b/src/router/modules/index.js index 7fff2f2e5..38bcd54d5 100644 --- a/src/router/modules/index.js +++ b/src/router/modules/index.js @@ -18,6 +18,7 @@ import Parking from './parking'; import Agency from './agency'; import ItemType from './itemType'; import Zone from './zone'; +import Monitor from './monitor'; export default [ Item, @@ -40,4 +41,5 @@ export default [ Agency, ItemType, Zone, + Monitor, ]; diff --git a/src/router/modules/monitor.js b/src/router/modules/monitor.js new file mode 100644 index 000000000..6c388a474 --- /dev/null +++ b/src/router/modules/monitor.js @@ -0,0 +1,36 @@ +import { RouterView } from 'vue-router'; + +export default { + path: '/monitor', + name: 'Monitor', + meta: { + title: 'monitors', + icon: 'grid_view', + moduleName: 'Monitor', + }, + component: RouterView, + redirect: { name: 'MonitorMain' }, + menus: { + main: ['MonitorList'], + card: [], + }, + children: [ + { + path: '', + name: 'MonitorMain', + component: () => import('src/pages/Monitor/MonitorMain.vue'), + redirect: { name: 'MonitorList' }, + children: [ + { + path: 'list', + name: 'MonitorList', + meta: { + title: 'list', + icon: 'grid_view', + }, + component: () => import('src/pages/Monitor/MonitorList.vue'), + }, + ], + }, + ], +}; diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js index eb6c1b6d2..6cb7291dc 100644 --- a/src/router/modules/ticket.js +++ b/src/router/modules/ticket.js @@ -12,7 +12,7 @@ export default { redirect: { name: 'TicketMain' }, menus: { main: ['TicketList'], - card: ['TicketBoxing', 'TicketSms'], + card: ['TicketBoxing', 'TicketSms', 'TicketSale'], }, children: [ { @@ -66,6 +66,15 @@ export default { }, component: () => import('src/pages/Ticket/Card/TicketBasicData.vue'), }, + { + name: 'TicketSale', + path: 'sale', + meta: { + title: 'sale', + icon: 'vn:lines', + }, + component: () => import('src/pages/Ticket/Card/TicketSale.vue'), + }, { path: 'boxing', name: 'TicketBoxing', diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index d4d3bc3e7..384978d13 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -22,6 +22,7 @@ export default { 'WorkerCalendar', 'WorkerDms', 'WorkerTimeControl', + 'WorkerLocker', ], departmentCard: ['BasicData'], }, @@ -167,6 +168,15 @@ export default { component: () => import('src/pages/Worker/Card/WorkerTimeControl.vue'), }, + { + name: 'WorkerLocker', + path: 'locker', + meta: { + title: 'locker', + icon: 'lock', + }, + component: () => import('src/pages/Worker/Card/WorkerLocker.vue'), + }, ], }, ], diff --git a/src/router/modules/zone.js b/src/router/modules/zone.js index 079dfaa84..a7dd1dbb5 100644 --- a/src/router/modules/zone.js +++ b/src/router/modules/zone.js @@ -11,58 +11,63 @@ export default { component: RouterView, redirect: { name: 'ZoneMain' }, menus: { - main: [ - /*'ZoneList', 'ZoneDeliveryList', 'ZoneUpcomingList'*/ - ], - card: [ - // - ], + main: ['ZoneList', 'ZoneDeliveryDays', 'ZoneUpcomingList'], + card: ['ZoneBasicData', 'ZoneHistory', 'ZoneLocations'], }, children: [ - // { - // path: '/zone', - // name: 'ZoneMain', - // component: () => import('src/pages/Zone/ZoneMain.vue'), - // redirect: { name: 'ZoneList' }, - // children: [ - // { - // path: 'list', - // name: 'ZoneList', - // meta: { - // title: 'zonesList', - // icon: 'vn:zone', - // }, - // component: () => import('src/pages/Zone/ZoneList.vue'), - // }, - // { - // path: 'create', - // name: 'ZoneCreate', - // meta: { - // title: 'zoneCreate', - // icon: 'create', - // }, - // component: () => import('src/pages/Zone/ZoneCreate.vue'), - // }, - // { - // path: ':id/edit', - // name: 'ZoneEdit', - // meta: { - // title: 'zoneEdit', - // icon: 'edit', - // }, - // component: () => import('src/pages/Zone/ZoneCreate.vue'), - // }, - // { - // path: 'counter', - // name: 'ZoneCounter', - // meta: { - // title: 'zoneCounter', - // icon: 'add_circle', - // }, - // component: () => import('src/pages/Zone/ZoneCounter.vue'), - // }, - // ], - // }, + { + path: '/zone', + name: 'ZoneMain', + component: () => import('src/pages/Zone/ZoneMain.vue'), + redirect: { name: 'ZoneList' }, + children: [ + { + path: 'list', + name: 'ZoneList', + meta: { + title: 'zonesList', + icon: 'vn:zone', + }, + component: () => import('src/pages/Zone/ZoneList.vue'), + }, + { + path: 'delivery-days', + name: 'ZoneDeliveryDays', + meta: { + title: 'deliveryDays', + icon: 'vn:calendar', + }, + component: () => import('src/pages/Zone/ZoneDeliveryDays.vue'), + }, + { + path: 'create', + name: 'ZoneCreate', + meta: { + title: 'zoneCreate', + icon: 'create', + }, + component: () => import('src/pages/Zone/ZoneCreate.vue'), + }, + { + path: ':id/edit', + name: 'ZoneEdit', + meta: { + title: 'zoneEdit', + icon: 'edit', + }, + component: () => import('src/pages/Zone/ZoneCreate.vue'), + }, + // { + // path: 'counter', + // name: 'ZoneCounter', + // meta: { + // title: 'zoneCounter', + // icon: 'add_circle', + // }, + // component: () => import('src/pages/Zone/ZoneCounter.vue'), + // }, + ], + }, { name: 'ZoneCard', path: ':id', @@ -78,6 +83,34 @@ export default { }, component: () => import('src/pages/Zone/Card/ZoneSummary.vue'), }, + { + name: 'ZoneLocations', + path: 'location', + meta: { + title: 'locations', + icon: 'vn:greuge', + }, + component: () => import('src/pages/Zone/Card/ZoneLocations.vue'), + }, + { + name: 'ZoneBasicData', + path: 'basic-data', + meta: { + title: 'basicData', + icon: 'vn:settings', + }, + component: () => import('src/pages/Zone/Card/ZoneBasicData.vue'), + }, + { + name: 'ZoneHistory', + path: 'history', + meta: { + title: 'log', + icon: 'history', + }, + component: () => import('src/pages/Zone/Card/ZoneLog.vue'), + }, + // { // path: '/zone/delivery', // name: 'ZoneDeliveryMain', diff --git a/src/router/routes.js b/src/router/routes.js index 04780ee17..6a0430d51 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -18,6 +18,7 @@ import roadmap from 'src/router/modules/roadmap'; import parking from 'src/router/modules/parking'; import agency from 'src/router/modules/agency'; import zone from 'src/router/modules/zone'; +import monitor from 'src/router/modules/monitor'; const routes = [ { @@ -65,6 +66,7 @@ const routes = [ shelving, invoiceOut, invoiceIn, + monitor, wagon, order, route, diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js index ee1e04e9b..263a9dec8 100644 --- a/src/stores/useNavigationStore.js +++ b/src/stores/useNavigationStore.js @@ -15,6 +15,7 @@ export const useNavigationStore = defineStore('navigationStore', () => { 'travel', 'invoiceOut', 'invoiceIn', + 'monitor', 'supplier', 'claim', 'route', @@ -31,7 +32,6 @@ export const useNavigationStore = defineStore('navigationStore', () => { for (const module of modules) { const moduleDef = routes.find((route) => toLowerCamel(route.name) === module); if (!moduleDef) continue; - const item = addMenuItem(module, moduleDef, modulesRoutes.value); if (!item) continue; diff --git a/src/stores/useWeekdayStore.js b/src/stores/useWeekdayStore.js index a7b0496c6..ac17356ae 100644 --- a/src/stores/useWeekdayStore.js +++ b/src/stores/useWeekdayStore.js @@ -85,6 +85,27 @@ export const useWeekdayStore = defineStore('weekdayStore', () => { return locales; }); + /** + * Transforms weekday set into an array whose indexes are weekday index + * with selected days set to %true. + * + * @param {String} weekDays Weekday codes separated by commas + * @return {Array} Array with selected days set to %true + */ + const fromSet = (_weekDays) => { + let wdays = []; + + if (_weekDays) { + let codes = _weekDays.split(','); + for (let code of codes) { + let data = weekdaysMap[code]; + if (data) wdays[data.index] = true; + } + } + + return wdays; + }; + return { initStore, weekdaysMap, @@ -93,5 +114,6 @@ export const useWeekdayStore = defineStore('weekdayStore', () => { weekdays, monthCodes, getLocaleMonths, + fromSet, }; }); diff --git a/test/cypress/integration/VnLocation.spec.js b/test/cypress/integration/VnLocation.spec.js index f373bad8a..d1cddd0e7 100644 --- a/test/cypress/integration/VnLocation.spec.js +++ b/test/cypress/integration/VnLocation.spec.js @@ -1,13 +1,13 @@ const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-item'; describe('VnLocation', () => { const dialogInputs = '.q-dialog label input'; - describe('Create', () => { + describe('Worker Create', () => { const inputLocation = - '.q-form .q-card> :nth-child(3) > :nth-child(1) > .q-field > .q-field__inner > .q-field__control'; + '.q-form .q-card > :nth-child(3) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'; beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); - cy.visit('/#/worker/create'); + cy.visit('/#/worker/create', { timeout: 5000 }); cy.waitForElement('.q-card'); }); it('Show all options', function () { @@ -25,34 +25,35 @@ describe('VnLocation', () => { cy.get(inputLocation).clear(); cy.get(inputLocation).type('ecuador'); cy.get(locationOptions).should('have.length.at.least', 1); - cy.get(`${locationOptions}:nth-child(1)`).click(); - cy.get(inputLocation + '> :nth-child(2) > .q-icon').click(); + cy.get( + '.q-form .q-card > :nth-child(3) > .q-field > .q-field__inner > .q-field__control > :nth-child(3) > .q-icon' + ).click(); }); }); describe('Fiscal-data', () => { beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); - cy.visit('/#/supplier/567/fiscal-data', { timeout: 2000 }); - cy.waitForElement('.q-card'); + cy.visit('/#/supplier/567/fiscal-data', { timeout: 7000 }); + cy.waitForElement('.q-form'); }); it('Create postCode', function () { cy.get( - ':nth-child(6) > :nth-child(1) > .q-field > .q-field__inner > .q-field__control > :nth-child(3) > .q-icon' + ':nth-child(6) > .q-field > .q-field__inner > .q-field__control > :nth-child(3) > .q-icon' ).click(); cy.get('.q-card > h1').should('have.text', 'New postcode'); cy.get(dialogInputs).eq(0).clear('12'); cy.get(dialogInputs).eq(0).type('1234453'); cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(4) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control ', + '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(4) > .q-select > .q-field__inner > .q-field__control ', 'Valencia' ); cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(5) > :nth-child(1) > .q-field > .q-field__inner > .q-field__control ', + '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(5) > .q-select > .q-field__inner > .q-field__control ', 'Province one' ); cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(5) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control ', + '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(6) > .q-select > .q-field__inner > .q-field__control ', 'España' ); cy.get('.q-mt-lg > .q-btn--standard').click(); diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js index fc989d6c5..963dda3e2 100644 --- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js @@ -1,7 +1,8 @@ /// describe('InvoiceInBasicData', () => { - const selects = '.q-form .q-card>:nth-child(1) > :nth-child(1) > .q-field'; - const appendBtns = 'label button'; + const formInputs = '.q-form > .q-card input'; + const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select'; + const appendBtns = '.q-form label button'; const dialogAppendBtns = '.q-dialog label button'; const dialogInputs = '.q-dialog input'; const dialogActionBtns = '.q-card__actions button'; @@ -12,15 +13,14 @@ describe('InvoiceInBasicData', () => { }); it('should edit the provideer and supplier ref', () => { - cy.selectOption(selects, 'Bros'); - + cy.selectOption(firstFormSelect, 'Bros'); cy.get('[title="Reset"]').click(); cy.get(appendBtns).eq(0).click(); - cy.get('input').eq(2).type(4739); + cy.get(formInputs).eq(1).type(4739); cy.saveCard(); - cy.get(`${selects} input`).eq(0).invoke('val').should('eq', 'Plants nick'); - cy.get('input').eq(2).invoke('val').should('eq', '4739'); + cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Plants nick'); + cy.get(formInputs).eq(1).invoke('val').should('eq', '4739'); }); it('should edit the dms data', () => { diff --git a/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js b/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js index f39c80809..124b60c34 100644 --- a/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInDueDay.spec.js @@ -1,6 +1,6 @@ /// describe('InvoiceInDueDay', () => { - const inputs = 'label input'; + const amountInput = 'tbody > tr:nth-child(1) td:nth-child(4)'; const addBtn = '.q-page-sticky > div > .q-btn > .q-btn__content'; beforeEach(() => { @@ -9,7 +9,7 @@ describe('InvoiceInDueDay', () => { }); it('should update the amount', () => { - cy.get(inputs).eq(3).type(23); + cy.get(amountInput).type('{selectall}{backspace}23'); cy.saveCard(); cy.get('.q-notification__message').should('have.text', 'Data saved'); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js index 306c0b8c0..c87fd4315 100644 --- a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js @@ -17,10 +17,7 @@ describe('InvoiceInIntrastat', () => { cy.saveCard(); cy.visit(`/#/invoice-in/1/intrastat`); - cy.getValue(firstLineCode).should( - 'equal', - 'Plantas vivas: Esqueje/injerto, Vid' - ); + cy.getValue(firstLineCode).should('equal', 'Plantas vivas: Esqueje/injerto, Vid'); }); it('should add a new row', () => { @@ -33,6 +30,6 @@ describe('InvoiceInIntrastat', () => { }); it('should remove the first line', () => { - cy.removeRow(1); + cy.removeRow(2); }); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js index ff891399b..389be671c 100644 --- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js @@ -29,7 +29,7 @@ describe('InvoiceInVat', () => { }); it('should remove the first line', () => { - cy.removeRow(1); + cy.removeRow(2); }); it('should throw an error if there are fields undefined', () => { diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js index 22401f0b4..fc920f346 100644 --- a/test/cypress/integration/ticket/ticketDescriptor.spec.js +++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js @@ -1,6 +1,6 @@ /// describe('Ticket descriptor', () => { - const toCloneOpt = '.q-list > :nth-child(5)'; + const toCloneOpt = '[role="menu"] .q-list > :nth-child(5)'; const warehouseValue = ':nth-child(1) > :nth-child(6) > .value > span'; const summaryHeader = '.summaryHeader > div'; diff --git a/test/cypress/integration/worker/workerLocker.spec.js b/test/cypress/integration/worker/workerLocker.spec.js new file mode 100644 index 000000000..01e74760b --- /dev/null +++ b/test/cypress/integration/worker/workerLocker.spec.js @@ -0,0 +1,19 @@ +describe('WorkerList', () => { + const workerId = 1109; + const lockerCode = '201A'; + const input = '.q-card input'; + const firstOpt = '[role="listbox"] .q-item:nth-child(1)'; + beforeEach(() => { + cy.viewport(1280, 720); + cy.login('productionBoss'); + cy.visit(`/#/worker/${workerId}/locker`); + }); + + it('should allocates a locker', () => { + cy.get(input).click(); + cy.get(input).type(lockerCode); + cy.get(firstOpt).click(); + cy.saveCard(); + cy.get(input).invoke('val').should('eq', lockerCode); + }); +}); diff --git a/test/vitest/__tests__/components/common/VnSearchBar.spec.js b/test/vitest/__tests__/components/common/VnSearchBar.spec.js deleted file mode 100644 index 0938ae9c0..000000000 --- a/test/vitest/__tests__/components/common/VnSearchBar.spec.js +++ /dev/null @@ -1,62 +0,0 @@ -import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; -import { createWrapper } from 'app/test/vitest/helper'; -import VnSearchbar from 'components/ui/VnSearchbar.vue'; -// Probar a importar como plugin vue-router en archivo helper -describe('VnSearchBar', () => { - let vm; - let wrapper; - let pushSpy; - - beforeAll(() => { - wrapper = createWrapper(VnSearchbar, { - propsData: { - dataKey: 'CustomerList', - label: 'Search customer', - info: 'Info customer', - }, - }); - vm = wrapper.vm; - vm.router.currentRoute.value.matched = [ - { - path: '/', - }, - { - path: '/customer', - }, - { - path: '/customer/:id', - }, - { - path: '/customer/:id/basic-data', - }, - ]; - - pushSpy = vi.spyOn(vm.router, 'push'); - vi.spyOn(vm.arrayData, 'applyFilter'); - }); - - beforeEach(() => (vm.store.data = [{ id: 1112, name: 'Trash' }])); - afterEach(() => vi.clearAllMocks()); - - it('should be defined', async () => { - expect(vm.searchText).toBeDefined(); - expect(vm.searchText).toEqual(''); - }); - - it('should redirect to list page if there are several results', async () => { - vm.store.data.push({ id: 1, name: 'employee' }); - await vm.search(); - expect(pushSpy).toHaveBeenCalledWith({ path: '/customer/list' }); - }); - - it('should redirect to list page if there is no results', async () => { - vm.store.data.pop(); - await vm.search(); - expect(pushSpy).toHaveBeenCalledWith({ path: '/customer/list' }); - }); - - it('should redirect to basic-data page if there is only one result', async () => { - await vm.search(); - expect(pushSpy).toHaveBeenCalledWith({ path: '/customer/1112/basic-data' }); - }); -}); diff --git a/test/vitest/__tests__/composables/useRedirect.spec.js b/test/vitest/__tests__/composables/useRedirect.spec.js new file mode 100644 index 000000000..ce56189b9 --- /dev/null +++ b/test/vitest/__tests__/composables/useRedirect.spec.js @@ -0,0 +1,52 @@ +import { vi, describe, expect, it, beforeEach, beforeAll } from 'vitest'; +import useRedirect from 'src/composables/useRedirect'; +import { useRouter } from 'vue-router'; + +vi.mock('vue-router'); + +describe('useRedirect', () => { + useRouter.mockReturnValue({ + push: vi.fn(), + currentRoute: { + value: { + matched: [ + { path: '/' }, + { path: '/customer' }, + { path: '/customer/:id' }, + { path: '/customer/:id/basic-data' }, + ], + }, + }, + }); + const data = []; + let navigate; + let spy; + + beforeAll(() => { + const { navigate: navigateFn } = useRedirect(); + navigate = navigateFn; + spy = useRouter().push; + }); + + beforeEach(() => { + data.length = 0; + spy.mockReset(); + }); + + it('should redirect to list page if there are several results', async () => { + data.push({ id: 1, name: 'employee' }, { id: 2, name: 'boss' }); + navigate(data, {}); + expect(spy).toHaveBeenCalledWith({ path: '/customer/' }); + }); + + it('should redirect to list page if there is no results', async () => { + navigate(data, {}); + expect(spy).toHaveBeenCalledWith({ path: '/customer/' }); + }); + + it('should redirect to basic-data page if there is only one result', async () => { + data.push({ id: 1, name: 'employee' }); + navigate(data, {}); + expect(spy).toHaveBeenCalledWith({ path: '/customer/1/basic-data' }); + }); +});
{{ t('order.summary.details') }}