340 lines
11 KiB
Vue
340 lines
11 KiB
Vue
<script setup>
|
|
import { onBeforeMount, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
import axios from 'axios';
|
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
|
import FetchData from 'components/FetchData.vue';
|
|
import FormModel from 'components/FormModel.vue';
|
|
import VnRow from 'components/ui/VnRow.vue';
|
|
import VnInput from 'src/components/common/VnInput.vue';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
|
import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
|
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
|
|
|
const { t } = useI18n();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
|
|
const urlUpdate = ref('');
|
|
const agencyModes = ref([]);
|
|
const incoterms = ref([]);
|
|
const customsAgents = ref([]);
|
|
const observationTypes = ref([]);
|
|
const notes = ref([]);
|
|
let originalNotes = [];
|
|
const deletes = ref([]);
|
|
|
|
onBeforeMount(() => {
|
|
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.addressId}`;
|
|
});
|
|
|
|
const getData = async (observations) => {
|
|
observationTypes.value = observations;
|
|
|
|
if (observationTypes.value.length) {
|
|
const filter = {
|
|
fields: ['id', 'addressFk', 'observationTypeFk', 'description'],
|
|
where: { addressFk: `${route.params.addressId}` },
|
|
};
|
|
const { data } = await axios.get('AddressObservations', {
|
|
params: { filter: JSON.stringify(filter) },
|
|
});
|
|
|
|
if (data.length) {
|
|
originalNotes = data;
|
|
notes.value = originalNotes
|
|
.map((observation) => {
|
|
const type = observationTypes.value.find(
|
|
(type) => type.id === observation.observationTypeFk
|
|
);
|
|
return type
|
|
? {
|
|
$isNew: false,
|
|
$oldData: null,
|
|
$orgIndex: null,
|
|
addressFk: `${route.params.addressId}`,
|
|
description: observation.description,
|
|
id: observation.id,
|
|
observationTypeFk: type.id,
|
|
}
|
|
: null;
|
|
})
|
|
.filter((item) => item !== null);
|
|
}
|
|
}
|
|
};
|
|
|
|
const addNote = () => {
|
|
notes.value.push({
|
|
$isNew: true,
|
|
$oldData: null,
|
|
$orgIndex: null,
|
|
addressFk: `${route.params.addressId}`,
|
|
description: '',
|
|
observationTypeFk: '',
|
|
});
|
|
};
|
|
|
|
const deleteNote = (id, index) => {
|
|
deletes.value.push(id);
|
|
notes.value.splice(index, 1);
|
|
};
|
|
|
|
const onDataSaved = async () => {
|
|
let payload = {
|
|
creates: notes.value.filter((note) => note.$isNew),
|
|
deletes: deletes.value,
|
|
updates: notes.value
|
|
.filter((note) =>
|
|
originalNotes.some(
|
|
(oNote) =>
|
|
oNote.id === note.id &&
|
|
(note.description !== oNote.description ||
|
|
note.observationTypeFk !== oNote.observationTypeFk)
|
|
)
|
|
)
|
|
.map((note) => ({
|
|
data: note,
|
|
where: { id: note.id },
|
|
})),
|
|
};
|
|
|
|
await axios.post('AddressObservations/crud', payload);
|
|
notes.value = [];
|
|
deletes.value = [];
|
|
toCustomerAddress();
|
|
};
|
|
|
|
const toCustomerAddress = () => {
|
|
router.push({
|
|
name: 'CustomerAddress',
|
|
params: {
|
|
id: route.params.id,
|
|
},
|
|
});
|
|
};
|
|
function handleLocation(data, location) {
|
|
const { town, code, provinceFk, countryFk } = location ?? {};
|
|
data.postalCode = code;
|
|
data.city = town;
|
|
data.provinceFk = provinceFk;
|
|
data.countryFk = countryFk;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<FetchData
|
|
@on-fetch="(data) => (agencyModes = data)"
|
|
auto-load
|
|
url="AgencyModes/isActive"
|
|
/>
|
|
<FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
|
|
<FetchData
|
|
@on-fetch="(data) => (customsAgents = data)"
|
|
auto-load
|
|
url="CustomsAgents"
|
|
/>
|
|
<FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
|
|
|
|
<FormModel
|
|
:observe-form-changes="false"
|
|
:url-update="urlUpdate"
|
|
:url="`Addresses/${route.params.addressId}`"
|
|
@on-data-saved="onDataSaved()"
|
|
auto-load
|
|
>
|
|
<template #moreActions>
|
|
<QBtn
|
|
:label="t('globals.cancel')"
|
|
@click="toCustomerAddress"
|
|
color="primary"
|
|
flat
|
|
icon="close"
|
|
/>
|
|
</template>
|
|
|
|
<template #form="{ data, validate }">
|
|
<VnRow>
|
|
<div class="col">
|
|
<QCheckbox :label="t('Enabled')" v-model="data.isActive" />
|
|
</div>
|
|
<div class="col">
|
|
<QCheckbox
|
|
:label="t('Is equalizated')"
|
|
v-model="data.isEqualizated"
|
|
/>
|
|
</div>
|
|
<div class="col">
|
|
<QCheckbox
|
|
:label="t('Is Loginflora allowed')"
|
|
v-model="data.isLogifloraAllowed"
|
|
/>
|
|
</div>
|
|
</VnRow>
|
|
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnInput :label="t('Consignee')" clearable v-model="data.nickname" />
|
|
</div>
|
|
<div class="col">
|
|
<VnInput :label="t('Street')" clearable v-model="data.street" />
|
|
</div>
|
|
</VnRow>
|
|
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnLocation
|
|
:rules="validate('Worker.postcode')"
|
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
|
:location="{
|
|
postcode: data.postalCode,
|
|
city: data.city,
|
|
province: data.province,
|
|
country: data.province.country,
|
|
}"
|
|
@update:model-value="(location) => handleLocation(data, location)"
|
|
></VnLocation>
|
|
</div>
|
|
</VnRow>
|
|
|
|
<VnRow>
|
|
<div class="col">
|
|
<VnSelect
|
|
:label="t('Agency')"
|
|
:options="agencyModes"
|
|
:rules="validate('route.agencyFk')"
|
|
hide-selected
|
|
option-label="name"
|
|
option-value="id"
|
|
v-model="data.agencyModeFk"
|
|
/>
|
|
</div>
|
|
<div class="col">
|
|
<VnInput :label="t('Phone')" clearable v-model="data.phone" />
|
|
</div>
|
|
<div class="col">
|
|
<VnInput :label="t('Mobile')" clearable v-model="data.mobile" />
|
|
</div>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnSelect
|
|
:label="t('Incoterms')"
|
|
:options="incoterms"
|
|
hide-selected
|
|
option-label="name"
|
|
option-value="code"
|
|
v-model="data.incotermsFk"
|
|
/>
|
|
<VnSelectDialog
|
|
:label="t('Customs agent')"
|
|
:options="customsAgents"
|
|
hide-selected
|
|
option-label="fiscalName"
|
|
option-value="id"
|
|
v-model="data.customsAgentFk"
|
|
:tooltip="t('New customs agent')"
|
|
>
|
|
<template #form>
|
|
<CustomerNewCustomsAgent />
|
|
</template>
|
|
</VnSelectDialog>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnInputNumber
|
|
:label="t('Longitude')"
|
|
clearable
|
|
v-model="data.longitude"
|
|
:decimal-places="7"
|
|
:positive="false"
|
|
/>
|
|
<VnInputNumber
|
|
:label="t('Latitude')"
|
|
clearable
|
|
v-model="data.latitude"
|
|
:decimal-places="7"
|
|
:positive="false"
|
|
/>
|
|
</VnRow>
|
|
<h4 class="q-mb-xs">{{ t('Notes') }}</h4>
|
|
<VnRow
|
|
:key="index"
|
|
class="row q-gutter-md q-mb-md"
|
|
v-for="(note, index) in notes"
|
|
>
|
|
<VnSelect
|
|
:label="t('Observation type')"
|
|
:options="observationTypes"
|
|
hide-selected
|
|
option-label="description"
|
|
option-value="id"
|
|
v-model="note.observationTypeFk"
|
|
/>
|
|
<VnInput
|
|
:label="t('Description')"
|
|
:rules="validate('route.description')"
|
|
clearable
|
|
v-model="note.description"
|
|
/>
|
|
<QIcon
|
|
:style="{ flex: 0, 'align-self': $q.screen.gt.xs ? 'end' : 'center' }"
|
|
@click.stop="deleteNote(note.id, index)"
|
|
class="cursor-pointer"
|
|
color="primary"
|
|
name="delete"
|
|
size="sm"
|
|
>
|
|
<QTooltip>
|
|
{{ t('Remove note') }}
|
|
</QTooltip>
|
|
</QIcon>
|
|
</VnRow>
|
|
<QBtn
|
|
@click.stop="addNote()"
|
|
class="cursor-pointer add-icon q-mt-md"
|
|
flat
|
|
icon="add"
|
|
shortcut="+"
|
|
>
|
|
<QTooltip>
|
|
{{ t('Add note') }}
|
|
</QTooltip>
|
|
</QBtn>
|
|
</template>
|
|
</FormModel>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.add-icon {
|
|
background-color: $primary;
|
|
border-radius: 50px;
|
|
}
|
|
</style>
|
|
|
|
<i18n>
|
|
es:
|
|
Enabled: Activo
|
|
Is equalizated: Recargo de equivalencia
|
|
Is Loginflora allowed: Compra directa en Holanda
|
|
Consignee: Consignatario
|
|
Street: Dirección fiscal
|
|
Postcode: Código postal
|
|
City: Población
|
|
Province: Provincia
|
|
Agency: Agencia
|
|
Phone: Teléfono
|
|
Mobile: Movíl
|
|
Incoterms: Incoterms
|
|
Customs agent: Agente de aduanas
|
|
New customs agent: Nuevo agente de aduanas
|
|
Notes: Notas
|
|
Observation type: Tipo de observación
|
|
Description: Descripción
|
|
Add note: Añadir nota
|
|
Remove note: Eliminar nota
|
|
Longitude: Longitud
|
|
Latitude: Latitud
|
|
</i18n>
|