salix-front/src/pages/Customer/CustomerList.vue

502 lines
14 KiB
Vue

<script setup>
import { ref, computed, markRaw } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { toDate } from 'src/filters';
import CustomerSummary from './Card/CustomerSummary.vue';
import CustomerFilter from './CustomerFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
const router = useRouter();
const tableRef = ref();
const dataKey = 'CustomerList';
const columns = computed(() => [
{
align: 'left',
name: 'id',
label: t('customer.extendedList.tableVisibleColumns.id'),
chip: {
condition: () => true,
},
isId: true,
columnFilter: {
component: 'select',
name: 'search',
attrs: {
url: 'Clients',
fields: ['id', 'name'],
},
},
},
{
align: 'left',
name: 'name',
label: t('globals.name'),
isTitle: true,
create: true,
columnClass: 'expand',
},
{
align: 'left',
name: 'socialName',
label: t('customer.extendedList.tableVisibleColumns.socialName'),
isTitle: true,
create: true,
columnClass: 'expand',
columnFilter: {
component: 'select',
attrs: {
url: 'Clients',
fields: ['socialName'],
optionLabel: 'socialName',
optionValue: 'socialName',
uppercase: false,
},
},
attrs: {
uppercase: true,
},
},
{
align: 'left',
name: 'fi',
label: t('customer.extendedList.tableVisibleColumns.fi'),
create: true,
},
{
align: 'left',
name: 'salesPersonFk',
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
optionFilter: 'firstName',
},
create: false,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
},
{
align: 'left',
name: 'credit',
label: t('customer.summary.credit'),
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
name: 'creditInsurance',
label: t('customer.extendedList.tableVisibleColumns.creditInsurance'),
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
name: 'phone',
label: t('customer.extendedList.tableVisibleColumns.phone'),
cardVisible: true,
columnFilter: {
component: 'number',
},
columnField: {
component: null,
after: {
component: markRaw(VnLinkPhone),
attrs: ({ model }) => {
return {
'phone-number': model,
};
},
},
},
},
{
align: 'left',
name: 'mobile',
label: t('customer.summary.mobile'),
cardVisible: true,
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
name: 'street',
label: t('customer.extendedList.tableVisibleColumns.street'),
create: true,
columnFilter: {
inWhere: true,
},
columnClass: 'expand',
},
{
align: 'left',
name: 'countryFk',
label: t('customer.extendedList.tableVisibleColumns.countryFk'),
columnFilter: {
component: 'select',
inWhere: true,
alias: 'c',
attrs: {
url: 'Countries',
},
},
format: (row, dashIfEmpty) => dashIfEmpty(row.country),
},
{
align: 'left',
name: 'provinceFk',
label: t('customer.extendedList.tableVisibleColumns.provinceFk'),
component: 'select',
attrs: {
url: 'Provinces',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.province),
},
{
align: 'left',
name: 'city',
label: t('customer.summary.city'),
},
{
align: 'left',
name: 'postcode',
label: t('customer.summary.postcode'),
},
{
align: 'left',
name: 'email',
label: t('globals.params.email'),
cardVisible: true,
},
{
align: 'left',
name: 'created',
label: t('customer.extendedList.tableVisibleColumns.created'),
format: ({ created }) => toDate(created),
columnFilter: {
component: 'date',
alias: 'c',
inWhere: true,
},
},
{
align: 'left',
name: 'businessTypeFk',
label: t('customer.extendedList.tableVisibleColumns.businessTypeFk'),
create: true,
component: 'select',
columnFilter: {
inWhere: true,
},
attrs: {
url: 'BusinessTypes',
fields: ['code', 'description'],
sortBy: 'description ASC ',
optionLabel: 'description',
optionValue: 'code',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.businessType),
},
{
align: 'left',
name: 'payMethodFk',
label: t('customer.summary.payMethodFk'),
columnFilter: {
component: 'select',
attrs: {
url: 'PayMethods',
},
inWhere: true,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.payMethod),
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.sageTaxTypeFk'),
name: 'sageTaxTypeFk',
columnFilter: {
component: 'select',
attrs: {
optionLabel: 'vat',
url: 'SageTaxTypes',
},
},
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTaxType),
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.sageTransactionTypeFk'),
name: 'sageTransactionTypeFk',
columnFilter: {
component: 'select',
attrs: {
optionLabel: 'transaction',
url: 'SageTransactionTypes',
},
},
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTransactionType),
},
{
align: 'left',
name: 'isActive',
label: t('customer.summary.isActive'),
chip: {
color: null,
condition: (value) => !value,
icon: 'vn:disabled',
},
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'isVies',
label: t('globals.isVies'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'isTaxDataChecked',
label: t('customer.extendedList.tableVisibleColumns.isTaxDataChecked'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'isEqualizated',
label: t('customer.summary.isEqualizated'),
create: true,
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'isFreezed',
label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
chip: {
color: null,
condition: (value) => value,
icon: 'vn:frozen',
},
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'hasToInvoice',
label: t('customer.extendedList.tableVisibleColumns.hasToInvoice'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'hasToInvoiceByAddress',
label: t('customer.extendedList.tableVisibleColumns.hasToInvoiceByAddress'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'isToBeMailed',
label: t('customer.extendedList.tableVisibleColumns.isToBeMailed'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'hasLcr',
label: t('customer.summary.hasLcr'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'hasCoreVnl',
label: t('customer.summary.hasCoreVnl'),
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
name: 'hasSepaVnl',
label: t('customer.extendedList.tableVisibleColumns.hasSepaVnl'),
columnFilter: {
inWhere: true,
},
},
{
align: 'right',
label: '',
name: 'tableActions',
actions: [
{
title: t('Client ticket list'),
icon: 'vn:ticket',
action: redirectToTicketsList,
isPrimary: true,
},
{
title: t('components.smartCard.viewSummary'),
icon: 'preview',
isPrimary: true,
action: (row) => viewSummary(row.id, CustomerSummary),
},
],
},
]);
const { viewSummary } = useSummaryDialog();
const redirectToTicketsList = (row) => {
router.push({
name: 'TicketList',
query: {
table: JSON.stringify({
clientFk: row.id,
}),
},
});
};
function handleLocation(data, location) {
const { town, code, provinceFk, countryFk } = location ?? {};
data.postcode = code;
data.city = town;
data.provinceFk = provinceFk;
data.countryFk = countryFk;
}
</script>
<template>
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="customer"
:array-data-props="{
url: 'Clients/filter',
order: ['id DESC'],
}"
>
<template #advanced-menu>
<CustomerFilter data-key="CustomerList" />
</template>
<template #body>
<VnTable
ref="tableRef"
:data-key="dataKey"
url="Clients/extendedListFilter"
:create="{
urlCreate: 'Clients/createWithUser',
title: t('globals.pageTitles.customerCreate'),
onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: {
active: true,
isEqualizated: false,
},
}"
:columns="columns"
:right-search="false"
redirect="customer"
>
<template #more-create-dialog="{ data }">
<VnSelectWorker
:label="t('customer.summary.salesPerson')"
v-model="data.salesPersonFk"
:params="{
departmentCodes: ['VT', 'shopping'],
}"
:has-avatar="true"
:id-value="data.salesPersonFk"
emit-value
auto-load
>
<template #prepend>
<VnAvatar
:worker-id="data.salesPersonFk"
color="primary"
:title="title"
/>
</template>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption
>{{ scope.opt?.nickname }},
{{ scope.opt?.code }}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelectWorker>
<VnLocation
:acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)"
/>
<QInput v-model="data.userName" :label="t('Web user')" />
<QInput
:label="t('Email')"
clearable
type="email"
v-model="data.email"
>
<template #append>
<QIcon name="info" class="cursor-info">
<QTooltip max-width="400px">{{
t('customer.basicData.youCanSaveMultipleEmails')
}}</QTooltip>
</QIcon>
</template>
</QInput>
</template>
</VnTable>
</template>
</VnSection>
</template>
<i18n>
es:
Web user: Usuario web
</i18n>
<style lang="scss" scoped>
.col-content {
border-radius: 4px;
padding: 6px;
}
</style>