fix: refs #6900 fine tunning #661

Merged
jorgep merged 13 commits from 6900-hotfix-fineTunning into master 2024-09-04 13:58:59 +00:00
4 changed files with 73 additions and 120 deletions
Showing only changes of commit b42385d7d6 - Show all commits

View File

@ -0,0 +1,52 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FormModelPopup from './FormModelPopup.vue';
const emit = defineEmits(['onDataSaved']);
const { t } = useI18n();
jorgep marked this conversation as resolved
Review

porque no usas $t directamente en el template?

porque no usas $t directamente en el template?
Review

Si son traducciones locales(declaradas dentro del mismo componente), no funciona.

Si son traducciones locales(declaradas dentro del mismo componente), no funciona.
Review

Okey, te lo compro pero las traducciones de code y description están definidas como global
Por tanto, eliminar del componente

Okey, te lo compro pero las traducciones de code y description están definidas como global Por tanto, eliminar del componente
</script>
<template>
<FormModelPopup
url-create="Expenses"
model="Expense"
:title="t('New expense')"
:form-initial-data="{ id: null, isWithheld: false, name: null }"
@on-data-saved="emit('onDataSaved', $event)"
>
<template #form-inputs="{ data, validate }">
<VnRow>
<VnInput
:label="`${t('Code')}`"
jorgep marked this conversation as resolved Outdated

global.code

global.code
v-model="data.id"
:required="true"
:rules="validate('expense.code')"
/>
<QCheckbox
dense
size="sm"
:label="`${t('It\'s a withholding')}`"
v-model="data.isWithheld"
:rules="validate('expense.isWithheld')"
/>
</VnRow>
<VnRow>
<VnInput
:label="`${t('Description')}`"
jorgep marked this conversation as resolved Outdated

globals.description

globals.description
v-model="data.name"
:required="true"
:rules="validate('expense.description')"
/>
</VnRow>
</template>
</FormModelPopup>
</template>
<i18n>
es:
New expense: Nuevo gasto
Code: Código
It's a withholding: Es una retención
Description: Descripción
</i18n>

View File

@ -2,19 +2,17 @@
import { ref, computed } from 'vue';
jorgep marked this conversation as resolved
Review

En el boton + de la tabla me falta un tooltip

