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

486 lines
13 KiB
Vue

<script setup>
import { ref, computed, markRaw } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import CustomerSummary from './Card/CustomerSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import RightMenu from 'src/components/common/RightMenu.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import { toDate } from 'src/filters';
import CustomerFilter from './CustomerFilter.vue';
const { t } = useI18n();
const router = useRouter();
const tableRef = ref();
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',
label: t('globals.name'),
name: 'name',
isTitle: true,
create: true,
columnClass: 'expand',
},
{
align: 'left',
name: 'socialName',
label: t('customer.extendedList.tableVisibleColumns.socialName'),
isTitle: true,
create: true,
columnClass: 'expand',
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.fi'),
name: 'fi',
create: true,
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
name: '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',
label: t('customer.summary.credit'),
name: 'credit',
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.creditInsurance'),
name: 'creditInsurance',
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.phone'),
name: 'phone',
cardVisible: true,
columnFilter: {
component: 'number',
},
columnField: {
component: null,
after: {
component: markRaw(VnLinkPhone),
attrs: ({ model }) => {
return {
'phone-number': model,
};
},
},
},
},
{
align: 'left',
label: t('customer.summary.mobile'),
name: 'mobile',
cardVisible: true,
columnFilter: {
component: 'number',
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.street'),
name: 'street',
create: true,
columnFilter: {
inWhere: true,
},
columnClass: 'expand',
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.countryFk'),
name: 'countryFk',
columnFilter: {
component: 'select',
inWhere: true,
alias: 'c',
attrs: {
url: 'Countries',
},
},
format: (row, dashIfEmpty) => dashIfEmpty(row.country),
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.provinceFk'),
name: 'provinceFk',
component: 'select',
attrs: {
url: 'Provinces',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.province),
},
{
align: 'left',
label: t('customer.summary.city'),
name: 'city',
},
{
align: 'left',
label: t('customer.summary.postcode'),
name: 'postcode',
},
{
align: 'left',
label: t('globals.params.email'),
name: 'email',
cardVisible: true,
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.created'),
name: 'created',
format: ({ created }) => toDate(created),
columnFilter: {
component: 'date',
alias: 'c',
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.businessTypeFk'),
name: 'businessTypeFk',
create: true,
component: 'select',
attrs: {
url: 'BusinessTypes',
fields: ['code', 'description'],
sortBy: 'description ASC ',
optionLabel: 'description',
optionValue: 'code',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.businessType),
},
{
align: 'left',
label: t('customer.summary.payMethodFk'),
name: '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',
},
alias: 'sti',
inWhere: true,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTaxType),
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.sageTransactionTypeFk'),
name: 'sageTransactionTypeFk',
columnFilter: {
component: 'select',
attrs: {
optionLabel: 'transaction',
url: 'SageTransactionTypes',
},
alias: 'stt',
inWhere: true,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTransactionType),
},
{
align: 'left',
label: t('customer.summary.isActive'),
name: 'isActive',
chip: {
color: null,
condition: (value) => !value,
icon: 'vn:disabled',
},
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.isVies'),
name: 'isVies',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.isTaxDataChecked'),
name: 'isTaxDataChecked',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.summary.isEqualizated'),
name: 'isEqualizated',
create: true,
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
name: 'isFreezed',
chip: {
color: null,
condition: (value) => value,
icon: 'vn:frozen',
},
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.hasToInvoice'),
name: 'hasToInvoice',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.hasToInvoiceByAddress'),
name: 'hasToInvoiceByAddress',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.isToBeMailed'),
name: 'isToBeMailed',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.summary.hasLcr'),
name: 'hasLcr',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.summary.hasCoreVnl'),
name: 'hasCoreVnl',
columnFilter: {
inWhere: true,
},
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.hasSepaVnl'),
name: '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>
<VnSearchbar
:info="t('You can search by customer id or name')"
:label="t('Search customer')"
data-key="CustomerList"
/>
<RightMenu>
<template #right-panel>
<CustomerFilter data-key="CustomerList" />
</template>
</RightMenu>
<VnTable
ref="tableRef"
data-key="CustomerList"
url="Clients/filter"
:create="{
urlCreate: 'Clients/createWithUser',
title: t('globals.pageTitles.customerCreate'),
onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: {
active: true,
isEqualizated: false,
},
}"
order="id DESC"
:columns="columns"
redirect="customer"
:right-search="false"
auto-load
>
<template #more-create-dialog="{ data }">
<VnSelect
url="Workers/search"
v-model="data.salesPersonFk"
:label="t('customer.summary.salesPerson')"
:params="{
departmentCodes: ['VT', 'shopping'],
}"
:fields="['id', 'nickname', 'code']"
sort-by="nickname ASC"
option-label="nickname"
option-value="id"
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>
</VnSelect>
<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>
<i18n>
es:
Web user: Usuario Web
</i18n>
<style lang="scss" scoped>
.col-content {
border-radius: 4px;
padding: 6px;
}
</style>