salix-front/src/pages/Customer/components/CustomerSamplesCreate.vue

386 lines
12 KiB
Vue

<script setup>
import { onBeforeMount, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { useQuasar } from 'quasar';
import { useState } from 'src/composables/useState';
import { useValidator } from 'src/composables/useValidator';
import useNotify from 'src/composables/useNotify';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import CustomerSamplesPreview from 'src/pages/Customer/components/CustomerSamplesPreview.vue';
import { useStateStore } from 'stores/useStateStore';
const { notify } = useNotify();
const { t } = useI18n();
const { validate } = useValidator();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const state = useState();
const user = state.getUser();
const stateStore = useStateStore();
const client = ref({});
const hasChanged = ref(false);
const isLoading = ref(false);
const optionsClientsAddressess = ref([]);
const optionsCompanies = ref([]);
const optionsEmailUsers = ref([]);
const optionsSamplesVisible = ref([]);
const sampleType = ref({ hasPreview: false });
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 { data } = await axios.get(`Clients/1/getCard`);
client.value = data;
initialData.clientFk = route.params?.id;
initialData.recipient = data.email;
initialData.recipientId = data.id;
});
const setEmailUser = (data) => {
optionsEmailUsers.value = data;
initialData.replyTo = data[0]?.email;
};
const setClientsAddresses = (data) => {
initialData.addressId = data[0].id;
optionsClientsAddressess.value = data;
};
const setSampleType = (sampleId) => {
hasChanged.value = true;
const { companyFk } = user.value;
sampleType.value = optionsSamplesVisible.value.find((option) => {
return option.id === sampleId;
});
initialData.companyFk = companyFk;
initialData.companyId = companyFk;
};
const setInitialData = () => {
hasChanged.value = false;
initialData.addressId = optionsClientsAddressess.value[0].id;
initialData.companyFk = null;
initialData.from = null;
initialData.recipient = client.value.email;
initialData.recipientId = client.value.id;
initialData.replyTo = optionsEmailUsers.value[0]?.email;
initialData.typeFk = '';
sampleType.value = {};
};
const validateMessage = () => {
if (!initialData.recipient) return 'Email cannot be blank';
if (!sampleType.value) return 'Choose a sample';
if (sampleType.value.hasCompany && !initialData.companyFk) return 'Choose a company';
if (sampleType.value.datepickerEnabled && !initialData.from) return 'Choose a date';
return '';
};
const setParams = (params) => {
if (sampleType.value.hasCompany) params.companyId = initialData.companyFk;
if (sampleType.value.datepickerEnabled) params.from = initialData.from;
if (initialData.addressId) params.addressId = initialData.addressId;
};
const getPreview = async () => {
try {
const params = {
recipientId: route.params.id,
};
const validationMessage = validateMessage();
if (validationMessage) return notify(t(validationMessage), 'negative');
setParams(params);
const path = `${sampleType.value.model}/${route.params.id}/${sampleType.value.code}-html`;
const { data } = await axios.get(path, { params });
if (!data) return;
quasar.dialog({
component: CustomerSamplesPreview,
componentProps: {
htmlContent: data,
},
});
} catch (err) {
notify('Errors getting preview', 'negative');
}
};
const onSubmit = async () => {
isLoading.value = true;
try {
const { data } = await axios.patch('ClientSamples', initialData);
notify('globals.dataSaved', 'positive');
onDataSaved(data);
} catch (error) {
notify('errors.create', 'negative');
} finally {
isLoading.value = false;
}
};
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,
});
toCustomerSamples();
};
const updateModelValue = () => {
hasChanged.value = true;
};
const toCustomerSamples = () => {
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="setClientsAddresses"
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"
/>
<Teleport v-if="stateStore?.isSubToolbarShown()" to="#st-actions">
<QBtnGroup push class="q-gutter-x-sm">
<QBtn
:label="t('globals.cancel')"
@click="toCustomerSamples"
color="primary"
flat
icon="close"
/>
<QBtn
:disabled="isLoading || !sampleType?.hasPreview"
:label="t('Preview')"
:loading="isLoading"
@click.stop="getPreview()"
color="primary"
flat
icon="preview"
/>
<QBtn
:disabled="!hasChanged"
:label="t('globals.reset')"
:loading="isLoading"
@click="setInitialData"
color="primary"
flat
icon="restart_alt"
type="reset"
/>
<QBtn
:disabled="!hasChanged"
:label="t('globals.save')"
:loading="isLoading"
@click="onSubmit"
color="primary"
icon="save"
/>
</QBtnGroup>
</Teleport>
<div class="full-width flex justify-center">
<QCard class="card-width q-pa-lg">
<QForm>
<div class="col">
<VnSelect
:label="t('Sample')"
:options="optionsSamplesVisible"
@update:model-value="setSampleType"
hide-selected
option-label="description"
option-value="id"
v-model="initialData.typeFk"
/>
</div>
<VnRow>
<div class="col">
<VnInput
:label="t('Recipient')"
@update:model-value="updateModelValue"
clearable
required="true"
v-model="initialData.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')"
@update:model-value="updateModelValue"
clearable
required="true"
v-model="initialData.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">
<VnSelect
:label="t('Company')"
:options="optionsCompanies"
:rules="validate('entry.companyFk')"
hide-selected
option-label="code"
option-value="id"
required="true"
v-model="initialData.companyFk"
v-if="sampleType.hasCompany"
/>
</div>
<div class="col">
<VnSelect
:label="t('Address')"
:options="optionsClientsAddressess"
hide-selected
option-label="nickname"
option-value="id"
required="true"
v-model="initialData.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>
<template #append>
<QIcon name="edit" class="cursor-pointer">
<QTooltip>{{ t('Edit address') }}</QTooltip>
</QIcon>
</template>
</VnSelect>
</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="initialData.from"
/>
</div>
</VnRow>
</QForm>
</QCard>
</div>
</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?
Edit address: Editar dirección
Preview: Vista previa
Email cannot be blank: Debes introducir un email
Choose a sample: Selecciona una plantilla
Choose a company: Selecciona una empresa
Choose a date: Selecciona una fecha
</i18n>