PR-CUSTOMER #186
|
@ -16,6 +16,7 @@ import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
|||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
|
@ -44,28 +45,27 @@ const filter = {
|
|||
};
|
||||
|
||||
const tableColumnComponents = {
|
||||
payed: {
|
||||
date: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
created: {
|
||||
creationDate: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
userName: {
|
||||
employee: {
|
||||
component: QBtn,
|
||||
props: () => ({ flat: true, color: 'blue' }),
|
||||
event: () => {},
|
||||
},
|
||||
description: {
|
||||
component: QField,
|
||||
attrs: () => ({ readonly: true, dense: true }),
|
||||
reference: {
|
||||
component: 'div',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
bankFk: {
|
||||
bank: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
|
@ -75,7 +75,7 @@ const tableColumnComponents = {
|
|||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
credit: {
|
||||
havings: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
|
@ -85,7 +85,7 @@ const tableColumnComponents = {
|
|||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
isConciliate: {
|
||||
conciliated: {
|
||||
component: QCheckbox,
|
||||
props: (prop) => ({
|
||||
disable: true,
|
||||
|
@ -101,32 +101,32 @@ const columns = computed(() => [
|
|||
field: 'payed',
|
||||
format: (value) => toDate(value),
|
||||
label: t('Date'),
|
||||
name: 'payed',
|
||||
name: 'date',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'created',
|
||||
format: (value) => toDateHour(value),
|
||||
label: t('Creation date'),
|
||||
name: 'created',
|
||||
name: 'creationDate',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'userName',
|
||||
|
||||
label: t('Employee'),
|
||||
name: 'userName',
|
||||
name: 'employee',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'description',
|
||||
label: t('Reference'),
|
||||
name: 'description',
|
||||
name: 'reference',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'bankFk',
|
||||
label: t('Bank'),
|
||||
name: 'bankFk',
|
||||
name: 'bank',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
jgallego
commented
el cambo debit son euros le falta el cambo debit son euros le falta
format: (value) => toCurrency(value),
cfonseca
commented
Corregido: Corregido: f8b698e4e7
jsegarra
commented
Yo lo he visto OK en customer/1101/balance Yo lo he visto OK en customer/1101/balance
|
||||
|
@ -139,7 +139,7 @@ const columns = computed(() => [
|
|||
field: 'credit',
|
||||
jgallego
commented
en las columnas debe y haber si el valor es cero no mostrarlo en las columnas debe y haber si el valor es cero no mostrarlo
tal como lo hace en salix.
cfonseca
commented
Corregido: Corregido: d74119f433
jsegarra
commented
Yo lo he visto OK Yo lo he visto OK
|
||||
format: (value) => toCurrency(value),
|
||||
label: t('Havings'),
|
||||
name: 'credit',
|
||||
name: 'havings',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -152,7 +152,7 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
field: 'isConciliate',
|
||||
label: t('Conciliated'),
|
||||
name: 'isConciliate',
|
||||
name: 'conciliated',
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -237,36 +237,52 @@ const saveFieldValue = async (event) => {
|
|||
>
|
||||
<template
|
||||
v-if="
|
||||
props.col.name !== 'isConciliate' &&
|
||||
props.col.name !== 'description'
|
||||
props.col.name !== 'conciliated' &&
|
||||
props.col.name !== 'reference'
|
||||
"
|
||||
>
|
||||
{{ props.value }}
|
||||
</template>
|
||||
|
||||
<template v-if="props.col.name === 'description'" #control>
|
||||
<div class="self-center full-width no-outline" tabindex="0">
|
||||
{{ props.value }}
|
||||
</div>
|
||||
<QPopupEdit
|
||||
:key="props.col.name"
|
||||
label-cancel="Close"
|
||||
label-set="Save"
|
||||
v-model="props.field"
|
||||
>
|
||||
<VnInput
|
||||
@keyup.enter="saveFieldValue(props)"
|
||||
autofocus
|
||||
clearable
|
||||
dense
|
||||
v-model="props.row.description"
|
||||
<template v-if="props.col.name === 'reference'">
|
||||
<div v-if="props.row.isInvoice">
|
||||
<QBtn color="blue" dense flat>
|
||||
{{ t('bill', { ref: props.value }) }}
|
||||
</QBtn>
|
||||
<InvoiceOutDescriptorProxy
|
||||
:id="props.row.id"
|
||||
v-if="props.col.name === 'reference'"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<QBtn
|
||||
:label="props.value"
|
||||
flat
|
||||
rounded
|
||||
class="dotted-border-btn"
|
||||
no-caps
|
||||
/>
|
||||
<QPopupEdit
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Revisar, si este es el componente que acordamos en la UX/UI. Revisar, si este es el componente que acordamos en la UX/UI.
Hablar con @buezas porque ha hecho un cambio en la parte de travel/extra-community y el tipo de componente quasar que se está usando aquí no es el mismo
cfonseca
commented
Corregido: Corregido: 86199d8197
|
||||
:key="props.col.name"
|
||||
label-cancel="Close"
|
||||
label-set="Save"
|
||||
v-model="props.field"
|
||||
>
|
||||
<VnInput
|
||||
@keyup.enter="saveFieldValue(props)"
|
||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
http://localhost:5000/#!/client/100/balance/index en salix hay un registro y el boton de enviar compensación, en lilium no aparece ni el registro ni el boton http://localhost:5000/#!/client/100/balance/index en salix hay un registro y el boton de enviar compensación, en lilium no aparece ni el registro ni el boton
cfonseca
commented
Corregido: Corregido: f8b698e4e7 hace falta cambiar el icono del mail, no lo he encontrado en Lilium aun
jsegarra
commented
Efectivamente no está. Hablamos con el responsable de la iconografía Gracias Efectivamente no está.
Hablamos con el responsable de la iconografía
Gracias
jsegarra
commented
Resuelto Resuelto
|
||||
autofocus
|
||||
clearable
|
||||
dense
|
||||
v-model="props.row.description"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<WorkerDescriptorProxy
|
||||
:id="props.row.workerFk"
|
||||
v-if="props.col.name === 'userName'"
|
||||
v-if="props.col.name === 'employee'"
|
||||
/>
|
||||
</component>
|
||||
</QTr>
|
||||
|
@ -318,9 +334,17 @@ const saveFieldValue = async (event) => {
|
|||
border-radius: 4px;
|
||||
padding: 6px;
|
||||
}
|
||||
.dotted-border-btn {
|
||||
border: 1px dotted var(--vn-label);
|
||||
&:hover {
|
||||
border: 1px dotted $primary;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
jgallego
commented
esta seccion va con scroll infinito como en salix esta seccion va con scroll infinito como en salix
cfonseca
commented
Corregido: Corregido: 09a2af4124
|
||||
en:
|
||||
bill: 'N/FRA {ref}'
|
||||
es:
|
||||
Company: Empresa
|
||||
Total by company: Total por empresa
|
||||
|
@ -329,6 +353,7 @@ es:
|
|||
Creation date: Fecha de creación
|
||||
Employee: Empleado
|
||||
Reference: Referencia
|
||||
bill: 'N/INV {ref}'
|
||||
Bank: Caja
|
||||
Debit: Debe
|
||||
Havings: Haber
|
||||
|
|
|
@ -7,6 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
|
|||
import { getUrl } from 'src/composables/getUrl';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
||||
import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -277,6 +278,12 @@ const creditWarning = computed(() => {
|
|||
:value="toDate(entity.recovery.started)"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard>
|
||||
<div class="header">
|
||||
{{ t('Latest tickets') }}
|
||||
jgallego
commented
falta traduccion falta traduccion
cfonseca
commented
Corregido: Corregido: 3bcd4984f5
jsegarra
commented
Lo veo OK Lo veo OK
|
||||
</div>
|
||||
<CustomerSummaryTable />
|
||||
</QCard>
|
||||
</template>
|
||||
</CardSummary>
|
||||
</template>
|
||||
|
|
|
@ -32,9 +32,8 @@ const workersOptions = ref([]);
|
|||
const businessTypesOptions = ref([]);
|
||||
const postcodesOptions = ref([]);
|
||||
|
||||
|
||||
function handleLocation(data, location ) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {}
|
||||
function handleLocation(data, location) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||
data.postcode = code;
|
||||
data.city = town;
|
||||
data.provinceFk = provinceFk;
|
||||
|
@ -95,7 +94,7 @@ function handleLocation(data, location ) {
|
|||
<div class="col">
|
||||
<QInput
|
||||
:label="t('Business name')"
|
||||
:rules="validate('Client.socialName')"
|
||||
:rules="validate('client.socialName')"
|
||||
v-model="data.socialName"
|
||||
/>
|
||||
</div>
|
||||
|
@ -104,7 +103,7 @@ function handleLocation(data, location ) {
|
|||
<div class="col">
|
||||
<QInput
|
||||
:label="t('Street')"
|
||||
:rules="validate('Client.street')"
|
||||
:rules="validate('client.street')"
|
||||
v-model="data.street"
|
||||
/>
|
||||
</div>
|
||||
|
@ -129,7 +128,21 @@ function handleLocation(data, location ) {
|
|||
<QInput v-model="data.userName" :label="t('Web user')" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<QInput v-model="data.email" :label="t('Email')" />
|
||||
<QInput
|
||||
:label="t('Email')"
|
||||
:rules="validate('client.email')"
|
||||
clearable
|
||||
type="email"
|
||||
v-model="data.email"
|
||||
>
|
||||
<template #append>
|
||||
<QIcon name="info" class="cursor-info">
|
||||
<QTooltip>{{
|
||||
t('customer.basicData.youCanSaveMultipleEmails')
|
||||
}}</QTooltip>
|
||||
</QIcon>
|
||||
</template>
|
||||
</QInput>
|
||||
</div>
|
||||
</VnRow>
|
||||
<QCheckbox
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { QBtn, date } from 'quasar';
|
||||
|
||||
import { toCurrency } from 'src/filters';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import CustomerSummaryTableActions from './CustomerSummaryTableActions.vue';
|
||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||
import RouteDescriptorProxy from 'src/pages/Route/Card/RouteDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const rows = ref([]);
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'ticketState',
|
||||
scope: {
|
||||
fields: ['stateFk', 'code', 'alertLevel'],
|
||||
include: { relation: 'state' },
|
||||
},
|
||||
},
|
||||
{ relation: 'invoiceOut', scope: { fields: ['id'] } },
|
||||
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
||||
],
|
||||
where: { clientFk: route.params.id },
|
||||
order: ['shipped DESC', 'id'],
|
||||
limit: 10,
|
||||
};
|
||||
|
||||
const tableColumnComponents = {
|
||||
id: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
nickname: {
|
||||
component: QBtn,
|
||||
props: () => ({ flat: true, color: 'blue' }),
|
||||
event: () => {},
|
||||
},
|
||||
agency: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
route: {
|
||||
component: QBtn,
|
||||
props: () => ({ flat: true, color: 'blue' }),
|
||||
event: () => {},
|
||||
},
|
||||
packages: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
date: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
state: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
total: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
actions: {
|
||||
component: CustomerSummaryTableActions,
|
||||
props: (prop) => ({
|
||||
id: prop.row.id,
|
||||
}),
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
field: 'id',
|
||||
label: t('Id'),
|
||||
name: 'id',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'nickname',
|
||||
label: t('Nickname'),
|
||||
name: 'nickname',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: (row) => row?.agencyMode?.name,
|
||||
label: t('Agency'),
|
||||
name: 'agency',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'routeFk',
|
||||
label: t('Route'),
|
||||
name: 'route',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'packages',
|
||||
label: t('Packages'),
|
||||
name: 'packages',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: (row) => date.formatDate(row?.shipped, 'DD/MM/YYYY'),
|
||||
label: t('Date'),
|
||||
name: 'date',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: (row) => row?.ticketState?.state?.name,
|
||||
label: t('State'),
|
||||
name: 'state',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'totalWithVat',
|
||||
label: t('Total'),
|
||||
name: 'total',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'totalWithVat',
|
||||
label: '',
|
||||
name: 'actions',
|
||||
},
|
||||
]);
|
||||
|
||||
const setStateColor = (ticket) => {
|
||||
const { ticketState } = ticket;
|
||||
if (!ticketState) return;
|
||||
const codeColorMap = { OK: 'success', FREE: 'notice' };
|
||||
const alertLevelColorMap = { 0: 'alert', 1: 'warning' };
|
||||
if (codeColorMap[ticketState.code]) return codeColorMap[ticketState.code];
|
||||
return alertLevelColorMap[ticketState.alertLevel];
|
||||
};
|
||||
|
||||
const setTotalPriceColor = (ticket) => {
|
||||
const total = parseInt(ticket.totalWithVat);
|
||||
if (total > 0 && total < 50) return 'warning';
|
||||
};
|
||||
|
||||
const navigateToticketSummary = (id) => {
|
||||
router.push({
|
||||
name: 'TicketSummary',
|
||||
params: { id },
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
:filter="filter"
|
||||
@on-fetch="(data) => (rows = data)"
|
||||
auto-load
|
||||
url="Tickets"
|
||||
/>
|
||||
<QTable
|
||||
:columns="columns"
|
||||
:pagination="{ rowsPerPage: 12 }"
|
||||
:rows="rows"
|
||||
class="full-width q-mt-md"
|
||||
row-key="id"
|
||||
v-if="rows?.length"
|
||||
>
|
||||
<template #body-cell="props">
|
||||
<QTd :props="props" @click="navigateToticketSummary(props.row.id)">
|
||||
<QTr :props="props" class="cursor-pointer">
|
||||
<component
|
||||
:is="tableColumnComponents[props.col.name].component"
|
||||
@click="tableColumnComponents[props.col.name].event(props)"
|
||||
class="rounded-borders q-pa-sm"
|
||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
||||
>
|
||||
<template
|
||||
v-if="
|
||||
props.col.name === 'id' ||
|
||||
props.col.name === 'nickname' ||
|
||||
props.col.name === 'agency' ||
|
||||
props.col.name === 'route' ||
|
||||
props.col.name === 'packages'
|
||||
"
|
||||
>
|
||||
{{ props.value }}
|
||||
</template>
|
||||
<template v-if="props.col.name === 'date'">
|
||||
<QBadge class="q-pa-sm" color="warning">
|
||||
{{ props.value }}
|
||||
</QBadge>
|
||||
</template>
|
||||
<template v-if="props.col.name === 'state'">
|
||||
<QBadge :color="setStateColor(props.row)" class="q-pa-sm">
|
||||
{{ props.value }}
|
||||
</QBadge>
|
||||
</template>
|
||||
<template v-if="props.col.name === 'total'">
|
||||
<QBadge
|
||||
:color="setTotalPriceColor(props.row)"
|
||||
class="q-pa-sm"
|
||||
v-if="setTotalPriceColor(props.row)"
|
||||
>
|
||||
{{ toCurrency(props.value) }}
|
||||
</QBadge>
|
||||
<div v-else>{{ toCurrency(props.value) }}</div>
|
||||
</template>
|
||||
<CustomerDescriptorProxy
|
||||
:id="props.row.clientFk"
|
||||
v-if="props.col.name === 'nickname'"
|
||||
/>
|
||||
<RouteDescriptorProxy
|
||||
:id="props.row.routeFk"
|
||||
v-if="props.col.name === 'route'"
|
||||
/>
|
||||
</component>
|
||||
</QTr>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Id: Id
|
||||
Nickname: Alias
|
||||
Agency: Agencia
|
||||
Route: Ruta
|
||||
Packages: Bultos
|
||||
Date: Fecha
|
||||
State: Estado
|
||||
Total: Total
|
||||
</i18n>
|
|
@ -0,0 +1,53 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
import TicketSummaryDialog from 'src/pages/Ticket/Card/TicketSummaryDialog.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Eliminar porque sale warning Eliminar porque sale warning
wbuezas
commented
Asignación de prop eliminada: Commit: Asignación de prop eliminada:
Commit: https://gitea.verdnatura.es/hyervoni/salix-front-mindshore/commit/107eaea704c5603a1bd72ae85e978199e51b88e9
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const viewSummary = () => {
|
||||
quasar.dialog({
|
||||
component: TicketSummaryDialog,
|
||||
componentProps: {
|
||||
id: $props.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<QIcon color="primary" name="vn:lines" size="sm">
|
||||
<QTooltip>
|
||||
{{ t('Go to lines') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
@click.stop="viewSummary"
|
||||
class="q-ml-md"
|
||||
color="primary"
|
||||
name="preview"
|
||||
size="sm"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Preview') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Go to lines: Ir a lineas
|
||||
Preview: Vista previa
|
||||
</i18n>
|
El usuario en minusculas igual que salix (cambiar para todos los sitios que se muestre)
Corregido:
663010a0d4
Yo lo he visto OK