346 lines
13 KiB
Vue
346 lines
13 KiB
Vue
<script setup>
|
|
import { computed, ref } from 'vue';
|
|
import { useRoute } from 'vue-router';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters';
|
|
import CardSummary from 'components/ui/CardSummary.vue';
|
|
import VnLv from 'src/components/ui/VnLv.vue';
|
|
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
|
import VnLinkMail from 'src/components/ui/VnLinkMail.vue';
|
|
import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue';
|
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
|
import VnRow from 'src/components/ui/VnRow.vue';
|
|
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
|
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
|
|
|
const route = useRoute();
|
|
const { t } = useI18n();
|
|
const grafanaUrl = 'https://grafana.verdnatura.es';
|
|
|
|
const $props = defineProps({
|
|
id: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
});
|
|
|
|
const entityId = computed(() => $props.id || route.params.id);
|
|
const customer = computed(() => summary.value.entity);
|
|
const summary = ref();
|
|
const defaulterAmount = computed(() => customer.value.defaulters[0]?.amount);
|
|
const balanceDue = computed(() => {
|
|
const amount = defaulterAmount.value;
|
|
if (!amount || amount < 0) {
|
|
return null;
|
|
}
|
|
return amount;
|
|
});
|
|
|
|
const balanceDueWarning = computed(() => (defaulterAmount.value ? 'negative' : ''));
|
|
|
|
const claimRate = computed(() => {
|
|
return customer.value.claimsRatio?.claimingRate ?? 0;
|
|
});
|
|
|
|
const priceIncreasingRate = computed(() => {
|
|
return customer.value.claimsRatio?.priceIncreasing ?? 0 / 100;
|
|
});
|
|
|
|
const debtWarning = computed(() => {
|
|
return customer.value?.debt?.debt > customer.value.credit ? 'negative' : '';
|
|
});
|
|
|
|
const creditWarning = computed(() => {
|
|
const data = customer.value;
|
|
const tooMuchInsurance = data.credit > data.creditInsurance;
|
|
const noCreditInsurance = data.credit && data.creditInsurance == null;
|
|
|
|
return tooMuchInsurance || noCreditInsurance ? 'negative' : '';
|
|
});
|
|
const sumRisk = ({ clientRisks }) => {
|
|
let total = clientRisks.reduce((acc, { amount }) => acc + amount, 0);
|
|
|
|
return total;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<CardSummary
|
|
ref="summary"
|
|
:url="`Clients/${entityId}/summary`"
|
|
data-key="CustomerSummary"
|
|
module-name="Customer"
|
|
>
|
|
<template #menu="{ entity }">
|
|
<CustomerDescriptorMenu :customer="entity" />
|
|
</template>
|
|
<template #body="{ entity }">
|
|
<QCard class="vn-one">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/basic-data`"
|
|
:text="t('customer.summary.basicData')"
|
|
/>
|
|
<VnLv :label="t('customer.summary.customerId')" :value="entity.id" />
|
|
<VnLv :label="t('globals.name')" :value="entity.name" />
|
|
<VnLv :label="t('customer.summary.contact')" :value="entity.contact" />
|
|
<VnLv :value="entity.phone">
|
|
<template #label>
|
|
{{ t('customer.extendedList.tableVisibleColumns.phone') }}
|
|
<VnLinkPhone :phone-number="entity.phone" />
|
|
</template>
|
|
</VnLv>
|
|
<VnLv :value="entity.mobile">
|
|
<template #label>
|
|
{{ t('customer.summary.mobile') }}
|
|
<VnLinkPhone :phone-number="entity.mobile" />
|
|
<VnLinkPhone
|
|
say-simple
|
|
:phone-number="entity.mobile"
|
|
:channel="entity.country?.saySimpleCountry?.channel"
|
|
class="q-ml-xs"
|
|
/>
|
|
</template>
|
|
</VnLv>
|
|
<VnLv :value="entity.email" copy
|
|
><template #label>
|
|
{{ t('globals.params.email') }}
|
|
<VnLinkMail email="entity.email"></VnLinkMail> </template
|
|
></VnLv>
|
|
<VnLv :label="t('globals.department')">
|
|
<template #value>
|
|
<span class="link" v-text="entity.department?.name" />
|
|
<DepartmentDescriptorProxy :id="entity?.department?.id" />
|
|
</template>
|
|
</VnLv>
|
|
<VnLv
|
|
:label="t('customer.summary.contactChannel')"
|
|
:value="entity?.contactChannel?.name"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.businessType')"
|
|
:value="entity.businessType.description"
|
|
/>
|
|
</QCard>
|
|
<QCard class="vn-one">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/fiscal-data`"
|
|
:text="t('customer.summary.fiscalAddress')"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.socialName')"
|
|
:value="entity.socialName"
|
|
/>
|
|
<VnLv :label="t('customer.summary.fiscalId')" :value="entity.fi" />
|
|
<VnLv :label="t('customer.summary.city')" :value="entity.city" />
|
|
<VnLv :label="t('customer.summary.postcode')" :value="entity.postcode" />
|
|
|
|
<VnLv
|
|
v-if="entity.province"
|
|
:label="t('customer.summary.province')"
|
|
:value="entity.province.name"
|
|
/>
|
|
<VnLv
|
|
v-if="entity.country"
|
|
:label="t('customer.summary.country')"
|
|
:value="entity.country.name"
|
|
/>
|
|
<VnLv :label="t('customer.summary.street')" :value="entity.street" />
|
|
</QCard>
|
|
<QCard class="vn-one">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/fiscal-data`"
|
|
:text="t('customer.summary.fiscalData')"
|
|
/>
|
|
<VnRow class="block">
|
|
<VnLv
|
|
:label="t('customer.summary.isEqualizated')"
|
|
:value="entity.isEqualizated"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.isActive')"
|
|
:value="entity.isActive"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.verifiedData')"
|
|
:value="entity.isTaxDataChecked"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.hasToInvoice')"
|
|
:value="entity.hasToInvoice"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.notifyByEmail')"
|
|
:value="entity.isToBeMailed"
|
|
/>
|
|
<VnLv :label="t('customer.summary.vies')" :value="entity.isVies" />
|
|
</VnRow>
|
|
</QCard>
|
|
<QCard class="vn-one">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/billing-data`"
|
|
:text="t('customer.summary.billingData')"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.payMethod')"
|
|
:value="entity.payMethod.name"
|
|
/>
|
|
<VnLv :label="t('customer.summary.bankAccount')" :value="entity.iban" />
|
|
<VnLv :label="t('customer.summary.dueDay')" :value="entity.dueDay" />
|
|
<VnRow class="q-mt-sm block">
|
|
<VnLv :label="t('customer.summary.hasLcr')" :value="entity.hasLcr" />
|
|
<VnLv
|
|
:label="t('customer.summary.hasCoreVnl')"
|
|
:value="entity.hasCoreVnl"
|
|
/>
|
|
|
|
<VnLv
|
|
:label="t('customer.summary.hasB2BVnl')"
|
|
:value="entity.hasSepaVnl"
|
|
/>
|
|
</VnRow>
|
|
</QCard>
|
|
<QCard class="vn-one" v-if="entity.defaultAddress">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/address`"
|
|
:text="t('customer.summary.consignee')"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.addressName')"
|
|
:value="entity.defaultAddress.nickname"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.addressCity')"
|
|
:value="entity.defaultAddress.city"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.street')"
|
|
:value="entity.defaultAddress.street"
|
|
/>
|
|
</QCard>
|
|
<QCard class="vn-one" v-if="entity.account">
|
|
<VnTitle
|
|
:url="`#/customer/${entityId}/web-access`"
|
|
:text="t('customer.summary.webAccess')"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.username')"
|
|
:value="entity.account.name"
|
|
/>
|
|
<QCheckbox
|
|
:label="t('customer.summary.webAccess')"
|
|
v-model="entity.account.active"
|
|
:disable="true"
|
|
/>
|
|
</QCard>
|
|
<QCard class="vn-one" v-if="entity.account">
|
|
<VnTitle
|
|
target="_blank"
|
|
:url="`${grafanaUrl}/d/adjlxzv5yjt34d/analisis-de-clientes-7c-crm?orgId=1&var-clientFk=${entityId}`"
|
|
:text="t('customer.summary.businessData')"
|
|
icon="vn:grafana"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.totalGreuge')"
|
|
:value="toCurrency(entity.totalGreuge)"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.mana')"
|
|
:value="toCurrency(entity?.mana?.mana)"
|
|
/>
|
|
<VnLv
|
|
v-if="entity.claimsRatio"
|
|
:label="t('customer.summary.priceIncreasingRate')"
|
|
:value="toPercentage(priceIncreasingRate)"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.averageInvoiced')"
|
|
:value="toCurrency(entity?.averageInvoiced?.invoiced)"
|
|
/>
|
|
<VnLv
|
|
v-if="entity.claimsRatio"
|
|
:label="t('customer.summary.claimRate')"
|
|
:value="toPercentage(claimRate)"
|
|
/>
|
|
</QCard>
|
|
<QCard class="vn-one" v-if="entity.account">
|
|
<VnTitle
|
|
target="_blank"
|
|
:url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
|
|
:text="t('customer.summary.financialData')"
|
|
icon="vn:grafana"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.risk')"
|
|
:value="toCurrency(entity?.debt?.debt)"
|
|
:class="debtWarning"
|
|
:info="t('customer.summary.riskInfo')"
|
|
/>
|
|
|
|
<VnLv
|
|
:label="t('customer.summary.credit')"
|
|
:value="toCurrency(entity.credit)"
|
|
:class="creditWarning"
|
|
:info="t('customer.summary.creditInfo')"
|
|
/>
|
|
|
|
<VnLv
|
|
v-if="entity.creditInsurance"
|
|
:label="t('customer.summary.securedCredit')"
|
|
:value="toCurrency(entity.creditInsurance)"
|
|
:info="t('customer.summary.securedCreditInfo')"
|
|
/>
|
|
|
|
<VnLv
|
|
:label="t('customer.summary.balance')"
|
|
:value="toCurrency(sumRisk(entity)) || toCurrency(0)"
|
|
:info="t('customer.summary.balanceInfo')"
|
|
/>
|
|
|
|
<VnLv
|
|
v-if="entity.defaulters"
|
|
:label="t('customer.summary.balanceDue')"
|
|
:value="dashOrCurrency(balanceDue)()"
|
|
:class="balanceDueWarning"
|
|
:info="t('customer.summary.balanceDueInfo')"
|
|
/>
|
|
<VnLv
|
|
v-if="entity.recovery"
|
|
:label="t('customer.summary.recoverySince')"
|
|
:value="toDate(entity.recovery.started)"
|
|
/>
|
|
<VnLv
|
|
:label="t('customer.summary.rating')"
|
|
:value="entity.rating"
|
|
:info="t('valueInfo', { min: 1, max: 20 })"
|
|
/>
|
|
|
|
<VnLv
|
|
:label="t('customer.summary.recommendCredit')"
|
|
:value="entity.recommendedCredit"
|
|
/>
|
|
</QCard>
|
|
<QCard class="vn-max">
|
|
<VnTitle :text="t('Latest tickets')" />
|
|
<CustomerSummaryTable :id="entityId" />
|
|
</QCard>
|
|
</template>
|
|
</CardSummary>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
@media (min-width: $breakpoint-md) {
|
|
.summary .vn-one {
|
|
min-width: 300px;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<i18n>
|
|
en:
|
|
valueInfo: Value from {min} to {max}. The higher the better value
|
|
es:
|
|
valueInfo: Valor de {min} a {max}. Cuanto más alto, mejor valor
|
|
Latest tickets: Últimos tickets
|
|
</i18n>
|