Ticket basic data #474
|
@ -246,7 +246,7 @@ function updateAndEmit(evt, val, res) {
|
|||
emit(evt, state.get(modelValue), res);
|
||||
}
|
||||
|
||||
defineExpose({ save, isLoading, hasChanges });
|
||||
defineExpose({ save, isLoading, hasChanges, formData });
|
||||
</script>
|
||||
<template>
|
||||
<div class="column items-center full-width">
|
||||
|
|
|
@ -1,29 +1,508 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'components/FormModel.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 { toTimeFormat } from 'filters/date.js';
|
||||
|
||||
const { notify } = useNotify();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const stepperRef = ref(null);
|
||||
const formModelRef = ref(null);
|
||||
const agencyFetchRef = ref(null);
|
||||
const zonesFetchRef = ref(null);
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{ relation: 'address' },
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked',
|
||||
'credit',
|
||||
'email',
|
||||
'phone',
|
||||
'mobile',
|
||||
'hasElectronicInvoice',
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: { fields: ['id', 'name'] },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ relation: 'invoiceOut' },
|
||||
],
|
||||
};
|
||||
|
||||
const step = ref(1);
|
||||
const clientsOptions = ref([]);
|
||||
const warehousesOptions = ref([]);
|
||||
const companiesOptions = ref([]);
|
||||
const agenciesOptions = ref([]);
|
||||
const zonesOptions = ref([]);
|
||||
const addresses = ref([]);
|
||||
|
||||
const agencyByWarehouseFilter = computed(() => ({
|
||||
fields: ['id', 'name'],
|
||||
order: 'name ASC',
|
||||
where: {
|
||||
warehouseFk: warehouseId.value,
|
||||
},
|
||||
}));
|
||||
|
||||
const zonesFilter = computed(() => ({
|
||||
fields: ['id', 'name'],
|
||||
order: 'name ASC',
|
||||
where: formModelRef.value?.formData?.agencyModeFk
|
||||
? {
|
||||
shipped: formModelRef.value?.formData?.shipped,
|
||||
addressFk: formModelRef.value?.formData?.addressFk,
|
||||
agencyModeFk: formModelRef.value?.formData?.agencyModeFk,
|
||||
warehouseFk: formModelRef.value?.formData?.warehouseFk,
|
||||
}
|
||||
: {},
|
||||
}));
|
||||
|
||||
const getLanded = async (params) => {
|
||||
try {
|
||||
const validParams =
|
||||
shipped.value && addressId.value && agencyModeId.value && warehouseId.value;
|
||||
if (!validParams) {
|
||||
// this.$q.resolve(); ???????
|
||||
return;
|
||||
}
|
||||
formModelRef.value.formData.zoneFk = null;
|
||||
const { data } = await axios.get(`Agencies/getLanded`, { params });
|
||||
if (data) {
|
||||
formModelRef.value.formData.zoneFk = data.zoneFk;
|
||||
formModelRef.value.formData.landed = data.landed;
|
||||
formModelRef.value.formData.shipped = params.shipped;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notify(t('basicData.noDeliveryZoneAvailable'), 'negative');
|
||||
}
|
||||
};
|
||||
|
||||
const getShipped = async (params) => {
|
||||
try {
|
||||
const validParams =
|
||||
landed.value && addressId.value && agencyModeId.value && warehouseId.value;
|
||||
if (!validParams) return;
|
||||
|
||||
formModelRef.value.formData.zoneFk = null;
|
||||
const { data } = await axios.get(`Agencies/getShipped`, { params });
|
||||
if (data) {
|
||||
formModelRef.value.formData.zoneFk = data.zoneFk;
|
||||
formModelRef.value.formData.landed = params.landed;
|
||||
formModelRef.value.formData.shipped = data.shipped;
|
||||
} else {
|
||||
notify(t('basicData.noDeliveryZoneAvailable'), 'negative');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notify(t('basicData.noDeliveryZoneAvailable'), 'negative');
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeZone = async (zoneId) => {
|
||||
try {
|
||||
formModelRef.value.formData.agencyModeFk = null;
|
||||
const { data } = await axios.get(`Zones/${zoneId}`);
|
||||
formModelRef.value.formData.agencyModeFk = data.agencyModeFk;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeAddress = async (addressId) => {
|
||||
try {
|
||||
formModelRef.value.formData.nickname = null;
|
||||
const { data } = await axios.get(`Addresses/${addressId}`);
|
||||
formModelRef.value.formData.nickname = data.nickname;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getClientDefaultAddress = async (clientId) => {
|
||||
try {
|
||||
const { data } = await axios.get(`Clients/${clientId}`);
|
||||
if (data) addressId.value = data.defaultAddressFk;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
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: () => formModelRef.value?.formData?.addressFk,
|
||||
set: (val) => {
|
||||
if (val != formModelRef.value?.formData?.addressFk) {
|
||||
formModelRef.value.formData.addressFk = val;
|
||||
onChangeAddress(val);
|
||||
getShipped({
|
||||
landed: formModelRef.value?.formData?.landed,
|
||||
addressFk: val,
|
||||
agencyModeFk: formModelRef.value?.formData?.agencyModeFk,
|
||||
warehouseFk: formModelRef.value?.formData?.warehouseFk,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const clientId = computed({
|
||||
get: () => formModelRef.value?.formData?.clientFk,
|
||||
set: (val) => {
|
||||
formModelRef.value.formData.clientFk = val;
|
||||
formModelRef.value.formData.addressFk = null;
|
||||
if (!val) return;
|
||||
getClientDefaultAddress(val);
|
||||
clientAddressesList(val);
|
||||
},
|
||||
});
|
||||
|
||||
const landed = computed({
|
||||
get: () => formModelRef.value?.formData?.landed,
|
||||
set: (val) => {
|
||||
formModelRef.value.formData.landed = val;
|
||||
getShipped({
|
||||
landed: val,
|
||||
addressFk: formModelRef.value?.formData?.addressFk,
|
||||
agencyModeFk: formModelRef.value?.formData?.agencyModeFk,
|
||||
warehouseFk: formModelRef.value?.formData?.warehouseFk,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const agencyModeId = computed({
|
||||
get: () => formModelRef.value?.formData?.agencyModeFk,
|
||||
set: (val) => {
|
||||
if (val != formModelRef.value?.formData?.agencyModeFk) {
|
||||
formModelRef.value.formData.agencyModeFk = val;
|
||||
if (!val) return;
|
||||
const agencyMode = agenciesOptions.value.find((a) => a.id == val);
|
||||
formModelRef.value.formData.warehouseFk = agencyMode.warehouseFk;
|
||||
|
||||
getLanded({
|
||||
shipped: formModelRef.value?.formData?.shipped,
|
||||
addressFk: formModelRef.value?.formData?.addressFk,
|
||||
agencyModeFk: val,
|
||||
warehouseFk: formModelRef.value?.formData?.warehouseFk,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const zoneId = computed({
|
||||
get: () => formModelRef.value?.formData?.zoneFk,
|
||||
set: (val) => {
|
||||
if (val != formModelRef.value.formData.zoneFk) {
|
||||
formModelRef.value.formData.zoneFk = val;
|
||||
onChangeZone(val);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const warehouseId = computed({
|
||||
get: () => formModelRef.value?.formData?.warehouseFk,
|
||||
set: (val) => {
|
||||
if (val != formModelRef.value.formData.warehouseFk) {
|
||||
formModelRef.value.formData.warehouseFk = val;
|
||||
getShipped({
|
||||
landed: formModelRef.value.formData.landed,
|
||||
addressFk: formModelRef.value.formData.addressFk,
|
||||
agencyModeFk: formModelRef.value.formData.agencyModeFk,
|
||||
warehouseFk: val,
|
||||
}).then(() => {
|
||||
if (zoneId.value == null) formModelRef.value.formData.agencyModeFk = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const shipped = computed({
|
||||
get: () => formModelRef.value?.formData?.shipped,
|
||||
set: (val) => {
|
||||
if (
|
||||
new Date(formModelRef.value?.formData?.shipped).toDateString() !=
|
||||
val.toDateString()
|
||||
)
|
||||
val.setHours(0, 0, 0, 0);
|
||||
formModelRef.value.formData.shipped = val;
|
||||
getLanded({
|
||||
shipped: val,
|
||||
addressFk: formModelRef.value?.formData?.addressFk,
|
||||
agencyModeFk: formModelRef.value?.formData?.agencyModeFk,
|
||||
warehouseFk: formModelRef.value?.formData?.warehouseFk,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const onFormModelInit = () => {
|
||||
if (formModelRef.value.formData.clientFk)
|
||||
clientAddressesList(formModelRef.value.formData.clientFk);
|
||||
};
|
||||
|
||||
const redirectToCustomerAddress = () => {
|
||||
router.push({
|
||||
name: 'CustomerAddressEditCard',
|
||||
params: { id: clientId.value, addressId: addressId.value },
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<QStepper v-model="step" ref="stepperRef" color="primary" header-nav animated>
|
||||
<QStep
|
||||
:name="1"
|
||||
title="Select campaign settings"
|
||||
icon="settings"
|
||||
:error="step < 3"
|
||||
:done="step > 1"
|
||||
>
|
||||
For each ad campaign that you create, you can control how much you're willing
|
||||
to spend on clicks and conversions, which networks and geographical locations
|
||||
you want your ads to show on, and more.
|
||||
<FetchData
|
||||
url="Clients"
|
||||
:filter="{
|
||||
fields: ['id', 'name'],
|
||||
order: 'id',
|
||||
}"
|
||||
@on-fetch="(data) => (clientsOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<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
|
||||
/>
|
||||
<FetchData
|
||||
ref="zonesFetchRef"
|
||||
url="Zones/includingExpired"
|
||||
:filter="zonesFilter"
|
||||
@on-fetch="(data) => (zonesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<QStepper
|
||||
v-model="step"
|
||||
ref="stepperRef"
|
||||
color="primary"
|
||||
header-nav
|
||||
animated
|
||||
keep-alive
|
||||
>
|
||||
<QStep :name="1" title="Select campaign settings" :done="step > 1">
|
||||
<FormModel
|
||||
ref="formModelRef"
|
||||
:url="`Tickets/${route.params.id}`"
|
||||
:url-update="`Tickets/${route.params.id}`"
|
||||
:filter="filter"
|
||||
model="Ticket"
|
||||
auto-load
|
||||
:default-actions="false"
|
||||
@on-fetch="onFormModelInit()"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnSelect
|
||||
:label="t('basicData.client')"
|
||||
v-model="clientId"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
:options="clientsOptions"
|
||||
hide-selected
|
||||
map-options
|
||||
:required="true"
|
||||
>
|
||||
<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"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnSelect
|
||||
:label="t('basicData.address')"
|
||||
v-model="addressId"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:options="addresses"
|
||||
hide-selected
|
||||
map-options
|
||||
:required="true"
|
||||
>
|
||||
<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="data.nickname" />
|
||||
</VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnSelect
|
||||
:label="t('basicData.company')"
|
||||
v-model="data.companyFk"
|
||||
option-value="id"
|
||||
option-label="code"
|
||||
:options="companiesOptions"
|
||||
hide-selected
|
||||
map-options
|
||||
:required="true"
|
||||
/>
|
||||
<VnSelect
|
||||
:label="t('basicData.agency')"
|
||||
v-model="agencyModeId"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
:options="agenciesOptions"
|
||||
hide-selected
|
||||
map-options
|
||||
:required="true"
|
||||
@focus="agencyFetchRef.fetch()"
|
||||
/>
|
||||
<VnSelect
|
||||
:label="t('basicData.zone')"
|
||||
v-model="zoneId"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
:options="zonesOptions"
|
||||
hide-selected
|
||||
map-options
|
||||
:required="true"
|
||||
@focus="zonesFetchRef.fetch()"
|
||||
>
|
||||
<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 class="row q-gutter-md q-mb-md">
|
||||
<VnInputDate
|
||||
:label="t('basicData.shipped')"
|
||||
v-model="data.shipped"
|
||||
:required="true"
|
||||
/>
|
||||
<VnInputTime
|
||||
:label="t('basicData.shippedHour')"
|
||||
v-model="data.shipped"
|
||||
/>
|
||||
<VnInputDate
|
||||
:label="t('basicData.landed')"
|
||||
v-model="data.landed"
|
||||
:required="true"
|
||||
/>
|
||||
</VnRow>
|
||||
</template>
|
||||
</FormModel>
|
||||
</QStep>
|
||||
<QStep
|
||||
:name="2"
|
||||
title="Create an ad group"
|
||||
caption="Optional"
|
||||
icon="create_new_folder"
|
||||
:done="step > 2"
|
||||
>
|
||||
<QStep :name="2" title="Create an ad group" caption="Optional">
|
||||
An ad group contains one or more ads which target a shared set of keywords.
|
||||
</QStep>
|
||||
|
||||
|
@ -32,17 +511,18 @@ const step = ref(1);
|
|||
<QBtn
|
||||
@click="stepperRef.next()"
|
||||
color="primary"
|
||||
:label="step === 3 ? 'Finish' : 'Continue'"
|
||||
:label="step === 2 ? t('basicData.finalize') : t('basicData.next')"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="step > 1"
|
||||
flat
|
||||
color="primary"
|
||||
@click="stepperRef.previous()"
|
||||
label="Back"
|
||||
:label="t('basicData.back')"
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</QStepperNavigation>
|
||||
</template>
|
||||
</QStepper>
|
||||
<pre v-if="formModelRef">{{ formModelRef.formData }}</pre>
|
||||
</template>
|
||||
|
|
|
@ -2,3 +2,16 @@ basicData:
|
|||
next: Next
|
||||
back: Back
|
||||
finalize: Finalize
|
||||
client: Client
|
||||
warehouse: Warehouse
|
||||
address: Address
|
||||
inactive: (Inactive)
|
||||
noDeliveryZoneAvailable: No delivery zone available for this landing date
|
||||
editAddress: Edit address
|
||||
alias: Alias
|
||||
company: Company
|
||||
agency: Agency
|
||||
zone: Zone
|
||||
shipped: Shipped
|
||||
landed: Landed
|
||||
shippedHour: Shipped hour
|
||||
|
|
|
@ -2,5 +2,18 @@ basicData:
|
|||
next: Siguiente
|
||||
back: Anterior
|
||||
finalize: Finalizar
|
||||
client: Cliente
|
||||
warehouse: Almacén
|
||||
address: Consignatario
|
||||
inactive: (Inactivo)
|
||||
noDeliveryZoneAvailable: No hay una zona de reparto disponible para la fecha de envío seleccionada
|
||||
editAddress: Editar dirección
|
||||
alias: Alias
|
||||
company: Empresa
|
||||
agency: Agencia
|
||||
zone: Zona
|
||||
shipped: F. Envío
|
||||
landed: F. Entrega
|
||||
shippedHour: Hora de envío
|
||||
Search ticket: Buscar ticket
|
||||
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
||||
|
|
Loading…
Reference in New Issue