#7134 SupplierBalance #905

Open
jsegarra wants to merge 46 commits from 7134-supplierBalance into dev
1 changed files with 329 additions and 0 deletions
Showing only changes of commit 4d602aadfd - Show all commits

View File

@ -0,0 +1,329 @@
<script setup>
import { computed, onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { useAcl } from 'src/composables/useAcl';
import axios from 'axios';
import { useQuasar } from 'quasar';
import { getSupplierRisk } from 'src/composables/getRisk';
import { toCurrency, toDate, toDateHourMin } from 'src/filters';
import { useState } from 'composables/useState';
import { useStateStore } from 'stores/useStateStore';
import { usePrintService } from 'composables/usePrintService';
import { useVnConfirm } from 'composables/useVnConfirm';
import VnTable from 'components/VnTable/VnTable.vue';
import VnInput from 'components/common/VnInput.vue';
import VnSubToolbar from 'components/ui/VnSubToolbar.vue';
import VnFilter from 'components/VnTable/VnFilter.vue';
import CreateNewPayment from 'src/components/CreateNewPayment.vue';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
const { openConfirmationModal } = useVnConfirm();
const { sendEmail, openReport } = usePrintService();
const { t } = useI18n();
const { hasAny } = useAcl();
const quasar = useQuasar();
const route = useRoute();
const state = useState();
const stateStore = useStateStore();
jsegarra marked this conversation as resolved Outdated

este uno podemo hacer que sea el back el que lo reciba por defecto? para no dejar numeros. De todas formas el back casi seguro lo tendrá

este uno podemo hacer que sea el back el que lo reciba por defecto? para no dejar numeros. De todas formas el back casi seguro lo tendrá

Lo he resuelto haciendo un fetchData

Lo he resuelto haciendo un fetchData
const user = state.getUser();
const supplierRisk = ref([]);
const tableRef = ref();
const companyId = ref();
const companyUser = ref(user.value.companyFk);
const balances = ref([]);
const vnFilterRef = ref({});
const filter = computed(() => {
return {
supplierId: route.params.id,
companyId: companyId.value ?? companyUser.value,
};
});
const companyFilterColumn = {
align: 'left',
name: 'companyId',
label: t('Company'),
component: 'select',
attrs: {
url: 'Companies',
optionLabel: 'code',
optionValue: 'id',
sortBy: 'code',
},
columnFilter: {
event: {
remove: () => (companyId.value = null),
'update:modelValue': (newCompanyFk) => {
jsegarra marked this conversation as resolved Outdated

duda
format: ({ invoiceEuros }) => toCurrency(invoiceEuros ?? 0)
esto serviria?

duda `format: ({ invoiceEuros }) => toCurrency(invoiceEuros ?? 0)` esto serviria?
if (!newCompanyFk) return;
vnFilterRef.value.addFilter(newCompanyFk);
companyUser.value = newCompanyFk;
},
blur: () => !companyId.value && (companyId.value = companyUser.value),
},
},
visible: false,
};
const columns = computed(() => [
{
align: 'left',
name: 'payed',
label: t('Date'),
format: ({ payed }) => toDate(payed),
cardVisible: true,
},
{
align: 'left',
name: 'created',
label: t('Creation date'),
format: ({ created }) => toDateHourMin(created),
cardVisible: true,
},
{
align: 'left',
label: t('Employee'),
columnField: {
component: 'userLink',
attrs: ({ row }) => {
return {
workerId: row.workerFk,
name: row.userName,
};
},
},
cardVisible: true,
},
{
align: 'left',
name: 'description',
label: t('Reference'),
isTitle: true,
class: 'extend',
},
{
align: 'left',
name: 'bankFk',
label: t('Bank'),
cardVisible: true,
},
{
align: 'left',
name: 'debit',
label: t('Debit'),
format: ({ debit }) => debit && toCurrency(debit),
isId: true,
},
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.
{
align: 'left',
name: 'credit',
label: t('Havings'),
format: ({ credit }) => credit && toCurrency(credit),
cardVisible: true,
},
{
align: 'left',
name: 'balance',
label: t('Balance'),
format: ({ balance }) => toCurrency(balance),
cardVisible: true,
},
{
align: 'left',
name: 'isConciliate',
label: t('Conciliated'),
cardVisible: true,
},
{
align: 'left',
name: 'tableActions',
actions: [
{
title: t('globals.downloadPdf'),
icon: 'cloud_download',
show: (row) => row.isInvoice,
action: (row) => showBalancePdf(row),
},
{
title: t('Send compensation'),
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)
icon: 'outgoing_mail',
show: (row) => !!row.isCompensation,
action: ({ id }) =>
openConfirmationModal(
t('Send compensation'),
t('Do you want to report compensation to the supplier by mail?'),
() => sendEmail(`Receipts/${id}/balance-compensation-email`)
),
},
],
},
]);
onBeforeMount(() => {
stateStore.rightDrawer = true;
companyId.value = companyUser.value;
});
async function getSupplierRisks() {
const filter = {
where: { supplierFk: route.params.id, companyFk: companyUser.value },
};
const { data } = await getSupplierRisk(filter);
supplierRisk.value = data;
return supplierRisk.value;
}
async function getCurrentBalance() {
const currentBalance = (await getSupplierRisks()).find((balance) => {
return balance.companyFk === companyId.value;
});
return currentBalance && currentBalance.amount;
}
async function onFetch(data) {
balances.value = [];
for (const [index, balance] of data.entries()) {
if (index === 0) {
balance.balance = await getCurrentBalance();
continue;
}
const previousBalance = data[index - 1];
balance.balance =
previousBalance?.balance - (previousBalance?.debit - previousBalance?.credit);
}
balances.value = data;
}
const showNewPaymentDialog = () => {
quasar.dialog({
component: CreateNewPayment,
componentProps: {
companyId: companyId.value,
totalCredit: supplierRisk.value[0]?.amount,
promise: () => tableRef.value.reload(),
},
});
};
const showBalancePdf = ({ id }) => {
openReport(`InvoiceOuts/${id}/download`, {}, '_blank');
};
</script>
<template>
<VnSubToolbar class="q-mb-md">
<template #st-data>
<div class="column justify-center q-px-md q-py-sm">
<span class="text-bold">{{ t('Total by company') }}</span>
<div class="row justify-center" v-if="supplierRisk?.length">
{{ supplierRisk[0].company.code }}:
{{ toCurrency(supplierRisk[0].amount) }}
</div>
</div>
</template>
<template #st-actions>
<div>
<VnFilter
ref="vnFilterRef"
v-model="companyId"
data-key="CustomerBalance"
:column="companyFilterColumn"
search-url="balance"
/>
</div>
</template>
</VnSubToolbar>
<VnTable
ref="tableRef"
data-key="CustomerBalance"
url="Receipts/filter"
search-url="balance"
:user-params="filter"
:columns="columns"
:right-search="false"
:is-editable="false"
:column-search="false"
@on-fetch="onFetch"
:disable-option="{ card: true }"
auto-load
>
<template #column-balance="{ rowIndex }">
{{ toCurrency(balances[rowIndex]?.balance) }}
</template>
<template #column-description="{ row }">
<div class="link" v-if="row.isInvoice">
{{ t('bill', { ref: row.description }) }}
<InvoiceOutDescriptorProxy :id="row.description" />
</div>
<span v-else class="q-pa-xs dotted rounded-borders" :title="row.description">
{{ row.description }}
</span>
<QPopupEdit
v-model="row.description"
v-slot="scope"
@save="
(value) =>
value != row.description &&
axios.patch(`Receipts/${row.id}`, { description: value })
"
auto-save
>
<VnInput
v-model="scope.value"
:disable="
!hasAny([{ model: 'Receipt', props: '*', accessType: 'WRITE' }])
"
@keypress.enter="scope.set"
autofocus
/>
</QPopupEdit>
</template>
</VnTable>
<QPageSticky :offset="[18, 18]" style="z-index: 2">
<QBtn
@click.stop="showNewPaymentDialog()"
color="primary"
fab
icon="add"
shortcut="+"
/>
<QTooltip>
{{ t('New payment') }}
</QTooltip>
</QPageSticky>
</template>
<i18n>
en:
bill: 'N/INV {ref}'
es:
Company: Empresa
Total by company: Total por empresa
New payment: Añadir pago
Date: Fecha
Creation date: Fecha de creación
Employee: Empleado
Reference: Referencia
bill: 'N/FRA {ref}'
Bank: Caja
Debit: Debe
Havings: Haber
Balance: Balance
Conciliated: Conciliado
Send compensation: Enviar compensación
Do you want to report compensation to the supplier by mail?: ¿Desea informar de la compensación al cliente por correo?
</i18n>
<style lang="scss" scoped>
.dotted {
border: 1px dotted var(--vn-header-color);
}
.dotted:hover {
border: 1px dotted $primary;
}
</style>