PR-CUSTOMER #186
|
@ -135,7 +135,7 @@ async function save() {
|
|||
} else {
|
||||
response = await axios.patch($props.urlUpdate || $props.url, body);
|
||||
}
|
||||
emit('onDataSaved', formData.value, response.data);
|
||||
emit('onDataSaved', formData.value, response?.data);
|
||||
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
||||
hasChanges.value = false;
|
||||
} catch (err) {
|
||||
|
|
|
@ -206,6 +206,17 @@ async function togglePinned(item, event) {
|
|||
<template v-if="$props.source === 'card'">
|
||||
<template v-for="item in items" :key="item.name">
|
||||
<LeftMenuItem v-if="!item.children" :item="item" />
|
||||
<QList v-else>
|
||||
<QExpansionItem
|
||||
v-ripple
|
||||
clickable
|
||||
:icon="item.icon"
|
||||
:label="t(item.title)"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<LeftMenuItemGroup :item="item" />
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
</template>
|
||||
</QList>
|
||||
|
|
|
@ -131,6 +131,8 @@ export default {
|
|||
log: 'Log',
|
||||
sms: 'Sms',
|
||||
creditManagement: 'Credit management',
|
||||
creditContracts: 'Credit contracts',
|
||||
creditOpinion: 'Credit opinion',
|
||||
others: 'Others',
|
||||
},
|
||||
list: {
|
||||
|
|
|
@ -131,6 +131,8 @@ export default {
|
|||
log: 'Historial',
|
||||
sms: 'Sms',
|
||||
creditManagement: 'Gestión de crédito',
|
||||
creditContracts: 'Contratos de crédito',
|
||||
creditOpinion: 'Opinión de crédito',
|
||||
others: 'Otros',
|
||||
},
|
||||
list: {
|
||||
|
|
|
@ -1,3 +1,282 @@
|
|||
<script setup>
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { date, QCheckbox, QBtn, useQuasar } from 'quasar';
|
||||
|
||||
import { toCurrency } from 'src/filters';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const stateStore = useStateStore();
|
||||
|
||||
const clientRisks = ref(null);
|
||||
const companiesOptions = ref([]);
|
||||
const companyId = ref(442);
|
||||
const rows = ref(null);
|
||||
const workerId = ref(0);
|
||||
const receiptsRef = ref(null);
|
||||
const clientRisksRef = ref(null);
|
||||
|
||||
const filterCompanies = { order: ['code'] };
|
||||
const params = {
|
||||
clientId: `${route.params.id}`,
|
||||
companyId: companyId.value,
|
||||
filter: { limit: 20 },
|
||||
};
|
||||
const filter = {
|
||||
include: { relation: 'company', scope: { fields: ['code'] } },
|
||||
where: { clientFk: `${route.params.id}`, companyFk: companyId.value },
|
||||
};
|
||||
|
||||
const tableColumnComponents = {
|
||||
payed: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
created: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
userName: {
|
||||
component: QBtn,
|
||||
props: () => ({ flat: true, color: 'blue' }),
|
||||
event: (prop) => {
|
||||
workerId.value = prop.row.clientFk;
|
||||
},
|
||||
},
|
||||
description: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
bankFk: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
debit: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
credit: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
balance: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
isConciliate: {
|
||||
component: QCheckbox,
|
||||
props: (prop) => ({
|
||||
disable: true,
|
||||
'model-value': Boolean(prop.value),
|
||||
}),
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
field: 'payed',
|
||||
format: (value) => date.formatDate(value, 'DD/MM/YYYY'),
|
||||
label: t('Date'),
|
||||
name: 'payed',
|
||||
},
|
||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
todos los campos de euros deben de ir alineados a la derecha como en salix. todos los campos de euros deben de ir alineados a la derecha como en salix.
jsegarra
commented
Así se ve para el cliente 1101. Ver imagen adjunta Así se ve para el cliente 1101. Ver imagen adjunta
Sin embargo, el cursor cambia a "la mano", induciendo a que se puede cambiar, cuando debería aparecer el prohibido o cambiar el color del checkbox a gris
cfonseca
commented
Corregido, campos de tipo moneda alineados a la derecha y el checkbox deshabilitado: Corregido, campos de tipo moneda alineados a la derecha y el checkbox deshabilitado: 0aa5a051fb
jsegarra
commented
Yo lo he visto OK Yo lo he visto OK
El checkbox es de color naranja pero se ve que está deshabilitado y tiene el cursor en prohibido
|
||||
{
|
||||
align: 'left',
|
||||
field: 'created',
|
||||
format: (value) => date.formatDate(value, 'DD/MM/YYYY hh:mm'),
|
||||
label: t('Creation date'),
|
||||
name: 'created',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'userName',
|
||||
label: t('Employee'),
|
||||
name: 'userName',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
jgallego
commented
El usuario en minusculas igual que salix (cambiar para todos los sitios que se muestre) El usuario en minusculas igual que salix (cambiar para todos los sitios que se muestre)
cfonseca
commented
Corregido: Corregido: 663010a0d4
jsegarra
commented
Yo lo he visto OK Yo lo he visto OK
|
||||
field: 'description',
|
||||
label: t('Reference'),
|
||||
name: 'description',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'bankFk',
|
||||
label: t('Bank'),
|
||||
name: 'bankFk',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'debit',
|
||||
label: t('Debit'),
|
||||
name: 'debit',
|
||||
},
|
||||
{
|
||||
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
|
||||
align: 'left',
|
||||
field: 'credit',
|
||||
format: (value) => toCurrency(value),
|
||||
label: t('Havings'),
|
||||
name: '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
|
||||
align: 'left',
|
||||
field: (value) => value.debit - value.credit,
|
||||
format: (value) => toCurrency(value),
|
||||
label: t('Balance'),
|
||||
name: 'balance',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'isConciliate',
|
||||
label: t('Conciliated'),
|
||||
name: 'isConciliate',
|
||||
},
|
||||
jgallego
commented
Revisar en salix el valor del campo balance el balance es un saldo por tanto, va acumulando el balance anterior +- el valor del debe/haber Revisar en salix el valor del campo balance
http://localhost:5000/#!/client/1101/balance/index
respecto a lilium
http://localhost:9000/#/customer/1101/balance
el balance es un saldo por tanto, va acumulando el balance anterior +- el valor del debe/haber
cfonseca
commented
Corregido: Corregido: d74119f433
jsegarra
commented
Not fixed! Ver imagen Not fixed! Ver imagen
cfonseca
commented
Corregido el valor del campo balance: Corregido el valor del campo balance: 38d3d49ecb
jsegarra
commented
He probado con los clientes 1101, 1102 y 1103 y lo he visto OK He probado con los clientes 1101, 1102 y 1103 y lo he visto OK
|
||||
]);
|
||||
|
||||
const getData = () => {
|
||||
stateStore.rightDrawer = true;
|
||||
receiptsRef.value?.fetch();
|
||||
clientRisksRef.value?.fetch();
|
||||
};
|
||||
|
||||
const showNewPaymentDialog = () => {
|
||||
quasar.dialog({
|
||||
jgallego
commented
no se porque el conciliado al lado del checkbox tiene un 1, http://localhost:9000/#/customer/1101/balance no se porque el conciliado al lado del checkbox tiene un 1, http://localhost:9000/#/customer/1101/balance
cfonseca
commented
Corregido: Corregido: d74119f433
jsegarra
commented
Yo lo he visto OK Yo lo he visto OK
|
||||
component: CustomerNewPayment,
|
||||
componentProps: {
|
||||
companyId: companyId.value,
|
||||
totalCredit: clientRisks.value[0]?.amount,
|
||||
promise: getData,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const updateCompanyId = (id) => {
|
||||
if (id) companyId.value = id;
|
||||
getData();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center">Balance</div>
|
||||
<FetchData
|
||||
:filter="filterCompanies"
|
||||
@on-fetch="(data) => (companiesOptions = data)"
|
||||
auto-load
|
||||
url="Companies"
|
||||
/>
|
||||
<FetchData
|
||||
:params="params"
|
||||
@on-fetch="(data) => (rows = data)"
|
||||
auto-load
|
||||
ref="receiptsRef"
|
||||
url="Receipts/filter"
|
||||
/>
|
||||
<FetchData
|
||||
:filter="filter"
|
||||
@on-fetch="(data) => (clientRisks = data)"
|
||||
auto-load
|
||||
ref="clientRisksRef"
|
||||
url="ClientRisks"
|
||||
/>
|
||||
|
||||
<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">
|
||||
<QTr :props="props" class="cursor-pointer">
|
||||
<component
|
||||
:is="tableColumnComponents[props.col.name].component"
|
||||
class="col-content"
|
||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
||||
@click="tableColumnComponents[props.col.name].event(props)"
|
||||
>
|
||||
<template v-if="props.col.name !== 'isConciliate'">
|
||||
{{ props.value }}
|
||||
</template>
|
||||
<WorkerDescriptorProxy :id="workerId" />
|
||||
</component>
|
||||
</QTr>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
|
||||
<h5 class="flex justify-center label-color" v-else>
|
||||
{{ t('globals.noResults') }}
|
||||
</h5>
|
||||
|
||||
<QDrawer :width="256" show-if-above side="right" v-model="stateStore.rightDrawer">
|
||||
<div class="q-mt-xl q-px-md">
|
||||
<VnSelectFilter
|
||||
:label="t('Company')"
|
||||
:options="companiesOptions"
|
||||
@update:model-value="updateCompanyId($event)"
|
||||
hide-selected
|
||||
option-label="code"
|
||||
option-value="id"
|
||||
v-model="companyId"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<QCard class="q-ma-md q-pa-md q-mt-lg" v-if="rows?.length">
|
||||
<QCardSection>
|
||||
<div class="flex justify-center text-subtitle1 text-bold">
|
||||
{{ t('Total by company') }}
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<div class="q-mr-sm" v-if="clientRisks?.length">
|
||||
{{ clientRisks[0].company.code }}:
|
||||
</div>
|
||||
<div v-if="clientRisks?.length">
|
||||
{{ toCurrency(clientRisks[0].amount) }}
|
||||
</div>
|
||||
</div>
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
</QDrawer>
|
||||
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn @click.stop="showNewPaymentDialog()" color="primary" fab icon="add" />
|
||||
<QTooltip>
|
||||
{{ t('New payment') }}
|
||||
</QTooltip>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
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
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Company: Empresa
|
||||
Total by company: Total por empresa
|
||||
New payment: Añadir pago
|
||||
Date: Fecha
|
||||
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
|
||||
Creation date: Fecha de creación
|
||||
Employee: Empleado
|
||||
Reference: Referencia
|
||||
Bank: Caja
|
||||
Debit: Debe
|
||||
Havings: Haber
|
||||
Balance: Balance
|
||||
Conciliated: Conciliado
|
||||
</i18n>
|
||||
|
|
|
@ -137,21 +137,15 @@ const toCustomerConsigneeEdit = (consigneeId) => {
|
|||
</div>
|
||||
</div>
|
||||
</QCard>
|
||||
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn
|
||||
@click.stop="toCustomerConsigneeCreate()"
|
||||
color="primary"
|
||||
fab
|
||||
icon="add"
|
||||
/>
|
||||
<QTooltip>
|
||||
{{ t('New consignee') }}
|
||||
</QTooltip>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
jgallego
commented
error que no pertenece a esta linea, pero sí al fichero: error que no pertenece a esta linea, pero sí al fichero:
En la linea
`<QIcon name="star" size="md" color="primary" />`
se muestra el icono de la estrella, debe estar marcado si el campos isDefaultAddress es <> false
se puede observar un ejemplo en http://localhost:5000/#!/client/1110/address/index
cfonseca
commented
Corregido: Corregido: 86199d8197
jsegarra
commented
@jgallego Yo lo he visto OK @jgallego Yo lo he visto OK
|
||||
</VnPaginate>
|
||||
</QCard>
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn @click.stop="toCustomerConsigneeCreate()" color="primary" fab icon="add" />
|
||||
<QTooltip>
|
||||
{{ t('New consignee') }}
|
||||
</QTooltip>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div class="flex justify-center">Customer credit contracts</div>
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div class="flex justify-center">Customer credit opinion</div>
|
||||
</template>
|
|
@ -1,22 +1,24 @@
|
|||
<script setup>
|
||||
import { ref, computed, onBeforeMount, onMounted } from 'vue';
|
||||
import { ref, computed, onBeforeMount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { date, QBtn } from 'quasar';
|
||||
|
||||
import { toCurrency, toDate } from 'src/filters';
|
||||
import { toCurrency } from 'src/filters';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const stateStore = useStateStore();
|
||||
|
||||
const arrayData = ref(null);
|
||||
const workerId = ref(0);
|
||||
const rows = computed(() => arrayData.value.store.data);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const filter = {
|
||||
|
@ -29,7 +31,7 @@ onBeforeMount(async () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
where: { clientFk: '1' },
|
||||
where: { clientFk: `${route.params.id}` },
|
||||
order: ['created DESC'],
|
||||
limit: 20,
|
||||
};
|
||||
|
@ -41,16 +43,6 @@ onBeforeMount(async () => {
|
|||
stateStore.rightDrawer = true;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const filteredColumns = columns.value.filter(
|
||||
(col) => col.name !== 'actions' && col.name !== 'customerStatus'
|
||||
);
|
||||
allColumnNames.value = filteredColumns.map((col) => col.name);
|
||||
});
|
||||
|
||||
const rows = computed(() => arrayData.value.store.data);
|
||||
const allColumnNames = ref([]);
|
||||
|
||||
const tableColumnComponents = {
|
||||
created: {
|
||||
component: 'span',
|
||||
|
|
|
@ -1,3 +1,202 @@
|
|||
<script setup>
|
||||
import { ref, computed, onBeforeMount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { date, QBtn } from 'quasar';
|
||||
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { toCurrency } from 'src/filters';
|
||||
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const stateStore = useStateStore();
|
||||
|
||||
const arrayData = ref(null);
|
||||
const totalAmount = ref(0);
|
||||
const workerId = ref(0);
|
||||
const rows = computed(() => arrayData.value.store.data);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'greugeType',
|
||||
scope: {
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
},
|
||||
],
|
||||
order: 'shipped DESC, amount',
|
||||
where: {
|
||||
clientFk: `${route.params.id}`,
|
||||
},
|
||||
limit: 20,
|
||||
};
|
||||
|
||||
arrayData.value = useArrayData('CustomerGreugesCard', {
|
||||
url: 'greuges',
|
||||
filter,
|
||||
});
|
||||
await arrayData.value.fetch({ append: false });
|
||||
totalAmount.value = arrayData.value.store.data.reduce((accumulator, currentValue) => {
|
||||
return accumulator + currentValue.amount;
|
||||
}, 0);
|
||||
stateStore.rightDrawer = true;
|
||||
});
|
||||
|
||||
const tableColumnComponents = {
|
||||
date: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
createdBy: {
|
||||
component: QBtn,
|
||||
props: () => ({ flat: true, color: 'blue' }),
|
||||
event: (prop) => {
|
||||
selectWorkerId(prop.row.clientFk);
|
||||
},
|
||||
},
|
||||
comment: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
type: {
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Duda, cuando actualicemos con dev no tendremos conflicto? Duda, cuando actualicemos con dev no tendremos conflicto?
wbuezas
commented
Se reemplazo Commit: Se reemplazo `toDateHourMinSec` por las nuevas utils ubicadas en `date.js`
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/73ea49df6340e32cc035ac132e666c4be2d1fa27
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
amount: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
field: 'shipped',
|
||||
label: t('Date'),
|
||||
name: 'date',
|
||||
format: (value) => date.formatDate(value, 'DD/MM/YYYY hh:mm:ss'),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: (value) => value.user.name,
|
||||
label: t('Created by'),
|
||||
name: 'createdBy',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'description',
|
||||
label: t('Comment'),
|
||||
name: 'comment',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: (value) => value.greugeType.name,
|
||||
label: t('Type'),
|
||||
name: 'type',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'amount',
|
||||
label: t('Amount'),
|
||||
name: 'amount',
|
||||
format: (value) => toCurrency(value),
|
||||
},
|
||||
]);
|
||||
|
||||
const selectWorkerId = (id) => {
|
||||
workerId.value = id;
|
||||
};
|
||||
|
||||
const toCustomerGreugeCreate = () => {
|
||||
router.push({ name: 'CustomerGreugeCreate' });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center">Greuges</div>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<QCard class="full-width" v-if="totalAmount">
|
||||
<h6 class="flex justify-end q-my-lg q-pr-lg">
|
||||
<span class="label-color q-mr-md">{{ t('Total') }}:</span>
|
||||
{{ toCurrency(totalAmount) }}
|
||||
</h6>
|
||||
</QCard>
|
||||
|
||||
<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">
|
||||
<QTr :props="props" class="cursor-pointer">
|
||||
<component
|
||||
:is="tableColumnComponents[props.col.name].component"
|
||||
class="col-content"
|
||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
||||
@click="tableColumnComponents[props.col.name].event(props)"
|
||||
>
|
||||
{{ props.value }}
|
||||
<WorkerDescriptorProxy :id="workerId" />
|
||||
</component>
|
||||
</QTr>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
|
||||
<QCard class="full-width" v-else>
|
||||
<h5 class="flex justify-center label-color">
|
||||
{{ t('globals.noResults') }}
|
||||
</h5>
|
||||
</QCard>
|
||||
</QPage>
|
||||
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn @click.stop="toCustomerGreugeCreate()" color="primary" fab icon="add" />
|
||||
<QTooltip>
|
||||
{{ t('New greuge') }}
|
||||
</QTooltip>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.consignees-card {
|
||||
border: 2px solid var(--vn-light-gray);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.label-color {
|
||||
color: var(--vn-label);
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Total: Total
|
||||
Date: Fecha
|
||||
Created by: Creado por
|
||||
Comment: Comentario
|
||||
Type: Tipo
|
||||
Amount: Importe
|
||||
New greuge: Nuevo greuge
|
||||
</i18n>
|
||||
|
|
|
@ -60,7 +60,7 @@ const toCustomerNoteCreate = () => {
|
|||
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn
|
||||
@click.stop="toCustomerConsigneeCreate()"
|
||||
@click.stop="toCustomerNoteCreate()"
|
||||
color="primary"
|
||||
fab
|
||||
icon="add"
|
||||
|
|
|
@ -1,3 +1,157 @@
|
|||
<script setup>
|
||||
import { ref, computed, onBeforeMount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { date, QBtn } from 'quasar';
|
||||
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { toCurrency } from 'src/filters';
|
||||
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const stateStore = useStateStore();
|
||||
|
||||
const arrayData = ref(null);
|
||||
const workerId = ref(0);
|
||||
const rows = computed(() => arrayData.value.store.data);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const filter = {
|
||||
where: { clientFk: `${route.params.id}` },
|
||||
order: ['started DESC'],
|
||||
limit: 20,
|
||||
};
|
||||
|
||||
arrayData.value = useArrayData('CustomerRecoveriesCard', {
|
||||
url: 'Recoveries',
|
||||
filter,
|
||||
});
|
||||
await arrayData.value.fetch({ append: false });
|
||||
stateStore.rightDrawer = true;
|
||||
});
|
||||
|
||||
const tableColumnComponents = {
|
||||
since: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
to: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
amount: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
period: {
|
||||
component: 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
field: 'started',
|
||||
label: t('Since'),
|
||||
name: 'since',
|
||||
format: (value) => date.formatDate(value, 'DD/MM/YYYY'),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'finished',
|
||||
label: t('To'),
|
||||
name: 'to',
|
||||
format: (value) => date.formatDate(value, 'DD/MM/YYYY'),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'amount',
|
||||
label: t('Amount'),
|
||||
name: 'amount',
|
||||
format: (value) => toCurrency(value),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
field: 'period',
|
||||
label: t('Period'),
|
||||
name: 'period',
|
||||
},
|
||||
]);
|
||||
|
||||
const toCustomerRecoverieCreate = () => {
|
||||
router.push({ name: 'CustomerRecoverieCreate' });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center">Recoveries</div>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<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">
|
||||
<QTr :props="props" class="cursor-pointer">
|
||||
<component
|
||||
:is="tableColumnComponents[props.col.name].component"
|
||||
class="col-content"
|
||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
||||
@click="tableColumnComponents[props.col.name].event(props)"
|
||||
>
|
||||
{{ props.value }}
|
||||
<WorkerDescriptorProxy :id="workerId" />
|
||||
</component>
|
||||
</QTr>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
|
||||
<QCard class="full-width" v-else>
|
||||
<h5 class="flex justify-center label-color">
|
||||
{{ t('globals.noResults') }}
|
||||
</h5>
|
||||
</QCard>
|
||||
</QPage>
|
||||
|
||||
<QPageSticky :offset="[18, 18]">
|
||||
<QBtn @click.stop="toCustomerRecoverieCreate()" color="primary" fab icon="add" />
|
||||
<QTooltip>
|
||||
{{ t('New recoverie') }}
|
||||
</QTooltip>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.consignees-card {
|
||||
border: 2px solid var(--vn-light-gray);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.label-color {
|
||||
color: var(--vn-label);
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Since: Desde
|
||||
To: Hasta
|
||||
Amount: Importe
|
||||
Period: Periodo
|
||||
New recoverie: Nuevo recobro
|
||||
</i18n>
|
||||
|
|
|
@ -1,3 +1,69 @@
|
|||
<script setup>
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
Falta botón de cambiar contraseña Falta botón de cambiar contraseña
Los campos no son clearables
cfonseca
commented
Corregido: Corregido: c0a9835e80
jsegarra
commented
Aparece el botón de cambiar contraseña, sin embargo, el formato del layout no es el estándar Aparece el botón de cambiar contraseña, sin embargo, el formato del layout no es el estándar
cfonseca
commented
Corregido: Corregido: ebd1ee07f4
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const filter = { where: { id: `${route.params.id}` } };
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center">Web access</div>
|
||||
<FormModel
|
||||
jgallego
commented
desde salix http://localhost:9000/#/customer/1101/web-access cambio BruceWayne por BruceWayne4 y funciona, desde http://localhost:9000/#/customer/1101/web-access me da dos errores
"UPDATE Parece que en el set falta el name = xx desde salix http://localhost:9000/#/customer/1101/web-access cambio BruceWayne por BruceWayne4 y funciona, desde http://localhost:9000/#/customer/1101/web-access me da dos errores
message
:
"ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE `id`=1101' at line 1"
name
:
"Error"
sql
:
"UPDATE `account`.`user` SET WHERE `id`=1101"
Parece que en el set falta el name = xx
cfonseca
commented
Corregido: Corregido: 5e2c668fec
jsegarra
commented
Yo lo he visto OK Yo lo he visto OK
|
||||
:filter="filter"
|
||||
:observe-form-changes="false"
|
||||
:url-update="`Clients/${route.params.id}/updateUser`"
|
||||
:url="'VnUsers/preview'"
|
||||
model="client"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<div
|
||||
v-for="(item, index) in data"
|
||||
:key="index"
|
||||
:class="{
|
||||
'q-mb-md': index < data.length - 1,
|
||||
}"
|
||||
>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<QCheckbox
|
||||
:label="t('Enable web access')"
|
||||
v-model="item.active"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput :label="t('User')" v-model="item.name" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput :label="t('Recovery email')" v-model="item.email">
|
||||
<template #append>
|
||||
<QIcon name="info" class="cursor-pointer">
|
||||
<QTooltip>{{
|
||||
t(
|
||||
'This email is used for user to regain access their account'
|
||||
)
|
||||
}}</QTooltip>
|
||||
</QIcon>
|
||||
</template>
|
||||
</VnInput>
|
||||
</div>
|
||||
</VnRow>
|
||||
</div>
|
||||
</template>
|
||||
</FormModel>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Enable web access: Habilitar acceso web
|
||||
User: Usuario
|
||||
Recovery email: Correo de recuperacion
|
||||
This email is used for user to regain access their account: Este correo electrónico se usa para que el usuario recupere el acceso a su cuenta
|
||||
</i18n>
|
||||
|
|
|
@ -12,7 +12,7 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import VnSelectCreate from 'src/components/common/VnSelectCreate.vue';
|
||||
import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
|
||||
import CustomsNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
|
||||
import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
@ -233,7 +233,7 @@ const refreshData = () => {
|
|||
v-model="data.customsAgentFk"
|
||||
>
|
||||
<template #form>
|
||||
<CustomsNewCustomsAgent @on-data-saved="refreshData()" />
|
||||
<CustomerNewCustomsAgent @on-data-saved="refreshData()" />
|
||||
</template>
|
||||
</VnSelectCreate>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<script setup>
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
El worker descriptor no va bien, porque usa clientFk en vez de worker, ya hay un comentario similar. El worker descriptor no va bien, porque usa clientFk en vez de worker, ya hay un comentario similar.
El campo/ valor de fecha no coincide...induce a error.
Las validaciones no se están aplicando
cfonseca
commented
Corregido: Corregido: 11eb597fa3
jsegarra
commented
Está OK. Está OK.
Por mi parte queda comprobar si ha habido cambio de criterio en el WorkerDescriptorProxy
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const initialData = reactive({
|
||||
amount: null,
|
||||
description: null,
|
||||
greugeTypeFk: null,
|
||||
shipped: '2001-01-01T11:00:00.000Z',
|
||||
});
|
||||
|
||||
const greugeTypes = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
initialData.clientFk = `${route.params.id}`;
|
||||
});
|
||||
|
||||
const toCustomerGreuges = () => {
|
||||
router.push({
|
||||
name: 'CustomerGreuges',
|
||||
params: {
|
||||
id: route.params.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data @on-fetch="(data) => (greugeTypes = data)" auto-load url="greugeTypes" />
|
||||
|
||||
<FormModel
|
||||
:form-initial-data="initialData"
|
||||
:observe-form-changes="false"
|
||||
@on-data-saved="toCustomerGreuges()"
|
||||
model="client"
|
||||
url-create="Greuges"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput :label="t('Amount')" type="number" v-model="data.amount" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInputDate :label="t('Date')" v-model="data.shipped" />
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput :label="t('Comment')" v-model="data.description" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Type')"
|
||||
:options="greugeTypes"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="data.greugeTypeFk"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
</template>
|
||||
</FormModel>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add-icon {
|
||||
cursor: pointer;
|
||||
background-color: $primary;
|
||||
border-radius: 50px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Amount: Importe
|
||||
Date: Fecha
|
||||
Comment: Comentario
|
||||
Type: Tipo
|
||||
</i18n>
|
|
@ -0,0 +1,286 @@
|
|||
<script setup>
|
||||
import { onBeforeMount, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const $props = defineProps({
|
||||
companyId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
totalCredit: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
promise: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const closeButton = ref(null);
|
||||
const urlCreate = ref([]);
|
||||
const companyOptions = ref([]);
|
||||
const bankOptions = ref([]);
|
||||
const clientFindOne = ref([]);
|
||||
const deliveredAmount = ref(null);
|
||||
const amountToReturn = ref(null);
|
||||
const viewRecipt = ref(true);
|
||||
const sendEmail = ref(false);
|
||||
const isLoading = ref(false);
|
||||
|
||||
const filterBanks = {
|
||||
fields: ['id', 'bank', 'accountingTypeFk'],
|
||||
include: { relation: 'accountingType' },
|
||||
order: 'id',
|
||||
limit: 30,
|
||||
};
|
||||
|
||||
const filterClientFindOne = {
|
||||
fields: ['email'],
|
||||
where: {
|
||||
id: `${route.params.id}`,
|
||||
},
|
||||
};
|
||||
|
||||
const initialData = reactive({
|
||||
amountPaid: $props.totalCredit,
|
||||
bankFk: null,
|
||||
clientFk: `${route.params.id}`,
|
||||
companyFk: $props.companyId,
|
||||
compensationAccount: null,
|
||||
description: null,
|
||||
email: clientFindOne.value.email,
|
||||
payed: null,
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
urlCreate.value = `Clients/${route.params.id}/createReceipt`;
|
||||
});
|
||||
|
||||
const setPaymentType = (id) => {
|
||||
initialData.payed = '2001-01-01T11:00:00.000Z';
|
||||
if (id === 1) initialData.description = 'Credit card';
|
||||
if (id === 2) initialData.description = 'Cash';
|
||||
if (id === 3 || id === 3117) initialData.description = '';
|
||||
if (id === 4) initialData.description = 'Transfer';
|
||||
};
|
||||
|
||||
const calculateFromAmount = (event) => {
|
||||
amountToReturn.value = parseFloat(event) * -1 + parseFloat(deliveredAmount.value);
|
||||
};
|
||||
|
||||
const calculateFromDeliveredAmount = (event) => {
|
||||
amountToReturn.value = parseFloat($props.totalCredit) * -1 + parseFloat(event);
|
||||
};
|
||||
|
||||
const setClientEmail = (data) => {
|
||||
initialData.email = data.email;
|
||||
};
|
||||
|
||||
const onDataSaved = async () => {
|
||||
isLoading.value = true;
|
||||
if ($props.promise) {
|
||||
try {
|
||||
await $props.promise();
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
if (closeButton.value) closeButton.value.click();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QDialog ref="dialogRef">
|
||||
<fetch-data
|
||||
@on-fetch="(data) => (companyOptions = data)"
|
||||
auto-load
|
||||
url="Companies"
|
||||
/>
|
||||
<fetch-data
|
||||
:filter="filterBanks"
|
||||
@on-fetch="(data) => (bankOptions = data)"
|
||||
auto-load
|
||||
url="Banks"
|
||||
/>
|
||||
<fetch-data
|
||||
:filter="filterClientFindOne"
|
||||
@on-fetch="setClientEmail"
|
||||
auto-load
|
||||
url="Clients/findOne"
|
||||
/>
|
||||
|
||||
<FormModel
|
||||
:default-actions="false"
|
||||
:form-initial-data="initialData"
|
||||
:observe-form-changes="false"
|
||||
:url-create="urlCreate"
|
||||
@on-data-saved="onDataSaved()"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
||||
<QIcon name="close" size="sm" />
|
||||
</span>
|
||||
|
||||
<h5 class="flex justify-center q-mt-xs">
|
||||
{{ t('New payment') }}
|
||||
</h5>
|
||||
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Porqué está en el centro si el resto de dialogos si el resto está a un lateral? Porqué está en el centro si el resto de dialogos si el resto está a un lateral?
cfonseca
commented
Corregido: Corregido: 3cf3687b84
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInputDate
|
||||
:label="t('Date')"
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
Los campos no son clearables Los campos no son clearables
cfonseca
commented
Corregido: Corregido: 7f1c4690e8
|
||||
:required="true"
|
||||
v-model="data.payed"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Company')"
|
||||
:options="companyOptions"
|
||||
:required="true"
|
||||
hide-selected
|
||||
option-label="code"
|
||||
option-value="id"
|
||||
v-model="data.companyFk"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Bank')"
|
||||
:options="bankOptions"
|
||||
:required="true"
|
||||
@update:model-value="setPaymentType($event)"
|
||||
hide-selected
|
||||
option-label="bank"
|
||||
option-value="id"
|
||||
v-model="data.bankFk"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt.id }}: {{ scope.opt.bank }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('Amount')"
|
||||
:required="true"
|
||||
@update:model-value="calculateFromAmount($event)"
|
||||
type="number"
|
||||
v-model.number="data.amountPaid"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<div class="text-h6" v-if="data.bankFk === 3 || data.bankFk === 3117">
|
||||
{{ t('Compensation') }}
|
||||
</div>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col" v-if="data.bankFk === 3 || data.bankFk === 3117">
|
||||
<VnInput
|
||||
:label="t('Compensation account')"
|
||||
v-model="data.compensationAccount"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('Reference')"
|
||||
:required="true"
|
||||
v-model="data.description"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<div class="q-mt-lg" v-if="data.bankFk === 2">
|
||||
<div class="text-h6">{{ t('Cash') }}</div>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('Delivered amount')"
|
||||
@update:model-value="calculateFromDeliveredAmount($event)"
|
||||
type="number"
|
||||
v-model="deliveredAmount"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('Amount to return')"
|
||||
disable
|
||||
type="number"
|
||||
v-model="amountToReturn"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<QCheckbox v-model="viewRecipt" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<QCheckbox v-model="sendEmail" />
|
||||
</div>
|
||||
</VnRow>
|
||||
</div>
|
||||
|
||||
<div class="q-mt-lg row justify-end">
|
||||
<QBtn
|
||||
:disabled="isLoading"
|
||||
:label="t('globals.cancel')"
|
||||
:loading="isLoading"
|
||||
class="q-ml-sm"
|
||||
color="primary"
|
||||
flat
|
||||
type="reset"
|
||||
v-close-popup
|
||||
/>
|
||||
<QBtn
|
||||
:disabled="isLoading"
|
||||
:label="t('globals.save')"
|
||||
:loading="isLoading"
|
||||
color="primary"
|
||||
type="submit"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</FormModel>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
New payment: Añadir pago
|
||||
Date: Fecha
|
||||
Company: Empresa
|
||||
Bank: Caja
|
||||
Amount: Importe
|
||||
Reference: Referencia
|
||||
Cash: Efectivo
|
||||
Delivered amount: Cantidad entregada
|
||||
Amount to return: Cantidad a devolver
|
||||
View recipt: Ver recibido
|
||||
Send email: Enviar correo
|
||||
Compensation: Compensación
|
||||
Compensation account: Cuenta para compensar
|
||||
</i18n>
|
|
@ -32,8 +32,8 @@ const toCustomerNotes = () => {
|
|||
<FormModel
|
||||
:form-initial-data="initialData"
|
||||
:observe-form-changes="false"
|
||||
url-create="ClientObservations"
|
||||
@on-data-saved="toCustomerNotes()"
|
||||
url-create="ClientObservations"
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
@alexm VnNotes?? @alexm VnNotes??
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<script setup>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const initialData = reactive({
|
||||
started: '2001-01-01T11:00:00.000Z',
|
||||
finished: null,
|
||||
amount: null,
|
||||
period: null,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
initialData.clientFk = `${route.params.id}`;
|
||||
});
|
||||
|
||||
const toCustomerRecoveries = () => {
|
||||
router.push({
|
||||
name: 'CustomerRecoveries',
|
||||
params: {
|
||||
id: route.params.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormModel
|
||||
:form-initial-data="initialData"
|
||||
:observe-form-changes="false"
|
||||
@on-data-saved="toCustomerRecoveries()"
|
||||
model="client"
|
||||
url-create="Recoveries"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInputDate :label="t('Since')" v-model="data.started" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInputDate :label="t('To')" v-model="data.finished" />
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput :label="t('Amount')" type="number" v-model="data.amount" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput :label="t('Period')" type="number" v-model="data.period" />
|
||||
</div>
|
||||
</VnRow>
|
||||
</template>
|
||||
</FormModel>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Since: Desde
|
||||
To: Hasta
|
||||
Amount: Importe
|
||||
Period: Periodo
|
||||
</i18n>
|
|
@ -71,8 +71,8 @@ const routeFilter = {
|
|||
};
|
||||
const onSave = (data, response) => {
|
||||
if (isNew) {
|
||||
axios.post(`Routes/${response.data?.id}/updateWorkCenter`);
|
||||
router.push({ name: 'RouteSummary', params: { id: response.data?.id } });
|
||||
axios.post(`Routes/${response?.id}/updateWorkCenter`);
|
||||
router.push({ name: 'RouteSummary', params: { id: response?.id } });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -15,11 +15,13 @@ import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
|
|||
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import RouteSummaryDialog from 'pages/Route/Card/RouteSummaryDialog.vue';
|
||||
import {useSession} from "composables/useSession";
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
const quasar = useQuasar();
|
||||
const session = useSession();
|
||||
|
||||
const to = Date.vnNew();
|
||||
to.setDate(to.getDate() + 1);
|
||||
|
@ -149,6 +151,23 @@ const cloneRoutes = () => {
|
|||
startingDate.value = null;
|
||||
};
|
||||
|
||||
const showRouteReport = () => {
|
||||
const ids = selectedRows.value.map(row => row?.id)
|
||||
const idString = ids.join(',')
|
||||
let url;
|
||||
|
||||
if (selectedRows.value.length <= 1) {
|
||||
url = `api/Routes/${idString}/driver-route-pdf?access_token=${session.getToken()}`;
|
||||
} else {
|
||||
const params = new URLSearchParams({
|
||||
access_token: session.getToken(),
|
||||
id: idString
|
||||
})
|
||||
url = `api/Routes/downloadZip?${params.toString()}`;
|
||||
}
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
const markAsServed = () => {
|
||||
selectedRows.value.forEach((row) => {
|
||||
if (row?.id) {
|
||||
|
@ -206,7 +225,6 @@ function previewRoute(id) {
|
|||
autofocus
|
||||
/>
|
||||
</QCardSection>
|
||||
<!-- TODO: Add report -->
|
||||
<QCardActions align="right">
|
||||
<QBtn flat :label="t('Cancel')" v-close-popup class="text-primary" />
|
||||
<QBtn color="primary" v-close-popup @click="cloneRoutes">
|
||||
|
@ -239,7 +257,15 @@ function previewRoute(id) {
|
|||
>
|
||||
<QTooltip>{{ t('Clone Selected Routes') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
||||
<QBtn
|
||||
icon="cloud_download"
|
||||
color="primary"
|
||||
class="q-mr-sm"
|
||||
:disable="!selectedRows?.length"
|
||||
@click="showRouteReport"
|
||||
>
|
||||
<QTooltip>{{ t('Download selected routes as PDF') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
icon="check"
|
||||
color="primary"
|
||||
|
@ -527,4 +553,5 @@ es:
|
|||
Cancel: Cancelar
|
||||
Clone: Clonar
|
||||
Mark as served: Marcar como servidas
|
||||
Download selected routes as PDF: Descargar rutas seleccionadas como PDF
|
||||
</i18n>
|
||||
|
|
|
@ -363,7 +363,6 @@ onMounted(async () => {
|
|||
</template>
|
||||
</VnSelectCreate>
|
||||
</VnRow>
|
||||
<pre>{{ data }}</pre>
|
||||
</template>
|
||||
</FormModel>
|
||||
</QPage>
|
||||
|
|
|
@ -254,13 +254,31 @@ export default {
|
|||
},
|
||||
{
|
||||
path: 'greuges',
|
||||
name: 'CustomerGreuges',
|
||||
meta: {
|
||||
title: 'greuges',
|
||||
icon: 'vn:greuge',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Customer/Card/CustomerGreuges.vue'),
|
||||
name: 'GreugesCard',
|
||||
redirect: { name: 'CustomerGreuges' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'CustomerGreuges',
|
||||
meta: {
|
||||
title: 'greuges',
|
||||
icon: 'vn:greuge',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Customer/Card/CustomerGreuges.vue'),
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'CustomerGreugeCreate',
|
||||
meta: {
|
||||
title: 'greuge-create',
|
||||
},
|
||||
component: () =>
|
||||
import(
|
||||
'src/pages/Customer/components/CustomerGreugeCreate.vue'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'balance',
|
||||
|
@ -274,13 +292,31 @@ export default {
|
|||
},
|
||||
{
|
||||
path: 'recoveries',
|
||||
name: 'CustomerRecoveries',
|
||||
meta: {
|
||||
title: 'recoveries',
|
||||
icon: 'vn:recovery',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Customer/Card/CustomerRecoveries.vue'),
|
||||
name: 'RecoveriesCard',
|
||||
redirect: { name: 'CustomerRecoveries' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'CustomerRecoveries',
|
||||
meta: {
|
||||
title: 'recoveries',
|
||||
icon: 'vn:recovery',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Customer/Card/CustomerRecoveries.vue'),
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'CustomerRecoverieCreate',
|
||||
meta: {
|
||||
title: 'recoverie-create',
|
||||
},
|
||||
component: () =>
|
||||
import(
|
||||
'src/pages/Customer/components/CustomerRecoverieCreate.vue'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'web-access',
|
||||
|
@ -316,10 +352,49 @@ export default {
|
|||
meta: {
|
||||
title: 'creditManagement',
|
||||
icon: 'paid',
|
||||
menuChildren: [
|
||||
{
|
||||
name: 'CustomerCreditContracts',
|
||||
title: 'creditContracts',
|
||||
icon: 'paid',
|
||||
},
|
||||
{
|
||||
name: 'CustomerCreditOpinion',
|
||||
title: 'creditOpinion',
|
||||
icon: 'paid',
|
||||
},
|
||||
],
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Customer/Card/CustomerCreditManagement.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'credit-contracts',
|
||||
name: 'CustomerCreditContracts',
|
||||
meta: {
|
||||
title: 'creditContracts',
|
||||
icon: 'paid',
|
||||
},
|
||||
component: () =>
|
||||
import(
|
||||
'src/pages/Customer/Card/CustomerCreditContracts.vue'
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'credit-opinion',
|
||||
name: 'CustomerCreditOpinion',
|
||||
meta: {
|
||||
title: 'creditOpinion',
|
||||
icon: 'paid',
|
||||
},
|
||||
component: () =>
|
||||
import(
|
||||
'src/pages/Customer/Card/CustomerCreditOpinion.vue'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: 'others',
|
||||
name: 'CustomerOthers',
|
||||
|
|
|
@ -52,13 +52,20 @@ export const useNavigationStore = defineStore('navigationStore', () => {
|
|||
|
||||
function addMenuItem(module, route, parent) {
|
||||
const { meta } = route;
|
||||
let { menuChildren = null } = meta;
|
||||
if (menuChildren)
|
||||
menuChildren = menuChildren.map(({ name, title, icon }) => ({
|
||||
name,
|
||||
icon,
|
||||
title: `${module}.pageTitles.${title}`,
|
||||
}));
|
||||
|
||||
if (meta && meta.roles && role.hasAny(meta.roles) === false) return;
|
||||
|
||||
const item = {
|
||||
name: route.name,
|
||||
children: menuChildren,
|
||||
};
|
||||
|
||||
if (meta) {
|
||||
item.title = `${module}.pageTitles.${meta.title}`;
|
||||
item.icon = meta.icon;
|
||||
|
|
Errores:
Corregido:
3cf3687b84
Revisamos porque la columna referencia no tiene el mismo formato. El campo, debería ser descriptor, si procede
Corregido:
17a0afda73
Revisar porque lago raro pasa
@wbuezas y yo hemos visto que las filas no siempre aparecen ordenadas con los customer 1102 y 1103.
He eliminado el "order:id DESC" y parece que va mejor, pero alguna vez aparece en otro orden
Pasaban 2 cosas:
Ambas cosas quedaron fixeadas en este commit:
1cff622898
Aquí también hay un error en los datos que vienen del back porque el campo payed y created, tiene la misma fecha y hora para los registros con id 1