diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue index 55b2f5fee..ed34e9eee 100644 --- a/src/components/VnTable/VnColumn.vue +++ b/src/components/VnTable/VnColumn.vue @@ -151,7 +151,7 @@ const col = computed(() => { }; } if ( - (newColumn.name.startsWith('is') || newColumn.name.startsWith('has')) && + (/^is[A-Z]/.test(newColumn.name) || /^has[A-Z]/.test(newColumn.name)) && newColumn.component == null ) newColumn.component = 'checkbox'; diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index be39570ee..dca30516f 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -154,7 +154,7 @@ watch( const isTableMode = computed(() => mode.value == TABLE_MODE); -function setUserParams(watchedParams) { +function setUserParams(watchedParams, watchedOrder) { if (!watchedParams) return; if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams); @@ -163,7 +163,7 @@ function setUserParams(watchedParams) { ? JSON.parse(watchedParams?.filter) : watchedParams?.filter; const where = filter?.where; - const order = filter?.order; + const order = watchedOrder ?? filter?.order; watchedParams = { ...watchedParams, ...where }; delete watchedParams.filter; diff --git a/src/components/common/VnCurrency.vue b/src/components/common/VnCurrency.vue deleted file mode 100644 index b892e5012..000000000 --- a/src/components/common/VnCurrency.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -es: - amount: importe - diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 7debe5b1e..0e41e53aa 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -82,23 +82,26 @@ onMounted(() => { }); function setUserParams(watchedParams) { - if (!watchedParams) return; + if (!watchedParams || Object.keys(watchedParams).length == 0) return; if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams); + if (typeof watchedParams?.filter == 'string') + watchedParams.filter = JSON.parse(watchedParams.filter); + watchedParams = { ...watchedParams, ...watchedParams.filter?.where }; + const order = watchedParams.filter?.order; + delete watchedParams.filter; - userParams.value = { ...userParams.value, ...watchedParams }; - emit('setUserParams', userParams.value); + userParams.value = { ...userParams.value, ...sanitizer(watchedParams) }; + emit('setUserParams', userParams.value, order); } watch( - () => route.query[$props.searchUrl], - (val) => setUserParams(val) -); - -watch( - () => [store.userParams, store.userFilter], - ([userParams, userFilter]) => setUserParams({ ...userParams, filter: userFilter }) + () => [route.query[$props.searchUrl], arrayData.store.userParams], + ([newSearchUrl, newUserParams], [oldSearchUrl, oldUserParams]) => { + if (newSearchUrl || oldSearchUrl) setUserParams(newSearchUrl); + if (newUserParams || oldUserParams) setUserParams(newUserParams); + } ); watch( diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index d2cd83560..12680d0cb 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -262,6 +262,7 @@ globals: unsavedPopup: title: Unsaved changes will be lost subtitle: Are you sure exit without saving? + createInvoiceIn: Create invoice in errors: statusUnauthorized: Access denied statusInternalServerError: An internal server error has ocurred diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index b926bd50b..747a10d51 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -264,6 +264,8 @@ globals: unsavedPopup: title: Los cambios que no haya guardado se perderán subtitle: ¿Seguro que quiere salir sin guardar? + createInvoiceIn: Crear factura recibida + errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor diff --git a/src/pages/Customer/Payments/CustomerPaymentsFilter.vue b/src/pages/Customer/Payments/CustomerPaymentsFilter.vue index 1b79868c0..8982cba5a 100644 --- a/src/pages/Customer/Payments/CustomerPaymentsFilter.vue +++ b/src/pages/Customer/Payments/CustomerPaymentsFilter.vue @@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const props = defineProps({ @@ -47,7 +47,11 @@ const props = defineProps({ - + diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue index da24e50fa..cba2a31d2 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue @@ -130,8 +130,6 @@ onBeforeMount(async () => { }); onBeforeRouteUpdate(async (to, from) => { - invoiceInCorrection.correcting.length = 0; - invoiceInCorrection.corrected = null; if (to.params.id !== from.params.id) { await setInvoiceCorrection(to.params.id); const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`); @@ -140,6 +138,8 @@ onBeforeRouteUpdate(async (to, from) => { }); async function setInvoiceCorrection(id) { + invoiceInCorrection.correcting.length = 0; + invoiceInCorrection.corrected = null; const { data: correctingData } = await axios.get('InvoiceInCorrections', { params: { filter: { where: { correctingFk: id } } }, }); @@ -198,7 +198,6 @@ async function cloneInvoice() { const isAdministrative = () => hasAny(['administrative']); const isAgricultural = () => { - console.error(config); if (!config.value) return false; return ( invoiceIn.value?.supplier?.sageFarmerWithholdingFk === diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue index d2b43c57a..d88996929 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue @@ -8,9 +8,11 @@ import { useArrayData } from 'src/composables/useArrayData'; import CrudModel from 'src/components/CrudModel.vue'; import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; import { toCurrency } from 'src/filters'; import useNotify from 'src/composables/useNotify.js'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnInputDate from 'src/components/common/VnInputDate.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const route = useRoute(); const { notify } = useNotify(); @@ -22,9 +24,6 @@ const rowsSelected = ref([]); const banks = ref([]); const invoiceInFormRef = ref(); const invoiceId = +route.params.id; - -const placeholder = 'yyyy/mm/dd'; - const filter = { where: { invoiceInFk: invoiceId } }; const columns = computed(() => [ @@ -104,42 +103,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, > - - - - - - - - - - - - - - + @@ -164,7 +128,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, - rows.reduce((acc, { amount }) => acc + +amount, - rows.reduce((acc, { amount }) => acc + +amount, - - - - - - - - - - - - - - + /> rows.reduce((acc, { amount }) => acc + +amount, - - - + @@ -203,7 +200,7 @@ const formatOpt = (row, { model, options }, prop) => { ]" :key="index" > - toCurrency(row.amount, currency.value), sortable: true, align: 'left', - style: 'width: 10px', }, { name: 'net', @@ -415,6 +413,11 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; + + + {{ codeCell }} + + diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue index 63a84b855..4dac5058e 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue @@ -9,7 +9,8 @@ import { toCurrency } from 'src/filters'; import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import CrudModel from 'src/components/CrudModel.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const quasar = useQuasar(); @@ -205,7 +206,7 @@ const formatOpt = (row, { model, options }, prop) => { :grid="$q.screen.lt.sm" > - + { name="close" @click.stop="value = null" class="cursor-pointer" + size="xs" /> { - { - { - - + { /> - diff --git a/src/pages/InvoiceIn/InvoiceInCreate.vue b/src/pages/InvoiceIn/InvoiceInCreate.vue index 4dec9ac7d..e6863beb1 100644 --- a/src/pages/InvoiceIn/InvoiceInCreate.vue +++ b/src/pages/InvoiceIn/InvoiceInCreate.vue @@ -26,8 +26,7 @@ const newInvoiceIn = reactive({ companyFk: user.value.companyFk || null, issued: Date.vnNew(), }); -const suppliersOptions = ref([]); -const companiesOptions = ref([]); +const companies = ref([]); const redirectToInvoiceInBasicData = (__, { id }) => { router.push({ name: 'InvoiceInBasicData', params: { id } }); @@ -35,19 +34,12 @@ const redirectToInvoiceInBasicData = (__, { id }) => { - (suppliersOptions = data)" - auto-load - /> (companiesOptions = data)" + @on-fetch="(data) => (companies = data)" auto-load /> @@ -69,9 +61,10 @@ const redirectToInvoiceInBasicData = (__, { id }) => { { + + + + + - + + + + + + + + + + @@ -76,39 +105,20 @@ const activities = ref([]); - - - - - - - - - - - - - - - - - @@ -133,32 +143,16 @@ const activities = ref([]); - - - - - - - + diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue index 192d0ccc7..234cfb50f 100644 --- a/src/pages/InvoiceIn/InvoiceInList.vue +++ b/src/pages/InvoiceIn/InvoiceInList.vue @@ -1,18 +1,19 @@ +const tableRef = ref(); +const cols = computed(() => [ + { + align: 'left', + name: 'id', + label: 'Id', + }, + { + align: 'left', + name: 'supplierFk', + label: t('invoiceIn.list.supplier'), + columnFilter: { + component: 'select', + attrs: { + url: 'Suppliers', + fields: ['id', 'name'], + }, + }, + columnClass: 'expand', + }, + { + align: 'left', + name: 'supplierRef', + label: t('invoiceIn.list.supplierRef'), + }, + + { + align: 'left', + name: 'serialNumber', + label: t('invoiceIn.list.serialNumber'), + }, + { + align: 'left', + name: 'serial', + label: t('invoiceIn.list.serial'), + }, + { + align: 'left', + label: t('invoiceIn.list.issued'), + name: 'issued', + component: null, + columnFilter: { + component: 'date', + }, + format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.issued)), + }, + { + align: 'left', + name: 'isBooked', + label: t('invoiceIn.list.isBooked'), + columnFilter: false, + }, + { + align: 'left', + name: 'awbCode', + label: t('invoiceIn.list.awb'), + }, + { + align: 'left', + name: 'amount', + label: t('invoiceIn.list.amount'), + format: ({ amount }) => toCurrency(amount), + }, + { + align: 'right', + name: 'tableActions', + actions: [ + { + title: t('components.smartCard.openSummary'), + icon: 'preview', + type: 'submit', + action: (row) => viewSummary(row.id, InvoiceInSummary), + }, + { + title: t('globals.download'), + icon: 'download', + type: 'submit', + isPrimary: true, + action: (row) => downloadFile(row.dmsFk), + }, + ], + }, +]); + @@ -29,92 +113,63 @@ onUnmounted(() => (stateStore.rightDrawer = false)); - - - + + + {{ row.supplierName }} + + + + + - - - - - - - - {{ row.supplierName }} - - - - - - - - - - - - - - - - - - + + + + {{ scope.opt?.nickname }} + #{{ scope.opt?.id }} + + - - - - - - + + + + + + diff --git a/src/pages/InvoiceOut/InvoiceOutFilter.vue b/src/pages/InvoiceOut/InvoiceOutFilter.vue index 103e175ec..d0d42ea9b 100644 --- a/src/pages/InvoiceOut/InvoiceOutFilter.vue +++ b/src/pages/InvoiceOut/InvoiceOutFilter.vue @@ -6,7 +6,7 @@ import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const props = defineProps({ @@ -58,7 +58,7 @@ function setWorkers(data) { - - (stateStore.rightDrawer = false)); @click="openDmsUploadDialog" > - {{ t('Create invoiceIn') }} + {{ t('globals.createInvoiceIn') }} @@ -267,7 +267,6 @@ onUnmounted(() => (stateStore.rightDrawer = false)); es: Search autonomous: Buscar autónomos You can search by autonomous reference: Puedes buscar por referencia del autónomo - Create invoiceIn: Crear factura recibida Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo Date: Fecha Agency route: Agencia Ruta diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue index a31a3bc8d..6e60a336c 100644 --- a/src/pages/Supplier/Card/SupplierDescriptor.vue +++ b/src/pages/Supplier/Card/SupplierDescriptor.vue @@ -177,7 +177,7 @@ const getEntryQueryParams = (supplier) => { icon="vn:invoice-in-create" color="primary" > - {{ t('Create invoiceIn') }} + {{ t('globals.createInvoiceIn') }} @@ -188,7 +188,6 @@ const getEntryQueryParams = (supplier) => { es: All entries with current supplier: Todas las entradas con proveedor actual Go to client: Ir a cliente - Create invoiceIn: Crear factura recibida Go to module index: Ir al índice del módulo Inactive supplier: Proveedor inactivo Unverified supplier: Proveedor no verificado diff --git a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js index a297a60f4..f6dac4c73 100644 --- a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js @@ -1,8 +1,9 @@ /// describe('InvoiceInIntrastat', () => { - const inputBtns = 'label button'; + const firstRow = 'tbody > :nth-child(1)'; const thirdRow = 'tbody > :nth-child(3)'; - const firstLineCode = 'tbody > :nth-child(1) > :nth-child(2)'; + const firstRowCode = `${firstRow} > :nth-child(2)`; + const firstRowAmount = `${firstRow} > :nth-child(3)`; beforeEach(() => { cy.login('developer'); @@ -10,10 +11,10 @@ describe('InvoiceInIntrastat', () => { }); it('should edit the first line', () => { - cy.selectOption(firstLineCode, 'Plantas vivas: Esqueje/injerto, Vid'); - cy.get(inputBtns).eq(1).click(); + cy.selectOption(firstRowCode, 'Plantas vivas: Esqueje/injerto, Vid'); + cy.get(firstRowAmount).clear(); cy.saveCard(); - cy.get(`${firstLineCode} span`).should( + cy.get(`${firstRowCode} span`).should( 'have.text', '6021010:Plantas vivas: Esqueje/injerto, Vid' ); diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js index b2fa10d52..fa0d1c5e4 100644 --- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js @@ -1,23 +1,23 @@ /// describe('InvoiceInList', () => { - const firstCard = '.q-card:nth-child(1)'; - const firstChipId = - ':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content'; - const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)'; + const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)'; + const firstId = `${firstRow} > td:nth-child(1) span`; + const firstDetailBtn = `${firstRow} .q-btn:nth-child(1)`; const summaryHeaders = '.summaryBody .header-link'; beforeEach(() => { cy.viewport(1920, 1080); cy.login('developer'); cy.visit(`/#/invoice-in/list`); + cy.get('#searchbar input').type('{enter}'); }); it('should redirect on clicking a invoice', () => { - cy.get(firstChipId) + cy.get(firstId) .invoke('text') .then((content) => { const id = content.replace(/\D/g, ''); - cy.get(firstCard).click(); + cy.get(firstRow).click(); cy.url().should('include', `/invoice-in/${id}/summary`); }); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js index 932aca96d..018ae7a53 100644 --- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js @@ -4,8 +4,7 @@ describe('InvoiceInVat', () => { const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)'; const dialogInputs = '.q-dialog label input'; const dialogBtns = '.q-dialog button'; - const acrossInput = - ':nth-child(1) > .q-td.q-table--col-auto-width > .q-field > .q-field__inner > .q-field__control > :nth-child(2) > .default-icon'; + const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon'; const randomInt = Math.floor(Math.random() * 100); beforeEach(() => {