En el boton + de la tabla me falta un tooltip
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 { getTotal } from 'src/composables/getTotal';
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 VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
import CreateNewExpenseForm from 'src/components/CreateNewExpenseForm.vue';
const { t } = useI18n();
const quasar = useQuasar();
const arrayData = useArrayData();
const invoiceIn = computed(() => arrayData.store.data);
@ -24,15 +22,7 @@ const expenses = ref([]);
const sageTaxTypes = ref([]);
const sageTransactionTypes = ref([]);
const rowsSelected = ref([]);
const newExpense = ref({
code: undefined,
isWithheld: false,
description: undefined,
});
const invoiceInFormRef = ref();
const expensesRef = ref();
const newExpenseRef = ref();
defineProps({
actionIcon: {
@ -133,37 +123,6 @@ function taxRate(invoiceInTax) {
return (taxTypeSage / 100) * taxableBase;
}

Pasado a componente CreateNewExpenseForm. Este ya tiene la lógica de FormModel para realizar una petición POST.

Pasado a componente **CreateNewExpenseForm**. Este ya tiene la lógica de FormModel para realizar una petición POST.
async function addExpense() {
try {
if (!newExpense.value.code) throw new Error(t(`The code can't be empty`));
if (isNaN(newExpense.value.code))
throw new Error(t(`The code have to be a number`));
if (!newExpense.value.description)
throw new Error(t(`The description can't be empty`));
const data = [
{
id: newExpense.value.code,
isWithheld: newExpense.value.isWithheld,
name: newExpense.value.description,
},
];
await axios.post(`Expenses`, data);
await expensesRef.value.fetch();
quasar.notify({
type: 'positive',
message: t('globals.dataSaved'),
});
newExpenseRef.value.hide();
} catch (error) {
quasar.notify({
type: 'negative',
message: t(`${error.message}`),
});
}
}

Ahora se usa un composable.

Ahora se usa un composable.
const formatOpt = (row, { model, options }, prop) => {
const obj = row[model];
const option = options.find(({ id }) => id == obj);
@ -205,7 +164,7 @@ const formatOpt = (row, { model, options }, prop) => {
>
<template #body-cell-expense="{ row, col }">
<QTd>
<VnSelect
<VnSelectDialog
v-model="row[col.model]"
:options="col.options"
:option-value="col.optionValue"
@ -217,25 +176,12 @@ const formatOpt = (row, { model, options }, prop) => {
{{ `${scope.opt.id}: ${scope.opt.name}` }}
</QItem>
</template>
<template #append>
<QIcon
name="close"
@click.stop="value = null"
class="cursor-pointer"
size="xs"
<template #form>
<CreateNewExpenseForm
jorgep marked this conversation as resolved
Review

Juraría que el botón del mas puede llevar tooltip

Juraría que el botón del mas puede llevar tooltip
@on-data-saved="$refs.expensesRef.fetch()"
/>
<QIcon
@click.stop.prevent="newExpenseRef.show()"
:name="actionIcon"
size="xs"
class="default-icon"
>
<QTooltip>
{{ t('Create expense') }}
</QTooltip>
</QIcon>
</template>
</VnSelect>
</VnSelectDialog>
</QTd>
</template>
<template #body-cell-taxablebase="{ row }">
@ -351,7 +297,7 @@ const formatOpt = (row, { model, options }, prop) => {
<QSeparator />
<QList>
<QItem>
<VnSelect
<VnSelectDialog
:label="t('Expense')"
class="full-width"
v-model="props.row['expenseFk']"
@ -365,7 +311,10 @@ const formatOpt = (row, { model, options }, prop) => {
{{ `${scope.opt.id}: ${scope.opt.name}` }}
</QItem>
</template>
</VnSelect>
<template #form>
<CreateNewExpenseForm />
</template>
</VnSelectDialog>
</QItem>
<QItem>
<VnInputNumber
@ -452,44 +401,6 @@ const formatOpt = (row, { model, options }, prop) => {
</QTable>
</template>
</CrudModel>
<QDialog ref="newExpenseRef">
<QCard>
<QCardSection class="q-pb-none">
<QItem class="q-pa-none">
<span class="text-primary text-h6 full-width">
<QIcon name="edit" class="q-mr-xs" />
{{ t('New expense') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QCardSection class="q-pt-none">
<QItem>
<VnInput
:label="`${t('Code')}*`"
v-model="newExpense.code"
:required="true"
/>
<QCheckbox
dense
size="sm"
:label="`${t('It\'s a withholding')}`"
v-model="newExpense.isWithheld"
/>
</QItem>
<QItem>
<VnInput
:label="`${t('Descripction')}*`"
v-model="newExpense.description"
/>
</QItem>
</QCardSection>
<QCardActions class="justify-end">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn :label="t('globals.save')" color="primary" @click="addExpense" />
</QCardActions>
</QCard>
</QDialog>
<QPageSticky position="bottom-right" :offset="[25, 25]">
<QBtn
color="primary"
@ -544,10 +455,7 @@ es:
Sage transaction: Sage transacción
Rate: Tasa
Foreign value: Divisa
New expense: Nuevo gasto
Code: Código
It's a withholding: Es una retención
Descripction: Descripción
The code can't be empty: El código no puede estar vacío
The description can't be empty: La descripción no puede estar vacía
The code have to be a number: El código debe ser un número.

View File

@ -36,8 +36,7 @@ describe('InvoiceInBasicData', () => {
});
it('should throw an error creating a new dms if a file is not attached', () => {
cy.get(formInputs).eq(5).click();
cy.get(formInputs).eq(5).type('{selectall}{backspace}');
cy.get(formInputs).eq(7).type('{selectall}{backspace}');
Review

Se ha cambiado el orden de los inputs de basic data.

Se ha cambiado el orden de los inputs de basic data.
cy.get(documentBtns).eq(0).click();
cy.get(dialogActionBtns).eq(1).click();
cy.get('.q-notification__message').should(

View File

@ -3,13 +3,14 @@ describe('InvoiceInVat', () => {
const thirdRow = 'tbody > :nth-child(3)';
const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)';
const dialogInputs = '.q-dialog label input';
const dialogBtns = '.q-dialog button';
const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon';
const addBtn = 'tbody tr:nth-child(1) td:nth-child(2) .--add-icon';
const randomInt = Math.floor(Math.random() * 100);
beforeEach(() => {
cy.login('developer');
cy.visit(`/#/invoice-in/1/vat`);
cy.intercept('GET', '/api/InvoiceIns/1/getTotals').as('lastCall');
cy.wait('@lastCall');
Review

En cypress, si abres un diálogo y modificas la url, este se cierra. He comprobado que en el navegador no se cierre. Si espero a que se hagan todas las llamadas funciona bien, me imagino que es porque cypress va lentorro.

En cypress, si abres un diálogo y modificas la url, este se cierra. He comprobado que en el navegador no se cierre. Si espero a que se hagan todas las llamadas funciona bien, me imagino que es porque cypress va lentorro.
});
it('should edit the sage iva', () => {
@ -26,22 +27,15 @@ describe('InvoiceInVat', () => {
});
it('should remove the first line', () => {
cy.removeRow(2);
});
it('should throw an error if there are fields undefined', () => {

Ahora se usa la prop rules, esta ya válida que se rellenen los campos obligatorios e impide que se envíe en caso contrario.

Ahora se usa la prop **rules**, esta ya válida que se rellenen los campos obligatorios e impide que se envíe en caso contrario.
cy.get(acrossInput).click();
cy.get(dialogBtns).eq(2).click();
cy.get('.q-notification__message').should('have.text', "The code can't be empty");
cy.removeRow(1);
});
it('should correctly handle expense addition', () => {
cy.get(acrossInput).click();
cy.get(addBtn).click();
cy.get(dialogInputs).eq(0).type(randomInt);
cy.get(dialogInputs).eq(1).click();
cy.get(dialogInputs).eq(1).type('This is a dummy expense');
cy.get(dialogBtns).eq(2).click();
cy.get('.q-notification__message').should('have.text', 'Data saved');
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should('have.text', 'Data created');
});
});