Compare commits
29 Commits
dev
...
7527-notCr
Author | SHA1 | Date |
---|---|---|
|
9721dc957f | |
|
ffafab33d1 | |
|
d5960617f4 | |
|
37773f2ce0 | |
|
f3a1816508 | |
|
5de59dfd62 | |
|
0bf295930d | |
|
a672fd96e7 | |
|
16a3a76530 | |
|
25fc7ba038 | |
|
59461d9f3c | |
|
226762bf69 | |
|
637b7585b9 | |
|
1128fc93b8 | |
|
57bc50300a | |
|
7610f8ffbd | |
|
fd51cabccb | |
|
dc52061cf2 | |
|
9b692bd966 | |
|
9d92c4c178 | |
|
80f987085f | |
|
33c6a94df4 | |
|
cb9eb61b16 | |
|
37265740de | |
|
3f399e5bd4 | |
|
0a330bfe8f | |
|
2486ddef36 | |
|
3e520499ef | |
|
9d5ef13bd6 |
|
@ -7,7 +7,7 @@ import { QLayout } from 'quasar';
|
||||||
import mainShortcutMixin from './mainShortcutMixin';
|
import mainShortcutMixin from './mainShortcutMixin';
|
||||||
import { useCau } from 'src/composables/useCau';
|
import { useCau } from 'src/composables/useCau';
|
||||||
|
|
||||||
export default boot(({ app, router }) => {
|
export default boot(({ app }) => {
|
||||||
QForm.mixins = [qFormMixin];
|
QForm.mixins = [qFormMixin];
|
||||||
QLayout.mixins = [mainShortcutMixin];
|
QLayout.mixins = [mainShortcutMixin];
|
||||||
|
|
||||||
|
@ -22,14 +22,6 @@ export default boot(({ app, router }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (response?.status) {
|
switch (response?.status) {
|
||||||
case 401:
|
|
||||||
if (!router.currentRoute.value.name.toLowerCase().includes('login')) {
|
|
||||||
message = 'errors.sessionExpired';
|
|
||||||
} else message = 'login.loginError';
|
|
||||||
break;
|
|
||||||
case 403:
|
|
||||||
if (!message || message.toLowerCase() === 'access denied')
|
|
||||||
message = 'errors.accessDenied';
|
|
||||||
case 422:
|
case 422:
|
||||||
if (error.name == 'ValidationError')
|
if (error.name == 'ValidationError')
|
||||||
message += ` "${responseError.details.context}.${Object.keys(
|
message += ` "${responseError.details.context}.${Object.keys(
|
||||||
|
|
|
@ -181,10 +181,6 @@ const col = computed(() => {
|
||||||
newColumn.component = 'checkbox';
|
newColumn.component = 'checkbox';
|
||||||
if ($props.default && !newColumn.component) newColumn.component = $props.default;
|
if ($props.default && !newColumn.component) newColumn.component = $props.default;
|
||||||
|
|
||||||
if (typeof newColumn.component !== 'string') {
|
|
||||||
newColumn.attrs = { ...newColumn.component.attrs, autofocus: $props.autofocus };
|
|
||||||
newColumn.event = { ...newColumn.component.event, ...$props?.eventHandlers };
|
|
||||||
}
|
|
||||||
return newColumn;
|
return newColumn;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,7 @@ watch(
|
||||||
defineExpose({
|
defineExpose({
|
||||||
create: createForm,
|
create: createForm,
|
||||||
showForm,
|
showForm,
|
||||||
|
openForm,
|
||||||
reload,
|
reload,
|
||||||
redirect: redirectFn,
|
redirect: redirectFn,
|
||||||
selected,
|
selected,
|
||||||
|
@ -646,6 +647,12 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
};
|
};
|
||||||
return () => {};
|
return () => {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function openForm(data) {
|
||||||
|
showForm.value = !showForm.value;
|
||||||
|
createForm.value = { ...$props.create, ...data };
|
||||||
|
}
|
||||||
|
|
||||||
const handleHeaderSelection = (evt, data) => {
|
const handleHeaderSelection = (evt, data) => {
|
||||||
if (evt === 'updateSelected' && selectAll.value) {
|
if (evt === 'updateSelected' && selectAll.value) {
|
||||||
selected.value = tableRef.value.rows;
|
selected.value = tableRef.value.rows;
|
||||||
|
@ -1055,9 +1062,7 @@ const handleHeaderSelection = (evt, data) => {
|
||||||
<QBtn
|
<QBtn
|
||||||
@click="
|
@click="
|
||||||
() =>
|
() =>
|
||||||
createAsDialog
|
createAsDialog ? openForm(create) : handleOnDataSaved(create)
|
||||||
? (showForm = !showForm)
|
|
||||||
: handleOnDataSaved(create)
|
|
||||||
"
|
"
|
||||||
class="cursor-pointer fill-icon"
|
class="cursor-pointer fill-icon"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -1076,10 +1081,7 @@ const handleHeaderSelection = (evt, data) => {
|
||||||
</CrudModel>
|
</CrudModel>
|
||||||
<QPageSticky v-if="$props.create" :offset="[20, 20]" style="z-index: 2">
|
<QPageSticky v-if="$props.create" :offset="[20, 20]" style="z-index: 2">
|
||||||
<QBtn
|
<QBtn
|
||||||
@click="
|
@click="() => (createAsDialog ? openForm(create) : handleOnDataSaved(create))"
|
||||||
() =>
|
|
||||||
createAsDialog ? (showForm = !showForm) : handleOnDataSaved(create)
|
|
||||||
"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
fab
|
fab
|
||||||
icon="add"
|
icon="add"
|
||||||
|
|
|
@ -7,7 +7,6 @@ import axios from 'axios';
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
import { usePrintService } from 'composables/usePrintService';
|
||||||
|
|
||||||
import VnUserLink from '../ui/VnUserLink.vue';
|
import VnUserLink from '../ui/VnUserLink.vue';
|
||||||
import { downloadFile } from 'src/composables/downloadFile';
|
|
||||||
import VnImg from 'components/ui/VnImg.vue';
|
import VnImg from 'components/ui/VnImg.vue';
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||||
import VnDms from 'src/components/common/VnDms.vue';
|
import VnDms from 'src/components/common/VnDms.vue';
|
||||||
|
@ -52,6 +51,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
deafult: undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const dmsFilter = {
|
const dmsFilter = {
|
||||||
|
@ -338,6 +341,7 @@ defineExpose({
|
||||||
<span
|
<span
|
||||||
v-if="props.col.component == 'span'"
|
v-if="props.col.component == 'span'"
|
||||||
style="white-space: wrap"
|
style="white-space: wrap"
|
||||||
|
:data-cy="`${props.col.name}_form`"
|
||||||
>{{ props.value }}</span
|
>{{ props.value }}</span
|
||||||
>
|
>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, useTemplateRef } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard';
|
|
||||||
import VnSelectDialog from './VnSelectDialog.vue';
|
|
||||||
import CreateNewExpenseForm from '../CreateNewExpenseForm.vue';
|
|
||||||
import FetchData from '../FetchData.vue';
|
|
||||||
|
|
||||||
const model = defineModel({ type: [String, Number, Object] });
|
|
||||||
const { t } = useI18n();
|
|
||||||
const expenses = ref([]);
|
|
||||||
const selectDialogRef = useTemplateRef('selectDialogRef');
|
|
||||||
|
|
||||||
async function autocompleteExpense(evt) {
|
|
||||||
const val = evt.target.value;
|
|
||||||
if (!val || isNaN(val)) return;
|
|
||||||
const lookup = expenses.value.find(({ id }) => id == useAccountShortToStandard(val));
|
|
||||||
if (selectDialogRef.value)
|
|
||||||
selectDialogRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<VnSelectDialog
|
|
||||||
v-bind="$attrs"
|
|
||||||
ref="selectDialogRef"
|
|
||||||
v-model="model"
|
|
||||||
:options="expenses"
|
|
||||||
option-value="id"
|
|
||||||
:option-label="(x) => `${x.id}: ${x.name}`"
|
|
||||||
:filter-options="['id', 'name']"
|
|
||||||
:tooltip="t('Create a new expense')"
|
|
||||||
:acls="[{ model: 'Expense', props: '*', accessType: 'WRITE' }]"
|
|
||||||
@keydown.tab.prevent="autocompleteExpense"
|
|
||||||
>
|
|
||||||
<template #form>
|
|
||||||
<CreateNewExpenseForm @on-data-saved="$refs.expensesRef.fetch()" />
|
|
||||||
</template>
|
|
||||||
</VnSelectDialog>
|
|
||||||
<FetchData
|
|
||||||
ref="expensesRef"
|
|
||||||
url="Expenses"
|
|
||||||
auto-load
|
|
||||||
@on-fetch="(data) => (expenses = data)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Create a new expense: Crear nuevo gasto
|
|
||||||
</i18n>
|
|
|
@ -220,12 +220,10 @@ globals:
|
||||||
mandates: Mandates
|
mandates: Mandates
|
||||||
contacts: Contacts
|
contacts: Contacts
|
||||||
webPayment: Web payment
|
webPayment: Web payment
|
||||||
fileManagement: File management
|
|
||||||
unpaid: Unpaid
|
unpaid: Unpaid
|
||||||
entries: Entries
|
entries: Entries
|
||||||
buys: Buys
|
buys: Buys
|
||||||
dms: File management
|
dms: File management
|
||||||
entryCreate: New entry
|
|
||||||
latestBuys: Latest buys
|
latestBuys: Latest buys
|
||||||
reserves: Reserves
|
reserves: Reserves
|
||||||
tickets: Tickets
|
tickets: Tickets
|
||||||
|
@ -244,14 +242,12 @@ globals:
|
||||||
invoiceOutCreate: Create invoice out
|
invoiceOutCreate: Create invoice out
|
||||||
order: Orders
|
order: Orders
|
||||||
orderList: List
|
orderList: List
|
||||||
orderCreate: New order
|
|
||||||
catalog: Catalog
|
catalog: Catalog
|
||||||
volume: Volume
|
volume: Volume
|
||||||
shelving: Shelving
|
shelving: Shelving
|
||||||
shelvingList: Shelving List
|
shelvingList: Shelving List
|
||||||
shelvingCreate: New shelving
|
shelvingCreate: New shelving
|
||||||
invoiceIns: Invoices In
|
invoiceIns: Invoices In
|
||||||
invoiceInCreate: Create invoice in
|
|
||||||
vat: VAT
|
vat: VAT
|
||||||
labeler: Labeler
|
labeler: Labeler
|
||||||
dueDay: Due day
|
dueDay: Due day
|
||||||
|
@ -278,21 +274,18 @@ globals:
|
||||||
routes: Routes
|
routes: Routes
|
||||||
cmrsList: CMRs
|
cmrsList: CMRs
|
||||||
RouteList: List
|
RouteList: List
|
||||||
routeCreate: New route
|
|
||||||
RouteRoadmap: Roadmaps
|
RouteRoadmap: Roadmaps
|
||||||
RouteRoadmapCreate: Create roadmap
|
RouteRoadmapCreate: Create roadmap
|
||||||
RouteExtendedList: Router
|
RouteExtendedList: Router
|
||||||
autonomous: Autonomous
|
autonomous: Autonomous
|
||||||
suppliers: Suppliers
|
suppliers: Suppliers
|
||||||
supplier: Supplier
|
supplier: Supplier
|
||||||
supplierCreate: New supplier
|
|
||||||
accounts: Accounts
|
accounts: Accounts
|
||||||
addresses: Addresses
|
addresses: Addresses
|
||||||
agencyTerm: Agency agreement
|
agencyTerm: Agency agreement
|
||||||
travel: Travels
|
travel: Travels
|
||||||
create: Create
|
create: Create
|
||||||
extraCommunity: Extra community
|
extraCommunity: Extra community
|
||||||
travelCreate: New travel
|
|
||||||
history: Log
|
history: Log
|
||||||
thermographs: Thermograph
|
thermographs: Thermograph
|
||||||
items: Items
|
items: Items
|
||||||
|
@ -400,8 +393,6 @@ errors:
|
||||||
updateUserConfig: Error updating user config
|
updateUserConfig: Error updating user config
|
||||||
tokenConfig: Error fetching token config
|
tokenConfig: Error fetching token config
|
||||||
writeRequest: The requested operation could not be completed
|
writeRequest: The requested operation could not be completed
|
||||||
sessionExpired: Your session has expired. Please log in again
|
|
||||||
accessDenied: Access denied
|
|
||||||
claimBeginningQuantity: Cannot import a line with a claimed quantity of 0
|
claimBeginningQuantity: Cannot import a line with a claimed quantity of 0
|
||||||
login:
|
login:
|
||||||
title: Login
|
title: Login
|
||||||
|
|
|
@ -223,12 +223,10 @@ globals:
|
||||||
mandates: Mandatos
|
mandates: Mandatos
|
||||||
contacts: Contactos
|
contacts: Contactos
|
||||||
webPayment: Pago web
|
webPayment: Pago web
|
||||||
fileManagement: Gestión documental
|
|
||||||
unpaid: Impago
|
unpaid: Impago
|
||||||
entries: Entradas
|
entries: Entradas
|
||||||
buys: Compras
|
buys: Compras
|
||||||
dms: Gestión documental
|
dms: Gestión documental
|
||||||
entryCreate: Nueva entrada
|
|
||||||
latestBuys: Últimas compras
|
latestBuys: Últimas compras
|
||||||
reserves: Reservas
|
reserves: Reservas
|
||||||
tickets: Tickets
|
tickets: Tickets
|
||||||
|
@ -247,14 +245,12 @@ globals:
|
||||||
invoiceOutCreate: Crear fact. emitida
|
invoiceOutCreate: Crear fact. emitida
|
||||||
order: Cesta
|
order: Cesta
|
||||||
orderList: Listado
|
orderList: Listado
|
||||||
orderCreate: Nueva orden
|
|
||||||
catalog: Catálogo
|
catalog: Catálogo
|
||||||
volume: Volumen
|
volume: Volumen
|
||||||
shelving: Carros
|
shelving: Carros
|
||||||
shelvingList: Listado de carros
|
shelvingList: Listado de carros
|
||||||
shelvingCreate: Nuevo carro
|
shelvingCreate: Nuevo carro
|
||||||
invoiceIns: Fact. recibidas
|
invoiceIns: Fact. recibidas
|
||||||
invoiceInCreate: Crear fact. recibida
|
|
||||||
vat: IVA
|
vat: IVA
|
||||||
labeler: Etiquetas
|
labeler: Etiquetas
|
||||||
dueDay: Vencimiento
|
dueDay: Vencimiento
|
||||||
|
@ -281,21 +277,18 @@ globals:
|
||||||
routes: Rutas
|
routes: Rutas
|
||||||
cmrsList: CMRs
|
cmrsList: CMRs
|
||||||
RouteList: Listado
|
RouteList: Listado
|
||||||
routeCreate: Nueva ruta
|
|
||||||
RouteRoadmap: Troncales
|
RouteRoadmap: Troncales
|
||||||
RouteRoadmapCreate: Crear troncal
|
RouteRoadmapCreate: Crear troncal
|
||||||
RouteExtendedList: Enrutador
|
RouteExtendedList: Enrutador
|
||||||
autonomous: Autónomos
|
autonomous: Autónomos
|
||||||
suppliers: Proveedores
|
suppliers: Proveedores
|
||||||
supplier: Proveedor
|
supplier: Proveedor
|
||||||
supplierCreate: Nuevo proveedor
|
|
||||||
accounts: Cuentas
|
accounts: Cuentas
|
||||||
addresses: Direcciones
|
addresses: Direcciones
|
||||||
agencyTerm: Acuerdo agencia
|
agencyTerm: Acuerdo agencia
|
||||||
travel: Envíos
|
travel: Envíos
|
||||||
create: Crear
|
create: Crear
|
||||||
extraCommunity: Extra comunitarios
|
extraCommunity: Extra comunitarios
|
||||||
travelCreate: Nuevo envío
|
|
||||||
history: Historial
|
history: Historial
|
||||||
thermographs: Termógrafos
|
thermographs: Termógrafos
|
||||||
items: Artículos
|
items: Artículos
|
||||||
|
@ -396,8 +389,6 @@ errors:
|
||||||
updateUserConfig: Error al actualizar la configuración de usuario
|
updateUserConfig: Error al actualizar la configuración de usuario
|
||||||
tokenConfig: Error al obtener configuración de token
|
tokenConfig: Error al obtener configuración de token
|
||||||
writeRequest: No se pudo completar la operación solicitada
|
writeRequest: No se pudo completar la operación solicitada
|
||||||
sessionExpired: Tu sesión ha expirado, por favor vuelve a iniciar sesión
|
|
||||||
accessDenied: Acceso denegado
|
|
||||||
claimBeginningQuantity: No se puede importar una linea sin una cantidad reclamada
|
claimBeginningQuantity: No se puede importar una linea sin una cantidad reclamada
|
||||||
login:
|
login:
|
||||||
title: Inicio de sesión
|
title: Inicio de sesión
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeMount, ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import CustomerAddressForm from '../components/CustomerAddressForm.vue';
|
||||||
|
import CustomerAddressEdit from '../components/CustomerAddressEdit.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const addresses = ref([]);
|
const addresses = ref([]);
|
||||||
const client = ref(null);
|
const client = ref(null);
|
||||||
|
const showFormCreate = ref();
|
||||||
|
const showFormEdit = ref();
|
||||||
|
const showFormEditModel = ref();
|
||||||
|
const vnPaginateRef = ref();
|
||||||
const addressFilter = {
|
const addressFilter = {
|
||||||
fields: [
|
fields: [
|
||||||
'id',
|
'id',
|
||||||
|
@ -27,6 +31,11 @@ const addressFilter = {
|
||||||
'isEqualizated',
|
'isEqualizated',
|
||||||
'isLogifloraAllowed',
|
'isLogifloraAllowed',
|
||||||
'postalCode',
|
'postalCode',
|
||||||
|
'agencyModeFk',
|
||||||
|
'longitude',
|
||||||
|
'latitude',
|
||||||
|
'incotermsFk',
|
||||||
|
'customsAgentFk',
|
||||||
],
|
],
|
||||||
order: ['isDefaultAddress DESC', 'isActive DESC', 'id DESC', 'nickname ASC'],
|
order: ['isDefaultAddress DESC', 'isActive DESC', 'id DESC', 'nickname ASC'],
|
||||||
include: [
|
include: [
|
||||||
|
@ -48,14 +57,15 @@ const addressFilter = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
relation: 'agencyMode',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
const { id } = route.params;
|
|
||||||
getClientData(id);
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
|
@ -65,16 +75,13 @@ watch(
|
||||||
);
|
);
|
||||||
|
|
||||||
const getClientData = async (id) => {
|
const getClientData = async (id) => {
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`Clients/${id}`);
|
const { data } = await axios.get(`Clients/${id}`);
|
||||||
client.value = data;
|
client.value = data;
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDefaultAddress = (address) => {
|
const isDefaultAddress = (address) => {
|
||||||
return client?.value?.defaultAddressFk === address.id ? 1 : 0;
|
address.isDefaultAddress = client?.value?.defaultAddressFk === address.id ? 1 : 0;
|
||||||
|
return address.isDefaultAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setDefault = async (address) => {
|
const setDefault = async (address) => {
|
||||||
|
@ -88,35 +95,35 @@ const setDefault = async (address) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortAddresses = (data) => {
|
const sortAddresses = async (data) => {
|
||||||
|
await getClientData(route.params.id);
|
||||||
if (!client.value || !data) return;
|
if (!client.value || !data) return;
|
||||||
addresses.value = data.sort((a, b) => {
|
addresses.value = data.sort((a, b) => {
|
||||||
return isDefaultAddress(b) - isDefaultAddress(a);
|
return isDefaultAddress(b) - isDefaultAddress(a);
|
||||||
});
|
});
|
||||||
|
openAddressForm();
|
||||||
};
|
};
|
||||||
|
|
||||||
const toCustomerAddressCreate = () => {
|
function openAddressForm() {
|
||||||
router.push({ name: 'CustomerAddressCreate' });
|
if (route.query.addressId) {
|
||||||
};
|
const address = addresses.value.find(
|
||||||
|
(address) => address.id == +route.query.addressId,
|
||||||
const toCustomerAddressEdit = (addressId) => {
|
);
|
||||||
router.push({
|
if (address) {
|
||||||
name: 'CustomerAddressEdit',
|
showFormEdit.value = true;
|
||||||
params: {
|
showFormEditModel.value = address;
|
||||||
id: route.params.id,
|
}
|
||||||
addressId,
|
}
|
||||||
},
|
}
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
ref="vnPaginateRef"
|
||||||
@on-fetch="sortAddresses"
|
@on-fetch="sortAddresses"
|
||||||
auto-load
|
auto-load
|
||||||
data-key="CustomerAddresses"
|
data-key="CustomerAddresses"
|
||||||
order="id DESC"
|
order="id DESC"
|
||||||
ref="vnPaginateRef"
|
|
||||||
:filter="addressFilter"
|
:filter="addressFilter"
|
||||||
:url="`Clients/${route.params.id}/addresses`"
|
:url="`Clients/${route.params.id}/addresses`"
|
||||||
/>
|
/>
|
||||||
|
@ -131,7 +138,7 @@ const toCustomerAddressEdit = (addressId) => {
|
||||||
'q-mb-md': index < addresses.length - 1,
|
'q-mb-md': index < addresses.length - 1,
|
||||||
'item-disabled': !item.isActive,
|
'item-disabled': !item.isActive,
|
||||||
}"
|
}"
|
||||||
@click="toCustomerAddressEdit(item.id)"
|
@click="(showFormEdit = !showFormEdit) && (showFormEditModel = item)"
|
||||||
>
|
>
|
||||||
<div class="q-ml-xs q-mr-md flex items-center">
|
<div class="q-ml-xs q-mr-md flex items-center">
|
||||||
<QIcon
|
<QIcon
|
||||||
|
@ -144,6 +151,7 @@ const toCustomerAddressEdit = (addressId) => {
|
||||||
name="star"
|
name="star"
|
||||||
size="md"
|
size="md"
|
||||||
@click.stop="!isDefaultAddress(item) && setDefault(item)"
|
@click.stop="!isDefaultAddress(item) && setDefault(item)"
|
||||||
|
data-cy="setDefaultAddress"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{
|
{{
|
||||||
|
@ -200,19 +208,18 @@ const toCustomerAddressEdit = (addressId) => {
|
||||||
v-for="(observation, obIndex) in item.observations"
|
v-for="(observation, obIndex) in item.observations"
|
||||||
>
|
>
|
||||||
<div class="text-weight-bold q-mr-sm">
|
<div class="text-weight-bold q-mr-sm">
|
||||||
{{ observation.observationType.description }}:
|
{{ observation?.observationType?.description }}:
|
||||||
</div>
|
</div>
|
||||||
<div>{{ observation.description }}</div>
|
<div>{{ observation?.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
</QCard>
|
</QCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<QPageSticky :offset="[18, 18]">
|
<QPageSticky :offset="[18, 18]">
|
||||||
<QBtn
|
<QBtn
|
||||||
@click.stop="toCustomerAddressCreate()"
|
@click.stop="showFormCreate = !showFormCreate"
|
||||||
color="primary"
|
color="primary"
|
||||||
fab
|
fab
|
||||||
icon="add"
|
icon="add"
|
||||||
|
@ -222,6 +229,28 @@ const toCustomerAddressEdit = (addressId) => {
|
||||||
{{ t('New consignee') }}
|
{{ t('New consignee') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
|
<QDialog v-model="showFormEdit" :full-width="true">
|
||||||
|
<CustomerAddressEdit
|
||||||
|
:id="showFormEditModel.id"
|
||||||
|
v-model="showFormEditModel"
|
||||||
|
@on-data-saved="() => vnPaginateRef.fetch()"
|
||||||
|
/>
|
||||||
|
</QDialog>
|
||||||
|
<QDialog v-model="showFormCreate" :full-width="true">
|
||||||
|
<CustomerAddressForm
|
||||||
|
:is-create="true"
|
||||||
|
:form-initial-data="{
|
||||||
|
isDefaultAddress: false,
|
||||||
|
isActive: true,
|
||||||
|
isEqualizated: false,
|
||||||
|
isLogifloraAllowed: false,
|
||||||
|
}"
|
||||||
|
:observe-form-changes="false"
|
||||||
|
:url-create="`Clients/${route.params.id}/createAddress`"
|
||||||
|
model="client"
|
||||||
|
@on-data-saved="() => vnPaginateRef.fetch()"
|
||||||
|
/>
|
||||||
|
</QDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script setup>
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import VnDmsList from 'src/components/common/VnDmsList.vue';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
const arrayData = useArrayData('Customer');
|
||||||
|
const { t } = useI18n();
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VnDmsList
|
||||||
|
v-if="arrayData?.store?.data"
|
||||||
|
model="ClientDms"
|
||||||
|
update-model="Clients"
|
||||||
|
default-dms-code="paymentsLaw"
|
||||||
|
filter="clientFk"
|
||||||
|
:description="
|
||||||
|
t('ClientFileDescription', {
|
||||||
|
clientId: $route.params.id,
|
||||||
|
clientName: arrayData.store.data.socialName,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
ClientFileDescription: Payment law from client {clientName} ID {clientId}
|
||||||
|
es:
|
||||||
|
ClientFileDescription: Ley de pagos del cliente {clientName} ID {clientId}
|
||||||
|
</i18n>
|
|
@ -1,269 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { computed, ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import { QBadge, QBtn, QCheckbox } from 'quasar';
|
|
||||||
|
|
||||||
import { downloadFile } from 'src/composables/downloadFile';
|
|
||||||
import { toDateTimeFormat } from 'src/filters/date';
|
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
|
||||||
import CustomerFileManagementActions from 'src/pages/Customer/components/CustomerFileManagementActions.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const ClientDmsRef = ref(null);
|
|
||||||
const rows = ref([]);
|
|
||||||
|
|
||||||
const filter = {
|
|
||||||
include: {
|
|
||||||
relation: 'dms',
|
|
||||||
scope: {
|
|
||||||
fields: [
|
|
||||||
'dmsTypeFk',
|
|
||||||
'reference',
|
|
||||||
'hardCopyNumber',
|
|
||||||
'workerFk',
|
|
||||||
'description',
|
|
||||||
'hasFile',
|
|
||||||
'file',
|
|
||||||
'created',
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{ relation: 'dmsType', scope: { fields: ['name'] } },
|
|
||||||
{
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: { relation: 'user', scope: { fields: ['name'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: { clientFk: route.params.id },
|
|
||||||
order: ['dmsFk DESC'],
|
|
||||||
limit: 20,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tableColumnComponents = {
|
|
||||||
id: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
order: {
|
|
||||||
component: QBadge,
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
reference: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
original: {
|
|
||||||
component: QCheckbox,
|
|
||||||
props: (prop) => ({
|
|
||||||
disable: true,
|
|
||||||
'model-value': Boolean(prop.value),
|
|
||||||
}),
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
file: {
|
|
||||||
component: QBtn,
|
|
||||||
props: () => ({ flat: true }),
|
|
||||||
event: ({ row }) => downloadFile(row.dmsFk),
|
|
||||||
},
|
|
||||||
employee: {
|
|
||||||
component: QBtn,
|
|
||||||
props: () => ({ flat: true }),
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
created: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
component: CustomerFileManagementActions,
|
|
||||||
props: (prop) => ({
|
|
||||||
id: prop.row.dmsFk,
|
|
||||||
promise: setData,
|
|
||||||
}),
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.id,
|
|
||||||
label: t('Id'),
|
|
||||||
name: 'id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.dmsType.name,
|
|
||||||
label: t('Type'),
|
|
||||||
name: 'type',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.hardCopyNumber,
|
|
||||||
label: t('Order'),
|
|
||||||
name: 'order',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.reference,
|
|
||||||
label: t('Reference'),
|
|
||||||
name: 'reference',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.description,
|
|
||||||
label: t('Description'),
|
|
||||||
name: 'description',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.hasFile,
|
|
||||||
label: t('Original'),
|
|
||||||
name: 'original',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.file,
|
|
||||||
label: t('File'),
|
|
||||||
name: 'file',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: ({ dms }) => dms.worker.user.name,
|
|
||||||
label: t('Employee'),
|
|
||||||
name: 'employee',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
field: (value) => value.dms.created,
|
|
||||||
label: t('Created'),
|
|
||||||
name: 'created',
|
|
||||||
format: (value) => toDateTimeFormat(value),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'right',
|
|
||||||
field: 'actions',
|
|
||||||
label: '',
|
|
||||||
name: 'actions',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const setData = () => {
|
|
||||||
ClientDmsRef.value.fetch();
|
|
||||||
};
|
|
||||||
|
|
||||||
const toCustomerFileManagementCreate = () => {
|
|
||||||
router.push({ name: 'CustomerFileManagementCreate' });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
ref="ClientDmsRef"
|
|
||||||
:filter="filter"
|
|
||||||
@on-fetch="(data) => (rows = data)"
|
|
||||||
auto-load
|
|
||||||
url="ClientDms"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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="
|
|
||||||
props.col.name === 'order' && !props.value
|
|
||||||
? 'span'
|
|
||||||
: tableColumnComponents[props.col.name].component
|
|
||||||
"
|
|
||||||
@click="tableColumnComponents[props.col.name].event(props)"
|
|
||||||
class="col-content"
|
|
||||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
|
||||||
>
|
|
||||||
<template v-if="props.col.name !== 'original'">
|
|
||||||
<span
|
|
||||||
:class="{
|
|
||||||
link:
|
|
||||||
props.col.name === 'employee' ||
|
|
||||||
props.col.name === 'file',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ props.value }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<WorkerDescriptorProxy
|
|
||||||
:id="props.row.dms.workerFk"
|
|
||||||
v-if="props.col.name === 'employee'"
|
|
||||||
/>
|
|
||||||
</component>
|
|
||||||
</QTr>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
|
|
||||||
<h5 class="flex justify-center color-vn-label" v-else>
|
|
||||||
{{ t('globals.noResults') }}
|
|
||||||
</h5>
|
|
||||||
</QPage>
|
|
||||||
|
|
||||||
<QPageSticky :offset="[18, 18]">
|
|
||||||
<QBtn
|
|
||||||
@click.stop="toCustomerFileManagementCreate()"
|
|
||||||
color="primary"
|
|
||||||
fab
|
|
||||||
v-shortcut="'+'"
|
|
||||||
icon="add"
|
|
||||||
/>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Upload file') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QPageSticky>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Id: Id
|
|
||||||
Type: Tipo
|
|
||||||
Order: Orden
|
|
||||||
Reference: Referencia
|
|
||||||
Description: Descripción
|
|
||||||
Original: Original
|
|
||||||
File: Fichero
|
|
||||||
Employee: Empleado
|
|
||||||
Created: Fecha creación
|
|
||||||
Upload file: Subir fichero
|
|
||||||
</i18n>
|
|
|
@ -19,9 +19,7 @@ const filter = {
|
||||||
{ relation: 'user', scope: { fields: ['id', 'name'] } },
|
{ relation: 'user', scope: { fields: ['id', 'name'] } },
|
||||||
{ relation: 'company', scope: { fields: ['code'] } },
|
{ relation: 'company', scope: { fields: ['code'] } },
|
||||||
],
|
],
|
||||||
where: { clientFk: route.params.id },
|
|
||||||
order: ['created DESC'],
|
order: ['created DESC'],
|
||||||
limit: 20,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
|
@ -76,6 +74,7 @@ const tableRef = ref();
|
||||||
data-key="CustomerSamples"
|
data-key="CustomerSamples"
|
||||||
auto-load
|
auto-load
|
||||||
:user-filter="filter"
|
:user-filter="filter"
|
||||||
|
:filter="{ where: { clientFk: route.params.id } }"
|
||||||
url="ClientSamples"
|
url="ClientSamples"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
|
|
|
@ -4,16 +4,14 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'components/FormModel.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import CustomerAddressForm from './CustomerAddressForm.vue';
|
||||||
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.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';
|
const emit = defineEmits(['onDataSaved']);
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -22,31 +20,31 @@ const quasar = useQuasar();
|
||||||
const urlUpdate = ref('');
|
const urlUpdate = ref('');
|
||||||
const agencyModes = ref([]);
|
const agencyModes = ref([]);
|
||||||
const incoterms = ref([]);
|
const incoterms = ref([]);
|
||||||
const customsAgents = ref([]);
|
|
||||||
const observationTypes = ref([]);
|
const observationTypes = ref([]);
|
||||||
const notes = ref([]);
|
const customsAgents = ref([]);
|
||||||
let originalNotes = [];
|
let originalNotes = [];
|
||||||
const deletes = ref([]);
|
const deletes = ref([]);
|
||||||
|
|
||||||
|
const model = defineModel({ type: Object });
|
||||||
|
const notes = ref(model.value.observations || []);
|
||||||
|
const $props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.addressId}`;
|
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${$props.id}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getData = async (observations) => {
|
const getData = async (observations) => {
|
||||||
observationTypes.value = observations;
|
observationTypes.value = observations;
|
||||||
|
|
||||||
if (observationTypes.value.length) {
|
if (observationTypes.value.length) {
|
||||||
const filter = {
|
if (notes.value.length) {
|
||||||
fields: ['id', 'addressFk', 'observationTypeFk', 'description'],
|
originalNotes = JSON.parse(JSON.stringify(notes.value));
|
||||||
where: { addressFk: `${route.params.addressId}` },
|
notes.value = notes.value
|
||||||
};
|
|
||||||
const { data } = await axios.get('AddressObservations', {
|
|
||||||
params: { filter: JSON.stringify(filter) },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data.length) {
|
|
||||||
originalNotes = data;
|
|
||||||
notes.value = originalNotes
|
|
||||||
.map((observation) => {
|
.map((observation) => {
|
||||||
const type = observationTypes.value.find(
|
const type = observationTypes.value.find(
|
||||||
(type) => type.id === observation.observationTypeFk,
|
(type) => type.id === observation.observationTypeFk,
|
||||||
|
@ -56,7 +54,7 @@ const getData = async (observations) => {
|
||||||
$isNew: false,
|
$isNew: false,
|
||||||
$oldData: null,
|
$oldData: null,
|
||||||
$orgIndex: null,
|
$orgIndex: null,
|
||||||
addressFk: `${route.params.addressId}`,
|
addressFk: `${$props.id}`,
|
||||||
description: observation.description,
|
description: observation.description,
|
||||||
id: observation.id,
|
id: observation.id,
|
||||||
observationTypeFk: type.id,
|
observationTypeFk: type.id,
|
||||||
|
@ -68,22 +66,6 @@ const getData = async (observations) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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 updateAddress = async (data) => {
|
const updateAddress = async (data) => {
|
||||||
await axios.patch(urlUpdate.value, data);
|
await axios.patch(urlUpdate.value, data);
|
||||||
};
|
};
|
||||||
|
@ -116,8 +98,9 @@ function cleanPayload(payload) {
|
||||||
async function updateAll({ data, payload }) {
|
async function updateAll({ data, payload }) {
|
||||||
await updateObservations(payload);
|
await updateObservations(payload);
|
||||||
await updateAddress(data);
|
await updateAddress(data);
|
||||||
toCustomerAddress();
|
emit('onDataSaved');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPayload() {
|
function getPayload() {
|
||||||
return {
|
return {
|
||||||
creates: notes.value.filter((note) => note.$isNew),
|
creates: notes.value.filter((note) => note.$isNew),
|
||||||
|
@ -162,23 +145,21 @@ async function handleDialog(data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const toCustomerAddress = () => {
|
const addNote = () => {
|
||||||
notes.value = [];
|
notes.value.push({
|
||||||
deletes.value = [];
|
$isNew: true,
|
||||||
router.push({
|
$oldData: null,
|
||||||
name: 'CustomerAddress',
|
$orgIndex: null,
|
||||||
params: {
|
addressFk: `${$props.id}`,
|
||||||
id: route.params.id,
|
description: '',
|
||||||
},
|
observationTypeFk: '',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
function handleLocation(data, location) {
|
|
||||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
const deleteNote = (id, index) => {
|
||||||
data.postalCode = code;
|
deletes.value.push(id);
|
||||||
data.city = town;
|
notes.value.splice(index, 1);
|
||||||
data.provinceFk = provinceFk;
|
};
|
||||||
data.countryFk = countryFk;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -194,128 +175,17 @@ function handleLocation(data, location) {
|
||||||
url="CustomsAgents"
|
url="CustomsAgents"
|
||||||
/>
|
/>
|
||||||
<FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
|
<FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
|
||||||
|
<CustomerAddressForm
|
||||||
<FormModel
|
|
||||||
:observe-form-changes="false"
|
|
||||||
:url-update="urlUpdate"
|
:url-update="urlUpdate"
|
||||||
:url="`Addresses/${route.params.addressId}`"
|
:form-initial-data="model"
|
||||||
:save-fn="handleDialog"
|
:save-fn="handleDialog"
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #moreActions>
|
<template #more-form="{ validate }">
|
||||||
<QBtn
|
<div class="column">
|
||||||
: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>
|
<h4 class="q-mb-xs">{{ t('Notes') }}</h4>
|
||||||
<VnRow
|
<VnRow
|
||||||
|
v-if="!isPopup"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="row q-gutter-md q-mb-md"
|
class="row q-gutter-md q-mb-md"
|
||||||
v-for="(note, index) in notes"
|
v-for="(note, index) in notes"
|
||||||
|
@ -335,7 +205,10 @@ function handleLocation(data, location) {
|
||||||
v-model="note.description"
|
v-model="note.description"
|
||||||
/>
|
/>
|
||||||
<QIcon
|
<QIcon
|
||||||
:style="{ flex: 0, 'align-self': $q.screen.gt.xs ? 'end' : 'center' }"
|
:style="{
|
||||||
|
flex: 0,
|
||||||
|
'align-self': $q.screen.gt.xs ? 'end' : 'center',
|
||||||
|
}"
|
||||||
@click.stop="deleteNote(note.id, index)"
|
@click.stop="deleteNote(note.id, index)"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -349,49 +222,27 @@ function handleLocation(data, location) {
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<QBtn
|
<QBtn
|
||||||
@click.stop="addNote()"
|
@click.stop="addNote()"
|
||||||
class="cursor-pointer add-icon q-mt-md"
|
|
||||||
flat
|
|
||||||
icon="add"
|
icon="add"
|
||||||
v-shortcut="'+'"
|
v-shortcut="'+'"
|
||||||
|
color="primary"
|
||||||
|
style="width: 10%"
|
||||||
|
data-cy="addNoteBtn_form"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('Add note') }}
|
{{ t('Add note') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</FormModel>
|
</CustomerAddressForm>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.add-icon {
|
|
||||||
background-color: $primary;
|
|
||||||
border-radius: 50px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
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
|
Notes: Notas
|
||||||
Observation type: Tipo de observación
|
Observation type: Tipo de observación
|
||||||
Description: Descripción
|
Description: Descripción
|
||||||
Add note: Añadir nota
|
Add note: Añadir nota
|
||||||
Remove note: Eliminar nota
|
Remove note: Eliminar nota
|
||||||
Longitude: Longitud
|
|
||||||
Latitude: Latitud
|
|
||||||
confirmTicket: ¿Desea modificar también los estados de todos los tickets que están a punto de ser servidos?
|
confirmTicket: ¿Desea modificar también los estados de todos los tickets que están a punto de ser servidos?
|
||||||
confirmDeletionMessage: Si le das a aceptar, se modificaran todas las notas de los ticket a futuro
|
confirmDeletionMessage: Si le das a aceptar, se modificaran todas las notas de los ticket a futuro
|
||||||
en:
|
en:
|
||||||
|
|
|
@ -1,36 +1,35 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { onBeforeMount, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'components/FormModel.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
||||||
import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
|
import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import FormModelPopup from 'src/components/FormModelPopup.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const urlUpdate = ref('');
|
||||||
|
|
||||||
const formInitialData = reactive({ isDefaultAddress: false });
|
|
||||||
|
|
||||||
const agencyModes = ref([]);
|
const agencyModes = ref([]);
|
||||||
const incoterms = ref([]);
|
const incoterms = ref([]);
|
||||||
const customsAgents = ref([]);
|
const customsAgents = ref([]);
|
||||||
|
|
||||||
const toCustomerAddress = () => {
|
const $props = defineProps({
|
||||||
router.push({
|
isCreate: {
|
||||||
name: 'CustomerAddress',
|
type: Boolean,
|
||||||
params: {
|
default: false,
|
||||||
id: route.params.id,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.addressId}`;
|
||||||
|
});
|
||||||
|
|
||||||
function handleLocation(data, location) {
|
function handleLocation(data, location) {
|
||||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||||
data.postalCode = code;
|
data.postalCode = code;
|
||||||
|
@ -38,33 +37,21 @@ function handleLocation(data, location) {
|
||||||
data.provinceFk = provinceFk;
|
data.provinceFk = provinceFk;
|
||||||
data.countryFk = countryFk;
|
data.countryFk = countryFk;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAgentCreated({ id, fiscalName }, data) {
|
|
||||||
customsAgents.value.push({ id, fiscalName });
|
|
||||||
data.customsAgentFk = id;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
@on-fetch="(data) => (customsAgents = data)"
|
|
||||||
auto-load
|
|
||||||
url="CustomsAgents"
|
|
||||||
/>
|
|
||||||
<FetchData
|
<FetchData
|
||||||
@on-fetch="(data) => (agencyModes = data)"
|
@on-fetch="(data) => (agencyModes = data)"
|
||||||
auto-load
|
auto-load
|
||||||
url="AgencyModes/isActive"
|
url="AgencyModes/isActive"
|
||||||
/>
|
/>
|
||||||
<FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
|
<FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
|
||||||
|
<FetchData
|
||||||
<FormModel
|
@on-fetch="(data) => (customsAgents = data)"
|
||||||
:form-initial-data="formInitialData"
|
auto-load
|
||||||
:observe-form-changes="false"
|
url="CustomsAgents"
|
||||||
:url-create="`Clients/${route.params.id}/createAddress`"
|
/>
|
||||||
@on-data-saved="toCustomerAddress()"
|
<FormModelPopup v-bind="$attrs" v-on="$attrs" :reload="false">
|
||||||
model="client"
|
|
||||||
>
|
|
||||||
<template #moreActions>
|
<template #moreActions>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.cancel')"
|
:label="t('globals.cancel')"
|
||||||
|
@ -74,34 +61,53 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
icon="close"
|
icon="close"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #form-inputs="{ data, validate }">
|
||||||
<template #form="{ data, validate }">
|
|
||||||
<QCheckbox :label="t('Default')" v-model="data.isDefaultAddress" />
|
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<QCheckbox
|
||||||
:label="t('Consignee')"
|
:label="t('Default')"
|
||||||
required
|
v-model="data.isDefaultAddress"
|
||||||
clearable
|
checked-icon="star"
|
||||||
v-model="data.nickname"
|
unchecked-icon="star"
|
||||||
|
indeterminate-icon="star"
|
||||||
|
size="lg"
|
||||||
|
color="primary"
|
||||||
|
:class="{ 'fill-icon': !!data.isDefaultAddress }"
|
||||||
|
data-cy="isDefaultAddress_form"
|
||||||
/>
|
/>
|
||||||
|
<QCheckbox
|
||||||
<VnInput
|
:label="t('Enabled')"
|
||||||
:label="t('Street address')"
|
v-model="data.isActive"
|
||||||
clearable
|
data-cy="enabled_form"
|
||||||
v-model="data.street"
|
/>
|
||||||
required
|
<QCheckbox
|
||||||
|
:label="t('Is equalizated')"
|
||||||
|
v-model="data.isEqualizated"
|
||||||
|
data-cy="isEqualizated_form"
|
||||||
|
/>
|
||||||
|
<QCheckbox
|
||||||
|
:label="t('Is Loginflora allowed')"
|
||||||
|
v-model="data.isLogifloraAllowed"
|
||||||
|
data-cy="isLoginfloraAllowed_form"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
|
<VnInput :label="t('Consignee')" clearable v-model="data.nickname" />
|
||||||
|
<VnInput :label="t('Street')" clearable v-model="data.street" />
|
||||||
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
<VnLocation
|
<VnLocation
|
||||||
:rules="validate('Worker.postcode')"
|
:rules="validate('Worker.postcode')"
|
||||||
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
||||||
v-model="data.location"
|
:location="{
|
||||||
|
postcode: data.postalCode,
|
||||||
|
city: data.city,
|
||||||
|
province: data.province,
|
||||||
|
country: data.province?.country,
|
||||||
|
}"
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
/>
|
></VnLocation>
|
||||||
|
</VnRow>
|
||||||
<div class="row justify-between q-gutter-md q-mb-md">
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Agency')"
|
:label="t('Agency')"
|
||||||
:options="agencyModes"
|
:options="agencyModes"
|
||||||
|
@ -110,17 +116,10 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="data.agencyModeFk"
|
v-model="data.agencyModeFk"
|
||||||
class="col"
|
|
||||||
/>
|
/>
|
||||||
<VnInput class="col" :label="t('Phone')" clearable v-model="data.phone" />
|
<VnInput :label="t('Phone')" clearable v-model="data.phone" />
|
||||||
<VnInput
|
<VnInput :label="t('Mobile')" clearable v-model="data.mobile" />
|
||||||
class="col"
|
</VnRow>
|
||||||
:label="t('Mobile')"
|
|
||||||
clearable
|
|
||||||
v-model="data.mobile"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Incoterms')"
|
:label="t('Incoterms')"
|
||||||
|
@ -130,23 +129,17 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
option-value="code"
|
option-value="code"
|
||||||
v-model="data.incotermsFk"
|
v-model="data.incotermsFk"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<VnSelectDialog
|
<VnSelectDialog
|
||||||
url="CustomsAgents"
|
|
||||||
:label="t('Customs agent')"
|
:label="t('Customs agent')"
|
||||||
:options="customsAgents"
|
:options="customsAgents"
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="fiscalName"
|
option-label="fiscalName"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="data.customsAgentFk"
|
v-model="data.customsAgentFk"
|
||||||
:tooltip="t('Create a new expense')"
|
:tooltip="t('New customs agent')"
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<CustomerNewCustomsAgent
|
<CustomerNewCustomsAgent />
|
||||||
@on-data-saved="
|
|
||||||
(requestResponse) => onAgentCreated(requestResponse, data)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</VnSelectDialog>
|
</VnSelectDialog>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -166,13 +159,13 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
:positive="false"
|
:positive="false"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
<slot name="more-form" :validate />
|
||||||
</template>
|
</template>
|
||||||
</FormModel>
|
</FormModelPopup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.add-icon {
|
.add-icon {
|
||||||
cursor: pointer;
|
|
||||||
background-color: $primary;
|
background-color: $primary;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
}
|
}
|
||||||
|
@ -180,9 +173,11 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Default: Predeterminado
|
Enabled: Activo
|
||||||
|
Is equalizated: Recargo de equivalencia
|
||||||
|
Is Loginflora allowed: Compra directa en Holanda
|
||||||
Consignee: Consignatario
|
Consignee: Consignatario
|
||||||
Street address: Dirección postal
|
Street: Dirección fiscal
|
||||||
Postcode: Código postal
|
Postcode: Código postal
|
||||||
City: Población
|
City: Población
|
||||||
Province: Provincia
|
Province: Provincia
|
||||||
|
@ -191,6 +186,17 @@ es:
|
||||||
Mobile: Movíl
|
Mobile: Movíl
|
||||||
Incoterms: Incoterms
|
Incoterms: Incoterms
|
||||||
Customs agent: Agente de aduanas
|
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
|
Longitude: Longitud
|
||||||
Latitude: Latitud
|
Latitude: Latitud
|
||||||
|
confirmTicket: ¿Desea modificar también los estados de todos los tickets que están a punto de ser servidos?
|
||||||
|
confirmDeletionMessage: Si le das a aceptar, se modificaran todas las notas de los ticket a futuro
|
||||||
|
en:
|
||||||
|
confirmTicket: Do you also want to modify the states of all the tickets that are about to be served?
|
||||||
|
confirmDeletionMessage: If you click accept, all the notes of the future tickets will be modified
|
||||||
</i18n>
|
</i18n>
|
|
@ -1,96 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { useQuasar } from 'quasar';
|
|
||||||
|
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
|
||||||
import { downloadFile } from 'src/composables/downloadFile';
|
|
||||||
|
|
||||||
import CustomerFileManagementDelete from 'src/pages/Customer/components/CustomerFileManagementDelete.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const quasar = useQuasar();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const { openReport } = usePrintService();
|
|
||||||
const $props = defineProps({
|
|
||||||
id: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
promise: {
|
|
||||||
type: Function,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const setDownloadFile = () => openReport(`dms/${$props.id}/downloadFile`, {}, '_blank');
|
|
||||||
|
|
||||||
const toCustomerFileManagementEdit = () => {
|
|
||||||
router.push({
|
|
||||||
name: 'CustomerFileManagementEdit',
|
|
||||||
params: {
|
|
||||||
id: route.params.id,
|
|
||||||
dmsId: $props.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const showCustomerFileManagementDeleteDialog = () => {
|
|
||||||
quasar.dialog({
|
|
||||||
component: CustomerFileManagementDelete,
|
|
||||||
componentProps: {
|
|
||||||
id: $props.id,
|
|
||||||
promise: setData,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setData = () => {
|
|
||||||
$props.promise();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<QIcon
|
|
||||||
@click.stop="setDownloadFile"
|
|
||||||
color="primary"
|
|
||||||
name="cloud_download"
|
|
||||||
size="sm"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('actionFile', { action: t('globals.download') }) }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
@click.stop="toCustomerFileManagementEdit"
|
|
||||||
class="q-ml-md"
|
|
||||||
color="primary"
|
|
||||||
name="edit"
|
|
||||||
size="sm"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('actionFile', { action: t('globals.edit') }) }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
@click.stop="showCustomerFileManagementDeleteDialog"
|
|
||||||
class="q-ml-md"
|
|
||||||
color="primary"
|
|
||||||
name="delete"
|
|
||||||
size="sm"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('actionFile', { action: t('globals.remove') }) }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
actionFile: '{action} file'
|
|
||||||
es:
|
|
||||||
actionFile: '{action} fichero'
|
|
||||||
</i18n>
|
|
|
@ -1,260 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { onBeforeMount, ref, watch } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
const { notify } = useNotify();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const { validate } = useValidator();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const state = useState();
|
|
||||||
const user = state.getUser();
|
|
||||||
|
|
||||||
const filterFindOne = { where: { code: 'paymentsLaw' } };
|
|
||||||
const filterCompanies = { order: ['code'] };
|
|
||||||
const filterWarehouses = { order: ['name'] };
|
|
||||||
|
|
||||||
const inputFileRef = ref();
|
|
||||||
const client = ref({});
|
|
||||||
const findOne = ref([]);
|
|
||||||
const allowedContentTypes = ref([]);
|
|
||||||
const optionsCompanies = ref([]);
|
|
||||||
const optionsWarehouses = ref([]);
|
|
||||||
const optionsDmsTypes = ref([]);
|
|
||||||
const isLoading = ref(false);
|
|
||||||
const dms = ref({
|
|
||||||
hasFile: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
const { companyFk, warehouseFk } = user.value;
|
|
||||||
dms.value.reference = route.params.id;
|
|
||||||
dms.value.companyId = companyFk;
|
|
||||||
dms.value.warehouseId = warehouseFk;
|
|
||||||
});
|
|
||||||
|
|
||||||
watch([client, findOne], ([newClient, newFindOne]) => {
|
|
||||||
dms.value.description = t('clientFileDescription', {
|
|
||||||
dmsTypeName: newFindOne.name?.toUpperCase(),
|
|
||||||
clientName: newClient.name?.toUpperCase(),
|
|
||||||
clientId: newClient.id,
|
|
||||||
});
|
|
||||||
dms.value.dmsTypeId = newFindOne.id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const saveData = async () => {
|
|
||||||
try {
|
|
||||||
const formData = new FormData();
|
|
||||||
const files = dms.value.files;
|
|
||||||
|
|
||||||
if (files && files.length > 0) {
|
|
||||||
for (let file of files) {
|
|
||||||
formData.append(file.name, file);
|
|
||||||
}
|
|
||||||
dms.value.hasFileAttached = true;
|
|
||||||
|
|
||||||
const url = `clients/${route.params.id}/uploadFile`;
|
|
||||||
await axios.post(url, formData, {
|
|
||||||
params: dms.value,
|
|
||||||
});
|
|
||||||
notify('globals.dataSaved', 'positive');
|
|
||||||
toCustomerFileManagement();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
notify(error.message, 'negative');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const toCustomerFileManagement = () => {
|
|
||||||
router.push({ name: 'CustomerFileManagement' });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
@on-fetch="(data) => (client = data)"
|
|
||||||
auto-load
|
|
||||||
:url="`Clients/${route.params.id}/getCard`"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterFindOne"
|
|
||||||
@on-fetch="(data) => (findOne = data)"
|
|
||||||
auto-load
|
|
||||||
url="DmsTypes/findOne"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
@on-fetch="(data) => (allowedContentTypes = data)"
|
|
||||||
auto-load
|
|
||||||
url="DmsContainers/allowedContentTypes"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterCompanies"
|
|
||||||
@on-fetch="(data) => (optionsCompanies = data)"
|
|
||||||
auto-load
|
|
||||||
url="Companies"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterWarehouses"
|
|
||||||
@on-fetch="(data) => (optionsWarehouses = data)"
|
|
||||||
auto-load
|
|
||||||
url="Warehouses"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterWarehouses"
|
|
||||||
@on-fetch="(data) => (optionsDmsTypes = data)"
|
|
||||||
auto-load
|
|
||||||
url="DmsTypes"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Teleport to="#st-actions">
|
|
||||||
<QBtnGroup push class="q-gutter-x-sm">
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.cancel')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click="toCustomerFileManagement"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
icon="close"
|
|
||||||
/>
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.save')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click.stop="saveData"
|
|
||||||
color="primary"
|
|
||||||
icon="save"
|
|
||||||
/>
|
|
||||||
</QBtnGroup>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<QCard class="q-pa-lg">
|
|
||||||
<QCardSection>
|
|
||||||
<QForm>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnInput
|
|
||||||
:label="t('Reference')"
|
|
||||||
clearable
|
|
||||||
v-model="dms.reference"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Company')"
|
|
||||||
:options="optionsCompanies"
|
|
||||||
:rules="validate('entry.companyFk')"
|
|
||||||
option-label="code"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.companyId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Warehouse')"
|
|
||||||
:options="optionsWarehouses"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.warehouseId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Type')"
|
|
||||||
:options="optionsDmsTypes"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.dmsTypeId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnInput
|
|
||||||
:label="t('Description')"
|
|
||||||
:rules="validate('route.description')"
|
|
||||||
clearable
|
|
||||||
type="textarea"
|
|
||||||
v-model="dms.description"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<QFile
|
|
||||||
ref="inputFileRef"
|
|
||||||
class="required"
|
|
||||||
:label="t('File')"
|
|
||||||
v-model="dms.files"
|
|
||||||
multiple
|
|
||||||
:accept="allowedContentTypes.join(',')"
|
|
||||||
clearable
|
|
||||||
clear-icon="close"
|
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<QBtn
|
|
||||||
icon="vn:attach"
|
|
||||||
flat
|
|
||||||
round
|
|
||||||
padding="xs"
|
|
||||||
@click="inputFileRef.pickFiles()"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Select a file') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
<QBtn icon="info" flat round padding="xs">
|
|
||||||
<QTooltip max-width="30rem">
|
|
||||||
{{
|
|
||||||
`${t(
|
|
||||||
'Allowed content types',
|
|
||||||
)}: ${allowedContentTypes.join(', ')}`
|
|
||||||
}}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
</template>
|
|
||||||
</QFile>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Generate identifier for original file')"
|
|
||||||
v-model="dms.hasFile"
|
|
||||||
/>
|
|
||||||
</QForm>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
clientFileDescription: '{dmsTypeName} FROM CLIENT {clientName} ID {clientId}'
|
|
||||||
es:
|
|
||||||
Reference: Referencia
|
|
||||||
Company: Empresa
|
|
||||||
Warehouse: Almacén
|
|
||||||
Type: Tipo
|
|
||||||
Description: Descripción
|
|
||||||
clientFileDescription: '{dmsTypeName} DEL CLIENTE {clientName} ID {clientId}'
|
|
||||||
File: Fichero
|
|
||||||
Select a file: Selecciona un fichero
|
|
||||||
Allowed content types: Tipos de archivo permitidos
|
|
||||||
Generate identifier for original file: Generar identificador para archivo original
|
|
||||||
</i18n>
|
|
|
@ -1,82 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
|
|
||||||
import { useDialogPluginComponent } from 'quasar';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
import useNotify from 'src/composables/useNotify';
|
|
||||||
|
|
||||||
const $props = defineProps({
|
|
||||||
id: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
promise: {
|
|
||||||
type: Function,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { dialogRef } = useDialogPluginComponent();
|
|
||||||
const { notify } = useNotify();
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const closeButton = ref(null);
|
|
||||||
|
|
||||||
const isLoading = ref(false);
|
|
||||||
|
|
||||||
const deleteDms = async () => {
|
|
||||||
isLoading.value = true;
|
|
||||||
try {
|
|
||||||
await axios.post(`ClientDms/${$props.id}/removeFile`);
|
|
||||||
if ($props.promise) await $props.promise();
|
|
||||||
notify('globals.dataDeleted', 'positive');
|
|
||||||
} catch (error) {
|
|
||||||
notify(error.message, 'negative');
|
|
||||||
} finally {
|
|
||||||
closeButton.value.click();
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<QDialog ref="dialogRef">
|
|
||||||
<QCard class="q-pa-md q-mb-md">
|
|
||||||
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
|
||||||
<QIcon name="close" size="sm" />
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<QCardSection>
|
|
||||||
<div class="mt-1 text-h6">{{ t('This file will be deleted') }}</div>
|
|
||||||
<div>{{ t('Are you sure you want to continue?') }}</div>
|
|
||||||
</QCardSection>
|
|
||||||
|
|
||||||
<QCardActions class="flex justify-end">
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.cancel')"
|
|
||||||
:loading="isLoading"
|
|
||||||
class="q-mr-xl"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
v-close-popup
|
|
||||||
/>
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.save')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click.stop="deleteDms"
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
</QCardActions>
|
|
||||||
</QCard>
|
|
||||||
</QDialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
This file will be deleted: Este fichero va a ser borrado
|
|
||||||
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
|
||||||
</i18n>
|
|
|
@ -1,237 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
const { notify } = useNotify();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const { validate } = useValidator();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const filterCompanies = { order: ['code'] };
|
|
||||||
const filterWarehouses = { order: ['name'] };
|
|
||||||
|
|
||||||
const inputFileRef = ref();
|
|
||||||
const allowedContentTypes = ref([]);
|
|
||||||
const optionsCompanies = ref([]);
|
|
||||||
const optionsWarehouses = ref([]);
|
|
||||||
const optionsDmsTypes = ref([]);
|
|
||||||
const isLoading = ref(false);
|
|
||||||
const dms = ref({
|
|
||||||
hasFile: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const setCurrentDms = (data) => {
|
|
||||||
dms.value.reference = data.reference;
|
|
||||||
dms.value.companyId = data.companyFk;
|
|
||||||
dms.value.warehouseId = data.warehouseFk;
|
|
||||||
dms.value.dmsTypeId = data.dmsTypeFk;
|
|
||||||
dms.value.description = data.description;
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveData = async () => {
|
|
||||||
try {
|
|
||||||
const formData = new FormData();
|
|
||||||
const files = dms.value.files;
|
|
||||||
|
|
||||||
if (files && files.length > 0) {
|
|
||||||
for (let file of files) {
|
|
||||||
formData.append(file.name, file);
|
|
||||||
}
|
|
||||||
dms.value.hasFileAttached = true;
|
|
||||||
|
|
||||||
const url = `dms/${route.params.dmsId}/updateFile`;
|
|
||||||
await axios.post(url, formData, {
|
|
||||||
params: dms.value,
|
|
||||||
});
|
|
||||||
notify('globals.dataSaved', 'positive');
|
|
||||||
toCustomerFileManagement();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
notify(error.message, 'negative');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const toCustomerFileManagement = () => {
|
|
||||||
router.push({ name: 'CustomerFileManagement' });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData :url="`Dms/${route.params.dmsId}`" @on-fetch="setCurrentDms" auto-load />
|
|
||||||
<FetchData
|
|
||||||
@on-fetch="(data) => (allowedContentTypes = data)"
|
|
||||||
auto-load
|
|
||||||
url="DmsContainers/allowedContentTypes"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterCompanies"
|
|
||||||
@on-fetch="(data) => (optionsCompanies = data)"
|
|
||||||
auto-load
|
|
||||||
url="Companies"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterWarehouses"
|
|
||||||
@on-fetch="(data) => (optionsWarehouses = data)"
|
|
||||||
auto-load
|
|
||||||
url="Warehouses"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterWarehouses"
|
|
||||||
@on-fetch="(data) => (optionsDmsTypes = data)"
|
|
||||||
auto-load
|
|
||||||
url="DmsTypes"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Teleport to="#st-actions">
|
|
||||||
<QBtnGroup push class="q-gutter-x-sm">
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.cancel')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click="toCustomerFileManagement"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
icon="close"
|
|
||||||
/>
|
|
||||||
<QBtn
|
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.save')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click.stop="saveData"
|
|
||||||
color="primary"
|
|
||||||
icon="save"
|
|
||||||
/>
|
|
||||||
</QBtnGroup>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<QCard class="q-pa-lg">
|
|
||||||
<QCardSection>
|
|
||||||
<QForm>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnInput
|
|
||||||
:label="t('Reference')"
|
|
||||||
clearable
|
|
||||||
v-model="dms.reference"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Company')"
|
|
||||||
:options="optionsCompanies"
|
|
||||||
:rules="validate('entry.companyFk')"
|
|
||||||
option-label="code"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.companyId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Warehouse')"
|
|
||||||
:options="optionsWarehouses"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.warehouseId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Type')"
|
|
||||||
:options="optionsDmsTypes"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="dms.dmsTypeId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnInput
|
|
||||||
:label="t('Description')"
|
|
||||||
:rules="validate('route.description')"
|
|
||||||
clearable
|
|
||||||
type="textarea"
|
|
||||||
v-model="dms.description"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<QFile
|
|
||||||
ref="inputFileRef"
|
|
||||||
class="required"
|
|
||||||
:label="t('File')"
|
|
||||||
v-model="dms.files"
|
|
||||||
multiple
|
|
||||||
:accept="allowedContentTypes.join(',')"
|
|
||||||
clearable
|
|
||||||
clear-icon="close"
|
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<QBtn
|
|
||||||
icon="vn:attach"
|
|
||||||
flat
|
|
||||||
round
|
|
||||||
padding="xs"
|
|
||||||
@click="inputFileRef.pickFiles()"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Select a file') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
<QBtn icon="info" flat round padding="xs">
|
|
||||||
<QTooltip max-width="30rem">
|
|
||||||
{{
|
|
||||||
`${t(
|
|
||||||
'Allowed content types',
|
|
||||||
)}: ${allowedContentTypes.join(', ')}`
|
|
||||||
}}
|
|
||||||
</QTooltip>
|
|
||||||
</QBtn>
|
|
||||||
</template>
|
|
||||||
</QFile>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Generate identifier for original file')"
|
|
||||||
v-model="dms.hasFile"
|
|
||||||
disable
|
|
||||||
/>
|
|
||||||
</QForm>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
clientFileDescription: '{dmsTypeName} FROM CLIENT {clientName} ID {clientId}'
|
|
||||||
es:
|
|
||||||
Reference: Referencia
|
|
||||||
Company: Empresa
|
|
||||||
Warehouse: Almacén
|
|
||||||
Type: Tipo
|
|
||||||
Description: Descripción
|
|
||||||
clientFileDescription: '{dmsTypeName} DEL CLIENTE {clientName} ID {clientId}'
|
|
||||||
File: Fichero
|
|
||||||
Select a file: Selecciona un fichero
|
|
||||||
Allowed content types: Tipos de archivo permitidos
|
|
||||||
Generate identifier for original file: Generar identificador para archivo original
|
|
||||||
</i18n>
|
|
|
@ -29,7 +29,7 @@ const saveData = async () => {
|
||||||
finished: timestamp,
|
finished: timestamp,
|
||||||
};
|
};
|
||||||
await axios.patch(`CreditClassifications/${$props.id}`, payload);
|
await axios.patch(`CreditClassifications/${$props.id}`, payload);
|
||||||
$props.promise();
|
await $props.promise();
|
||||||
closeButton.value.click();
|
closeButton.value.click();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive, ref } 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 VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { useState } from 'src/composables/useState';
|
|
||||||
import { toDate } from 'src/filters';
|
|
||||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
|
||||||
|
|
||||||
const state = useState();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
|
|
||||||
const user = state.getUser();
|
|
||||||
const newEntryForm = reactive({
|
|
||||||
supplierFk: null,
|
|
||||||
travelFk: Number(route.query?.travelFk) || null,
|
|
||||||
companyFk: user.value.companyFk || null,
|
|
||||||
});
|
|
||||||
const travelsOptions = ref([]);
|
|
||||||
const companiesOptions = ref([]);
|
|
||||||
|
|
||||||
const redirectToEntryBasicData = (_, { id }) => {
|
|
||||||
router.push({ name: 'EntryBasicData', params: { id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
url="Travels/filter"
|
|
||||||
:filter="{ fields: ['id', 'warehouseInName'] }"
|
|
||||||
order="id"
|
|
||||||
@on-fetch="(data) => (travelsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
ref="companiesRef"
|
|
||||||
url="Companies"
|
|
||||||
:filter="{ fields: ['id', 'code'] }"
|
|
||||||
order="code"
|
|
||||||
@on-fetch="(data) => (companiesOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<template v-if="stateStore.isHeaderMounted()">
|
|
||||||
<Teleport to="#searchbar">
|
|
||||||
<VnSearchbar
|
|
||||||
url="Entries/filter"
|
|
||||||
custom-route-redirect-name="EntrySummary"
|
|
||||||
data-key="Entry"
|
|
||||||
:label="t('Search entries')"
|
|
||||||
:info="t('You can search by entry reference')"
|
|
||||||
/>
|
|
||||||
</Teleport>
|
|
||||||
</template>
|
|
||||||
<QPage>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<FormModel
|
|
||||||
url-create="Entries"
|
|
||||||
model="entry"
|
|
||||||
:form-initial-data="newEntryForm"
|
|
||||||
@on-data-saved="redirectToEntryBasicData"
|
|
||||||
>
|
|
||||||
<template #form="{ data, validate }">
|
|
||||||
<VnRow>
|
|
||||||
<VnSelectSupplier
|
|
||||||
class="full-width"
|
|
||||||
v-model="data.supplierFk"
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
:rules="validate('entry.supplierFk')"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Travel')"
|
|
||||||
class="full-width"
|
|
||||||
v-model="data.travelFk"
|
|
||||||
:options="travelsOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="warehouseInName"
|
|
||||||
map-options
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
:rules="validate('entry.travelFk')"
|
|
||||||
>
|
|
||||||
<template #option="scope">
|
|
||||||
<QItem v-bind="scope.itemProps">
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel
|
|
||||||
>{{ scope.opt?.agencyModeName }} -
|
|
||||||
{{ scope.opt?.warehouseInName }} ({{
|
|
||||||
toDate(scope.opt?.shipped)
|
|
||||||
}}) → {{ scope.opt?.warehouseOutName }} ({{
|
|
||||||
toDate(scope.opt?.landed)
|
|
||||||
}})</QItemLabel
|
|
||||||
>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Company')"
|
|
||||||
class="full-width"
|
|
||||||
v-model="data.companyFk"
|
|
||||||
:options="companiesOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="code"
|
|
||||||
map-options
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
:rules="validate('entry.companyFk')"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Travel: Envío
|
|
||||||
Company: Empresa
|
|
||||||
</i18n>
|
|
|
@ -73,7 +73,6 @@ const columns = computed(() => [
|
||||||
optionLabel: 'code',
|
optionLabel: 'code',
|
||||||
options: companies.value,
|
options: companies.value,
|
||||||
},
|
},
|
||||||
orderBy: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'warehouse',
|
name: 'warehouse',
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, markRaw } from 'vue';
|
import { ref, computed, nextTick } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { getTotal } from 'src/composables/getTotal';
|
import { getTotal } from 'src/composables/getTotal';
|
||||||
import { toCurrency } from 'src/filters';
|
import { toCurrency } from 'src/filters';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
||||||
|
import CreateNewExpenseForm from 'src/components/CreateNewExpenseForm.vue';
|
||||||
import { getExchange } from 'src/composables/getExchange';
|
import { getExchange } from 'src/composables/getExchange';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard';
|
||||||
import VnSelectExpense from 'src/components/common/VnSelectExpense.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const arrayData = useArrayData();
|
const arrayData = useArrayData();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const invoiceIn = computed(() => arrayData.store.data);
|
const invoiceIn = computed(() => arrayData.store.data);
|
||||||
|
@ -19,142 +24,100 @@ const expenses = ref([]);
|
||||||
const sageTaxTypes = ref([]);
|
const sageTaxTypes = ref([]);
|
||||||
const sageTransactionTypes = ref([]);
|
const sageTransactionTypes = ref([]);
|
||||||
const rowsSelected = ref([]);
|
const rowsSelected = ref([]);
|
||||||
const invoiceInVatTableRef = ref();
|
const invoiceInFormRef = ref();
|
||||||
|
|
||||||
defineProps({ actionIcon: { type: String, default: 'add' } });
|
defineProps({
|
||||||
|
actionIcon: {
|
||||||
function taxRate(invoiceInTax) {
|
type: String,
|
||||||
const sageTaxTypeId = invoiceInTax.taxTypeSageFk;
|
default: 'add',
|
||||||
const taxRateSelection = sageTaxTypes.value.find(
|
},
|
||||||
(transaction) => transaction.id == sageTaxTypeId,
|
});
|
||||||
);
|
|
||||||
const taxTypeSage = taxRateSelection?.rate ?? 0;
|
|
||||||
const taxableBase = invoiceInTax?.taxableBase ?? 0;
|
|
||||||
|
|
||||||
return (taxTypeSage / 100) * taxableBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'expenseFk',
|
name: 'expense',
|
||||||
label: t('Expense'),
|
label: t('Expense'),
|
||||||
component: markRaw(VnSelectExpense),
|
field: (row) => row.expenseFk,
|
||||||
format: (row) => {
|
options: expenses.value,
|
||||||
const expense = expenses.value.find((e) => e.id === row.expenseFk);
|
model: 'expenseFk',
|
||||||
return expense ? `${expense.id}: ${expense.name}` : row.expenseFk;
|
optionValue: 'id',
|
||||||
},
|
optionLabel: (row) => `${row.id}: ${row.name}`,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
isEditable: true,
|
|
||||||
create: true,
|
|
||||||
width: '250px',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'taxableBase',
|
name: 'taxablebase',
|
||||||
label: t('Taxable base'),
|
label: t('Taxable base'),
|
||||||
component: 'number',
|
field: (row) => row.taxableBase,
|
||||||
attrs: {
|
model: 'taxableBase',
|
||||||
clearable: true,
|
|
||||||
'clear-icon': 'close',
|
|
||||||
},
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
isEditable: true,
|
|
||||||
create: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'isDeductible',
|
name: 'isDeductible',
|
||||||
label: t('invoiceIn.isDeductible'),
|
label: t('invoiceIn.isDeductible'),
|
||||||
component: 'checkbox',
|
field: (row) => row.isDeductible,
|
||||||
|
model: 'isDeductible',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
isEditable: true,
|
|
||||||
create: true,
|
|
||||||
createAttrs: {
|
|
||||||
defaultValue: true,
|
|
||||||
},
|
|
||||||
width: '100px',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'taxTypeSageFk',
|
name: 'sageiva',
|
||||||
label: t('Sage iva'),
|
label: t('Sage iva'),
|
||||||
component: 'select',
|
field: (row) => row.taxTypeSageFk,
|
||||||
attrs: {
|
|
||||||
options: sageTaxTypes.value,
|
options: sageTaxTypes.value,
|
||||||
|
model: 'taxTypeSageFk',
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
optionLabel: (row) => `${row.id}: ${row.vat}`,
|
optionLabel: (row) => `${row.id}: ${row.vat}`,
|
||||||
filterOptions: ['id', 'vat'],
|
|
||||||
'data-cy': 'vat-sageiva',
|
|
||||||
},
|
|
||||||
format: (row) => {
|
|
||||||
const taxType = sageTaxTypes.value.find((t) => t.id === row.taxTypeSageFk);
|
|
||||||
return taxType ? `${taxType.id}: ${taxType.vat}` : row.taxTypeSageFk;
|
|
||||||
},
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
isEditable: true,
|
|
||||||
create: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'transactionTypeSageFk',
|
name: 'sagetransaction',
|
||||||
label: t('Sage transaction'),
|
label: t('Sage transaction'),
|
||||||
component: 'select',
|
field: (row) => row.transactionTypeSageFk,
|
||||||
attrs: {
|
|
||||||
options: sageTransactionTypes.value,
|
options: sageTransactionTypes.value,
|
||||||
|
model: 'transactionTypeSageFk',
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
optionLabel: (row) => `${row.id}: ${row.transaction}`,
|
optionLabel: (row) => `${row.id}: ${row.transaction}`,
|
||||||
filterOptions: ['id', 'transaction'],
|
|
||||||
},
|
|
||||||
format: (row) => {
|
|
||||||
const transType = sageTransactionTypes.value.find(
|
|
||||||
(t) => t.id === row.transactionTypeSageFk,
|
|
||||||
);
|
|
||||||
return transType
|
|
||||||
? `${transType.id}: ${transType.transaction}`
|
|
||||||
: row.transactionTypeSageFk;
|
|
||||||
},
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
isEditable: true,
|
|
||||||
create: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'rate',
|
name: 'rate',
|
||||||
label: t('Rate'),
|
label: t('Rate'),
|
||||||
sortable: false,
|
sortable: true,
|
||||||
format: (row) => taxRate(row).toFixed(2),
|
field: (row) => taxRate(row, row.taxTypeSageFk),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'foreignValue',
|
name: 'foreignvalue',
|
||||||
label: t('Foreign value'),
|
label: t('Foreign value'),
|
||||||
component: 'number',
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
field: (row) => row.foreignValue,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
create: true,
|
|
||||||
disable: !isNotEuro(currency.value),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'total',
|
name: 'total',
|
||||||
label: t('Total'),
|
label: 'Total',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (row) => (Number(row.taxableBase || 0) + Number(taxRate(row))).toFixed(2),
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tableRows = computed(
|
|
||||||
() => invoiceInVatTableRef.value?.CrudModelRef?.formData || [],
|
|
||||||
);
|
|
||||||
const taxableBaseTotal = computed(() => {
|
const taxableBaseTotal = computed(() => {
|
||||||
return getTotal(tableRows.value, 'taxableBase');
|
return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
|
||||||
});
|
});
|
||||||
|
|
||||||
const taxRateTotal = computed(() => {
|
const taxRateTotal = computed(() => {
|
||||||
return tableRows.value.reduce((sum, row) => sum + Number(taxRate(row)), 0);
|
return getTotal(invoiceInFormRef.value.formData, null, {
|
||||||
|
cb: taxRate,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const combinedTotal = computed(() => {
|
const combinedTotal = computed(() => {
|
||||||
return +taxableBaseTotal.value + +taxRateTotal.value;
|
return +taxableBaseTotal.value + +taxRateTotal.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
const filter = computed(() => ({
|
const filter = {
|
||||||
fields: [
|
fields: [
|
||||||
'id',
|
'id',
|
||||||
'invoiceInFk',
|
'invoiceInFk',
|
||||||
|
@ -168,75 +131,389 @@ const filter = computed(() => ({
|
||||||
where: {
|
where: {
|
||||||
invoiceInFk: route.params.id,
|
invoiceInFk: route.params.id,
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
const isNotEuro = (code) => code != 'EUR';
|
const isNotEuro = (code) => code != 'EUR';
|
||||||
|
|
||||||
async function handleForeignValueUpdate(val, row) {
|
function taxRate(invoiceInTax) {
|
||||||
if (!isNotEuro(currency.value)) return;
|
const sageTaxTypeId = invoiceInTax.taxTypeSageFk;
|
||||||
row.taxableBase = await getExchange(
|
const taxRateSelection = sageTaxTypes.value.find(
|
||||||
val,
|
(transaction) => transaction.id == sageTaxTypeId,
|
||||||
invoiceIn.value?.currencyFk,
|
|
||||||
invoiceIn.value?.issued,
|
|
||||||
);
|
);
|
||||||
|
const taxTypeSage = taxRateSelection?.rate ?? 0;
|
||||||
|
const taxableBase = invoiceInTax?.taxableBase ?? 0;
|
||||||
|
|
||||||
|
return ((taxTypeSage / 100) * taxableBase).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autocompleteExpense(evt, row, col, ref) {
|
||||||
|
const val = evt.target.value;
|
||||||
|
if (!val) return;
|
||||||
|
|
||||||
|
const param = isNaN(val) ? row[col.model] : val;
|
||||||
|
const lookup = expenses.value.find(
|
||||||
|
({ id }) => id == useAccountShortToStandard(param),
|
||||||
|
);
|
||||||
|
|
||||||
|
ref.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCursor(ref) {
|
||||||
|
nextTick(() => {
|
||||||
|
const select = ref.vnSelectDialogRef
|
||||||
|
? ref.vnSelectDialogRef.vnSelectRef
|
||||||
|
: ref.vnSelectRef;
|
||||||
|
select.$el.querySelector('input').setSelectionRange(0, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData url="Expenses" auto-load @on-fetch="(data) => (expenses = data)" />
|
<FetchData
|
||||||
|
ref="expensesRef"
|
||||||
|
url="Expenses"
|
||||||
|
auto-load
|
||||||
|
@on-fetch="(data) => (expenses = data)"
|
||||||
|
/>
|
||||||
<FetchData url="SageTaxTypes" auto-load @on-fetch="(data) => (sageTaxTypes = data)" />
|
<FetchData url="SageTaxTypes" auto-load @on-fetch="(data) => (sageTaxTypes = data)" />
|
||||||
<FetchData
|
<FetchData
|
||||||
url="sageTransactionTypes"
|
url="sageTransactionTypes"
|
||||||
auto-load
|
auto-load
|
||||||
@on-fetch="(data) => (sageTransactionTypes = data)"
|
@on-fetch="(data) => (sageTransactionTypes = data)"
|
||||||
/>
|
/>
|
||||||
<VnTable
|
<CrudModel
|
||||||
|
ref="invoiceInFormRef"
|
||||||
v-if="invoiceIn"
|
v-if="invoiceIn"
|
||||||
ref="invoiceInVatTableRef"
|
|
||||||
data-key="InvoiceInTaxes"
|
data-key="InvoiceInTaxes"
|
||||||
url="InvoiceInTaxes"
|
url="InvoiceInTaxes"
|
||||||
save-url="InvoiceInTaxes/crud"
|
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
:data-required="{ invoiceInFk: $route.params.id }"
|
:data-required="{ invoiceInFk: $route.params.id }"
|
||||||
:insert-on-load="true"
|
:insert-on-load="true"
|
||||||
auto-load
|
auto-load
|
||||||
v-model:selected="rowsSelected"
|
v-model:selected="rowsSelected"
|
||||||
:columns="columns"
|
:go-to="`/invoice-in/${$route.params.id}/due-day`"
|
||||||
:is-editable="true"
|
|
||||||
:table="{ selection: 'multiple', 'row-key': '$index' }"
|
|
||||||
footer
|
|
||||||
:right-search="false"
|
|
||||||
:column-search="false"
|
|
||||||
:disable-option="{ card: true }"
|
|
||||||
class="q-pa-none"
|
|
||||||
:create="{
|
|
||||||
urlCreate: 'InvoiceInTaxes',
|
|
||||||
title: t('Add tax'),
|
|
||||||
formInitialData: { invoiceInFk: $route.params.id, isDeductible: true },
|
|
||||||
onDataSaved: () => invoiceInVatTableRef.reload(),
|
|
||||||
}"
|
|
||||||
:crud-model="{ goTo: `/invoice-in/${$route.params.id}/due-day` }"
|
|
||||||
>
|
>
|
||||||
<template #column-footer-taxableBase>
|
<template #body="{ rows }">
|
||||||
|
<QTable
|
||||||
|
v-model:selected="rowsSelected"
|
||||||
|
selection="multiple"
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
row-key="$index"
|
||||||
|
:grid="$q.screen.lt.sm"
|
||||||
|
>
|
||||||
|
<template #body-cell-expense="{ row, col }">
|
||||||
|
<QTd>
|
||||||
|
<VnSelectDialog
|
||||||
|
:ref="`expenseRef-${row.$index}`"
|
||||||
|
v-model="row[col.model]"
|
||||||
|
:options="col.options"
|
||||||
|
:option-value="col.optionValue"
|
||||||
|
:option-label="col.optionLabel"
|
||||||
|
:filter-options="['id', 'name']"
|
||||||
|
:tooltip="t('Create a new expense')"
|
||||||
|
:acls="[
|
||||||
|
{ model: 'Expense', props: '*', accessType: 'WRITE' },
|
||||||
|
]"
|
||||||
|
@keydown.tab.prevent="
|
||||||
|
autocompleteExpense(
|
||||||
|
$event,
|
||||||
|
row,
|
||||||
|
col,
|
||||||
|
$refs[`expenseRef-${row.$index}`],
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:model-value="
|
||||||
|
setCursor($refs[`expenseRef-${row.$index}`])
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
{{ `${scope.opt.id}: ${scope.opt.name}` }}
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
<template #form>
|
||||||
|
<CreateNewExpenseForm
|
||||||
|
@on-data-saved="$refs.expensesRef.fetch()"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VnSelectDialog>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-isDeductible="{ row }">
|
||||||
|
<QTd align="center">
|
||||||
|
<QCheckbox
|
||||||
|
v-model="row.isDeductible"
|
||||||
|
data-cy="isDeductible_checkbox"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-taxablebase="{ row }">
|
||||||
|
<QTd shrink>
|
||||||
|
<VnInputNumber
|
||||||
|
clear-icon="close"
|
||||||
|
v-model="row.taxableBase"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-sageiva="{ row, col }">
|
||||||
|
<QTd>
|
||||||
|
<VnSelect
|
||||||
|
:ref="`sageivaRef-${row.$index}`"
|
||||||
|
v-model="row[col.model]"
|
||||||
|
:options="col.options"
|
||||||
|
:option-value="col.optionValue"
|
||||||
|
:option-label="col.optionLabel"
|
||||||
|
:filter-options="['id', 'vat']"
|
||||||
|
data-cy="vat-sageiva"
|
||||||
|
@update:model-value="
|
||||||
|
setCursor($refs[`sageivaRef-${row.$index}`])
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{ scope.opt.vat }}</QItemLabel>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ `#${scope.opt.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-sagetransaction="{ row, col }">
|
||||||
|
<QTd>
|
||||||
|
<VnSelect
|
||||||
|
:ref="`sagetransactionRef-${row.$index}`"
|
||||||
|
v-model="row[col.model]"
|
||||||
|
:options="col.options"
|
||||||
|
:option-value="col.optionValue"
|
||||||
|
:option-label="col.optionLabel"
|
||||||
|
:filter-options="['id', 'transaction']"
|
||||||
|
@update:model-value="
|
||||||
|
setCursor($refs[`sagetransactionRef-${row.$index}`])
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
scope.opt.transaction
|
||||||
|
}}</QItemLabel>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ `#${scope.opt.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-foreignvalue="{ row }">
|
||||||
|
<QTd shrink>
|
||||||
|
<VnInputNumber
|
||||||
|
:class="{
|
||||||
|
'no-pointer-events': !isNotEuro(currency),
|
||||||
|
}"
|
||||||
|
:disable="!isNotEuro(currency)"
|
||||||
|
v-model="row.foreignValue"
|
||||||
|
@update:model-value="
|
||||||
|
async (val) => {
|
||||||
|
if (!isNotEuro(currency)) return;
|
||||||
|
row.taxableBase = await getExchange(
|
||||||
|
val,
|
||||||
|
row.currencyFk,
|
||||||
|
invoiceIn.issued,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #bottom-row>
|
||||||
|
<QTr class="bg">
|
||||||
|
<QTd />
|
||||||
|
<QTd />
|
||||||
|
<QTd>
|
||||||
{{ toCurrency(taxableBaseTotal) }}
|
{{ toCurrency(taxableBaseTotal) }}
|
||||||
</template>
|
</QTd>
|
||||||
<template #column-footer-rate>
|
<QTd />
|
||||||
|
<QTd />
|
||||||
|
<QTd />
|
||||||
|
<QTd>
|
||||||
{{ toCurrency(taxRateTotal) }}
|
{{ toCurrency(taxRateTotal) }}
|
||||||
</template>
|
</QTd>
|
||||||
<template #column-footer-total>
|
<QTd />
|
||||||
|
<QTd>
|
||||||
{{ toCurrency(combinedTotal) }}
|
{{ toCurrency(combinedTotal) }}
|
||||||
|
</QTd>
|
||||||
|
</QTr>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
|
||||||
|
<template #item="props">
|
||||||
|
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
||||||
|
<QCard bordered flat class="q-my-xs">
|
||||||
|
<QCardSection>
|
||||||
|
<QCheckbox v-model="props.selected" dense />
|
||||||
|
</QCardSection>
|
||||||
|
<QSeparator />
|
||||||
|
<QList>
|
||||||
|
<QItem>
|
||||||
|
<VnSelectDialog
|
||||||
|
:label="t('Expense')"
|
||||||
|
class="full-width"
|
||||||
|
v-model="props.row['expenseFk']"
|
||||||
|
:options="expenses"
|
||||||
|
option-value="id"
|
||||||
|
:option-label="(row) => `${row.id}:${row.name}`"
|
||||||
|
:filter-options="['id', 'name']"
|
||||||
|
:tooltip="t('Create a new expense')"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
{{ `${scope.opt.id}: ${scope.opt.name}` }}
|
||||||
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
<template #form>
|
||||||
|
<CreateNewExpenseForm />
|
||||||
|
</template>
|
||||||
|
</VnSelectDialog>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<VnInputNumber
|
||||||
|
:label="t('Taxable base')"
|
||||||
|
:class="{
|
||||||
|
'no-pointer-events': isNotEuro(currency),
|
||||||
|
}"
|
||||||
|
class="full-width"
|
||||||
|
:disable="isNotEuro(currency)"
|
||||||
|
clear-icon="close"
|
||||||
|
v-model="props.row.taxableBase"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<VnSelect
|
||||||
|
:label="t('Sage iva')"
|
||||||
|
class="full-width"
|
||||||
|
v-model="props.row['taxTypeSageFk']"
|
||||||
|
:options="sageTaxTypes"
|
||||||
|
option-value="id"
|
||||||
|
:option-label="(row) => `${row.id}:${row.vat}`"
|
||||||
|
:filter-options="['id', 'vat']"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
scope.opt.vat
|
||||||
|
}}</QItemLabel>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ `#${scope.opt.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<VnSelect
|
||||||
|
class="full-width"
|
||||||
|
v-model="props.row['transactionTypeSageFk']"
|
||||||
|
:options="sageTransactionTypes"
|
||||||
|
option-value="id"
|
||||||
|
:option-label="
|
||||||
|
(row) => `${row.id}:${row.transaction}`
|
||||||
|
"
|
||||||
|
:filter-options="['id', 'transaction']"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
scope.opt.transaction
|
||||||
|
}}</QItemLabel>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ `#${scope.opt.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
{{ toCurrency(taxRate(props.row), currency) }}
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<VnInputNumber
|
||||||
|
:label="t('Foreign value')"
|
||||||
|
class="full-width"
|
||||||
|
:class="{
|
||||||
|
'no-pointer-events': !isNotEuro(currency),
|
||||||
|
}"
|
||||||
|
:disable="!isNotEuro(currency)"
|
||||||
|
v-model="props.row.foreignValue"
|
||||||
|
/>
|
||||||
|
</QItem>
|
||||||
|
</QList>
|
||||||
|
</QCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</template>
|
||||||
|
</CrudModel>
|
||||||
|
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||||
|
<QBtn
|
||||||
|
color="primary"
|
||||||
|
icon="add"
|
||||||
|
size="lg"
|
||||||
|
v-shortcut="'+'"
|
||||||
|
round
|
||||||
|
@click="invoiceInFormRef.insert()"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('Add tax') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
|
</QPageSticky>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.bg {
|
||||||
|
background-color: var(--vn-light-gray);
|
||||||
|
}
|
||||||
|
@media (max-width: $breakpoint-xs) {
|
||||||
|
.q-dialog {
|
||||||
|
.q-card {
|
||||||
|
&__section:not(:first-child) {
|
||||||
|
.q-item {
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.q-checkbox {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.q-item {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
.default-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: $primary;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Expense: Gasto
|
Expense: Gasto
|
||||||
Create a new expense: Crear nuevo gasto
|
Create a new expense: Crear nuevo gasto
|
||||||
Add tax: Añadir Gasto/IVA # Changed label slightly
|
Add tax: Crear gasto
|
||||||
Taxable base: Base imp.
|
Taxable base: Base imp.
|
||||||
Sage iva: Sage iva # Kept original label
|
Sage tax: Sage iva
|
||||||
Sage transaction: Sage transacción
|
Sage transaction: Sage transacción
|
||||||
Rate: Cuota # Changed label
|
Rate: Tasa
|
||||||
Foreign value: Divisa
|
Foreign value: Divisa
|
||||||
Total: Total
|
|
||||||
invoiceIn.isDeductible: Deducible
|
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive, ref } 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 VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { useState } from 'src/composables/useState';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
|
||||||
|
|
||||||
const state = useState();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
|
|
||||||
const user = state.getUser();
|
|
||||||
const newInvoiceIn = reactive({
|
|
||||||
supplierFk: +route.query?.supplierFk || null,
|
|
||||||
supplierRef: null,
|
|
||||||
companyFk: user.value.companyFk || null,
|
|
||||||
issued: Date.vnNew(),
|
|
||||||
});
|
|
||||||
const companies = ref([]);
|
|
||||||
|
|
||||||
const redirectToInvoiceInBasicData = (__, { id }) => {
|
|
||||||
router.push({ name: 'InvoiceInBasicData', params: { id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
ref="companiesRef"
|
|
||||||
url="Companies"
|
|
||||||
:filter="{ fields: ['id', 'code'] }"
|
|
||||||
order="code"
|
|
||||||
@on-fetch="(data) => (companies = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<template v-if="stateStore.isHeaderMounted()">
|
|
||||||
<Teleport to="#searchbar">
|
|
||||||
<VnSearchbar
|
|
||||||
custom-route-redirect-name="InvoiceInSummary"
|
|
||||||
data-key="InvoiceInSummary"
|
|
||||||
/>
|
|
||||||
</Teleport>
|
|
||||||
</template>
|
|
||||||
<QPage>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<FormModel
|
|
||||||
url-create="InvoiceIns"
|
|
||||||
model="InvoiceIn"
|
|
||||||
:form-initial-data="newInvoiceIn"
|
|
||||||
@on-data-saved="redirectToInvoiceInBasicData"
|
|
||||||
>
|
|
||||||
<template #form="{ data, validate }">
|
|
||||||
<VnRow>
|
|
||||||
<VnSelectSupplier
|
|
||||||
v-model="data.supplierFk"
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
:rules="validate('entry.supplierFk')"
|
|
||||||
/>
|
|
||||||
<VnInput
|
|
||||||
:label="t('invoiceIn.list.supplierRef')"
|
|
||||||
v-model="data.supplierRef"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Company')"
|
|
||||||
v-model="data.companyFk"
|
|
||||||
:options="companies"
|
|
||||||
option-value="id"
|
|
||||||
option-label="code"
|
|
||||||
map-options
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
:rules="validate('invoiceIn.companyFk')"
|
|
||||||
/>
|
|
||||||
<VnInputDate
|
|
||||||
:label="t('invoiceIn.summary.issued')"
|
|
||||||
v-model="data.issued"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Travel: Envío
|
|
||||||
Company: Empresa
|
|
||||||
</i18n>
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import VnInputPassword from 'src/components/common/VnInputPassword.vue';
|
import VnInputPassword from 'src/components/common/VnInputPassword.vue';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import { useLogin } from 'src/composables/useLogin';
|
import { useLogin } from 'src/composables/useLogin';
|
||||||
import useNotify from 'src/composables/useNotify';
|
|
||||||
import VnLogo from 'components/ui/VnLogo.vue';
|
import VnLogo from 'components/ui/VnLogo.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
@ -14,14 +15,16 @@ const session = useSession();
|
||||||
const loginCache = useLogin();
|
const loginCache = useLogin();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
|
||||||
|
|
||||||
const username = ref('');
|
const username = ref('');
|
||||||
const password = ref('');
|
const password = ref('');
|
||||||
const keepLogin = ref(true);
|
const keepLogin = ref(true);
|
||||||
|
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
const params = { user: username.value, password: password.value };
|
const params = {
|
||||||
|
user: username.value,
|
||||||
|
password: password.value,
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
const { data } = await axios.post('Accounts/login', params);
|
const { data } = await axios.post('Accounts/login', params);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
@ -30,7 +33,11 @@ async function onSubmit() {
|
||||||
await session.setLogin(data);
|
await session.setLogin(data);
|
||||||
} catch (res) {
|
} catch (res) {
|
||||||
if (res.response?.data?.error?.code === 'REQUIRES_2FA') {
|
if (res.response?.data?.error?.code === 'REQUIRES_2FA') {
|
||||||
notify(t('login.twoFactorRequired'), 'warning', 'phoneLink_lock');
|
Notify.create({
|
||||||
|
message: t('login.twoFactorRequired'),
|
||||||
|
icon: 'phoneLink_lock',
|
||||||
|
type: 'warning',
|
||||||
|
});
|
||||||
params.keepLogin = keepLogin.value;
|
params.keepLogin = keepLogin.value;
|
||||||
loginCache.setUser(params);
|
loginCache.setUser(params);
|
||||||
return router.push({
|
return router.push({
|
||||||
|
@ -38,7 +45,10 @@ async function onSubmit() {
|
||||||
query: router.currentRoute.value?.query,
|
query: router.currentRoute.value?.query,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
throw res;
|
Notify.create({
|
||||||
|
message: t('login.loginError'),
|
||||||
|
type: 'negative',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import FormModel from 'components/FormModel.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
|
|
||||||
const newSupplierForm = reactive({
|
|
||||||
name: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
const redirectToSupplierFiscalData = (_, responseData) => {
|
|
||||||
router.push({ name: 'SupplierFiscalData', params: { id: responseData.id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<template v-if="stateStore.isHeaderMounted()">
|
|
||||||
<Teleport to="#searchbar">
|
|
||||||
<VnSearchbar
|
|
||||||
data-key="SuppliersList"
|
|
||||||
:limit="20"
|
|
||||||
:label="t('Search suppliers')"
|
|
||||||
/>
|
|
||||||
</Teleport>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<QPage>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<FormModel
|
|
||||||
url-create="Suppliers/newSupplier"
|
|
||||||
model="supplier"
|
|
||||||
:form-initial-data="newSupplierForm"
|
|
||||||
@on-data-saved="redirectToSupplierFiscalData"
|
|
||||||
>
|
|
||||||
<template #form="{ data }">
|
|
||||||
<VnRow>
|
|
||||||
<VnInput
|
|
||||||
v-model="data.name"
|
|
||||||
:label="t('supplier.create.supplierName')"
|
|
||||||
@keyup="newSupplierForm.name = newSupplierForm.name.toUpperCase()"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
|
|
@ -232,8 +232,9 @@ const onFormModelInit = () => {
|
||||||
|
|
||||||
const redirectToCustomerAddress = () => {
|
const redirectToCustomerAddress = () => {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'CustomerAddressEditCard',
|
name: 'CustomerAddress',
|
||||||
params: { id: clientId.value, addressId: addressId.value },
|
params: { id: clientId.value },
|
||||||
|
query: { addressId: addressId.value },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { onBeforeMount, reactive, ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
|
|
||||||
import FormModel from 'components/FormModel.vue';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import { getClient } from 'src/pages/Customer/composables/getClient';
|
|
||||||
import { getAddresses } from 'src/pages/Customer/composables/getAddresses';
|
|
||||||
import { getAgencies } from 'src/pages/Route/Agency/composables/getAgencies';
|
|
||||||
|
|
||||||
import { useState } from 'composables/useState';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const state = useState();
|
|
||||||
const user = state.getUser();
|
|
||||||
|
|
||||||
const initialFormState = reactive({
|
|
||||||
clientId: Number(route.query?.clientFk) || null,
|
|
||||||
addressId: null,
|
|
||||||
agencyModeId: null,
|
|
||||||
warehouseId: user.value.warehouseFk,
|
|
||||||
landed: null,
|
|
||||||
});
|
|
||||||
const clientOptions = ref([]);
|
|
||||||
const agenciesOptions = ref([]);
|
|
||||||
const addressesOptions = ref([]);
|
|
||||||
const warehousesOptions = ref([]);
|
|
||||||
const selectedClient = ref(null);
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
await onClientSelected(initialFormState);
|
|
||||||
});
|
|
||||||
|
|
||||||
function resetAgenciesSelector(formData) {
|
|
||||||
agenciesOptions.value = [];
|
|
||||||
formData.agencyModeId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchClient = async (formData) => {
|
|
||||||
const response = await getClient(formData.clientId);
|
|
||||||
if (!response) return;
|
|
||||||
const [client] = response.data;
|
|
||||||
selectedClient.value = client;
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchAddresses = async (formData) => {
|
|
||||||
const response = await getAddresses(formData.clientId);
|
|
||||||
if (!response) return;
|
|
||||||
addressesOptions.value = response.data;
|
|
||||||
|
|
||||||
const { defaultAddress } = selectedClient.value;
|
|
||||||
formData.addressId = defaultAddress.id;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClientSelected = async (formData) => {
|
|
||||||
resetAgenciesSelector(formData);
|
|
||||||
await fetchClient(formData);
|
|
||||||
await fetchAddresses(formData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchAvailableAgencies = async (formData) => {
|
|
||||||
resetAgenciesSelector(formData);
|
|
||||||
const response = await getAgencies(formData, selectedClient.value);
|
|
||||||
if (!response) return;
|
|
||||||
|
|
||||||
const { options, agency } = response;
|
|
||||||
if (options) agenciesOptions.value = options;
|
|
||||||
if (agency) formData.agencyModeId = agency;
|
|
||||||
};
|
|
||||||
|
|
||||||
const redirectToTicketList = (_, { id }) => {
|
|
||||||
router.push({ name: 'TicketSummary', params: { id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
url="Clients"
|
|
||||||
@on-fetch="(data) => (clientOptions = data)"
|
|
||||||
:filter="{ fields: ['id', 'name', 'defaultAddressFk'], order: 'id' }"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
url="Warehouses"
|
|
||||||
@on-fetch="(data) => (warehousesOptions = data)"
|
|
||||||
:where="{
|
|
||||||
isForTicket: true,
|
|
||||||
}"
|
|
||||||
order="name"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<div class="q-pa-md">
|
|
||||||
<FormModel
|
|
||||||
url-create="Tickets/new"
|
|
||||||
model="ticket"
|
|
||||||
:form-initial-data="initialFormState"
|
|
||||||
@on-data-saved="redirectToTicketList"
|
|
||||||
>
|
|
||||||
<template #form="{ data }">
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.client')"
|
|
||||||
v-model="data.clientId"
|
|
||||||
:options="clientOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="name"
|
|
||||||
hide-selected
|
|
||||||
@update:model-value="(client) => onClientSelected(data)"
|
|
||||||
>
|
|
||||||
<template #option="scope">
|
|
||||||
<QItem v-bind="scope.itemProps">
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel>
|
|
||||||
{{ scope.opt.name }}
|
|
||||||
</QItemLabel>
|
|
||||||
<QItemLabel caption>
|
|
||||||
{{ `#${scope.opt.id}` }}
|
|
||||||
</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('ticket.create.address')"
|
|
||||||
v-model="data.addressId"
|
|
||||||
:options="addressesOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="nickname"
|
|
||||||
hide-selected
|
|
||||||
:disable="!data.clientId"
|
|
||||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
||||||
>
|
|
||||||
<template #option="scope">
|
|
||||||
<QItem v-bind="scope.itemProps">
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel>
|
|
||||||
{{ scope.opt.nickname }}
|
|
||||||
</QItemLabel>
|
|
||||||
<QItemLabel caption>
|
|
||||||
{{ `${scope.opt.street}, ${scope.opt.city}` }}
|
|
||||||
</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnInputDate
|
|
||||||
placeholder="dd-mm-aaa"
|
|
||||||
:label="t('globals.landed')"
|
|
||||||
v-model="data.landed"
|
|
||||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.warehouse')"
|
|
||||||
v-model="data.warehouseId"
|
|
||||||
:options="warehousesOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="name"
|
|
||||||
hide-selected
|
|
||||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<div class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.agency')"
|
|
||||||
v-model="data.agencyModeId"
|
|
||||||
:options="agenciesOptions"
|
|
||||||
option-value="agencyModeFk"
|
|
||||||
option-label="agencyMode"
|
|
||||||
hide-selected
|
|
||||||
:disable="!data.clientId || !data.landed || !data.warehouseId"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -21,25 +21,21 @@ const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
const canDelete = computed(() => useAcl().hasAcl('Travel', '*', 'WRITE'));
|
||||||
|
|
||||||
const redirectToCreateView = (queryParams) => {
|
function cloneTravel() {
|
||||||
router.push({ name: 'TravelCreate', query: { travelData: queryParams } });
|
router.push({
|
||||||
};
|
name: 'TravelList',
|
||||||
|
query: { createForm: JSON.stringify($props.travel) },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const cloneTravel = () => {
|
async function cloneTravelWithEntries() {
|
||||||
const stringifiedTravelData = JSON.stringify($props.travel);
|
|
||||||
redirectToCreateView(stringifiedTravelData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const cloneTravelWithEntries = async () => {
|
|
||||||
const { data } = await axios.post(`Travels/${$props.travel.id}/cloneWithEntries`);
|
const { data } = await axios.post(`Travels/${$props.travel.id}/cloneWithEntries`);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
router.push({ name: 'TravelBasicData', params: { id: data.id } });
|
router.push({ name: 'TravelBasicData', params: { id: data.id } });
|
||||||
};
|
}
|
||||||
|
function openDeleteEntryDialog(id) {
|
||||||
const canDelete = computed(() => useAcl().hasAcl('Travel', '*', 'WRITE'));
|
|
||||||
|
|
||||||
const openDeleteEntryDialog = (id) => {
|
|
||||||
quasar
|
quasar
|
||||||
.dialog({
|
.dialog({
|
||||||
component: VnConfirm,
|
component: VnConfirm,
|
||||||
|
@ -51,13 +47,13 @@ const openDeleteEntryDialog = (id) => {
|
||||||
.onOk(async () => {
|
.onOk(async () => {
|
||||||
await deleteTravel(id);
|
await deleteTravel(id);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
const deleteTravel = async (id) => {
|
async function deleteTravel(id) {
|
||||||
await axios.delete(`Travels/${id}`);
|
await axios.delete(`Travels/${id}`);
|
||||||
router.push({ name: 'TravelList' });
|
router.push({ name: 'TravelList' });
|
||||||
notify('globals.dataDeleted', 'positive');
|
notify('globals.dataDeleted', 'positive');
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -82,7 +78,10 @@ const deleteTravel = async (id) => {
|
||||||
<QItem v-ripple clickable>
|
<QItem v-ripple clickable>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'EntryCreate', query: { travelFk: travel.id } }"
|
:to="{
|
||||||
|
name: 'EntryList',
|
||||||
|
query: { createForm: JSON.stringify({ travelFk: travel.id }) },
|
||||||
|
}"
|
||||||
class="color-vn-text"
|
class="color-vn-text"
|
||||||
>
|
>
|
||||||
{{ t('travel.summary.AddEntry') }}
|
{{ t('travel.summary.AddEntry') }}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import useNotify from 'src/composables/useNotify.js';
|
||||||
import { toDate, toCelsius } from 'src/filters';
|
import { toDate, toCelsius } from 'src/filters';
|
||||||
import { downloadFile } from 'src/composables/downloadFile';
|
import { downloadFile } from 'src/composables/downloadFile';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import TravelThermographsForm from './TravelThermographsForm.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
@ -22,8 +23,10 @@ const { notify } = useNotify();
|
||||||
|
|
||||||
const travel = computed(() => useArrayData('Travel').store.data);
|
const travel = computed(() => useArrayData('Travel').store.data);
|
||||||
const thermographPaginateRef = ref();
|
const thermographPaginateRef = ref();
|
||||||
|
const saveType= ref('create');
|
||||||
const warehouses = ref([]);
|
const warehouses = ref([]);
|
||||||
|
const showForm = ref(false);
|
||||||
|
const formData = ref({});
|
||||||
const thermographFilter = {
|
const thermographFilter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -38,13 +41,21 @@ const thermographFilter = {
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
relation: 'dms',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
where: { travelFk: route.params.id },
|
|
||||||
order: ['created'],
|
order: ['created'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const TableColumns = computed(() => {
|
const TableColumns = computed(() => {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
label: t('globals.id'),
|
||||||
|
field: 'id',
|
||||||
|
name: 'id',
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.code'),
|
label: t('globals.code'),
|
||||||
field: 'thermographFk',
|
field: 'thermographFk',
|
||||||
|
@ -59,23 +70,23 @@ const TableColumns = computed(() => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('travel.thermographs.carrier'),
|
label: t('travel.thermographs.carrier'),
|
||||||
field: (row) => row.agencyMode?.name,
|
|
||||||
name: 'agencyModeFk',
|
name: 'agencyModeFk',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
format: (row) => row.agencyMode?.name,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.maxTemperature'),
|
label: t('globals.maxTemperature'),
|
||||||
field: 'maxTemperature',
|
field: 'maxTemperature',
|
||||||
name: 'maxTemperature',
|
name: 'maxTemperature',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (val) => toCelsius(val),
|
format: ({ maxTemperature }) => toCelsius(maxTemperature),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.minTemperature'),
|
label: t('globals.minTemperature'),
|
||||||
field: 'minTemperature',
|
field: 'minTemperature',
|
||||||
name: 'minTemperature',
|
name: 'minTemperature',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (val) => toCelsius(val),
|
format: ({ minTemperature }) => toCelsius(minTemperature),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.state'),
|
label: t('globals.state'),
|
||||||
|
@ -88,60 +99,47 @@ const TableColumns = computed(() => {
|
||||||
field: 'warehouseFk',
|
field: 'warehouseFk',
|
||||||
name: 'destination',
|
name: 'destination',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (val) =>
|
format: ({ warehouseFk }) =>
|
||||||
warehouses.value.find((warehouse) => warehouse.id === val)?.name,
|
warehouses.value.find((warehouse) => warehouse.id === warehouseFk)?.name,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.created'),
|
label: t('globals.created'),
|
||||||
field: 'created',
|
field: 'created',
|
||||||
name: 'created',
|
name: 'created',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
format: (val) => toDate(val),
|
format: ({ created }) => toDate(created),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'downloadFile',
|
name: 'downloadFile',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'editFile',
|
name: 'editFile',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'removeThermograph',
|
name: 'removeThermograph',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
const openRemoveDialog = async (id) => {
|
const openRemoveDialog = async (id) => {
|
||||||
quasar
|
quasar.dialog({
|
||||||
.dialog({
|
|
||||||
component: VnConfirm,
|
component: VnConfirm,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
message: t('Are you sure you want to remove the thermograph?'),
|
message: t('Are you sure you want to remove the thermograph?'),
|
||||||
|
promise: () => removeThermograph(id),
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.onOk(async () => {
|
|
||||||
await removeThermograph(id);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const redirectToThermographForm = (action, id) => {
|
|
||||||
const routeDetails = {
|
|
||||||
name: action === 'create' ? 'TravelThermographsCreate' : 'TravelThermographsEdit',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (action === 'edit' && id) {
|
|
||||||
routeDetails.query = { id };
|
|
||||||
} else if (action === 'create') {
|
|
||||||
routeDetails.query = { agencyModeFk: travel.value?.agencyModeFk };
|
|
||||||
}
|
|
||||||
router.push(routeDetails);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeThermograph = async (id) => {
|
const removeThermograph = async (id) => {
|
||||||
await axios.delete(`Travels/deleteThermograph?id=${id}`);
|
await axios.delete(`Travels/deleteThermograph?id=${id}`);
|
||||||
await thermographPaginateRef.value.fetch();
|
await thermographPaginateRef.value.reload();
|
||||||
notify(t('Thermograph removed'), 'positive');
|
notify(t('Thermograph removed'), 'positive');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -154,23 +152,16 @@ const removeThermograph = async (id) => {
|
||||||
@on-fetch="(data) => (warehouses = data)"
|
@on-fetch="(data) => (warehouses = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<VnPaginate
|
<VnTable
|
||||||
ref="thermographPaginateRef"
|
ref="thermographPaginateRef"
|
||||||
data-key="TravelThermographs"
|
data-key="TravelThermographs"
|
||||||
url="TravelThermographs"
|
url="TravelThermographs"
|
||||||
:user-filter="thermographFilter"
|
:user-filter="thermographFilter"
|
||||||
|
:filter="{ where: { travelFk: route.params.id } }"
|
||||||
|
:columns="TableColumns"
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #column-downloadFile="{ row }">
|
||||||
<QTable
|
|
||||||
:rows="rows"
|
|
||||||
:columns="TableColumns"
|
|
||||||
:no-data-label="t('No results')"
|
|
||||||
row-key="id"
|
|
||||||
class="full-width q-mt-md"
|
|
||||||
>
|
|
||||||
<template #body-cell-downloadFile="{ row }">
|
|
||||||
<QTd auto-width>
|
|
||||||
<QIcon
|
<QIcon
|
||||||
name="cloud_download"
|
name="cloud_download"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -180,23 +171,25 @@ const removeThermograph = async (id) => {
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Download file') }}</QTooltip>
|
<QTooltip>{{ t('Download file') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-editFile="{ row }">
|
<template #column-editFile="{ row }">
|
||||||
<QTd auto-width>
|
|
||||||
<QIcon
|
<QIcon
|
||||||
name="edit"
|
name="edit"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@click="redirectToThermographForm('edit', row.id)"
|
@click="
|
||||||
|
() => {
|
||||||
|
formData = row;
|
||||||
|
showForm = !showForm;
|
||||||
|
saveType = 'update';
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Edit file') }}</QTooltip>
|
<QTooltip>{{ t('Edit file') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-removeThermograph="{ row }">
|
<template #column-removeThermograph="{ row }">
|
||||||
<QTd auto-width>
|
|
||||||
<QIcon
|
<QIcon
|
||||||
name="delete"
|
name="delete"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -206,23 +199,33 @@ const removeThermograph = async (id) => {
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Remove thermograph') }}</QTooltip>
|
<QTooltip>{{ t('Remove thermograph') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</VnTable>
|
||||||
</template>
|
|
||||||
</VnPaginate>
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
<QPageSticky :offset="[20, 20]">
|
||||||
<QBtn
|
<QBtn
|
||||||
fab
|
fab
|
||||||
icon="add"
|
icon="add"
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="redirectToThermographForm('create')"
|
@click="
|
||||||
|
() => {
|
||||||
|
formData = { dms: {} };
|
||||||
|
saveType = 'create';
|
||||||
|
showForm = !showForm;
|
||||||
|
}
|
||||||
|
"
|
||||||
v-shortcut="'+'"
|
v-shortcut="'+'"
|
||||||
/>
|
/>
|
||||||
<QTooltip class="text-no-wrap">
|
<QTooltip class="text-no-wrap">
|
||||||
{{ t('Add thermograph') }}
|
{{ t('Add thermograph') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
|
<QDialog v-model="showForm">
|
||||||
|
<TravelThermographsForm
|
||||||
|
:form-initial-data="formData"
|
||||||
|
:agencyModeFk="travel?.agencyModeFk"
|
||||||
|
:save-type="saveType"
|
||||||
|
/>
|
||||||
|
</QDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ref, onBeforeMount } from 'vue';
|
import { ref, onBeforeMount, useAttrs } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
@ -11,22 +11,14 @@ import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import CreateThermographForm from 'src/components/CreateThermographForm.vue';
|
import CreateThermographForm from 'src/components/CreateThermographForm.vue';
|
||||||
|
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import FormModelPopup from 'src/components/FormModelPopup.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const attrs = useAttrs();
|
||||||
viewAction: {
|
|
||||||
type: String,
|
|
||||||
default: 'create',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
@ -37,26 +29,27 @@ const dmsTypesOptions = ref([]);
|
||||||
const companiesOptions = ref([]);
|
const companiesOptions = ref([]);
|
||||||
const warehousesOptions = ref([]);
|
const warehousesOptions = ref([]);
|
||||||
const temperaturesOptions = ref([]);
|
const temperaturesOptions = ref([]);
|
||||||
const thermographForm = ref({});
|
|
||||||
const inputFileRef = ref(null);
|
const inputFileRef = ref(null);
|
||||||
const agencyModeOptions = ref([]);
|
const agencyModeOptions = ref([]);
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
const $props = defineProps({
|
||||||
if (props.viewAction === 'create') {
|
agencyModeFk: {
|
||||||
setCreateDefaultParams();
|
type: Number,
|
||||||
} else {
|
default: undefined,
|
||||||
await setEditDefaultParams();
|
},
|
||||||
}
|
saveType: {
|
||||||
|
type: String,
|
||||||
if (route.query.thermographData) {
|
default: 'create',
|
||||||
const thermographData = JSON.parse(route.query.thermographData);
|
|
||||||
for (let key in thermographForm.value) {
|
|
||||||
thermographForm.value[key] = thermographData[key];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchDmsTypes = async () => {
|
onBeforeMount(async () => {
|
||||||
|
if (!attrs['form-initial-data'].thermographFk) {
|
||||||
|
await setCreateDefaultParams();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchDmsTypes() {
|
||||||
const params = {
|
const params = {
|
||||||
filter: {
|
filter: {
|
||||||
where: { code: 'thermograph' },
|
where: { code: 'thermograph' },
|
||||||
|
@ -64,74 +57,79 @@ const fetchDmsTypes = async () => {
|
||||||
};
|
};
|
||||||
const { data } = await axios.get('DmsTypes/findOne', { params });
|
const { data } = await axios.get('DmsTypes/findOne', { params });
|
||||||
return data;
|
return data;
|
||||||
};
|
|
||||||
|
|
||||||
const setCreateDefaultParams = async () => {
|
|
||||||
const dataResponse = await fetchDmsTypes();
|
|
||||||
thermographForm.value.companyId = user.value.companyFk;
|
|
||||||
thermographForm.value.warehouseId = user.value.warehouseFk;
|
|
||||||
thermographForm.value.reference = route.params.id;
|
|
||||||
thermographForm.value.dmsTypeId = dataResponse.id;
|
|
||||||
thermographForm.value.state = 'Ok';
|
|
||||||
thermographForm.value.agencyModeFk = +route.query.agencyModeFk;
|
|
||||||
thermographForm.value.description = t('travel.thermographs.travelFileDescription', {
|
|
||||||
travelId: route.params.id,
|
|
||||||
}).toUpperCase();
|
|
||||||
};
|
|
||||||
|
|
||||||
const setEditDefaultParams = async () => {
|
|
||||||
const filterObj = { include: { relation: 'dms' } };
|
|
||||||
const filter = encodeURIComponent(JSON.stringify(filterObj));
|
|
||||||
const { data } = await axios.get(
|
|
||||||
`TravelThermographs/${route.query.id}?filter=${filter}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
thermographForm.value.thermographFk = data.thermographFk;
|
|
||||||
thermographForm.value.state = data.result;
|
|
||||||
thermographForm.value.reference = data.dms?.reference;
|
|
||||||
thermographForm.value.warehouseId = data.warehouseFk;
|
|
||||||
thermographForm.value.companyId = data.dms?.companyFk;
|
|
||||||
thermographForm.value.dmsTypeId = data.dms?.dmsTypeFk;
|
|
||||||
thermographForm.value.description = data.dms?.description || '';
|
|
||||||
thermographForm.value.hasFile = data.dms?.hasFile;
|
|
||||||
thermographForm.value.hasFileAttached = false;
|
|
||||||
thermographForm.value.maxTemperature = data.maxTemperature;
|
|
||||||
thermographForm.value.minTemperature = data.minTemperature;
|
|
||||||
thermographForm.value.temperatureFk = data.temperatureFk;
|
|
||||||
thermographForm.value.travelThermographFk = data.id;
|
|
||||||
thermographForm.value.agencyModeFk = data.agencyModeFk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setCreateDefaultParams() {
|
||||||
|
const dataResponse = await fetchDmsTypes();
|
||||||
|
attrs['form-initial-data'].companyFk = user.value.companyFk;
|
||||||
|
attrs['form-initial-data'].warehouseFk = user.value.warehouseFk;
|
||||||
|
attrs['form-initial-data'].dms.reference = route.params.id;
|
||||||
|
attrs['form-initial-data'].dms.dmsTypeFk = dataResponse.id;
|
||||||
|
attrs['form-initial-data'].state = 'Ok';
|
||||||
|
attrs['form-initial-data'].agencyModeFk = $props.agencyModeFk;
|
||||||
|
attrs['form-initial-data'].dms.description = t(
|
||||||
|
'travel.thermographs.travelFileDescription',
|
||||||
|
{
|
||||||
|
travelId: route.params.id,
|
||||||
|
},
|
||||||
|
).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onSubmit(data) {
|
||||||
|
const basicData = {
|
||||||
|
state: data.result,
|
||||||
|
reference: data.dms.reference,
|
||||||
|
warehouseId: +data.warehouseFk,
|
||||||
|
companyId: +data.dms.companyFk,
|
||||||
|
dmsTypeId: +data.dms.dmsTypeFk,
|
||||||
|
description: data.dms.description,
|
||||||
|
hasFile: data.dms.hasFile,
|
||||||
|
maxTemperature: +data.maxTemperature,
|
||||||
|
minTemperature: +data.minTemperature,
|
||||||
|
temperatureFk: data.temperatureFk,
|
||||||
|
agencyModeFk: +data.agencyModeFk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const updateData = {
|
||||||
|
travelThermographFk: data.id,
|
||||||
|
thermographFk: data.thermographFk,
|
||||||
|
}
|
||||||
|
|
||||||
|
const createData = {
|
||||||
|
travelThermographFk: data.thermographFk
|
||||||
|
}
|
||||||
|
|
||||||
|
const aditionalData = $props.saveType === 'create' ? createData : updateData
|
||||||
|
|
||||||
|
const dataParsed = {...basicData, ...aditionalData };
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
if (Array.isArray(thermographForm.value.files)) {
|
if (Array.isArray(data.files)) {
|
||||||
thermographForm.value.hasFileAttached = true;
|
dataParsed.hasFileAttached = true;
|
||||||
thermographForm.value.files.forEach((file) => {
|
data.files.forEach((file) => {
|
||||||
formData.append(file.name, file);
|
formData.append(file.name, file);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
delete thermographForm.value.files;
|
delete data.files;
|
||||||
|
|
||||||
|
delete dataParsed.dms;
|
||||||
await axios.post(`/travels/${route.params.id}/saveThermograph`, formData, {
|
await axios.post(`/travels/${route.params.id}/saveThermograph`, formData, {
|
||||||
params: thermographForm.value,
|
params: dataParsed,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
router.push({ name: 'TravelThermographsIndex' });
|
|
||||||
notify(t('Thermograph created'), 'positive');
|
notify(t('Thermograph created'), 'positive');
|
||||||
};
|
}
|
||||||
|
|
||||||
const onThermographCreated = async (data) => {
|
async function onThermographCreated(newThermograph, data) {
|
||||||
await fetchTravelThermographsRef.value.fetch();
|
data = {
|
||||||
thermographForm.value = {
|
|
||||||
...thermographForm.value,
|
|
||||||
...data,
|
...data,
|
||||||
travelThermographFk: data.id,
|
...newThermograph,
|
||||||
warehouseId: data.warehouseFk,
|
travelThermographFk: newThermograph.id,
|
||||||
};
|
warehouseId: newThermograph.warehouseFk,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
@ -167,41 +165,17 @@ const onThermographCreated = async (data) => {
|
||||||
auto-load
|
auto-load
|
||||||
url="AgencyModeIncomings"
|
url="AgencyModeIncomings"
|
||||||
/>
|
/>
|
||||||
|
<FormModelPopup
|
||||||
<QPage class="column items-center full-width">
|
v-if="attrs['form-initial-data'].dms?.dmsTypeFk"
|
||||||
<QForm
|
v-bind="$attrs"
|
||||||
:form-initial-data="thermographForm"
|
|
||||||
:observe-form-changes="viewAction === 'create'"
|
:observe-form-changes="viewAction === 'create'"
|
||||||
:default-actions="true"
|
:save-fn="(data) => onSubmit(data)"
|
||||||
@submit="onSubmit()"
|
|
||||||
class="full-width"
|
|
||||||
style="max-width: 800px"
|
|
||||||
>
|
>
|
||||||
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
<template #form-inputs="{ data }">
|
||||||
<div>
|
|
||||||
<QBtnGroup push class="q-gutter-x-sm">
|
|
||||||
<slot name="moreActions" />
|
|
||||||
<QBtn
|
|
||||||
color="primary"
|
|
||||||
icon="restart_alt"
|
|
||||||
flat
|
|
||||||
@click="reset()"
|
|
||||||
:label="t('globals.reset')"
|
|
||||||
/>
|
|
||||||
<QBtn
|
|
||||||
color="primary"
|
|
||||||
icon="save"
|
|
||||||
@click="onSubmit()"
|
|
||||||
:label="t('globals.save')"
|
|
||||||
/>
|
|
||||||
</QBtnGroup>
|
|
||||||
</div>
|
|
||||||
</Teleport>
|
|
||||||
<QCard class="q-pa-lg">
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelectDialog
|
<VnSelectDialog
|
||||||
:label="t('travel.thermographs.thermograph')"
|
:label="t('travel.thermographs.thermograph')"
|
||||||
v-model="thermographForm.travelThermographFk"
|
v-model="data.thermographFk"
|
||||||
url="TravelThermographs"
|
url="TravelThermographs"
|
||||||
:fields="['id', 'thermographFk']"
|
:fields="['id', 'thermographFk']"
|
||||||
:where="{
|
:where="{
|
||||||
|
@ -210,47 +184,45 @@ const onThermographCreated = async (data) => {
|
||||||
sort-by="thermographFk ASC"
|
sort-by="thermographFk ASC"
|
||||||
option-label="thermographFk"
|
option-label="thermographFk"
|
||||||
option-filter-value="thermographFk"
|
option-filter-value="thermographFk"
|
||||||
:disable="viewAction === 'edit'"
|
:disable="!!$attrs['form-initial-data'].thermographFk"
|
||||||
:tooltip="t('New thermograph')"
|
:tooltip="t('New thermograph')"
|
||||||
:roles-allowed-to-create="['logistic']"
|
:roles-allowed-to-create="['logistic']"
|
||||||
data-key="travelThermographSelect"
|
data-key="travelThermographSelect"
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<CreateThermographForm
|
<CreateThermographForm
|
||||||
@on-data-saved="onThermographCreated"
|
@on-data-saved="
|
||||||
|
(newThermograph) =>{
|
||||||
|
onThermographCreated(newThermograph, data);
|
||||||
|
}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnSelectDialog>
|
</VnSelectDialog>
|
||||||
<VnInput
|
<VnInput v-model="data.result" :label="t('globals.state')" />
|
||||||
v-model="thermographForm.state"
|
|
||||||
:label="t('globals.state')"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('travel.thermographs.carrier')"
|
:label="t('travel.thermographs.carrier')"
|
||||||
v-model="thermographForm.agencyModeFk"
|
v-model="data.agencyModeFk"
|
||||||
:options="agencyModeOptions"
|
:options="agencyModeOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<VnInput
|
<VnInput v-model="data.dms.reference" :label="t('globals.reference')" />
|
||||||
v-model="thermographForm.reference"
|
|
||||||
:label="t('globals.reference')"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.type')"
|
:label="t('globals.type')"
|
||||||
v-model="thermographForm.dmsTypeId"
|
v-model="data.dms.dmsTypeFk"
|
||||||
:options="dmsTypesOptions"
|
:options="dmsTypesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.company')"
|
:label="t('globals.company')"
|
||||||
v-model="thermographForm.companyId"
|
v-model="data.dms.companyFk"
|
||||||
:options="companiesOptions"
|
:options="companiesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="code"
|
option-label="code"
|
||||||
|
@ -259,7 +231,7 @@ const onThermographCreated = async (data) => {
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.warehouse')"
|
:label="t('globals.warehouse')"
|
||||||
v-model="thermographForm.warehouseId"
|
v-model="data.warehouseFk"
|
||||||
:options="warehousesOptions"
|
:options="warehousesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
|
@ -270,17 +242,17 @@ const onThermographCreated = async (data) => {
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
v-model="thermographForm.temperatureFk"
|
v-model="data.temperatureFk"
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
v-model="thermographForm.maxTemperature"
|
v-model="data.maxTemperature"
|
||||||
:label="t('globals.maxTemperature')"
|
:label="t('globals.maxTemperature')"
|
||||||
/>
|
/>
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
v-model="thermographForm.minTemperature"
|
v-model="data.minTemperature"
|
||||||
:label="t('globals.minTemperature')"
|
:label="t('globals.minTemperature')"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -289,7 +261,7 @@ const onThermographCreated = async (data) => {
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('globals.description')"
|
:label="t('globals.description')"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="thermographForm.description"
|
v-model="data.description"
|
||||||
fill-input
|
fill-input
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
@ -299,7 +271,7 @@ const onThermographCreated = async (data) => {
|
||||||
:label="t('globals.file')"
|
:label="t('globals.file')"
|
||||||
multiple
|
multiple
|
||||||
:accept="allowedContentTypes"
|
:accept="allowedContentTypes"
|
||||||
v-model="thermographForm.files"
|
v-model="data.files"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon
|
<QIcon
|
||||||
|
@ -319,9 +291,8 @@ const onThermographCreated = async (data) => {
|
||||||
</template>
|
</template>
|
||||||
</QFile>
|
</QFile>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</QCard>
|
</template>
|
||||||
</QForm>
|
</FormModelPopup>
|
||||||
</QPage>
|
|
||||||
</template>
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { ref, onBeforeMount } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
import FormModel from 'components/FormModel.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const agenciesOptions = ref([]);
|
|
||||||
const warehousesOptions = ref([]);
|
|
||||||
const viewAction = ref();
|
|
||||||
|
|
||||||
const newTravelForm = ref({});
|
|
||||||
onBeforeMount(() => {
|
|
||||||
viewAction.value = route.query.travelData ? 'clone' : 'create';
|
|
||||||
|
|
||||||
if (route.query.travelData) {
|
|
||||||
const travelData = JSON.parse(route.query.travelData);
|
|
||||||
|
|
||||||
newTravelForm.value = { ...newTravelForm.value, ...travelData };
|
|
||||||
delete newTravelForm.value.id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const redirectToTravelBasicData = (_, { id }) => {
|
|
||||||
router.push({ name: 'TravelBasicData', params: { id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
url="AgencyModes"
|
|
||||||
:filter="{ fields: ['id', 'name'], order: ['name ASC'] }"
|
|
||||||
@on-fetch="(data) => (agenciesOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
url="Warehouses"
|
|
||||||
@on-fetch="(data) => (warehousesOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<QPage>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<FormModel
|
|
||||||
url-create="Travels"
|
|
||||||
model="travelCreate"
|
|
||||||
:form-initial-data="newTravelForm"
|
|
||||||
:observe-form-changes="viewAction === 'create'"
|
|
||||||
@on-data-saved="redirectToTravelBasicData"
|
|
||||||
>
|
|
||||||
<template #form="{ data }">
|
|
||||||
<VnRow>
|
|
||||||
<VnInput v-model="data.ref" :label="t('globals.reference')" />
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.agency')"
|
|
||||||
v-model="data.agencyModeFk"
|
|
||||||
:options="agenciesOptions"
|
|
||||||
option-value="agencyFk"
|
|
||||||
option-label="name"
|
|
||||||
hide-selected
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
|
|
||||||
<VnInputDate :label="t('globals.landed')" v-model="data.landed" />
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.warehouseOut')"
|
|
||||||
v-model="data.warehouseOutFk"
|
|
||||||
:options="warehousesOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="name"
|
|
||||||
hide-selected
|
|
||||||
:where="{
|
|
||||||
isOrigin: true,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.warehouseIn')"
|
|
||||||
v-model="data.warehouseInFk"
|
|
||||||
:options="warehousesOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="name"
|
|
||||||
hide-selected
|
|
||||||
:where="{
|
|
||||||
isDestiny: true,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
|
|
@ -28,19 +28,6 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
|
|
||||||
const cloneTravel = (travelData) => {
|
|
||||||
const stringifiedTravelData = JSON.stringify(travelData);
|
|
||||||
redirectToCreateView(stringifiedTravelData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const redirectToCreateView = (queryParams) => {
|
|
||||||
router.push({ name: 'TravelCreate', query: { travelData: queryParams } });
|
|
||||||
};
|
|
||||||
|
|
||||||
const redirectCreateEntryView = (travelData) => {
|
|
||||||
router.push({ name: 'EntryCreate', query: { travelFk: travelData.id } });
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'status',
|
name: 'status',
|
||||||
|
@ -209,6 +196,19 @@ const columns = computed(() => [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
function cloneTravel(travelData) {
|
||||||
|
const data = { formInitialData: travelData };
|
||||||
|
delete data.formInitialData.id;
|
||||||
|
tableRef.value.openForm({ formInitialData: travelData });
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirectCreateEntryView(travelData) {
|
||||||
|
router.push({
|
||||||
|
name: 'EntryList',
|
||||||
|
query: { createForm: JSON.stringify({ travelFk: travelData.id }) },
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -66,8 +66,6 @@ const excludeType = computed({
|
||||||
const arrayData = useArrayData('ZoneEvents');
|
const arrayData = useArrayData('ZoneEvents');
|
||||||
|
|
||||||
const exclusionGeoCreate = async () => {
|
const exclusionGeoCreate = async () => {
|
||||||
if (await zoneHasTickets(route.params.id, dated.value)) return;
|
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
zoneFk: parseInt(route.params.id),
|
zoneFk: parseInt(route.params.id),
|
||||||
date: dated.value,
|
date: dated.value,
|
||||||
|
@ -89,8 +87,6 @@ const exclusionCreate = async () => {
|
||||||
};
|
};
|
||||||
const zoneIds = props.zoneIds?.length ? props.zoneIds : [route.params.id];
|
const zoneIds = props.zoneIds?.length ? props.zoneIds : [route.params.id];
|
||||||
for (const id of zoneIds) {
|
for (const id of zoneIds) {
|
||||||
if (await zoneHasTickets(id, dated.value)) return;
|
|
||||||
|
|
||||||
const url = `Zones/${id}/exclusions`;
|
const url = `Zones/${id}/exclusions`;
|
||||||
let today = moment(dated.value);
|
let today = moment(dated.value);
|
||||||
let lastDay = today.clone().add(nMonths, 'months').endOf('month');
|
let lastDay = today.clone().add(nMonths, 'months').endOf('month');
|
||||||
|
@ -127,26 +123,6 @@ const exclusionCreate = async () => {
|
||||||
await refetchEvents();
|
await refetchEvents();
|
||||||
};
|
};
|
||||||
|
|
||||||
const zoneHasTickets = async (zoneId, date) => {
|
|
||||||
const filter = {
|
|
||||||
where: {
|
|
||||||
zoneFk: zoneId,
|
|
||||||
shipped: date,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const params = { filter: JSON.stringify(filter) };
|
|
||||||
const { data } = await axios.get('Tickets', { params });
|
|
||||||
if (data.length > 0) {
|
|
||||||
quasar.notify({
|
|
||||||
message: t('eventsExclusionForm.cantCloseZone'),
|
|
||||||
type: 'negative',
|
|
||||||
});
|
|
||||||
await refetchEvents();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
if (excludeType.value === 'all') exclusionCreate();
|
if (excludeType.value === 'all') exclusionCreate();
|
||||||
else exclusionGeoCreate();
|
else exclusionGeoCreate();
|
||||||
|
|
|
@ -80,7 +80,6 @@ eventsExclusionForm:
|
||||||
all: All
|
all: All
|
||||||
specificLocations: Specific locations
|
specificLocations: Specific locations
|
||||||
rootTreeLabel: Locations where it is not distributed
|
rootTreeLabel: Locations where it is not distributed
|
||||||
cantCloseZone: Can not close this zone because there are tickets programmed for that day
|
|
||||||
eventsInclusionForm:
|
eventsInclusionForm:
|
||||||
addEvent: Add event
|
addEvent: Add event
|
||||||
editEvent: Edit event
|
editEvent: Edit event
|
||||||
|
|
|
@ -81,7 +81,6 @@ eventsExclusionForm:
|
||||||
all: Todo
|
all: Todo
|
||||||
specificLocations: Localizaciones concretas
|
specificLocations: Localizaciones concretas
|
||||||
rootTreeLabel: Localizaciones en las que no se reparte
|
rootTreeLabel: Localizaciones en las que no se reparte
|
||||||
cantCloseZone: No se puede cerrar la zona porque hay tickets programados para ese día
|
|
||||||
eventsInclusionForm:
|
eventsInclusionForm:
|
||||||
addEvent: Añadir evento
|
addEvent: Añadir evento
|
||||||
editEvent: Editar evento
|
editEvent: Editar evento
|
||||||
|
|
|
@ -75,33 +75,6 @@ const customerCard = {
|
||||||
component: () =>
|
component: () =>
|
||||||
import('src/pages/Customer/Card/CustomerAddress.vue'),
|
import('src/pages/Customer/Card/CustomerAddress.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerAddressCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'address-create',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Customer/components/CustomerAddressCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':addressId',
|
|
||||||
name: 'CustomerAddressEditCard',
|
|
||||||
redirect: { name: 'CustomerAddressEdit' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'edit',
|
|
||||||
name: 'CustomerAddressEdit',
|
|
||||||
meta: {
|
|
||||||
title: 'addressEdit',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerAddressEdit.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -212,14 +185,6 @@ const customerCard = {
|
||||||
'src/pages/Customer/Card/CustomerCreditContracts.vue'
|
'src/pages/Customer/Card/CustomerCreditContracts.vue'
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerCreditContractsCreate',
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerCreditContractsCreate.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'insurance/:creditId',
|
path: 'insurance/:creditId',
|
||||||
name: 'CustomerCreditContractsInsurance',
|
name: 'CustomerCreditContractsInsurance',
|
||||||
|
@ -274,9 +239,9 @@ const customerCard = {
|
||||||
icon: 'vn:onlinepayment',
|
icon: 'vn:onlinepayment',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CustomerFileManagement',
|
name: 'CustomerDms',
|
||||||
title: 'fileManagement',
|
title: 'dms',
|
||||||
icon: 'Upload',
|
icon: 'cloud_upload',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CustomerUnpaid',
|
name: 'CustomerUnpaid',
|
||||||
|
@ -309,14 +274,6 @@ const customerCard = {
|
||||||
component: () =>
|
component: () =>
|
||||||
import('src/pages/Customer/Card/CustomerSamples.vue'),
|
import('src/pages/Customer/Card/CustomerSamples.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerSamplesCreate',
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerSamplesCreate.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -356,47 +313,12 @@ const customerCard = {
|
||||||
import('src/pages/Customer/Card/CustomerWebPayment.vue'),
|
import('src/pages/Customer/Card/CustomerWebPayment.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'file-management',
|
path: 'dms',
|
||||||
name: 'CustomerFileManagement',
|
name: 'CustomerDms',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'fileManagement',
|
title: 'dms',
|
||||||
},
|
},
|
||||||
component: () =>
|
component: () => import('src/pages/Customer/Card/CustomerDms.vue'),
|
||||||
import('src/pages/Customer/Card/CustomerFileManagement.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'file-management',
|
|
||||||
name: 'CustomerFileManagementCard',
|
|
||||||
redirect: { name: 'CustomerFileManagement' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
name: 'CustomerFileManagement',
|
|
||||||
meta: {
|
|
||||||
title: 'fileManagement',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/Card/CustomerFileManagement.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerFileManagementCreate',
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerFileManagementCreate.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':dmsId/edit',
|
|
||||||
name: 'CustomerFileManagementEdit',
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerFileManagementEdit.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'unpaid',
|
path: 'unpaid',
|
||||||
|
|
|
@ -116,15 +116,6 @@ export default {
|
||||||
entryCard,
|
entryCard,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'EntryCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'entryCreate',
|
|
||||||
icon: 'add',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Entry/EntryCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'my',
|
path: 'my',
|
||||||
name: 'EntrySupplier',
|
name: 'EntrySupplier',
|
||||||
|
|
|
@ -122,15 +122,7 @@ export default {
|
||||||
invoiceInCard,
|
invoiceInCard,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'InvoiceInCreare',
|
|
||||||
meta: {
|
|
||||||
title: 'invoiceInCreate',
|
|
||||||
icon: 'create',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/InvoiceIn/InvoiceInCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'serial',
|
path: 'serial',
|
||||||
name: 'InvoiceInSerial',
|
name: 'InvoiceInSerial',
|
||||||
|
|
|
@ -93,15 +93,6 @@ export default {
|
||||||
orderCard,
|
orderCard,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'OrderCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'orderCreate',
|
|
||||||
icon: 'add',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Order/OrderList.vue'),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -16,7 +16,7 @@ const routeCard = {
|
||||||
title: 'basicData',
|
title: 'basicData',
|
||||||
icon: 'vn:settings',
|
icon: 'vn:settings',
|
||||||
},
|
},
|
||||||
component: () => import('pages/Route/Card/RouteForm.vue'),
|
component: () => import('pages/Route/Card/RouteBasicData.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'RouteSummary',
|
name: 'RouteSummary',
|
||||||
|
@ -270,15 +270,6 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Route/RouteExtendedList.vue'),
|
component: () => import('src/pages/Route/RouteExtendedList.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'RouteCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'routeCreate',
|
|
||||||
icon: 'add',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Route/Card/RouteForm.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'agency-term',
|
path: 'agency-term',
|
||||||
name: 'RouteAutonomous',
|
name: 'RouteAutonomous',
|
||||||
|
|
|
@ -180,15 +180,6 @@ export default {
|
||||||
supplierCard,
|
supplierCard,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'SupplierCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'supplierCreate',
|
|
||||||
icon: 'add',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Supplier/SupplierCreate.vue'),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -226,15 +226,6 @@ export default {
|
||||||
ticketCard,
|
ticketCard,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'TicketCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'createTicket',
|
|
||||||
icon: 'vn:ticketAdd',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'negative',
|
path: 'negative',
|
||||||
redirect: { name: 'TicketNegative' },
|
redirect: { name: 'TicketNegative' },
|
||||||
|
|
|
@ -42,31 +42,7 @@ const travelCard = {
|
||||||
title: 'thermographs',
|
title: 'thermographs',
|
||||||
icon: 'vn:thermometer',
|
icon: 'vn:thermometer',
|
||||||
},
|
},
|
||||||
redirect: {
|
component: () => import('src/pages/Travel/Card/TravelThermographs.vue'),
|
||||||
name: 'TravelThermographsIndex',
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'TravelThermographsIndex',
|
|
||||||
path: 'index',
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Travel/Card/TravelThermographs.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'TravelThermographsCreate',
|
|
||||||
path: 'create',
|
|
||||||
props: { viewAction: 'create' },
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Travel/Card/TravelThermographsForm.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'TravelThermographsEdit',
|
|
||||||
path: 'edit',
|
|
||||||
props: { viewAction: 'edit' },
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Travel/Card/TravelThermographsForm.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -115,15 +91,6 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Travel/ExtraCommunity.vue'),
|
component: () => import('src/pages/Travel/ExtraCommunity.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'TravelCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'travelCreate',
|
|
||||||
icon: 'add',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Travel/TravelCreate.vue'),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -24,8 +24,13 @@ export CI=true
|
||||||
export TZ=Europe/Madrid
|
export TZ=Europe/Madrid
|
||||||
|
|
||||||
# IMAGES
|
# IMAGES
|
||||||
docker-compose -f test/cypress/docker-compose.yml --project-directory . pull db
|
docker build -t registry.verdnatura.es/salix-back:dev -f "$salix_dir/back/Dockerfile" "$salix_dir"
|
||||||
docker-compose -f test/cypress/docker-compose.yml --project-directory . pull back
|
cd "$salix_dir" && npx myt run -t
|
||||||
|
docker exec vn-database sh -c "rm -rf /mysql-template"
|
||||||
|
docker exec vn-database sh -c "cp -a /var/lib/mysql /mysql-template"
|
||||||
|
docker commit vn-database registry.verdnatura.es/salix-db:dev
|
||||||
|
docker rm -f vn-database
|
||||||
|
cd "$current_dir"
|
||||||
docker build -f ./docs/Dockerfile.dev -t lilium-dev .
|
docker build -f ./docs/Dockerfile.dev -t lilium-dev .
|
||||||
# END IMAGES
|
# END IMAGES
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/// <reference types="cypress" />
|
|
||||||
describe('Client consignee', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.viewport(1280, 720);
|
|
||||||
cy.login('developer');
|
|
||||||
cy.visit('#/customer/1107/address');
|
|
||||||
});
|
|
||||||
it('Should load layout', () => {
|
|
||||||
cy.get('.q-card').should('be.visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check as equalizated', () => {
|
|
||||||
cy.get('.q-card__section > .address-card').then(($el) => {
|
|
||||||
const addressCards_before = $el.length;
|
|
||||||
|
|
||||||
cy.get('.q-page-sticky > div > .q-btn').click();
|
|
||||||
const addressName = 'test';
|
|
||||||
cy.dataCy('Consignee_input').type(addressName);
|
|
||||||
cy.dataCy('Location_select').click();
|
|
||||||
cy.getOption();
|
|
||||||
cy.dataCy('Street address_input').type('TEST ADDRESS');
|
|
||||||
cy.get('.q-btn-group > .q-btn--standard').click();
|
|
||||||
cy.location('href').should('contain', '#/customer/1107/address');
|
|
||||||
cy.get('.q-card__section > .address-card').should(
|
|
||||||
'have.length',
|
|
||||||
addressCards_before + 1,
|
|
||||||
);
|
|
||||||
cy.get('.q-card__section > .address-card')
|
|
||||||
.eq(addressCards_before)
|
|
||||||
.should('be.visible')
|
|
||||||
.get('.text-weight-bold')
|
|
||||||
.eq(addressCards_before - 1)
|
|
||||||
.should('contain', addressName)
|
|
||||||
.click();
|
|
||||||
});
|
|
||||||
cy.get(
|
|
||||||
'.q-card > :nth-child(1) > :nth-child(2) > .q-checkbox > .q-checkbox__inner',
|
|
||||||
)
|
|
||||||
.should('have.class', 'q-checkbox__inner--falsy')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
|
|
||||||
cy.get(
|
|
||||||
':nth-child(2) > :nth-child(2) > .flex > .q-mr-lg > .q-checkbox__inner',
|
|
||||||
).should('have.class', 'q-checkbox__inner--truthy');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,5 +1,8 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client credit contracts', () => {
|
describe('Client credit contracts', () => {
|
||||||
|
const firstCredit = 123;
|
||||||
|
const secondCredit = 321;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
|
@ -7,9 +10,10 @@ describe('Client credit contracts', () => {
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should add a new contract and an additional credit', () => {
|
it('Should add a new contract and an additional credit', () => {
|
||||||
cy.dataCy('createBtn').click();
|
cy.dataCy('createBtn').click();
|
||||||
cy.dataCy('Credit_input').type(123);
|
cy.dataCy('Credit_input').type(firstCredit);
|
||||||
cy.dataCy('Grade_input').type(9);
|
cy.dataCy('Grade_input').type(9);
|
||||||
cy.dataCy('FormModelPopup_save').click();
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
cy.checkNotification('Data created');
|
cy.checkNotification('Data created');
|
||||||
|
@ -19,12 +23,27 @@ describe('Client credit contracts', () => {
|
||||||
it('Should add an additional credit', () => {
|
it('Should add an additional credit', () => {
|
||||||
cy.dataCy('viewBtn').eq(0).click();
|
cy.dataCy('viewBtn').eq(0).click();
|
||||||
cy.get('.q-page-sticky > div').click();
|
cy.get('.q-page-sticky > div').click();
|
||||||
cy.dataCy('Credit_input').type(321);
|
cy.dataCy('Credit_input').type(secondCredit);
|
||||||
cy.dataCy('Grade_input').type(89);
|
cy.dataCy('Grade_input').type(89);
|
||||||
cy.dataCy('FormModelPopup_save').click();
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
cy.checkNotification('Data created');
|
cy.checkNotification('Data created');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should view correctly credit contracts', () => {
|
||||||
|
cy.get('.q-card > .q-card__section')
|
||||||
|
.first()
|
||||||
|
.find('[data-cy="vnLvCredit"]')
|
||||||
|
.first()
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', firstCredit);
|
||||||
|
cy.get('.q-card > .q-card__section')
|
||||||
|
.first()
|
||||||
|
.find('[data-cy="vnLvCredit"]')
|
||||||
|
.last()
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', secondCredit);
|
||||||
|
});
|
||||||
|
|
||||||
it('Should close a contract', () => {
|
it('Should close a contract', () => {
|
||||||
cy.dataCy('closeBtn').eq(0).click();
|
cy.dataCy('closeBtn').eq(0).click();
|
||||||
cy.get('.q-btn--unelevated').click();
|
cy.get('.q-btn--unelevated').click();
|
|
@ -0,0 +1,85 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
describe('CustomerAddress (consignee)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1280, 720);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit('#/customer/1107/address');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should change default address', () => {
|
||||||
|
cy.dataCy('setDefaultAddress')
|
||||||
|
.first()
|
||||||
|
.should('have.attr', 'style')
|
||||||
|
.and('include', '"FILL" 1');
|
||||||
|
cy.dataCy('setDefaultAddress').last().click();
|
||||||
|
cy.dataCy('setDefaultAddress')
|
||||||
|
.first()
|
||||||
|
.should('have.attr', 'style')
|
||||||
|
.and('include', '"FILL" 0');
|
||||||
|
cy.dataCy('setDefaultAddress')
|
||||||
|
.last()
|
||||||
|
.should('have.attr', 'style')
|
||||||
|
.and('include', '"FILL" 1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('check as equalizated', () => {
|
||||||
|
cy.get('.q-card__section > .address-card').then(($el) => {
|
||||||
|
const addressCards_before = $el.length;
|
||||||
|
|
||||||
|
cy.get('.q-page-sticky > div > .q-btn').click();
|
||||||
|
const addressName = 'test';
|
||||||
|
cy.dataCy('Consignee_input').type(addressName);
|
||||||
|
cy.dataCy('Location_select').click();
|
||||||
|
cy.getOption();
|
||||||
|
cy.dataCy('Street_input').type('TEST ADDRESS');
|
||||||
|
cy.saveCard();
|
||||||
|
|
||||||
|
cy.get('.q-card__section > .address-card').should(
|
||||||
|
'have.length',
|
||||||
|
addressCards_before + 1,
|
||||||
|
);
|
||||||
|
cy.get('.q-card__section > .address-card')
|
||||||
|
.eq(addressCards_before)
|
||||||
|
.should('be.visible')
|
||||||
|
.get('.text-weight-bold')
|
||||||
|
.eq(addressCards_before - 1)
|
||||||
|
.should('contain', addressName)
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get('[data-cy="isEqualizated_form"] > .q-checkbox__inner')
|
||||||
|
.should('have.class', 'q-checkbox__inner--falsy')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.saveCard();
|
||||||
|
cy.get(
|
||||||
|
':nth-child(2) > :nth-child(2) > .flex > .q-mr-lg > .q-checkbox__inner',
|
||||||
|
).should('have.class', 'q-checkbox__inner--truthy');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should edit address', () => {
|
||||||
|
const updateData = {
|
||||||
|
Consignee: { val: 'Stark tower' },
|
||||||
|
Street: { val: 'test' },
|
||||||
|
Location: { val: 'Algemesi', type: 'select' },
|
||||||
|
Agency: { val: 'inhouse pickup', type: 'select' },
|
||||||
|
Phone: { val: '3333333333' },
|
||||||
|
Mobile: { val: '4444444444' },
|
||||||
|
Incoterms: { val: 'Free Alongside Ship', type: 'select' },
|
||||||
|
'Customs agent': { val: 'Agent two', type: 'select' },
|
||||||
|
Longitude: { val: '123' },
|
||||||
|
Latitude: { val: '123' },
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.get('.address-card').last().click();
|
||||||
|
cy.fillInForm(updateData);
|
||||||
|
cy.dataCy('enabled_form').click();
|
||||||
|
cy.dataCy('isEqualizated_form').click();
|
||||||
|
cy.dataCy('isLoginfloraAllowed_form').click();
|
||||||
|
cy.dataCy('addNoteBtn_form').click();
|
||||||
|
cy.selectOption('[data-cy="Observation type_select"]', '6');
|
||||||
|
cy.dataCy('Description_input').click().type('Test description');
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
cy.checkNotification('Data saved');
|
||||||
|
cy.get('.address-card').last().should('have.class', 'item-disabled');
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client balance', () => {
|
describe('CustomerBalance', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/1101/balance');
|
cy.visit('#/customer/1101/balance');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client basic data', () => {
|
describe('CustomerBasicData', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client billing data', () => {
|
describe('CustomerBillingData', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client credits', () => {
|
describe('CustomerCredits', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -0,0 +1,16 @@
|
||||||
|
describe('CustomerDms', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/customer/1104/others/dms`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display customer DMS', () => {
|
||||||
|
const expectedValue = '104';
|
||||||
|
|
||||||
|
cy.get('[data-cy="reference_form"]').each(($el) => {
|
||||||
|
const actualText = $el.text().trim();
|
||||||
|
expect(actualText).to.contain(expectedValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client fiscal data', { testIsolation: true }, () => {
|
describe('CustomerFiscalData', { testIsolation: true }, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client greuges', () => {
|
describe('CustomerGreuges', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client list', { testIsolation: true }, () => {
|
describe('CustomerList', { testIsolation: true }, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('/#/customer/list', {
|
cy.visit('/#/customer/list', {
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client notes', () => {
|
describe('CustomerNotes', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client recoveries', () => {
|
describe('CustomerRecoveries', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client notes', () => {
|
describe('CustomerSms', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -1,5 +1,5 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
describe('Client web-access', () => {
|
describe('CustomerWebAccess', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
|
@ -6,11 +6,14 @@ describe('EntryList', () => {
|
||||||
cy.visit(`/#/entry/list`);
|
cy.visit(`/#/entry/list`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('View popup summary', () => {
|
it('Should create and delete entry', () => {
|
||||||
cy.createEntry();
|
cy.createEntry();
|
||||||
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
||||||
cy.waitForElement('[data-cy="entry-buys"]');
|
cy.waitForElement('[data-cy="entry-buys"]');
|
||||||
cy.deleteEntry();
|
cy.deleteEntry();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('View popup summary', () => {
|
||||||
cy.typeSearchbar('{enter}');
|
cy.typeSearchbar('{enter}');
|
||||||
cy.get('button[title="Summary"]').eq(1).should('be.visible').click();
|
cy.get('button[title="Summary"]').eq(1).should('be.visible').click();
|
||||||
cy.dataCy('entry-summary').should('be.visible');
|
cy.dataCy('entry-summary').should('be.visible');
|
||||||
|
|
|
@ -5,13 +5,14 @@ describe('Logout', { testIsolation: true }, () => {
|
||||||
cy.visit(`/#/dashboard`);
|
cy.visit(`/#/dashboard`);
|
||||||
cy.waitForElement('.q-page', 6000);
|
cy.waitForElement('.q-page', 6000);
|
||||||
});
|
});
|
||||||
|
describe('by user', () => {
|
||||||
it('should logout', () => {
|
it('should logout', () => {
|
||||||
cy.get('#user').click();
|
cy.get('#user').click();
|
||||||
cy.get('#logout').click();
|
cy.get('#logout').click();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
it('should throw session expired error if token has expired or is not valid during navigation', () => {
|
describe('not user', () => {
|
||||||
|
beforeEach(() => {
|
||||||
cy.intercept('GET', '**StarredModules**', {
|
cy.intercept('GET', '**StarredModules**', {
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
body: {
|
body: {
|
||||||
|
@ -24,9 +25,13 @@ describe('Logout', { testIsolation: true }, () => {
|
||||||
},
|
},
|
||||||
statusMessage: 'AUTHORIZATION_REQUIRED',
|
statusMessage: 'AUTHORIZATION_REQUIRED',
|
||||||
}).as('badRequest');
|
}).as('badRequest');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when token not exists', () => {
|
||||||
cy.get('.q-list').should('be.visible').first().should('be.visible').click();
|
cy.get('.q-list').should('be.visible').first().should('be.visible').click();
|
||||||
cy.wait('@badRequest');
|
cy.wait('@badRequest');
|
||||||
|
|
||||||
cy.checkNotification('Your session has expired. Please log in again');
|
cy.checkNotification('Authorization Required');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
describe.skip('RoadMap', () => {
|
describe('RoadMap', () => {
|
||||||
const getSelector = (colField) =>
|
const getSelector = (colField) =>
|
||||||
`tr:last-child > [data-col-field="${colField}"] > .no-padding`;
|
`tr:last-child > [data-col-field="${colField}"] > .no-padding`;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
describe('Travel List', () => {
|
||||||
|
const selectors = {
|
||||||
|
listItem: '[role="menu"] .q-list .q-item',
|
||||||
|
addEntryOpt: 'Add entry',
|
||||||
|
warhouseIn: 'vnLvWarehouse In',
|
||||||
|
entryTravelReference: 'vnLvReference',
|
||||||
|
descriptorTitle: 'vnDescriptor_title',
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1280, 720);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit('#/travel/3/summary');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should add entry', () => {
|
||||||
|
const data = {
|
||||||
|
Supplier: { val: 'FARMER KING', type: 'select' },
|
||||||
|
Company: { val: 'VNL', type: 'select' },
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.dataCy(selectors.warhouseIn)
|
||||||
|
.find('.value > span')
|
||||||
|
.invoke('attr', 'title')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('warehouseIn');
|
||||||
|
|
||||||
|
cy.dataCy(selectors.descriptorTitle)
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('reference');
|
||||||
|
|
||||||
|
cy.openActionsDescriptor();
|
||||||
|
cy.contains(selectors.listItem, selectors.addEntryOpt).click();
|
||||||
|
|
||||||
|
cy.get('@warehouseIn').then((warehouseIn) => {
|
||||||
|
cy.dataCy('entry-travel-select').invoke('val').should('contain', warehouseIn);
|
||||||
|
});
|
||||||
|
cy.fillInForm(data);
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
|
||||||
|
cy.get('@reference').then((reference) => {
|
||||||
|
cy.dataCy(selectors.entryTravelReference).should('contain', reference);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,108 @@
|
||||||
|
describe('Travel List', () => {
|
||||||
|
const selectors = {
|
||||||
|
cloneBtn: 'tableAction-0',
|
||||||
|
addEntryBtn: 'tableAction-1',
|
||||||
|
openSummaryBtn: 'tableAction-2',
|
||||||
|
summaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]',
|
||||||
|
descriptorTitle: 'vnDescriptor_title',
|
||||||
|
warehouseInField: 'vnTableCell_warehouseInFk',
|
||||||
|
referenceField: 'vnTableCell_ref',
|
||||||
|
entryTravelReference: 'vnLvReference',
|
||||||
|
};
|
||||||
|
|
||||||
|
const travelSummaryUrlRegex = /travel\/\d+\/summary/;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1280, 720);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit('#/travel/list');
|
||||||
|
cy.typeSearchbar('{enter}');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should create travel', () => {
|
||||||
|
const data = {
|
||||||
|
Reference: { val: 'Travel' },
|
||||||
|
Agency: { val: 'inhouse pickup', type: 'select' },
|
||||||
|
'Warehouse In': { val: 'Warehouse One', type: 'select' },
|
||||||
|
Shipped: { val: '1.2', type: 'date' },
|
||||||
|
'Warehouse Out': { val: 'Warehouse Two', type: 'select' },
|
||||||
|
Landed: { val: '2.2', type: 'date' },
|
||||||
|
'Total entries': { val: '1' },
|
||||||
|
Availabled: { val: '2.2', type: 'date' },
|
||||||
|
'Available hour': { val: '11:10', type: 'time' },
|
||||||
|
};
|
||||||
|
cy.addBtnClick();
|
||||||
|
cy.fillInForm(data);
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
cy.dataCy(selectors.descriptorTitle).should('contain', data.Reference.val);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should clone travel', () => {
|
||||||
|
cy.dataCy(selectors.cloneBtn).first().click();
|
||||||
|
const data = {
|
||||||
|
Reference: { val: 'Travel clone' },
|
||||||
|
};
|
||||||
|
cy.fillInForm(data);
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
cy.dataCy(selectors.descriptorTitle).should('contain', data.Reference.val);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should add entry', () => {
|
||||||
|
const data = {
|
||||||
|
Supplier: { val: 'FARMER KING', type: 'select' },
|
||||||
|
Company: { val: 'VNL', type: 'select' },
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.dataCy(selectors.warehouseInField)
|
||||||
|
.first()
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('warehouseIn');
|
||||||
|
|
||||||
|
cy.dataCy(selectors.referenceField)
|
||||||
|
.first()
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('reference');
|
||||||
|
|
||||||
|
cy.dataCy(selectors.addEntryBtn).first().click();
|
||||||
|
cy.get('@warehouseIn').then((warehouseIn) => {
|
||||||
|
cy.dataCy('entry-travel-select').invoke('val').should('contain', warehouseIn);
|
||||||
|
});
|
||||||
|
cy.fillInForm(data);
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
|
||||||
|
cy.get('@reference').then((reference) => {
|
||||||
|
cy.dataCy(selectors.entryTravelReference).should('contain', reference);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should redirect to vehicle summary when click summary icon on summary pop-up', () => {
|
||||||
|
cy.dataCy(selectors.referenceField)
|
||||||
|
.first()
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('reference');
|
||||||
|
|
||||||
|
cy.dataCy(selectors.openSummaryBtn).first().click();
|
||||||
|
cy.get(selectors.summaryGoToSummaryBtn).click();
|
||||||
|
cy.location().should('match', travelSummaryUrlRegex);
|
||||||
|
cy.get('@reference').then((label) => {
|
||||||
|
cy.dataCy(selectors.descriptorTitle).should('contain', label);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should redirect to travel summary when click on row', () => {
|
||||||
|
cy.dataCy(selectors.referenceField)
|
||||||
|
.first()
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => text.trim())
|
||||||
|
.as('reference');
|
||||||
|
|
||||||
|
cy.dataCy(selectors.referenceField).first().click();
|
||||||
|
cy.location().should('match', travelSummaryUrlRegex);
|
||||||
|
cy.get('@reference').then((label) => {
|
||||||
|
cy.dataCy(selectors.descriptorTitle).should('contain', label);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,48 @@
|
||||||
|
describe('TravelThermographs', () => {
|
||||||
|
const selectors = {
|
||||||
|
fileInput: 'input[type="file"]',
|
||||||
|
editBtn: 'vnTableCell_editFile',
|
||||||
|
removeBtn: 'vnTableCell_removeThermograph',
|
||||||
|
temperatureField: 'vnTableCell_temperatureFk',
|
||||||
|
codeField: 'vnTableCell_thermographFk',
|
||||||
|
}
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/travel/10/thermographs`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should create thermograph', () => {
|
||||||
|
const data = {
|
||||||
|
Thermograph: { val: 138350-0, type: 'select' },
|
||||||
|
State: { val: 'Ok'},
|
||||||
|
Company: { val: 'VNL', type: 'select' },
|
||||||
|
Temperature: { val: 'Cool', type: 'select' },
|
||||||
|
Max: { val: '10' },
|
||||||
|
Min: { val: '5' },
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.addBtnClick();
|
||||||
|
cy.fillInForm(data);
|
||||||
|
cy.get(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', {
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
cy.dataCy(selectors.codeField).invoke('text').should('contain', data.Thermograph.val);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should edit thermograph', () => {
|
||||||
|
cy.dataCy(selectors.editBtn).eq(0).click();
|
||||||
|
const updateData = {
|
||||||
|
Temperature: { val: 'Warm', type: 'select' },
|
||||||
|
}
|
||||||
|
cy.fillInForm(updateData);
|
||||||
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
|
cy.dataCy(selectors.temperatureField).invoke('text').should('contain', 'warm');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should delete thermograph', () => {
|
||||||
|
cy.dataCy(selectors.removeBtn).eq(0).click();
|
||||||
|
cy.clickConfirm();
|
||||||
|
cy.checkNotification('Thermograph removed');
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
describe('ZoneCalendar', { testIsolation: true }, () => {
|
describe('ZoneCalendar', () => {
|
||||||
const addEventBtn = '.q-page-sticky > div > .q-btn';
|
const addEventBtn = '.q-page-sticky > div > .q-btn';
|
||||||
const submitBtn = '.q-mt-lg > .q-btn--standard';
|
const submitBtn = '.q-mt-lg > .q-btn--standard';
|
||||||
const deleteBtn = 'ZoneEventsPanelDeleteBtn';
|
const deleteBtn = 'ZoneEventsPanelDeleteBtn';
|
||||||
|
@ -47,20 +47,4 @@ describe('ZoneCalendar', { testIsolation: true }, () => {
|
||||||
cy.dataCy('ZoneEventExclusionDeleteBtn').click();
|
cy.dataCy('ZoneEventExclusionDeleteBtn').click();
|
||||||
cy.dataCy('VnConfirm_confirm').click();
|
cy.dataCy('VnConfirm_confirm').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
|
||||||
'should not exclude an event if there are tickets for that zone and day',
|
|
||||||
{ testIsoaltion: true },
|
|
||||||
() => {
|
|
||||||
cy.visit(`/#/zone/3/events`);
|
|
||||||
cy.get('.q-mb-sm > .q-radio__inner').click();
|
|
||||||
cy.get(
|
|
||||||
'.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]',
|
|
||||||
).click();
|
|
||||||
cy.get('.q-mt-lg > .q-btn--standard').click();
|
|
||||||
cy.checkNotification(
|
|
||||||
'Can not close this zone because there are tickets programmed for that day',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,8 +26,27 @@ describe('ZoneDeliveryDays', () => {
|
||||||
});
|
});
|
||||||
}).as('events');
|
}).as('events');
|
||||||
|
|
||||||
cy.selectOption('[data-cy="ZoneDeliveryDaysPostcodeSelect"]', postcode);
|
cy.dataCy('ZoneDeliveryDaysPostcodeSelect').type(postcode);
|
||||||
cy.selectOption('[data-cy="ZoneDeliveryDaysAgencySelect"]', agency);
|
cy.get('.q-menu .q-item').contains(postcode).click();
|
||||||
|
cy.get('.q-menu').then(($menu) => {
|
||||||
|
if ($menu.is(':visible')) {
|
||||||
|
cy.get('[data-cy="ZoneDeliveryDaysPostcodeSelect"]')
|
||||||
|
.as('focusedElement')
|
||||||
|
.focus();
|
||||||
|
cy.get('@focusedElement').blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.dataCy('ZoneDeliveryDaysAgencySelect').type(agency);
|
||||||
|
cy.get('.q-menu .q-item').contains(agency).click();
|
||||||
|
cy.get('.q-menu').then(($menu) => {
|
||||||
|
if ($menu.is(':visible')) {
|
||||||
|
cy.get('[data-cy="ZoneDeliveryDaysAgencySelect"]')
|
||||||
|
.as('focusedElement')
|
||||||
|
.focus();
|
||||||
|
cy.get('@focusedElement').blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
cy.get(submitForm).click();
|
cy.get(submitForm).click();
|
||||||
cy.wait('@events').then((interception) => {
|
cy.wait('@events').then((interception) => {
|
||||||
|
|
Loading…
Reference in New Issue