0
0
Fork 0

Desarrollo de tarjetas varias en el modulo de clientes en el summary

This commit is contained in:
carlosfonseca 2024-01-31 07:32:34 -05:00
parent 26a1b29070
commit 7b3ff319d4
25 changed files with 1381 additions and 56 deletions

View File

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

View File

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

View File

@ -1,10 +1,11 @@
<script setup>
import { computed, ref } from 'vue';
import { computed, onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { date, QCheckbox, QBtn, useQuasar } from 'quasar';
import { useState } from 'src/composables/useState';
import { toCurrency } from 'src/filters';
import { useStateStore } from 'stores/useStateStore';
@ -17,10 +18,12 @@ const { t } = useI18n();
const route = useRoute();
const quasar = useQuasar();
const stateStore = useStateStore();
const state = useState();
const user = state.getUser();
const clientRisks = ref(null);
const companiesOptions = ref([]);
const companyId = ref(442);
const companyId = ref(null);
const rows = ref(null);
const workerId = ref(0);
const receiptsRef = ref(null);
@ -29,12 +32,12 @@ const clientRisksRef = ref(null);
const filterCompanies = { order: ['code'] };
const params = {
clientId: `${route.params.id}`,
companyId: companyId.value,
companyId: user.value.companyFk,
filter: { limit: 20 },
};
const filter = {
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 = {
@ -151,8 +154,12 @@ const columns = computed(() => [
},
]);
const getData = () => {
onBeforeMount(() => {
stateStore.rightDrawer = true;
companyId.value = user.value.companyFk;
});
const getData = () => {
receiptsRef.value?.fetch();
clientRisksRef.value?.fetch();
};
@ -169,7 +176,11 @@ const showNewPaymentDialog = () => {
};
const updateCompanyId = (id) => {
if (id) companyId.value = id;
if (id) {
companyId.value = id;
params.companyId = id;
filter.where.companyFk = id;
}
getData();
};
</script>

View File

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

View File

@ -140,6 +140,7 @@ const toCustomerConsigneeEdit = (consigneeId) => {
</template>
</VnPaginate>
</QCard>
<QPageSticky :offset="[18, 18]">
<QBtn @click.stop="toCustomerConsigneeCreate()" color="primary" fab icon="add" />
<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,214 @@
<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>
<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,
}"
>
<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>
<style lang="scss" scoped>
.label-color {
color: var(--vn-label);
}
.customer-card {
border: 2px solid var(--vn-light-gray);
background-color: var(--vn-light-gray);
border-radius: 10px;
padding: 10px;
display: flex;
justify-content: space-between;
}
</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>
<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>
<i18n>
es:
Rating: Clasificación
Recommended credit: Crédito recomendado
</i18n>

View File

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

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

@ -0,0 +1,165 @@
<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 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 = {
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,
};
arrayData.value = useArrayData('CustomerSamplesCard', {
url: 'ClientSamples',
filter,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
const tableColumnComponents = {
sent: {
component: 'span',
props: () => {},
event: () => {},
},
description: {
component: 'span',
props: () => {},
event: () => {},
},
worker: {
component: QBtn,
props: () => ({ flat: true, color: 'blue' }),
event: (prop) => {
selectWorkerId(prop.row.clientFk);
},
},
company: {
component: 'span',
props: () => {},
event: () => {},
},
};
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 selectWorkerId = (id) => {
workerId.value = id;
};
const toCustomerSamplesCreate = () => {
router.push({ name: 'CustomerSamplesCreate' });
};
</script>
<template>
<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,6 +21,7 @@ const filter = { where: { id: `${route.params.id}` } };
model="client"
>
<template #form="{ data }">
<div v-if="data?.length">
<div
v-for="(item, index) in data"
:key="index"
@ -56,6 +57,7 @@ const filter = { where: { id: `${route.params.id}` } };
</div>
</VnRow>
</div>
</div>
</template>
</FormModel>
</template>

View File

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

View File

@ -321,7 +321,7 @@ const onDataSaved = () => {
size="sm"
>
<QTooltip>
{{ t('Remove') }}
{{ t('Remove note') }}
</QTooltip>
</QIcon>
</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,108 @@
<script setup>
import { computed, onBeforeMount, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import { date } from 'quasar';
import { useArrayData } from 'src/composables/useArrayData';
import { toCurrency } from 'src/filters';
import { useStateStore } from 'src/stores/useStateStore';
const { t } = useI18n();
const route = useRoute();
const stateStore = useStateStore();
const arrayData = ref(null);
const rows = computed(() => arrayData.value.store.data);
onBeforeMount(async () => {
const filter = {
where: {
creditClassificationFk: `${route.params.creditId}`,
},
limit: 20,
};
arrayData.value = useArrayData('CustomerCreditsContractsInsuranceCard', {
url: 'CreditInsurances',
filter,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
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>
<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>
import { reactive, ref } from 'vue';
import { reactive } from 'vue';
import { useI18n } from 'vue-i18n';
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 { useRoute } from 'vue-router';
import { useDialogPluginComponent } from 'quasar';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
@ -12,6 +14,7 @@ import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const route = useRoute();
const { dialogRef } = useDialogPluginComponent();
const $props = defineProps({
companyId: {

View File

@ -0,0 +1,248 @@
<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>
<style lang="scss" scoped>
.add-icon {
cursor: pointer;
background-color: $primary;
border-radius: 50px;
}
</style>
<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: [
{
path: 'credit-contracts',
@ -380,6 +378,41 @@ export default {
'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',
name: 'CustomerCreditOpinion',
@ -394,15 +427,151 @@ export default {
},
],
},
{
path: 'others',
name: 'CustomerOthers',
meta: {
title: 'others',
icon: 'pending',
menuChildren: [
{
name: 'CustomerSamples',
title: 'samples',
icon: 'pending',
},
component: () => import('src/pages/Customer/Card/CustomerOthers.vue'),
{
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',
},
],
},
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: 'unpaid',
name: 'CustomerUnpaid',
meta: {
title: 'unpaid',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerUnpaid.vue'),
},
],
},
],
},