salix-front/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue

443 lines
14 KiB
Vue

<script setup>
import { ref, computed, onMounted, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
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 VnInputTime from 'components/common/VnInputTime.vue';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
import { useAcl } from 'src/composables/useAcl';
import { useValidator } from 'src/composables/useValidator';
import { toTimeFormat } from 'filters/date.js';
const formData = defineModel({
type: Object,
required: true,
});
const emit = defineEmits(['updateForm']);
const { validate } = useValidator();
const { notify } = useNotify();
const router = useRouter();
const { t } = useI18n();
const canEditZone = useAcl().hasAny([
{ model: 'Ticket', props: 'editZone', accessType: 'WRITE' },
]);
const agencyFetchRef = ref();
const warehousesOptions = ref([]);
const companiesOptions = ref([]);
const agenciesOptions = ref([]);
const zonesOptions = ref([]);
const addresses = ref([]);
const zoneSelectRef = ref();
watch(
() => formData.value,
(val) => emit('updateForm', val),
{ deep: true }
);
onMounted(() => onFormModelInit());
const agencyByWarehouseFilter = computed(() => ({
fields: ['id', 'name'],
order: 'name ASC',
where: {
warehouseFk: warehouseId.value,
},
}));
const zoneWhere = computed(() => {
return formData.value?.agencyModeFk
? {
shipped: formData.value?.shipped,
addressFk: formData.value?.addressFk,
agencyModeFk: formData.value?.agencyModeFk,
warehouseFk: formData.value?.warehouseFk,
}
: {};
});
async function getLanded(params) {
getDate(`Agencies/getLanded`, params);
}
async function getShipped(params) {
getDate(`Agencies/getShipped`, params);
}
async function getDate(query, params) {
for (const param in params) {
if (!params[param]) return;
}
formData.value.zoneFk = null;
zonesOptions.value = [];
const { data } = await axios.get(query, { params });
if (!data) return notify(t('basicData.noDeliveryZoneAvailable'), 'negative');
formData.value.zoneFk = data.zoneFk;
if (data.landed) formData.value.landed = data.landed;
if (data.shipped) formData.value.shipped = data.shipped;
}
const onChangeZone = async (zoneId) => {
formData.value.agencyModeFk = null;
const { data } = await axios.get(`Zones/${zoneId}`);
formData.value.agencyModeFk = data.agencyModeFk;
};
const onChangeAddress = async (addressId) => {
formData.value.nickname = null;
const { data } = await axios.get(`Addresses/${addressId}`);
formData.value.nickname = data.nickname;
};
const getClientDefaultAddress = async (clientId) => {
const { data } = await axios.get(`Clients/${clientId}`);
if (data) addressId.value = data.defaultAddressFk;
};
const clientAddressesList = async (value) => {
let filter = {
include: [
{
relation: 'province',
scope: {
fields: ['name'],
},
},
{
relation: 'agencyMode',
scope: {
fields: ['name'],
},
},
],
};
const params = { filter: JSON.stringify(filter) };
const { data } = await axios.get(`Clients/${value}/addresses`, { params });
if (data) addresses.value = data;
};
const addressId = computed({
get: () => formData.value?.addressFk,
set: (val) => {
if (val != formData.value?.addressFk) {
formData.value.addressFk = val;
onChangeAddress(val);
getShipped({
landed: formData.value?.landed,
addressFk: val,
agencyModeFk: formData.value?.agencyModeFk,
warehouseFk: formData.value?.warehouseFk,
});
}
},
});
const clientId = computed({
get: () => formData.value?.clientFk,
set: (val) => {
formData.value.clientFk = val;
formData.value.addressFk = null;
if (!val) return;
getClientDefaultAddress(val);
clientAddressesList(val);
},
});
function addDateParams(obj) {
return {
...obj,
...{
addressFk: formData.value?.addressFk,
agencyModeFk: formData.value?.agencyModeFk,
warehouseFk: formData.value?.warehouseFk,
},
};
}
async function setLanded(landed) {
if (!landed) return;
getShipped(addDateParams({ landed }));
}
async function setShipped(shipped) {
if (!shipped) return;
getLanded(addDateParams({ shipped }));
}
const agencyModeId = computed({
get: () => formData.value.agencyModeFk,
set: (val) => {
if (val != formData.value.agencyModeFk) {
formData.value.agencyModeFk = val;
if (!val) return;
const agencyMode = agenciesOptions.value.find((a) => a.id == val);
formData.value.warehouseFk = agencyMode.warehouseFk;
getLanded({
shipped: formData.value?.shipped,
addressFk: formData.value?.addressFk,
agencyModeFk: val,
warehouseFk: formData.value?.warehouseFk,
});
}
},
});
const zoneId = computed({
get: () => formData.value?.zoneFk,
set: (val) => {
if (val != formData.value?.zoneFk) {
formData.value.zoneFk = val;
onChangeZone(val);
}
},
});
const warehouseId = computed({
get: () => formData.value?.warehouseFk,
set: (val) => {
if (val != formData.value?.warehouseFk) {
formData.value.warehouseFk = val;
getShipped({
landed: formData.value?.landed,
addressFk: formData.value?.addressFk,
agencyModeFk: formData.value?.agencyModeFk,
warehouseFk: val,
}).then(() => {
if (zoneId.value == null) formData.value.agencyModeFk = null;
});
}
},
});
const onFormModelInit = () => {
if (formData.value?.clientFk) clientAddressesList(formData.value?.clientFk);
};
const redirectToCustomerAddress = () => {
router.push({
name: 'CustomerAddressEditCard',
params: { id: clientId.value, addressId: addressId.value },
});
};
async function getZone(options) {
if (!zoneId.value) return;
const zone = options.find((z) => z.id == zoneId.value);
if (zone) return;
const { data } = await axios.get('Zones/' + zoneId.value, {
params: { filter: JSON.stringify({ fields: ['id', 'name'] }) },
});
zoneSelectRef.value.opts.push(data);
}
</script>
<template>
<FetchData
url="Warehouses"
@on-fetch="(data) => (warehousesOptions = data)"
auto-load
/>
<FetchData
url="Companies"
:filter="{
fields: ['id', 'code'],
order: 'code ASC',
}"
@on-fetch="(data) => (companiesOptions = data)"
auto-load
/>
<FetchData
ref="agencyFetchRef"
url="AgencyModes/byWarehouse"
:filter="agencyByWarehouseFilter"
@on-fetch="(data) => (agenciesOptions = data)"
auto-load
/>
<QForm>
<VnRow>
<VnSelect
:label="t('basicData.client')"
v-model="clientId"
option-value="id"
option-label="name"
url="Clients"
:fields="['id', 'name']"
sort-by="id"
hide-selected
map-options
:required="true"
:rules="validate('basicData.client')"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel
>#{{ scope.opt?.id }} {{ scope.opt?.name }}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
:label="t('basicData.warehouse')"
v-model="warehouseId"
option-value="id"
option-label="name"
:options="warehousesOptions"
hide-selected
map-options
:required="true"
:rules="validate('basicData.warehouse')"
/>
</VnRow>
<VnRow>
<VnSelect
:label="t('basicData.address')"
v-model="addressId"
option-value="id"
option-label="nickname"
:options="addresses"
hide-selected
map-options
:required="true"
:rules="validate('basicData.address')"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel
:class="{
'color-vn-label': !scope.opt?.isActive,
}"
>
{{
`${
!scope.opt?.isActive
? t('basicData.inactive')
: ''
} `
}}
<span> {{ scope.opt?.nickname }}</span>
<span
v-if="
scope.opt?.province ||
scope.opt?.city ||
scope.opt?.street
"
>, {{ scope.opt?.street }}, {{ scope.opt?.city }},
{{ scope.opt?.province?.name }} -
{{ scope.opt?.agencyMode?.name }}</span
>
</QItemLabel>
</QItemSection>
</QItem>
</template>
<template #append>
<QIcon
name="edit"
color="primary"
size="sm"
class="fill-icon cursor-pointer"
@click.stop="redirectToCustomerAddress()"
>
<QTooltip>{{ t('basicData.editAddress') }}</QTooltip>
</QIcon>
</template>
</VnSelect>
<VnInput
:label="t('basicData.alias')"
v-model="formData.nickname"
:required="true"
:rules="validate('basicData.alias')"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md no-wrap">
<VnSelect
:label="t('basicData.company')"
v-model="formData.companyFk"
option-value="id"
option-label="code"
:options="companiesOptions"
hide-selected
map-options
:required="true"
:rules="validate('basicData.company')"
/>
<VnSelect
:label="t('basicData.agency')"
v-model="agencyModeId"
option-value="id"
option-label="name"
:options="agenciesOptions"
hide-selected
map-options
@focus="agencyFetchRef.fetch()"
:rules="validate('basicData.agency')"
/>
<VnSelect
ref="zoneSelectRef"
:label="t('basicData.zone')"
v-model="zoneId"
option-value="id"
option-label="name"
url="Zones/includingExpired"
:fields="['id', 'name']"
sort-by="id"
:where="zoneWhere"
:rules="validate('basicData.zone')"
:required="true"
:disable="!canEditZone"
@update:options="getZone"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel
>{{ scope.opt?.name }} - Max.
{{ toTimeFormat(scope.opt?.hour) }}
h.</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
<VnRow>
<VnInputDate
:label="t('basicData.shipped')"
v-model="formData.shipped"
:required="true"
:rules="validate('basicData.shipped')"
@update:model-value="setShipped"
/>
<VnInputTime
:label="t('basicData.shippedHour')"
v-model="formData.shipped"
:required="true"
:rules="validate('basicData.shippedHour')"
@update:model-value="setShipped"
/>
<VnInputDate
:label="t('basicData.landed')"
v-model="formData.landed"
:required="true"
:rules="validate('basicData.landed')"
@update:model-value="setLanded"
/>
</VnRow>
</QForm>
</template>