0
0
Fork 0

Merge pull request 'Desarrollo de tarjetas varias en el modulo de clientes en el summary' (#86) from features/ms_160_contracts_opinion_credit_cards into dev

Reviewed-on: hyervoni/salix-front-mindshore#86
This commit is contained in:
Carlos Fonseca 2024-02-02 13:25:42 +00:00
commit 94ca3318a3
31 changed files with 1538 additions and 246 deletions

View File

@ -134,6 +134,13 @@ export default {
creditContracts: 'Credit contracts', creditContracts: 'Credit contracts',
creditOpinion: 'Credit opinion', creditOpinion: 'Credit opinion',
others: 'Others', others: 'Others',
samples: 'Samples',
consumption: 'Consumption',
mandates: 'Mandates',
contacts: 'Contacts',
webPayment: 'Web payment',
fileManagement: 'File management',
unpaid: 'Unpaid',
}, },
list: { list: {
phone: 'Phone', phone: 'Phone',

View File

@ -134,6 +134,13 @@ export default {
creditContracts: 'Contratos de crédito', creditContracts: 'Contratos de crédito',
creditOpinion: 'Opinión de crédito', creditOpinion: 'Opinión de crédito',
others: 'Otros', others: 'Otros',
samples: 'Plantillas',
consumption: 'Consumo',
mandates: 'Mandatos',
contacts: 'Contactos',
webPayment: 'Pago web',
fileManagement: 'Getión documental',
unpaid: 'Impago',
}, },
list: { list: {
phone: 'Teléfono', phone: 'Teléfono',

View File

@ -1,10 +1,11 @@
<script setup> <script setup>
import { computed, ref } from 'vue'; import { computed, onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { date, QCheckbox, QBtn, useQuasar } from 'quasar'; import { date, QCheckbox, QBtn, useQuasar } from 'quasar';
import { useState } from 'src/composables/useState';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
@ -17,68 +18,68 @@ const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const quasar = useQuasar(); const quasar = useQuasar();
const stateStore = useStateStore(); const stateStore = useStateStore();
const state = useState();
const user = state.getUser();
const clientRisks = ref(null); 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 clientRisksRef = ref(null);
const companiesOptions = ref([]);
const companyId = ref(null);
const receiptsRef = ref(null);
const rows = ref([]);
const workerId = ref(null);
const filterCompanies = { order: ['code'] }; const filterCompanies = { order: ['code'] };
const params = { const params = {
clientId: `${route.params.id}`, clientId: `${route.params.id}`,
companyId: companyId.value, companyId: user.value.companyFk,
filter: { limit: 20 }, filter: { limit: 20 },
}; };
const filter = { const filter = {
include: { relation: 'company', scope: { fields: ['code'] } }, include: { relation: 'company', scope: { fields: ['code'] } },
where: { clientFk: `${route.params.id}`, companyFk: companyId.value }, where: { clientFk: `${route.params.id}`, companyFk: user.value.companyFk },
}; };
const tableColumnComponents = { const tableColumnComponents = {
payed: { payed: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
created: { created: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
userName: { userName: {
component: QBtn, component: QBtn,
props: () => ({ flat: true, color: 'blue' }), props: () => ({ flat: true, color: 'blue' }),
event: (prop) => { event: ({ row }) => (workerId.value = row.clientFk),
workerId.value = prop.row.clientFk;
},
}, },
description: { description: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
bankFk: { bankFk: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
debit: { debit: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
credit: { credit: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
balance: { balance: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
isConciliate: { isConciliate: {
component: QCheckbox, component: QCheckbox,
@ -86,7 +87,7 @@ const tableColumnComponents = {
disable: true, disable: true,
'model-value': Boolean(prop.value), 'model-value': Boolean(prop.value),
}), }),
event: () => {}, event: () => (workerId.value = null),
}, },
}; };
@ -151,8 +152,12 @@ const columns = computed(() => [
}, },
]); ]);
const getData = () => { onBeforeMount(() => {
stateStore.rightDrawer = true; stateStore.rightDrawer = true;
companyId.value = user.value.companyFk;
});
const getData = () => {
receiptsRef.value?.fetch(); receiptsRef.value?.fetch();
clientRisksRef.value?.fetch(); clientRisksRef.value?.fetch();
}; };
@ -169,7 +174,11 @@ const showNewPaymentDialog = () => {
}; };
const updateCompanyId = (id) => { const updateCompanyId = (id) => {
if (id) companyId.value = id; if (id) {
companyId.value = id;
params.companyId = id;
filter.where.companyFk = id;
}
getData(); getData();
}; };
</script> </script>

View File

@ -1,10 +1,8 @@
<script setup> <script setup>
import { onMounted, ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';

View File

@ -140,6 +140,7 @@ const toCustomerConsigneeEdit = (consigneeId) => {
</template> </template>
</VnPaginate> </VnPaginate>
</QCard> </QCard>
<QPageSticky :offset="[18, 18]"> <QPageSticky :offset="[18, 18]">
<QBtn @click.stop="toCustomerConsigneeCreate()" color="primary" fab icon="add" /> <QBtn @click.stop="toCustomerConsigneeCreate()" color="primary" fab icon="add" />
<QTooltip> <QTooltip>

View File

@ -0,0 +1,22 @@
<script setup>
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
<template>
<h5 class="flex justify-center label-color">
{{ t('Enter a new search') }}
</h5>
</template>
<style lang="scss">
.label-color {
color: var(--vn-label);
}
</style>
<i18n>
es:
Enter a new search: Introduce una nueva búsqueda
</i18n>

View File

@ -0,0 +1,147 @@
<script setup>
import { onBeforeMount, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';
import useNotify from 'src/composables/useNotify';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const route = useRoute();
const { notify } = useNotify();
let notes = reactive([]);
const isLoading = ref(false);
onBeforeMount(() => {
getData();
});
const getData = async () => {
const filter = {
fields: ['id', 'name', 'phone', 'clientFk'],
where: { clientFk: route.params.id },
};
const { data } = await axios.get('ClientContacts', {
params: { filter: JSON.stringify(filter) },
});
notes.length = 0;
data.forEach((element) => {
element.isNew = false;
addNote(element);
});
};
const addNote = ({ id, name, phone, isNew }) => {
if (!notes.some((note) => note.id === id)) {
notes.push({
id,
$isNew: isNew,
name,
phone,
$oldData: null,
$orgIndex: null,
clientFk: route.params.id,
});
}
};
const deleteNote = (index) => {
notes.splice(index, 1);
};
const onSubmit = async () => {
isLoading.value = true;
const payload = {
creates: notes.filter((element) => element.$isNew),
};
try {
await axios.post('ClientContacts/crud', payload);
notes = [];
await getData();
} catch (error) {
notify('errors.create', 'negative');
} finally {
isLoading.value = false;
}
};
</script>
<template>
<QCard class="q-pa-lg">
<QCardSection>
<QForm @submit.prevent="onSubmit">
<VnRow
:key="index"
class="row q-gutter-md q-mb-md"
v-for="(note, index) in notes"
>
<div class="col">
<VnInput :label="t('Name')" v-model="note.name" />
</div>
<div class="col">
<VnInput :label="t('Phone')" v-model="note.phone" />
</div>
<div class="flex items-center">
<QIcon
@click.stop="deleteNote(index)"
class="cursor-pointer"
color="primary"
name="delete"
size="sm"
>
<QTooltip>
{{ t('Remove contact') }}
</QTooltip>
</QIcon>
</div>
</VnRow>
<div class="flex justify-between q-mt-xl">
<div class="flex items-center">
<QIcon
@click.stop="addNote({ name: '', phone: '', isNew: true })"
class="cursor-pointer add-icon"
name="add"
size="sm"
>
<QTooltip>
{{ t('Add contact') }}
</QTooltip>
</QIcon>
</div>
<QBtn
:label="t('globals.save')"
type="submit"
color="primary"
:disabled="isLoading"
:loading="isLoading"
/>
</div>
</QForm>
</QCardSection>
</QCard>
</template>
<style lang="scss" scoped>
.add-icon {
background-color: $primary;
border-radius: 50px;
}
</style>
<i18n>
es:
Name: Nombre
Phone: Teléfono
Remove contact: Eliminar contacto
Add contact: Añadir contacto
</i18n>

View File

@ -1,3 +1,217 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import VnPaginate from 'src/components/ui/VnPaginate.vue';
import ModalCloseContract from 'src/pages/Customer/components/ModalCloseContract.vue';
import { toDate } from 'src/filters';
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const quasar = useQuasar();
const vnPaginateRef = ref(null);
const showQPageSticky = ref(true);
const filter = {
order: 'finished ASC, started DESC',
include: [
{
relation: 'insurances',
scope: {
fields: ['id', 'credit', 'created', 'grade'],
order: 'created DESC',
limit: 2,
},
},
],
where: { client: `${route.params.id}` },
};
const fetch = (data) => {
data.forEach((element) => {
if (!element.finished) {
showQPageSticky.value = false;
return;
}
});
};
const toCustomerCreditContractsCreate = () => {
router.push({ name: 'CustomerCreditContractsCreate' });
};
const openDialog = (item) => {
quasar.dialog({
component: ModalCloseContract,
componentProps: {
id: item.id,
promise: updateData,
},
});
};
const openViewCredit = (credit) => {
router.push({
name: 'CustomerCreditContractsInsurance',
params: {
creditId: credit.id,
},
});
};
const updateData = () => {
vnPaginateRef.value?.fetch();
};
</script>
<template> <template>
<div class="flex justify-center">Customer credit contracts</div> <QCard class="q-pa-lg">
<VnPaginate
:filter="filter"
@on-fetch="fetch"
auto-load
data-key="CustomerCreditContracts"
order="id DESC"
ref="vnPaginateRef"
url="CreditClassifications"
>
<template #body="{ rows }">
<div v-if="rows.length">
<QCard
v-for="(item, index) in rows"
:key="index"
:class="{
'customer-card': true,
'q-mb-md': index < rows.length - 1,
'is-active': !item.finished,
}"
>
<QCardSection class="flex q-py-none">
<div
class="flex items-center q-ml-md cursor-pointer"
v-if="!item.finished"
>
<QIcon
@click.stop="openDialog(item)"
color="primary"
name="lock"
size="md"
>
<QTooltip>{{ t('Close contract') }}</QTooltip>
</QIcon>
</div>
<div class="q-ml-lg">
<div class="flex q-mb-xs">
<div class="q-mr-sm label-color">
{{ t('Since') }}:
</div>
<div class="text-weight-bold">
{{ toDate(item.started) }}
</div>
</div>
<div class="flex">
<div class="q-mr-sm label-color">{{ t('To') }}:</div>
<div class="text-weight-bold">
{{ toDate(item.finished) }}
</div>
</div>
</div>
</QCardSection>
<QSeparator class="q-mx-lg" vertical />
<div class="flex">
<div class="flex items-center">
<div class="flex q-mr-xl">
<div class="q-mr-sm label-color">
{{ t('Credit') }}:
</div>
<div class="text-weight-bold">
{{ item.insurances[0].credit }}
</div>
</div>
<div class="flex q-mr-xl">
<div class="q-mr-sm label-color">
{{ t('Grade') }}:
</div>
<div class="text-weight-bold">
{{ item.insurances[0].grade }}
</div>
</div>
<div class="flex">
<div class="q-mr-sm label-color">
{{ t('Date') }}:
</div>
<div class="text-weight-bold">
{{ toDate(item.insurances[0].created) }}
</div>
</div>
</div>
<div class="flex items-center q-ml-lg q-mr-md cursor-pointer">
<QIcon
@click.stop="openViewCredit(item)"
color="primary"
name="preview"
size="md"
>
<QTooltip>{{ t('View credits') }}</QTooltip>
</QIcon>
</div>
</div>
</QCard>
</div>
<h5 class="flex justify-center label-color" v-else>
{{ t('globals.noResults') }}
</h5>
</template>
</VnPaginate>
</QCard>
<QPageSticky :offset="[18, 18]" v-if="showQPageSticky">
<QBtn
@click.stop="toCustomerCreditContractsCreate()"
color="primary"
fab
icon="add"
/>
<QTooltip>
{{ t('New contract') }}
</QTooltip>
</QPageSticky>
</template> </template>
<style lang="scss" scoped>
.label-color {
color: var(--vn-label);
}
.customer-card {
border: 2px solid var(--vn-light-gray);
border-radius: 10px;
padding: 10px;
display: flex;
justify-content: space-between;
}
.is-active {
background-color: var(--vn-light-gray);
}
</style>
<i18n>
es:
Close contract: Cerrar contrato
Since: Desde
To: Hasta
Credit: Crédito
Grade: Grade
Date: Fecha
View credits: Ver créditos
Created: Fecha creación
New contract: Nuevo contrato
</i18n>

View File

@ -1,3 +0,0 @@
<template>
<div class="flex justify-center">Credit management</div>
</template>

View File

@ -1,3 +1,75 @@
<script setup>
import { 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 VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const route = useRoute();
const informationOptions = ref([]);
const filter = {
include: [
{
relation: 'worker',
scope: {
fields: ['id'],
include: { relation: 'user', scope: { fields: ['nickname'] } },
},
},
],
where: { clientFk: `${route.params.id}` },
order: ['created DESC'],
limit: 20,
};
const initialData = reactive({
rating: null,
recommendedCredit: null,
});
</script>
<template> <template>
<div class="flex justify-center">Customer credit opinion</div> <FetchData
:filter="filter"
@on-fetch="(data) => (informationOptions = data)"
auto-load
url="ClientInformas"
/>
<FormModel
:form-initial-data="initialData"
:observe-form-changes="false"
:url-create="`Clients/${route.params.id}/setRating`"
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Rating')"
type="number"
v-model.number="data.rating"
/>
</div>
<div class="col">
<VnInput
:label="t('Recommended credit')"
type="number"
v-model.number="data.recommendedCredit"
/>
</div>
</VnRow>
</template>
</FormModel>
</template> </template>
<i18n>
es:
Rating: Clasificación
Recommended credit: Crédito recomendado
</i18n>

View File

@ -1,65 +1,52 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { date, QBtn } from 'quasar'; import { date, QBtn } from 'quasar';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore();
const arrayData = ref(null); const workerId = ref(null);
const workerId = ref(0); const rows = ref([]);
const rows = computed(() => arrayData.value.store.data);
onBeforeMount(async () => { const filter = {
const filter = { include: [
include: [ {
{ relation: 'worker',
relation: 'worker', scope: {
scope: { fields: ['id'],
fields: ['id'], include: { relation: 'user', scope: { fields: ['name'] } },
include: { relation: 'user', scope: { fields: ['name'] } },
},
}, },
], },
where: { clientFk: `${route.params.id}` }, ],
order: ['created DESC'], where: { clientFk: `${route.params.id}` },
limit: 20, order: ['created DESC'],
}; limit: 20,
arrayData.value = useArrayData('CustomerCreditsCard', { };
url: 'ClientCredits',
filter,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
const tableColumnComponents = { const tableColumnComponents = {
created: { created: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
employee: { employee: {
component: QBtn, component: QBtn,
props: () => ({ flat: true, color: 'blue' }), props: () => ({ flat: true, color: 'blue' }),
event: (prop) => { event: ({ row }) => (workerId.value = row.clientFk),
selectWorkerId(prop.row.clientFk);
},
}, },
amount: { amount: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
}; };
@ -86,16 +73,19 @@ const columns = computed(() => [
}, },
]); ]);
const selectWorkerId = (id) => {
workerId.value = id;
};
const toCustomerCreditCreate = () => { const toCustomerCreditCreate = () => {
router.push({ name: 'CustomerCreditCreate' }); router.push({ name: 'CustomerCreditCreate' });
}; };
</script> </script>
<template> <template>
<FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="ClientCredits"
/>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QTable <QTable
:columns="columns" :columns="columns"

View File

@ -0,0 +1,3 @@
<template>
<div class="flex justify-center">Customer file management</div>
</template>

View File

@ -1,87 +1,70 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { date, QBtn } from 'quasar'; import { date, QBtn } from 'quasar';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore();
const arrayData = ref(null); const rows = ref([]);
const totalAmount = ref(0); const totalAmount = ref(0);
const workerId = ref(0); const workerId = ref(null);
const rows = computed(() => arrayData.value.store.data);
onBeforeMount(async () => { const filter = {
const filter = { include: [
include: [ {
{ relation: 'greugeType',
relation: 'greugeType', scope: {
scope: { fields: ['id', 'name'],
fields: ['id', 'name'],
},
}, },
{
relation: 'user',
scope: {
fields: ['id', 'name'],
},
},
],
order: 'shipped DESC, amount',
where: {
clientFk: `${route.params.id}`,
}, },
limit: 20, {
}; relation: 'user',
scope: {
arrayData.value = useArrayData('CustomerGreugesCard', { fields: ['id', 'name'],
url: 'greuges', },
filter, },
}); ],
await arrayData.value.fetch({ append: false }); order: 'shipped DESC, amount',
totalAmount.value = arrayData.value.store.data.reduce((accumulator, currentValue) => { where: {
return accumulator + currentValue.amount; clientFk: `${route.params.id}`,
}, 0); },
stateStore.rightDrawer = true; limit: 20,
}); };
const tableColumnComponents = { const tableColumnComponents = {
date: { date: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
createdBy: { createdBy: {
component: QBtn, component: QBtn,
props: () => ({ flat: true, color: 'blue' }), props: () => ({ flat: true, color: 'blue' }),
event: (prop) => { event: ({ row }) => (workerId.value = row.clientFk),
selectWorkerId(prop.row.clientFk);
},
}, },
comment: { comment: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
type: { type: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
amount: { amount: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => (workerId.value = null),
}, },
}; };
@ -120,8 +103,11 @@ const columns = computed(() => [
}, },
]); ]);
const selectWorkerId = (id) => { const setRows = (data) => {
workerId.value = id; rows.value = data;
totalAmount.value = data.reduce((accumulator, currentValue) => {
return accumulator + currentValue.amount;
}, 0);
}; };
const toCustomerGreugeCreate = () => { const toCustomerGreugeCreate = () => {
@ -130,6 +116,8 @@ const toCustomerGreugeCreate = () => {
</script> </script>
<template> <template>
<FetchData :filter="filter" @on-fetch="setRows" auto-load url="greuges" />
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QCard class="full-width" v-if="totalAmount"> <QCard class="full-width" v-if="totalAmount">
<h6 class="flex justify-end q-my-lg q-pr-lg"> <h6 class="flex justify-end q-my-lg q-pr-lg">

View File

@ -0,0 +1,17 @@
<script setup>
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
<template>
<h5 class="flex justify-center label-color">
{{ t('globals.noResults') }}
</h5>
</template>
<style lang="scss">
.label-color {
color: var(--vn-label);
}
</style>

View File

@ -1,3 +0,0 @@
<template>
<div class="flex justify-center">Others</div>
</template>

View File

@ -1,39 +1,24 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { date, QBtn } from 'quasar'; import { date, QBtn } from 'quasar';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import FetchData from 'components/FetchData.vue';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore(); const rows = ref([]);
const arrayData = ref(null); const filter = {
const workerId = ref(0); where: { clientFk: `${route.params.id}` },
const rows = computed(() => arrayData.value.store.data); order: ['started DESC'],
limit: 20,
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 = { const tableColumnComponents = {
since: { since: {
@ -94,6 +79,13 @@ const toCustomerRecoverieCreate = () => {
</script> </script>
<template> <template>
<FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="Recoveries"
/>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QTable <QTable
:columns="columns" :columns="columns"
@ -113,7 +105,6 @@ const toCustomerRecoverieCreate = () => {
@click="tableColumnComponents[props.col.name].event(props)" @click="tableColumnComponents[props.col.name].event(props)"
> >
{{ props.value }} {{ props.value }}
<WorkerDescriptorProxy :id="workerId" />
</component> </component>
</QTr> </QTr>
</QTd> </QTd>

View File

@ -0,0 +1,153 @@
<script setup>
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { date, QBtn } from 'quasar';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const workerId = ref(null);
const rows = ref([]);
const filter = {
include: [
{ relation: 'type', scope: { fields: ['code', 'description'] } },
{ relation: 'user', scope: { fields: ['id', 'name'] } },
{ relation: 'company', scope: { fields: ['code'] } },
],
where: { clientFk: route.params.id },
order: ['created DESC'],
limit: 20,
};
const tableColumnComponents = {
sent: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
description: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
worker: {
component: QBtn,
props: () => ({ flat: true, color: 'blue' }),
event: ({ row }) => (workerId.value = row.clientFk),
},
company: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
};
const columns = computed(() => [
{
align: 'left',
field: 'created',
label: t('Sent'),
name: 'sent',
format: (value) => date.formatDate(value, 'DD/MM/YYYY hh:mm'),
},
{
align: 'left',
field: (value) => value.type.description,
label: t('Description'),
name: 'description',
},
{
align: 'left',
field: (value) => value.user.name,
label: t('Worker'),
name: 'worker',
},
{
align: 'left',
field: (value) => value.company.code,
label: t('Company'),
name: 'company',
},
]);
const toCustomerSamplesCreate = () => {
router.push({ name: 'CustomerSamplesCreate' });
};
</script>
<template>
<FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="ClientSamples"
/>
<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="toCustomerSamplesCreate()" color="primary" fab icon="add" />
<QTooltip>
{{ t('Send sample') }}
</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:
Sent: Enviado
Description: Descripción
Worker: Trabajador
Company: Empresa
Send sample: Enviar plantilla
</i18n>

View File

@ -0,0 +1,3 @@
<template>
<div class="flex justify-center">Customer unpaid</div>
</template>

View File

@ -21,40 +21,42 @@ const filter = { where: { id: `${route.params.id}` } };
model="client" model="client"
> >
<template #form="{ data }"> <template #form="{ data }">
<div <div v-if="data?.length">
v-for="(item, index) in data" <div
:key="index" v-for="(item, index) in data"
:class="{ :key="index"
'q-mb-md': index < data.length - 1, :class="{
}" 'q-mb-md': index < data.length - 1,
> }"
<VnRow class="row q-gutter-md q-mb-md"> >
<div class="col"> <VnRow class="row q-gutter-md q-mb-md">
<QCheckbox <div class="col">
:label="t('Enable web access')" <QCheckbox
v-model="item.active" :label="t('Enable web access')"
/> v-model="item.active"
</div> />
</VnRow> </div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<VnInput :label="t('User')" v-model="item.name" /> <VnInput :label="t('User')" v-model="item.name" />
</div> </div>
<div class="col"> <div class="col">
<VnInput :label="t('Recovery email')" v-model="item.email"> <VnInput :label="t('Recovery email')" v-model="item.email">
<template #append> <template #append>
<QIcon name="info" class="cursor-pointer"> <QIcon name="info" class="cursor-pointer">
<QTooltip>{{ <QTooltip>{{
t( t(
'This email is used for user to regain access their account' 'This email is used for user to regain access their account'
) )
}}</QTooltip> }}</QTooltip>
</QIcon> </QIcon>
</template> </template>
</VnInput> </VnInput>
</div> </div>
</VnRow> </VnRow>
</div>
</div> </div>
</template> </template>
</FormModel> </FormModel>

View File

@ -0,0 +1,17 @@
<script setup>
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
<template>
<h5 class="flex justify-center label-color">
{{ t('globals.noResults') }}
</h5>
</template>
<style lang="scss">
.label-color {
color: var(--vn-label);
}
</style>

View File

@ -1,13 +1,12 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { QBtn, QCheckbox, useQuasar } from 'quasar'; import { QBtn, QCheckbox, useQuasar } from 'quasar';
import { toCurrency, toDate } from 'filters/index'; import { toCurrency, toDate } from 'filters/index';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import FetchData from 'components/FetchData.vue';
import CustomerNotificationsFilter from './CustomerDefaulterFilter.vue'; import CustomerNotificationsFilter from './CustomerDefaulterFilter.vue';
import CustomerBalanceDueTotal from './CustomerBalanceDueTotal.vue'; import CustomerBalanceDueTotal from './CustomerBalanceDueTotal.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
@ -15,16 +14,13 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v
import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue'; import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue';
const { t } = useI18n(); const { t } = useI18n();
const stateStore = useStateStore();
const quasar = useQuasar(); const quasar = useQuasar();
const arrayData = ref(null);
const balanceDueTotal = ref(0); const balanceDueTotal = ref(0);
const customerId = ref(0); const customerId = ref(0);
const selected = ref([]); const selected = ref([]);
const workerId = ref(0); const workerId = ref(0);
const rows = ref([]);
const rows = computed(() => arrayData.value.store.data);
const tableColumnComponents = { const tableColumnComponents = {
client: { client: {
@ -155,23 +151,11 @@ const columns = computed(() => [
}, },
]); ]);
onBeforeMount(() => { const setRows = (data) => {
getArrayData(); rows.value = data;
}); balanceDueTotal.value = data.reduce((accumulator, currentValue) => {
return accumulator + (currentValue['amount'] || 0);
const getArrayData = async () => { }, 0);
arrayData.value = useArrayData('CustomerDefaulter', {
url: 'Defaulters/filter',
limit: 0,
});
await arrayData.value.fetch({ append: false });
balanceDueTotal.value = arrayData.value.store.data.reduce(
(accumulator, currentValue) => {
return accumulator + (currentValue['amount'] || 0);
},
0
);
stateStore.rightDrawer = true;
}; };
const selectCustomerId = (id) => { const selectCustomerId = (id) => {
@ -195,12 +179,19 @@ const viewAddObservation = (rowsSelected) => {
}; };
const refreshData = () => { const refreshData = () => {
getArrayData(); setRows();
}; };
</script> </script>
<template> <template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="Defaulters/filter"
/>
<QDrawer side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<CustomerNotificationsFilter data-key="CustomerDefaulter" /> <CustomerNotificationsFilter data-key="CustomerDefaulter" />
</QScrollArea> </QScrollArea>

View File

@ -1,33 +1,29 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount, onMounted } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { QBtn, QIcon } from 'quasar'; import { QBtn, QIcon } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import { dashIfEmpty, toDate } from 'src/filters';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import CustomerExtendedListActions from './CustomerExtendedListActions.vue'; import CustomerExtendedListActions from './CustomerExtendedListActions.vue';
import CustomerExtendedListFilter from './CustomerExtendedListFilter.vue'; import CustomerExtendedListFilter from './CustomerExtendedListFilter.vue';
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue'; import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import { dashIfEmpty, toDate } from 'src/filters';
const { t } = useI18n(); const { t } = useI18n();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore(); const stateStore = useStateStore();
const arrayData = ref(null); const allColumnNames = ref([]);
const rows = ref([]);
onBeforeMount(async () => { const selectedCustomerId = ref(0);
arrayData.value = useArrayData('CustomerExtendedList', { const selectedSalesPersonId = ref(0);
url: 'Clients/extendedListFilter', const visibleColumns = ref([]);
limit: 0,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
onMounted(() => { onMounted(() => {
const filteredColumns = columns.value.filter( const filteredColumns = columns.value.filter(
@ -36,13 +32,6 @@ onMounted(() => {
allColumnNames.value = filteredColumns.map((col) => col.name); allColumnNames.value = filteredColumns.map((col) => col.name);
}); });
const rows = computed(() => arrayData.value.store.data);
const selectedCustomerId = ref(0);
const selectedSalesPersonId = ref(0);
const allColumnNames = ref([]);
const visibleColumns = ref([]);
const tableColumnComponents = { const tableColumnComponents = {
customerStatus: { customerStatus: {
component: QIcon, component: QIcon,
@ -490,6 +479,13 @@ const selectSalesPersonId = (id) => {
</script> </script>
<template> <template>
<FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="Clients/extendedListFilter"
/>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<CustomerExtendedListFilter <CustomerExtendedListFilter

View File

@ -1,32 +1,17 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { QBtn } from 'quasar'; import { QBtn } from 'quasar';
import { useArrayData } from 'composables/useArrayData'; import FetchData from 'components/FetchData.vue';
import { useStateStore } from 'stores/useStateStore';
import CustomerNotificationsFilter from './CustomerNotificationsFilter.vue'; import CustomerNotificationsFilter from './CustomerNotificationsFilter.vue';
import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
const { t } = useI18n(); const { t } = useI18n();
const stateStore = useStateStore();
const arrayData = ref(null);
onBeforeMount(async () => {
arrayData.value = useArrayData('CustomerNotifications', {
url: 'Clients',
limit: 0,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
const rows = computed(() => arrayData.value.store.data);
const rows = ref([]);
const selected = ref([]); const selected = ref([]);
const selectedCustomerId = ref(0); const selectedCustomerId = ref(0);
@ -97,7 +82,14 @@ const selectCustomerId = (id) => {
</script> </script>
<template> <template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="Clients"
/>
<QDrawer side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<CustomerNotificationsFilter data-key="CustomerNotifications" /> <CustomerNotificationsFilter data-key="CustomerNotifications" />
</QScrollArea> </QScrollArea>

View File

@ -321,7 +321,7 @@ const onDataSaved = () => {
size="sm" size="sm"
> >
<QTooltip> <QTooltip>
{{ t('Remove') }} {{ t('Remove note') }}
</QTooltip> </QTooltip>
</QIcon> </QIcon>
</div> </div>

View File

@ -0,0 +1,61 @@
<script setup>
import { 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 'src/components/common/VnInputDate.vue';
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const initialData = reactive({
clientFK: Number(route.params.id),
});
const onDataSaved = () => {
router.push({ name: 'CustomerCreditContractsCreate' });
};
</script>
<template>
<FormModel
:form-initial-data="initialData"
:observe-form-changes="false"
:default-actions="true"
url-create="creditClassifications/createWithInsurance"
@on-data-saved="onDataSaved()"
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Credit')"
type="number"
v-model.number="data.credit"
/>
</div>
<div class="col">
<VnInput
:label="t('Grade')"
type="number"
v-model.number="data.grade"
/>
</div>
<div class="col">
<VnInputDate :label="t('Since')" v-model="data.started" />
</div>
</VnRow>
</template>
</FormModel>
</template>
<i18n>
es:
Credit: Crédito
Grade: Grade
Since: Desde
</i18n>

View File

@ -0,0 +1,105 @@
<script setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { date } from 'quasar';
import { toCurrency } from 'src/filters';
import FetchData from 'components/FetchData.vue';
const { t } = useI18n();
const route = useRoute();
const rows = ref([]);
const filter = {
where: {
creditClassificationFk: `${route.params.creditId}`,
},
limit: 20,
};
const tableColumnComponents = {
created: {
component: 'span',
props: () => {},
event: () => {},
},
grade: {
component: 'span',
props: () => {},
event: () => {},
},
credit: {
component: 'span',
props: () => {},
event: () => {},
},
};
const columns = computed(() => [
{
align: 'left',
field: 'created',
format: (value) => date.formatDate(value, 'DD/MM/YYYY'),
label: t('Created'),
name: 'created',
},
{
align: 'left',
field: 'grade',
label: t('Grade'),
name: 'grade',
},
{
align: 'left',
field: 'credit',
format: (value) => toCurrency(value),
label: t('Credit'),
name: 'credit',
},
]);
</script>
<template>
<FetchData
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="CreditInsurances"
/>
<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"
>
<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 }}
</component>
</QTr>
</QTd>
</template>
</QTable>
</QPage>
</template>
<i18n>
es:
Created: Fecha creación
Grade: Grade
Credit: Crédito
</i18n>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { reactive, ref } from 'vue'; import { reactive } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';

View File

@ -3,6 +3,8 @@ import { onBeforeMount, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useDialogPluginComponent } from 'quasar';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
@ -12,6 +14,7 @@ import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const { dialogRef } = useDialogPluginComponent();
const $props = defineProps({ const $props = defineProps({
companyId: { companyId: {

View File

@ -0,0 +1,240 @@
<script setup>
import { onBeforeMount, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { useState } from 'src/composables/useState';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const state = useState();
const user = state.getUser();
const optionsEmailUsers = ref([]);
const optionsClientsAddressess = ref([]);
const optionsCompanies = ref([]);
const optionsSamplesVisible = ref([]);
const sampleType = ref(0);
const filterEmailUsers = { where: { userFk: user.value.id } };
const filterClientsAddresses = {
include: [
{ relation: 'province', scope: { fields: ['name'] } },
{ relation: 'agencyMode', scope: { fields: ['name'] } },
],
};
const filterCompanies = { order: ['code'] };
const filterSamplesVisible = {
fields: [
'id',
'code',
'description',
'model',
'hasCompany',
'hasAddress',
'hasPreview',
'datepickerEnabled',
],
order: ['description'],
};
const initialData = reactive({});
onBeforeMount(async () => {
const { companyFk } = user.value;
const { data } = await axios.get(`Clients/1/getCard`);
initialData.addressId = data.defaultAddressFk;
initialData.clientFk = route.params.id;
initialData.companyFk = companyFk;
initialData.companyId = companyFk;
initialData.recipient = data.email;
});
const setEmailUser = (data) => {
optionsEmailUsers.value = data;
initialData.replyTo = data[0]?.email;
};
const setSampleType = (sampleId) => {
sampleType.value = optionsSamplesVisible.value.find(
(option) => option.id === sampleId
);
};
const onDataSaved = async ({
addressId,
companyFk,
companyId,
from,
recipient,
replyTo,
}) => {
await axios.post(`Clients/${route.params.id}/incoterms-authorization-email`, {
addressId,
companyFk,
companyId,
from,
recipient,
replyTo,
});
router.push({ name: 'CustomerSamples' });
};
</script>
<template>
<fetch-data
:filter="filterEmailUsers"
@on-fetch="setEmailUser"
auto-load
url="EmailUsers"
/>
<fetch-data
:filter="filterClientsAddresses"
:url="`Clients/${route.params.id}/addresses`"
@on-fetch="(data) => (optionsClientsAddressess = data)"
auto-load
/>
<fetch-data
:filter="filterCompanies"
@on-fetch="(data) => (optionsCompanies = data)"
auto-load
url="Companies"
/>
<fetch-data
:filter="filterSamplesVisible"
@on-fetch="(data) => (optionsSamplesVisible = data)"
auto-load
url="Samples/visible"
/>
<FormModel
:form-initial-data="initialData"
:observe-form-changes="false"
@on-data-saved="onDataSaved"
model="client"
url-create="ClientSamples"
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnSelectFilter
:label="t('Sample')"
:options="optionsSamplesVisible"
@update:model-value="setSampleType"
hide-selected
option-label="description"
option-value="id"
required="true"
v-model="data.typeFk"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Recipient')"
required="true"
v-model="data.recipient"
>
<template #append>
<QIcon name="info" class="cursor-pointer">
<QTooltip>{{
t('Its only used when sample is sent')
}}</QTooltip>
</QIcon>
</template>
</VnInput>
</div>
<div class="col">
<VnInput
:label="t('Reply to')"
required="true"
v-model="data.replyTo"
>
<template #append>
<QIcon name="info" class="cursor-pointer">
<QTooltip>{{
t('To who should the recipient replay?')
}}</QTooltip>
</QIcon>
</template>
</VnInput>
</div>
</VnRow>
<VnRow
class="row q-gutter-md q-mb-md"
v-if="sampleType.hasCompany || sampleType.datepickerEnabled"
>
<div class="col">
<VnSelectFilter
:label="t('Company')"
:options="optionsCompanies"
hide-selected
option-label="code"
option-value="id"
required="true"
v-model="data.companyFk"
v-if="sampleType.hasCompany"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('Address')"
:options="optionsClientsAddressess"
hide-selected
option-label="nickname"
option-value="id"
required="true"
v-model="data.addressId"
v-if="sampleType.id === 20"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>
{{
`${scope.opt.nickname}, ${scope.opt.street}, ${scope.opt.city}, ${scope.opt.province.name} - ${scope.opt.agencyMode.name}`
}}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelectFilter>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md" v-if="sampleType.datepickerEnabled">
<div class="col">
<VnInputDate
:label="t('Since')"
required="true"
v-model="data.from"
/>
</div>
</VnRow>
</template>
</FormModel>
</template>
<i18n>
es:
Sample: Plantilla
Recipient: Destinatario
Reply to: Responder a
Company: Empresa
Address: Dirección
Since: Desde
Its only used when sample is sent: Se utiliza únicamente cuando se envía la plantilla
To who should the recipient replay?: ¿A quien debería responder el destinatario?
</i18n>

View File

@ -0,0 +1,73 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useDialogPluginComponent } from 'quasar';
const { t } = useI18n();
const { dialogRef } = useDialogPluginComponent();
const closeButton = ref(null);
const $props = defineProps({
id: {
type: Number,
required: true,
},
promise: {
type: Function,
required: true,
},
});
const isLoading = ref(false);
const saveData = async () => {
const timestamp = new Date().getTime();
const payload = {
finished: timestamp,
};
await axios.patch(`CreditClassifications/${$props.id}`, payload);
$props.promise();
closeButton.value.click();
};
</script>
<template>
<QDialog ref="dialogRef">
<QCard class="q-pa-sm">
<span
ref="closeButton"
class="flex justify-end cursor-pointer q-mb-sm"
v-close-popup
>
<QIcon name="close" size="sm" />
</span>
<QCardSection>
<div class="text-h6 q-mb-sm">
{{ t('Are you sure you want to close this contract?') }}
</div>
<div class="q-mb-sm">{{ t('Close contract') }}</div>
</QCardSection>
<QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn
:label="t('globals.confirm')"
color="primary"
:loading="isLoading"
@click="saveData"
unelevated
/>
</QCardActions>
</QCard>
</QDialog>
</template>
<i18n>
es:
Are you sure you want to close this contract?: ¿Seguro que quieres cerrar este contrato?
Close contract: Cerrar contrato
</i18n>

View File

@ -365,8 +365,6 @@ export default {
}, },
], ],
}, },
component: () =>
import('src/pages/Customer/Card/CustomerCreditManagement.vue'),
children: [ children: [
{ {
path: 'credit-contracts', path: 'credit-contracts',
@ -380,6 +378,41 @@ export default {
'src/pages/Customer/Card/CustomerCreditContracts.vue' 'src/pages/Customer/Card/CustomerCreditContracts.vue'
), ),
}, },
{
path: 'credit-contracts',
name: 'CreditContractsCard',
redirect: { name: 'CustomerCreditContracts' },
children: [
{
path: '',
name: 'CustomerCreditContracts',
meta: {
title: 'creditContracts',
icon: 'paid',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerCreditContracts.vue'
),
},
{
path: 'create',
name: 'CustomerCreditContractsCreate',
component: () =>
import(
'src/pages/Customer/components/CustomerCreditContractsCreate.vue'
),
},
{
path: 'insurance/:creditId',
name: 'CustomerCreditContractsInsurance',
component: () =>
import(
'src/pages/Customer/components/CustomerCreditContractsInsurance.vue'
),
},
],
},
{ {
path: 'credit-opinion', path: 'credit-opinion',
name: 'CustomerCreditOpinion', name: 'CustomerCreditOpinion',
@ -394,15 +427,178 @@ export default {
}, },
], ],
}, },
{ {
path: 'others', path: 'others',
name: 'CustomerOthers', name: 'CustomerOthers',
meta: { meta: {
title: 'others', title: 'others',
icon: 'pending', icon: 'pending',
menuChildren: [
{
name: 'CustomerSamples',
title: 'samples',
icon: 'pending',
},
{
name: 'CustomerConsumption',
title: 'consumption',
icon: 'pending',
},
{
name: 'CustomerMandates',
title: 'mandates',
icon: 'pending',
},
{
name: 'CustomerContacts',
title: 'contacts',
icon: 'pending',
},
{
name: 'CustomerWebPayment',
title: 'webPayment',
icon: 'pending',
},
{
name: 'CustomerFileManagement',
title: 'fileManagement',
icon: 'pending',
},
{
name: 'CustomerUnpaid',
title: 'unpaid',
icon: 'pending',
},
],
}, },
component: () => import('src/pages/Customer/Card/CustomerOthers.vue'), children: [
{
path: 'samples',
name: 'CustomerSamples',
meta: {
title: 'samples',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerSamples.vue'),
},
{
path: 'samples',
name: 'CustomerSamplesCard',
redirect: { name: 'CustomerSamples' },
children: [
{
path: '',
name: 'CustomerSamples',
meta: {
title: 'samples',
icon: 'paid',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerSamples.vue'
),
},
{
path: 'create',
name: 'CustomerSamplesCreate',
component: () =>
import(
'src/pages/Customer/components/CustomerSamplesCreate.vue'
),
},
],
},
{
path: 'consumption',
name: 'CustomerConsumption',
meta: {
title: 'consumption',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerConsumption.vue'),
},
{
path: 'mandates',
name: 'CustomerMandates',
meta: {
title: 'mandates',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerMandates.vue'),
},
{
path: 'contacts',
name: 'CustomerContacts',
meta: {
title: 'contacts',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerContacts.vue'),
},
{
path: 'web-payment',
name: 'CustomerWebPayment',
meta: {
title: 'webPayment',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerWebPayment.vue'),
},
{
path: 'file-management',
name: 'CustomerFileManagement',
meta: {
title: 'fileManagement',
icon: 'paid',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerFileManagement.vue'
),
},
{
path: 'file-management',
name: 'CustomerFileManagementCard',
redirect: { name: 'CustomerFileManagement' },
children: [
{
path: '',
name: 'CustomerFileManagement',
meta: {
title: 'fileManagement',
icon: 'paid',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerFileManagement.vue'
),
},
{
path: 'create',
name: 'CustomerFileManagementCreate',
component: () =>
import(
'src/pages/Customer/components/CustomerFileManagementCreate.vue'
),
},
],
},
{
path: 'unpaid',
name: 'CustomerUnpaid',
meta: {
title: 'unpaid',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerUnpaid.vue'),
},
],
}, },
], ],
}, },