diff --git a/src/components/CreateNewExpenseForm.vue b/src/components/CreateNewExpenseForm.vue
new file mode 100644
index 000000000..7088cec03
--- /dev/null
+++ b/src/components/CreateNewExpenseForm.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ New expense: Nuevo gasto
+ It's a withholding: Es una retención
+
diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue
index 213c08d7e..03fe11a85 100644
--- a/src/components/LeftMenu.vue
+++ b/src/components/LeftMenu.vue
@@ -1,6 +1,6 @@
{
-
+
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index 7dbd0fe9e..e475bc4ed 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -5,10 +5,10 @@ import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { toDate } from 'src/filters';
import { useArrayData } from 'src/composables/useArrayData';
+import { getTotal } from 'src/composables/getTotal';
import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
-import { toCurrency } from 'src/filters';
import useNotify from 'src/composables/useNotify.js';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
@@ -71,7 +71,6 @@ async function insert() {
await invoiceInFormRef.value.reload();
notify(t('globals.dataSaved'), 'positive');
}
-const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, 0);
rows.reduce((acc, { amount }) => acc + +amount,
- {{
- toCurrency(getTotalAmount(rows), invoiceIn.currency.code)
- }}
+ {{ getTotal(rows, 'amount', { currency: 'default' }) }}
+
+
+
+ {{
+ getTotal(rows, 'foreignValue', {
+ currency: invoiceIn.currency.code,
+ })
+ }}
+
-
diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
index 481698832..717f30b7f 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
@@ -2,18 +2,15 @@
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
-import { toCurrency } from 'src/filters';
+import { getTotal } from 'src/composables/getTotal';
import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
-import { useArrayData } from 'src/composables/useArrayData';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n();
const route = useRoute();
-const arrayData = useArrayData();
-const currency = computed(() => arrayData.store.data?.currency?.code);
const invoceInIntrastat = ref([]);
const rowsSelected = ref([]);
const countries = ref([]);
@@ -72,9 +69,6 @@ const columns = computed(() => [
},
]);
-const getTotal = (data, key) =>
- data.reduce((acc, cur) => acc + +String(cur[key] || 0).replace(',', '.'), 0);
-
const formatOpt = (row, { model, options }, prop) => {
const obj = row[model];
const option = options.find(({ id }) => id == obj);
@@ -154,7 +148,7 @@ const formatOpt = (row, { model, options }, prop) => {
- {{ toCurrency(getTotal(rows, 'amount'), currency) }}
+ {{ getTotal(rows, 'amount', { currency: 'default' }) }}
{{ getTotal(rows, 'net') }}
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index 644b472e2..bf2e7db48 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -35,7 +35,7 @@ const vatColumns = ref([
name: 'landed',
label: 'invoiceIn.summary.taxableBase',
field: (row) => row.taxableBase,
- format: (value) => toCurrency(value, currency.value),
+ format: (value) => toCurrency(value),
sortable: true,
align: 'left',
},
@@ -64,7 +64,7 @@ const vatColumns = ref([
name: 'rate',
label: 'invoiceIn.summary.rate',
field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate),
- format: (value) => toCurrency(value, currency.value),
+ format: (value) => toCurrency(value),
sortable: true,
align: 'left',
},
@@ -72,7 +72,7 @@ const vatColumns = ref([
name: 'currency',
label: 'invoiceIn.summary.currency',
field: (row) => row.foreignValue,
- format: (value) => value,
+ format: (val) => val && toCurrency(val, currency.value),
sortable: true,
align: 'left',
},
@@ -97,7 +97,7 @@ const dueDayColumns = ref([
name: 'amount',
label: 'invoiceIn.summary.amount',
field: (row) => row.amount,
- format: (value) => toCurrency(value, currency.value),
+ format: (value) => toCurrency(value),
sortable: true,
align: 'left',
},
@@ -105,7 +105,7 @@ const dueDayColumns = ref([
name: 'landed',
label: 'invoiceIn.summary.foreignValue',
field: (row) => row.foreignValue,
- format: (value) => value,
+ format: (val) => val && toCurrency(val, currency.value),
sortable: true,
align: 'left',
},
@@ -124,7 +124,7 @@ const intrastatColumns = ref([
{
name: 'amount',
label: 'invoiceIn.summary.amount',
- field: (row) => toCurrency(row.amount, currency.value),
+ field: (row) => toCurrency(row.amount),
sortable: true,
align: 'left',
},
@@ -179,7 +179,6 @@ const getTotalTax = (tax) =>
const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
-
`#/invoice-in/${entityId.value}/${param}`;
:label="t('invoiceIn.summary.currency')"
:value="entity.currency?.code"
/>
-
+
@@ -293,12 +289,9 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
-
+
`#/invoice-in/${entityId.value}/${param}`;
: t('invoiceIn.summary.dueTotal')
"
>
- {{ toCurrency(entity.totals.totalDueDay, currency) }}
+ {{ toCurrency(entity.totals.totalDueDay) }}
@@ -350,15 +343,17 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
+ {{ toCurrency(entity.totals.totalTaxableBase) }}
+
+
+ {{ toCurrency(getTotalTax(entity.invoiceInTax)) }}
{{
- toCurrency(entity.totals.totalTaxableBase, currency)
+ entity.totals.totalTaxableBaseForeignValue &&
+ toCurrency(
+ entity.totals.totalTaxableBaseForeignValue,
+ currency
+ )
}}
-
-
- {{
- toCurrency(getTotalTax(entity.invoiceInTax, currency))
- }}
-
@@ -384,9 +379,17 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
- {{ toCurrency(entity.totals.totalDueDay, currency) }}
+ {{ toCurrency(entity.totals.totalDueDay) }}
+
+
+ {{
+ entity.totals.totalDueDayForeignValue &&
+ toCurrency(
+ entity.totals.totalDueDayForeignValue,
+ currency
+ )
+ }}
-
@@ -421,7 +424,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
- {{ toCurrency(intrastatTotals.amount, currency) }}
+ {{ toCurrency(intrastatTotals.amount) }}
{{ intrastatTotals.net }}
{{ intrastatTotals.stems }}
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index 4dac5058e..78cf65871 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -2,18 +2,17 @@
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 { 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);
@@ -23,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: {
@@ -56,7 +47,7 @@ const columns = computed(() => [
{
name: 'taxablebase',
label: t('Taxable base'),
- field: (row) => toCurrency(row.taxableBase, currency.value),
+ field: (row) => row.taxableBase,
model: 'taxableBase',
sortable: true,
tabIndex: 2,
@@ -91,7 +82,7 @@ const columns = computed(() => [
label: t('Rate'),
sortable: true,
tabIndex: 5,
- field: (row) => toCurrency(taxRate(row, row.taxTypeSageFk), currency.value),
+ field: (row) => taxRate(row, row.taxTypeSageFk),
align: 'left',
},
{
@@ -132,40 +123,6 @@ function taxRate(invoiceInTax) {
return (taxTypeSage / 100) * taxableBase;
}
-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}`),
- });
- }
-}
-const getTotalTaxableBase = (rows) =>
- rows.reduce((acc, { taxableBase }) => acc + +(taxableBase || 0), 0);
-const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0);
-
const formatOpt = (row, { model, options }, prop) => {
const obj = row[model];
const option = options.find(({ id }) => id == obj);
@@ -207,37 +164,25 @@ const formatOpt = (row, { model, options }, prop) => {
>
-
{{ `${scope.opt.id}: ${scope.opt.name}` }}
-
-
+
-
-
- {{ t('Create expense') }}
-
-
-
+
@@ -324,12 +269,24 @@ const formatOpt = (row, { model, options }, prop) => {
- {{ toCurrency(getTotalTaxableBase(rows), currency) }}
+ {{ getTotal(rows, 'taxableBase', { currency: 'default' }) }}
- {{ toCurrency(getTotalRate(rows), currency) }}
-
+
+ {{
+ getTotal(rows, null, { cb: taxRate, currency: 'default' })
+ }}
+
+
+ {{
+ getTotal(rows, 'foreignValue', {
+ currency: invoiceIn.currency.code,
+ })
+ }}
+
+
@@ -341,7 +298,7 @@ const formatOpt = (row, { model, options }, prop) => {
- {
option-value="id"
option-label="name"
:filter-options="['id', 'name']"
+ :tooltip="t('Create a new expense')"
>
{{ `${scope.opt.id}: ${scope.opt.name}` }}
-
+
+
+
+
{
-
-
-
-
-
-
- {{ t('New expense') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
size="lg"
round
@click="invoiceInFormRef.insert()"
- />
+ >
+ {{ t('Add tax') }}
+
@@ -527,18 +452,11 @@ const formatOpt = (row, { model, options }, prop) => {
es:
Expense: Gasto
- Create expense: Crear gasto
+ Create a new expense: Crear nuevo gasto
Add tax: Crear gasto
Taxable base: Base imp.
Sage tax: Sage iva
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.
diff --git a/src/pages/InvoiceIn/InvoiceInFilter.vue b/src/pages/InvoiceIn/InvoiceInFilter.vue
index 2f87c2b2e..bf4e023a9 100644
--- a/src/pages/InvoiceIn/InvoiceInFilter.vue
+++ b/src/pages/InvoiceIn/InvoiceInFilter.vue
@@ -28,6 +28,16 @@ const activities = ref([]);
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -179,6 +154,7 @@ en:
correctedFk: Rectified
issued: Issued
to: To
+ from: From
awbCode: AWB
correctingFk: Rectificative
supplierActivityFk: Supplier activity
@@ -201,6 +177,8 @@ es:
correctedFk: Rectificada
correctingFk: Rectificativa
supplierActivityFk: Actividad proveedor
+ from: Desde
+ to: Hasta
From: Desde
To: Hasta
Amount: Importe
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index 234cfb50f..0cad09378 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -47,12 +47,6 @@ const cols = computed(() => [
name: 'supplierRef',
label: t('invoiceIn.list.supplierRef'),
},
-
- {
- align: 'left',
- name: 'serialNumber',
- label: t('invoiceIn.list.serialNumber'),
- },
{
align: 'left',
name: 'serial',
@@ -141,7 +135,7 @@ const cols = computed(() => [
v-model="data.supplierFk"
url="Suppliers"
:fields="['id', 'nickname']"
- :label="t('Supplier')"
+ :label="t('globals.supplier')"
option-value="id"
option-label="nickname"
:filter-options="['id', 'name']"
@@ -162,7 +156,7 @@ const cols = computed(() => [
/>
route.name === 'InvoiceInCard');
+ const corrective = card.children.find(
+ (route) => route.name === 'InvoiceInCorrective'
+ );
+
+ corrective.meta.hidden = !(
+ await axios.get('InvoiceInCorrections', {
+ params: { filter: { where: { correctingFk: route.params.id } } },
+ })
+ ).data.length;
+}
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
new file mode 100644
index 000000000..824fd6e12
--- /dev/null
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -0,0 +1,49 @@
+invoiceIn:
+ serial: Serial
+ list:
+ ref: Reference
+ supplier: Supplier
+ supplierRef: Supplier ref.
+ serial: Serial
+ file: File
+ issued: Issued
+ isBooked: Is booked
+ awb: AWB
+ amount: Amount
+ card:
+ issued: Issued
+ amount: Amount
+ client: Client
+ company: Company
+ customerCard: Customer card
+ ticketList: Ticket List
+ vat: Vat
+ dueDay: Due day
+ intrastat: Intrastat
+ summary:
+ supplier: Supplier
+ supplierRef: Supplier ref.
+ currency: Currency
+ issued: Expedition date
+ operated: Operation date
+ bookEntried: Entry date
+ bookedDate: Booked date
+ sage: Sage withholding
+ vat: Undeductible VAT
+ company: Company
+ booked: Booked
+ expense: Expense
+ taxableBase: Taxable base
+ rate: Rate
+ sageVat: Sage vat
+ sageTransaction: Sage transaction
+ dueDay: Date
+ bank: Bank
+ amount: Amount
+ foreignValue: Foreign value
+ dueTotal: Due day
+ noMatch: Do not match
+ code: Code
+ net: Net
+ stems: Stems
+ country: Country
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
new file mode 100644
index 000000000..944708364
--- /dev/null
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -0,0 +1,47 @@
+invoiceIn:
+ serial: Serie
+ list:
+ ref: Referencia
+ supplier: Proveedor
+ supplierRef: Ref. proveedor
+ shortIssued: F. emisión
+ file: Fichero
+ issued: Fecha emisión
+ isBooked: Conciliada
+ awb: AWB
+ amount: Importe
+ card:
+ issued: Fecha emisión
+ amount: Importe
+ client: Cliente
+ company: Empresa
+ customerCard: Ficha del cliente
+ ticketList: Listado de tickets
+ vat: Iva
+ dueDay: Fecha de vencimiento
+ summary:
+ supplier: Proveedor
+ supplierRef: Ref. proveedor
+ currency: Divisa
+ docNumber: Número documento
+ issued: Fecha de expedición
+ operated: Fecha operación
+ bookEntried: Fecha asiento
+ bookedDate: Fecha contable
+ sage: Retención sage
+ vat: Iva no deducible
+ company: Empresa
+ booked: Contabilizada
+ expense: Gasto
+ taxableBase: Base imp.
+ rate: Tasa
+ sageTransaction: Sage transación
+ dueDay: Fecha
+ bank: Caja
+ amount: Importe
+ foreignValue: Divisa
+ dueTotal: Vencimiento
+ code: Código
+ net: Neto
+ stems: Tallos
+ country: País
diff --git a/src/router/modules/invoiceIn.js b/src/router/modules/invoiceIn.js
index 906db8a58..64c7b23e9 100644
--- a/src/router/modules/invoiceIn.js
+++ b/src/router/modules/invoiceIn.js
@@ -1,5 +1,5 @@
import { RouterView } from 'vue-router';
-
+import { setRectificative } from 'src/pages/InvoiceIn/composables/setRectificative';
export default {
path: '/invoice-in',
name: 'InvoiceIn',
@@ -63,6 +63,10 @@ export default {
path: ':id',
component: () => import('src/pages/InvoiceIn/Card/InvoiceInCard.vue'),
redirect: { name: 'InvoiceInSummary' },
+ beforeEnter: async (to, from, next) => {
+ await setRectificative(to);
+ next();
+ },
children: [
{
name: 'InvoiceInSummary',
diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js
index 961e80377..ad671a7f9 100644
--- a/src/stores/useNavigationStore.js
+++ b/src/stores/useNavigationStore.js
@@ -56,6 +56,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
function addMenuItem(module, route, parent) {
const { meta } = route;
let { menuChildren = null } = meta;
+ if (meta.hidden) return;
if (menuChildren)
menuChildren = menuChildren.map(({ name, title, icon }) => ({
name,
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 77a11969b..e1939fe5a 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -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}');
cy.get(documentBtns).eq(0).click();
cy.get(dialogActionBtns).eq(1).click();
cy.get('.q-notification__message').should(
diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
index 018ae7a53..b84d743d1 100644
--- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
@@ -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');
});
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', () => {
- 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');
});
});