#7134 SupplierBalance #905

Open
jsegarra wants to merge 46 commits from 7134-supplierBalance into dev
7 changed files with 348 additions and 4 deletions

View File

@ -0,0 +1,12 @@
export default function (initialFooter, data) {
const footer = data.reduce(
(acc, row) => {
Object.entries(initialFooter).forEach(([key, initialValue]) => {
acc[key] += row?.[key] !== undefined ? row[key] : initialValue;
});
return acc;
},
{ ...initialFooter }
);
return footer;
}

View File

@ -10,4 +10,4 @@ import DepartmentDescriptor from 'pages/Department/Card/DepartmentDescriptor.vue
base-url="Departments" base-url="Departments"
:descriptor="DepartmentDescriptor" :descriptor="DepartmentDescriptor"
/> />
</template> </template>

View File

@ -0,0 +1,191 @@
<script setup>
import { computed, onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import tableFooter from 'src/components/VnTable/filters/tableFooter';
import { dashIfEmpty, toCurrency, toDateHourMin } from 'src/filters';
import { useState } from 'src/composables/useState';
import { useStateStore } from 'src/stores/useStateStore';
import VnTable from 'src/components/VnTable/VnTable.vue';
import InvoiceInDescriptorProxy from 'src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
import SupplierBalanceFilter from './SupplierBalanceFilter.vue';
import { onMounted } from 'vue';
import FetchData from 'src/components/FetchData.vue';
const { t } = useI18n();
const route = useRoute();
const state = useState();
const stateStore = useStateStore();
const user = state.getUser();
const tableRef = ref();
const companyId = ref();
const companyUser = ref(user.value.companyFk);
const balances = ref([]);
const userParams = ref({
supplierId: route.params.id,
companyId: companyId.value ?? companyUser.value,
isBooked: false,
});
const columns = computed(() => [
{
align: 'left',
name: 'dated',
label: t('Creation date'),
format: ({ dated }) => toDateHourMin(dated),
cardVisible: true,
},
{
align: 'left',
name: 'sref',
label: t('Reference'),
isTitle: true,
class: 'extend',
format: ({ sref }) => dashIfEmpty(sref),
},
{
align: 'left',
name: 'bank',
label: t('Bank'),
cardVisible: true,
},
{
align: 'left',
name: 'invoiceEuros',
label: t('Debit'),
format: ({ invoiceEuros }) => toCurrency(invoiceEuros),
isId: true,
},
{
align: 'left',
name: 'paymentEuros',
label: t('Havings'),
format: ({ paymentEuros }) => toCurrency(paymentEuros),
cardVisible: true,
},
{
align: 'left',
name: 'euroBalance',
label: t('Balance'),
format: ({ euroBalance }) => toCurrency(euroBalance),
cardVisible: true,
},
{
align: 'left',
name: 'isBooked',
label: t('Conciliated'),
cardVisible: true,
},
]);
onBeforeMount(() => {
stateStore.rightDrawer = true;
companyId.value = companyUser.value;
});
onMounted(async () => {
Object.assign(userParams, {
supplierId: route.params.id,
companyId: companyId.value ?? companyUser.value,
isConciliated: false,
});
});
function setFooter(data) {
const initialFooter = {
invoiceEuros: 0,
paymentEuros: 0,
euroBalance: 0,
};
tableRef.value.footer = tableFooter(initialFooter, data);
}
async function onFetch(data) {
setFooter(data);
return;
}
function round(value) {
return Math.round(value * 100) / 100;
}
const onFetchCurrencies = ([currency]) => {
userParams.value.currencyFk = currency?.id;
};
</script>
<template>
<QDrawer side="right" :width="265" v-model="stateStore.rightDrawer">
Review

de momento seguimos con el 265 pero ticketBasicData ya tiene witdth 265, hay que ir mirando de hacerlo en una clase css a nivel aplicacion o un como los iconos md, xs, como creas mas conveniente.

de momento seguimos con el 265 **pero** ticketBasicData ya tiene witdth 265, hay que ir mirando de hacerlo en una clase css a nivel aplicacion o un como los iconos md, xs, como creas mas conveniente.
<SupplierBalanceFilter data-key="SupplierBalance" />
</QDrawer>
<FetchData
url="Currencies"
:filter="{ fields: ['id', 'code'], where: { code: 'EUR' } }"
sort-by="code"
@on-fetch="onFetchCurrencies"
auto-load
/>
<VnTable
v-if="userParams.currencyFk"
ref="tableRef"
data-key="SupplierBalance"
url="Suppliers/receipts"
search-url="balance"
:user-params="userParams"
:columns="columns"
:right-search="false"
:is-editable="false"
:column-search="false"
@on-fetch="onFetch"
:disable-option="{ card: true }"
:footer="true"
:order="['dated ASC']"
data-cy="supplierBalanceTable"
auto-load
:map-key="false"
>
<template #column-balance="{ rowIndex }">
{{ toCurrency(balances[rowIndex]?.balance) }}
</template>
<template #column-sref="{ row }">
jsegarra marked this conversation as resolved
Review

el redondeo lo hace el toCurrency creo que tiene un parametro para los decimales

el redondeo lo hace el toCurrency creo que tiene un parametro para los decimales
Review

Pero por defecto es 2
toCurrency =>(value, symbol = 'EUR', fractionSize = 2)

Pero por defecto es 2 toCurrency =>(value, symbol = 'EUR', fractionSize = 2)
<span class="link" v-if="row.statementType === 'invoiceIn'">
{{ dashIfEmpty(row.sref) }}
<InvoiceInDescriptorProxy :id="row.id" />
</span>
<span v-else> {{ dashIfEmpty(row.sref) }}</span>
</template>
<template #column-footer-invoiceEuros>
<span>
{{ toCurrency(round(tableRef.footer.invoiceEuros)) }}
</span>
</template>
<template #column-footer-paymentEuros>
<span>
{{ toCurrency(round(tableRef.footer.paymentEuros)) }}
</span>
</template>
<template #column-footer-euroBalance>
<span>
{{ toCurrency(round(tableRef.footer.euroBalance)) }}
</span>
</template>
</VnTable>
</template>
<i18n>
es:
Company: Empresa
Total by company: Total por empresa
Date: Fecha
Creation date: Fecha de creación
Reference: Referencia
Bank: Caja
Debit: Debe
Havings: Haber
Balance: Balance
Conciliated: Conciliado
</i18n>

View File

@ -0,0 +1,121 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
const { t } = useI18n();
defineProps({
dataKey: {
type: String,
required: true,
},
});
</script>
<template>
<VnFilterPanel
:data-key="dataKey"
:search-button="true"
:redirect="false"
:unremovable-params="['supplierId', 'companyId']"
>
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params, searchFn }">
<QItem>
<QItemSection>
<VnInputDate
:label="t('params.from')"
v-model="params.from"
@update:model-value="searchFn()"
is-outlined
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
:label="t('params.bankFk')"
v-model="params.bankFk"
url="Accountings"
option-label="bank"
:include="{ relation: 'accountingType' }"
sort-by="id"
dense
outlined
rounded
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>
{{ scope.opt.id }} {{ scope.opt.bank }}
</QItemLabel>
</QItemSection>
jsegarra marked this conversation as resolved
Review

porque no pones directamente el espacio?

porque no pones directamente el espacio?
</QItem>
</template>
</VnSelect>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
:label="t('params.currencyFk')"
url="Currencies"
:filter="{ fields: ['id', 'name'] }"
order="code"
v-model="params.currencyFk"
option-value="id"
option-label="name"
hide-selected
dense
outlined
rounded
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<QCheckbox
v-model="params.isConciliated"
:label="t('params.isConciliated')"
/></QItemSection>
</QItem>
</template>
</VnFilterPanel>
</template>
<i18n>
en:
params:
search: General search
supplierId: Supplier
categoryId: Category
from: From
to: To
isConciliated: Is conciliated
currencyFk: Currency
bankFk: Bank
companyId: Comapany
isBooked: Is booked
es:
params:
supplierId: Proveedor
isConciliated: Conciliado
currencyFk: Moneda
New payment: Añadir pago
Date: Fecha
from: Desde
to: Hasta
companyId: Empresa
isBooked: Contabilizado
bankFk: Caja
Amount: Importe
Reference: Referencia
Cash: Efectivo
</i18n>

View File

@ -21,6 +21,7 @@ export default {
'SupplierAccounts', 'SupplierAccounts',
'SupplierContacts', 'SupplierContacts',
'SupplierAddresses', 'SupplierAddresses',
'SupplierBalance',
'SupplierConsumption', 'SupplierConsumption',
'SupplierAgencyTerm', 'SupplierAgencyTerm',
'SupplierDms', 'SupplierDms',
@ -144,6 +145,16 @@ export default {
component: () => component: () =>
import('src/pages/Supplier/Card/SupplierAddressesCreate.vue'), import('src/pages/Supplier/Card/SupplierAddressesCreate.vue'),
}, },
{
path: 'balance',
name: 'SupplierBalance',
meta: {
title: 'balance',
icon: 'balance',
},
component: () =>
import('src/pages/Supplier/Card/SupplierBalance.vue'),
},
{ {
path: 'consumption', path: 'consumption',
name: 'SupplierConsumption', name: 'SupplierConsumption',

View File

@ -0,0 +1,11 @@
describe('Supplier Balance', () => {
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/supplier/1/balance`);
});
it('Should load layout', () => {
cy.get('.q-page').should('be.visible');
});
});

View File

@ -3,9 +3,7 @@ describe('Client balance', () => {
beforeEach(() => { beforeEach(() => {
cy.viewport(1280, 720); cy.viewport(1280, 720);
cy.login('developer'); cy.login('developer');
cy.visit('#/customer/1101/balance', { cy.visit('#/customer/1101/balance');
timeout: 5000,
});
}); });
it('Should load layout', () => { it('Should load layout', () => {
cy.get('.q-page').should('be.visible'); cy.get('.q-page').should('be.visible');