Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 8717-reviewAndFixAgencySection
This commit is contained in:
commit
8e35b49927
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
@ -18,6 +18,14 @@ const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const appName = 'Lilium';
|
const appName = 'Lilium';
|
||||||
const pinnedModulesRef = ref();
|
const pinnedModulesRef = ref();
|
||||||
|
const hostname = window.location.hostname;
|
||||||
|
const env = ref();
|
||||||
|
|
||||||
|
const getEnvironment = computed(() => {
|
||||||
|
env.value = hostname.split('-');
|
||||||
|
if (env.value.length <= 1) return;
|
||||||
|
return env.value[0];
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => stateStore.setMounted());
|
onMounted(() => stateStore.setMounted());
|
||||||
const refresh = () => window.location.reload();
|
const refresh = () => window.location.reload();
|
||||||
|
@ -49,6 +57,9 @@ const refresh = () => window.location.reload();
|
||||||
{{ t('globals.backToDashboard') }}
|
{{ t('globals.backToDashboard') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
<QBadge v-if="getEnvironment" color="primary" align="top">
|
||||||
|
{{ getEnvironment }}
|
||||||
|
</QBadge>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<VnBreadcrumbs v-if="$q.screen.gt.sm" />
|
<VnBreadcrumbs v-if="$q.screen.gt.sm" />
|
||||||
<QSpinner
|
<QSpinner
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {useDialogPluginComponent} from 'quasar';
|
import { useDialogPluginComponent } from 'quasar';
|
||||||
import {useI18n} from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import {computed, ref} from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
import VnInput from 'components/common/VnInput.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from "composables/useNotify";
|
import useNotify from 'composables/useNotify';
|
||||||
|
|
||||||
const MESSAGE_MAX_LENGTH = 160;
|
const MESSAGE_MAX_LENGTH = 160;
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const {notify} = useNotify();
|
const { notify } = useNotify();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -34,7 +34,7 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits([...useDialogPluginComponent.emits, 'sent']);
|
const emit = defineEmits([...useDialogPluginComponent.emits, 'sent']);
|
||||||
const {dialogRef, onDialogHide} = useDialogPluginComponent();
|
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||||
|
|
||||||
const smsRules = [
|
const smsRules = [
|
||||||
(val) => (val && val.length > 0) || t("The message can't be empty"),
|
(val) => (val && val.length > 0) || t("The message can't be empty"),
|
||||||
|
@ -43,10 +43,10 @@ const smsRules = [
|
||||||
t("The message it's too long"),
|
t("The message it's too long"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const message = ref('');
|
const message = ref(t('routeDelay'));
|
||||||
|
|
||||||
const charactersRemaining = computed(
|
const charactersRemaining = computed(
|
||||||
() => MESSAGE_MAX_LENGTH - new Blob([message.value]).size
|
() => MESSAGE_MAX_LENGTH - new Blob([message.value]).size,
|
||||||
);
|
);
|
||||||
|
|
||||||
const charactersChipColor = computed(() => {
|
const charactersChipColor = computed(() => {
|
||||||
|
@ -114,7 +114,7 @@ const onSubmit = async () => {
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{
|
{{
|
||||||
t(
|
t(
|
||||||
'Special characters like accents counts as a multiple'
|
'Special characters like accents counts as a multiple',
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
|
@ -144,7 +144,10 @@ const onSubmit = async () => {
|
||||||
max-width: 450px;
|
max-width: 450px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
en:
|
||||||
|
routeDelay: "Your order has been delayed in transit.\nDelivery will take place throughout the day.\nWe apologize for the inconvenience and appreciate your patience."
|
||||||
es:
|
es:
|
||||||
Message: Mensaje
|
Message: Mensaje
|
||||||
Send: Enviar
|
Send: Enviar
|
||||||
|
@ -153,4 +156,5 @@ es:
|
||||||
The destination can't be empty: El destinatario no puede estar vacio
|
The destination can't be empty: El destinatario no puede estar vacio
|
||||||
The message can't be empty: El mensaje no puede estar vacio
|
The message can't be empty: El mensaje no puede estar vacio
|
||||||
The message it's too long: El mensaje es demasiado largo
|
The message it's too long: El mensaje es demasiado largo
|
||||||
</i18n>
|
routeDelay: "Retraso en ruta.\nInformamos que la ruta que lleva su pedido ha sufrido un retraso y la entrega se hará a lo largo del día.\nDisculpe las molestias."
|
||||||
|
</i18n>
|
||||||
|
|
|
@ -35,6 +35,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
hasFile: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const warehouses = ref();
|
const warehouses = ref();
|
||||||
|
@ -90,6 +94,7 @@ function defaultData() {
|
||||||
if ($props.formInitialData) return (dms.value = $props.formInitialData);
|
if ($props.formInitialData) return (dms.value = $props.formInitialData);
|
||||||
return addDefaultData({
|
return addDefaultData({
|
||||||
reference: route.params.id,
|
reference: route.params.id,
|
||||||
|
hasFile: $props.hasFile,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import VnSelect from './VnSelect.vue';
|
||||||
|
|
||||||
|
const stateBtnDropdownRef = ref();
|
||||||
|
|
||||||
|
const emit = defineEmits(['changeState']);
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
optionLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'name',
|
||||||
|
},
|
||||||
|
optionValue: {
|
||||||
|
type: String,
|
||||||
|
default: 'id',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
async function changeState(value) {
|
||||||
|
stateBtnDropdownRef.value?.hide();
|
||||||
|
emit('changeState', value);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QBtnDropdown
|
||||||
|
ref="stateBtnDropdownRef"
|
||||||
|
color="black"
|
||||||
|
text-color="white"
|
||||||
|
:label="$t('globals.changeState')"
|
||||||
|
:disable="$props.disable"
|
||||||
|
>
|
||||||
|
<VnSelect
|
||||||
|
:options="$props.options"
|
||||||
|
:option-label="$props.optionLabel"
|
||||||
|
:option-value="$props.optionValue"
|
||||||
|
hide-selected
|
||||||
|
hide-dropdown-icon
|
||||||
|
focus-on-mount
|
||||||
|
@update:model-value="changeState"
|
||||||
|
>
|
||||||
|
</VnSelect>
|
||||||
|
</QBtnDropdown>
|
||||||
|
</template>
|
|
@ -561,9 +561,7 @@ watch(
|
||||||
}}:
|
}}:
|
||||||
</span>
|
</span>
|
||||||
<VnLogValue
|
<VnLogValue
|
||||||
:value="
|
:value="value.val"
|
||||||
value.val.val
|
|
||||||
"
|
|
||||||
:name="value.name"
|
:name="value.name"
|
||||||
/>
|
/>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -616,7 +614,7 @@ watch(
|
||||||
{{ prop.nameI18n }}:
|
{{ prop.nameI18n }}:
|
||||||
</span>
|
</span>
|
||||||
<VnLogValue
|
<VnLogValue
|
||||||
:value="prop.val.val"
|
:value="prop.val"
|
||||||
:name="prop.name"
|
:name="prop.name"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
@ -647,7 +645,7 @@ watch(
|
||||||
</span>
|
</span>
|
||||||
<span v-if="log.action == 'update'">
|
<span v-if="log.action == 'update'">
|
||||||
<VnLogValue
|
<VnLogValue
|
||||||
:value="prop.old.val"
|
:value="prop.old"
|
||||||
:name="prop.name"
|
:name="prop.name"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
@ -658,7 +656,7 @@ watch(
|
||||||
</span>
|
</span>
|
||||||
→
|
→
|
||||||
<VnLogValue
|
<VnLogValue
|
||||||
:value="prop.val.val"
|
:value="prop.val"
|
||||||
:name="prop.name"
|
:name="prop.name"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
@ -670,7 +668,7 @@ watch(
|
||||||
</span>
|
</span>
|
||||||
<span v-else="prop.old.val">
|
<span v-else="prop.old.val">
|
||||||
<VnLogValue
|
<VnLogValue
|
||||||
:value="prop.val.val"
|
:value="prop.val"
|
||||||
:name="prop.name"
|
:name="prop.name"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -5,18 +5,24 @@ import { computed } from 'vue';
|
||||||
const descriptorStore = useDescriptorStore();
|
const descriptorStore = useDescriptorStore();
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
name: { type: [String], default: undefined },
|
value: { type: Object, default: () => {} },
|
||||||
|
name: { type: String, default: undefined },
|
||||||
});
|
});
|
||||||
|
|
||||||
const descriptor = computed(() => descriptorStore.has($props.name));
|
const descriptor = computed(() => descriptorStore.has($props.name));
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnJsonValue v-bind="$attrs" />
|
<VnJsonValue :value="value.val" />
|
||||||
<QIcon
|
<span
|
||||||
name="launch"
|
v-if="(value.id || typeof value.val == 'number') && descriptor"
|
||||||
class="link"
|
style="margin-left: 2px"
|
||||||
v-if="$attrs.value && descriptor"
|
>
|
||||||
:data-cy="'iconLaunch-' + $props.name"
|
<QIcon
|
||||||
/>
|
name="launch"
|
||||||
<component :is="descriptor" :id="$attrs.value" v-if="$attrs.value && descriptor" />
|
class="link"
|
||||||
|
:data-cy="'iconLaunch-' + $props.name"
|
||||||
|
style="padding-bottom: 2px"
|
||||||
|
/>
|
||||||
|
<component :is="descriptor" :id="value.id ?? value.val" />
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -842,6 +842,7 @@ travel:
|
||||||
availabledHour: Availabled hour
|
availabledHour: Availabled hour
|
||||||
thermographs: Thermographs
|
thermographs: Thermographs
|
||||||
hb: HB
|
hb: HB
|
||||||
|
roundedCc: Rounded CC
|
||||||
basicData:
|
basicData:
|
||||||
daysInForward: Automatic movement (Raid)
|
daysInForward: Automatic movement (Raid)
|
||||||
isRaid: Raid
|
isRaid: Raid
|
||||||
|
@ -884,7 +885,7 @@ components:
|
||||||
openCard: View
|
openCard: View
|
||||||
openSummary: Summary
|
openSummary: Summary
|
||||||
viewSummary: Summary
|
viewSummary: Summary
|
||||||
cardDescriptor:
|
vnDescriptor:
|
||||||
mainList: Main list
|
mainList: Main list
|
||||||
summary: Summary
|
summary: Summary
|
||||||
moreOptions: More options
|
moreOptions: More options
|
||||||
|
|
|
@ -925,6 +925,7 @@ travel:
|
||||||
availabled: F. Disponible
|
availabled: F. Disponible
|
||||||
availabledHour: Hora Disponible
|
availabledHour: Hora Disponible
|
||||||
hb: HB
|
hb: HB
|
||||||
|
roundedCc: CC redondeado
|
||||||
basicData:
|
basicData:
|
||||||
daysInForward: Desplazamiento automatico (redada)
|
daysInForward: Desplazamiento automatico (redada)
|
||||||
isRaid: Redada
|
isRaid: Redada
|
||||||
|
@ -968,7 +969,7 @@ components:
|
||||||
openCard: Ficha
|
openCard: Ficha
|
||||||
openSummary: Detalles
|
openSummary: Detalles
|
||||||
viewSummary: Vista previa
|
viewSummary: Vista previa
|
||||||
cardDescriptor:
|
vnDescriptor:
|
||||||
mainList: Listado principal
|
mainList: Listado principal
|
||||||
summary: Resumen
|
summary: Resumen
|
||||||
moreOptions: Más opciones
|
moreOptions: Más opciones
|
||||||
|
|
|
@ -21,6 +21,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
|
import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
|
||||||
|
import VnDropdown from 'src/components/common/VnDropdown.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -36,7 +37,7 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
const ClaimStates = ref([]);
|
const claimStates = ref([]);
|
||||||
const claimDmsRef = ref();
|
const claimDmsRef = ref();
|
||||||
const claimDms = ref([]);
|
const claimDms = ref([]);
|
||||||
const multimediaDialog = ref();
|
const multimediaDialog = ref();
|
||||||
|
@ -173,7 +174,9 @@ function openDialog(dmsId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeState(value) {
|
async function changeState(value) {
|
||||||
await axios.patch(`Claims/updateClaim/${entityId.value}`, { claimStateFk: value });
|
await axios.patch(`Claims/updateClaim/${entityId.value}`, {
|
||||||
|
claimStateFk: value,
|
||||||
|
});
|
||||||
router.go(route.fullPath);
|
router.go(route.fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,13 +186,18 @@ function claimUrl(section) {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<FetchData
|
||||||
|
url="ClaimStates"
|
||||||
|
:filter="{ fields: ['id', 'description'] }"
|
||||||
|
@on-fetch="(data) => (claimStates = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="ClaimDms"
|
url="ClaimDms"
|
||||||
:filter="claimDmsFilter"
|
:filter="claimDmsFilter"
|
||||||
@on-fetch="(data) => setClaimDms(data)"
|
@on-fetch="(data) => setClaimDms(data)"
|
||||||
ref="claimDmsRef"
|
ref="claimDmsRef"
|
||||||
/>
|
/>
|
||||||
<FetchData url="ClaimStates" @on-fetch="(data) => (ClaimStates = data)" auto-load />
|
|
||||||
<CardSummary
|
<CardSummary
|
||||||
ref="summary"
|
ref="summary"
|
||||||
:url="`Claims/${entityId}/getSummary`"
|
:url="`Claims/${entityId}/getSummary`"
|
||||||
|
@ -201,34 +209,11 @@ function claimUrl(section) {
|
||||||
{{ claim.id }} - {{ claim.client.name }} ({{ claim.client.id }})
|
{{ claim.id }} - {{ claim.client.name }} ({{ claim.client.id }})
|
||||||
</template>
|
</template>
|
||||||
<template #header-right>
|
<template #header-right>
|
||||||
<QBtnDropdown
|
<VnDropdown
|
||||||
side
|
:options="claimStates"
|
||||||
top
|
option-label="description"
|
||||||
color="black"
|
@change-state="changeState"
|
||||||
text-color="white"
|
/>
|
||||||
:label="t('globals.changeState')"
|
|
||||||
>
|
|
||||||
<QList>
|
|
||||||
<QVirtualScroll
|
|
||||||
class="max-container-height"
|
|
||||||
:items="ClaimStates"
|
|
||||||
separator
|
|
||||||
v-slot="{ item, index }"
|
|
||||||
>
|
|
||||||
<QItem
|
|
||||||
:key="index"
|
|
||||||
dense
|
|
||||||
clickable
|
|
||||||
v-close-popup
|
|
||||||
@click="changeState(item.id)"
|
|
||||||
>
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel>{{ item.description }}</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</QVirtualScroll>
|
|
||||||
</QList>
|
|
||||||
</QBtnDropdown>
|
|
||||||
</template>
|
</template>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
<ClaimDescriptorMenu :claim="entity.claim" />
|
<ClaimDescriptorMenu :claim="entity.claim" />
|
||||||
|
|
|
@ -8,6 +8,6 @@ import filter from './EntryFilter.js';
|
||||||
data-key="Entry"
|
data-key="Entry"
|
||||||
url="Entries"
|
url="Entries"
|
||||||
:descriptor="EntryDescriptor"
|
:descriptor="EntryDescriptor"
|
||||||
:filter="filter"
|
:filter="{ ...filter, where: { id: $route.params.id } }"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -249,7 +249,6 @@ function getBadgeAttrs(row) {
|
||||||
let timeDiff = today - timeTicket;
|
let timeDiff = today - timeTicket;
|
||||||
|
|
||||||
if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
|
if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
|
||||||
if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
|
|
||||||
switch (row.entryTypeCode) {
|
switch (row.entryTypeCode) {
|
||||||
case 'regularization':
|
case 'regularization':
|
||||||
case 'life':
|
case 'life':
|
||||||
|
@ -274,6 +273,7 @@ function getBadgeAttrs(row) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
|
||||||
return { color: 'transparent' };
|
return { color: 'transparent' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ const invoiceInFormRef = ref();
|
||||||
const invoiceId = +route.params.id;
|
const invoiceId = +route.params.id;
|
||||||
const filter = { where: { invoiceInFk: invoiceId } };
|
const filter = { where: { invoiceInFk: invoiceId } };
|
||||||
const areRows = ref(false);
|
const areRows = ref(false);
|
||||||
const totals = ref();
|
const totalTaxableBase = ref();
|
||||||
|
const noMatch = computed(() => totalAmount.value != totalTaxableBase.value);
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'duedate',
|
name: 'duedate',
|
||||||
|
@ -74,9 +75,12 @@ async function insert() {
|
||||||
notify(t('globals.dataSaved'), 'positive');
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
async function setTaxableBase() {
|
||||||
totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data;
|
const { data } = await axios.get(`InvoiceIns/${invoiceId}/getTotals`);
|
||||||
});
|
totalTaxableBase.value = data.totalTaxableBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount(async () => await setTaxableBase());
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<CrudModel
|
<CrudModel
|
||||||
|
@ -89,13 +93,14 @@ onBeforeMount(async () => {
|
||||||
:data-required="{ invoiceInFk: invoiceId }"
|
:data-required="{ invoiceInFk: invoiceId }"
|
||||||
v-model:selected="rowsSelected"
|
v-model:selected="rowsSelected"
|
||||||
@on-fetch="(data) => (areRows = !!data.length)"
|
@on-fetch="(data) => (areRows = !!data.length)"
|
||||||
|
@save-changes="setTaxableBase"
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<QTable
|
<QTable
|
||||||
v-model:selected="rowsSelected"
|
v-model:selected="rowsSelected"
|
||||||
selection="multiple"
|
selection="multiple"
|
||||||
:columns="columns"
|
:columns
|
||||||
:rows="rows"
|
:rows
|
||||||
row-key="$index"
|
row-key="$index"
|
||||||
:grid="$q.screen.lt.sm"
|
:grid="$q.screen.lt.sm"
|
||||||
>
|
>
|
||||||
|
@ -151,7 +156,18 @@ onBeforeMount(async () => {
|
||||||
<QTd />
|
<QTd />
|
||||||
<QTd />
|
<QTd />
|
||||||
<QTd>
|
<QTd>
|
||||||
{{ toCurrency(totalAmount) }}
|
<QChip
|
||||||
|
dense
|
||||||
|
:color="noMatch ? 'negative' : 'transparent'"
|
||||||
|
class="q-pa-xs"
|
||||||
|
:title="
|
||||||
|
noMatch
|
||||||
|
? t('invoiceIn.noMatch', { totalTaxableBase })
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ toCurrency(totalAmount) }}
|
||||||
|
</QChip>
|
||||||
</QTd>
|
</QTd>
|
||||||
<QTd>
|
<QTd>
|
||||||
<template v-if="isNotEuro(invoiceIn.currency.code)">
|
<template v-if="isNotEuro(invoiceIn.currency.code)">
|
||||||
|
@ -237,7 +253,7 @@ onBeforeMount(async () => {
|
||||||
if (!areRows) insert();
|
if (!areRows) insert();
|
||||||
else
|
else
|
||||||
invoiceInFormRef.insert({
|
invoiceInFormRef.insert({
|
||||||
amount: (totals.totalTaxableBase - totalAmount).toFixed(2),
|
amount: (totalTaxableBase - totalAmount).toFixed(2),
|
||||||
invoiceInFk: invoiceId,
|
invoiceInFk: invoiceId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -249,6 +265,10 @@ onBeforeMount(async () => {
|
||||||
.bg {
|
.bg {
|
||||||
background-color: var(--vn-light-gray);
|
background-color: var(--vn-light-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.q-chip {
|
||||||
|
color: var(--vn-text-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
|
@ -304,7 +304,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
||||||
:color="amountsNotMatch ? 'negative' : 'transparent'"
|
:color="amountsNotMatch ? 'negative' : 'transparent'"
|
||||||
:title="
|
:title="
|
||||||
amountsNotMatch
|
amountsNotMatch
|
||||||
? t('invoiceIn.summary.noMatch')
|
? t('invoiceIn.noMatch', {
|
||||||
|
totalTaxableBase:
|
||||||
|
entity.totals.totalTaxableBase,
|
||||||
|
})
|
||||||
: t('invoiceIn.summary.dueTotal')
|
: t('invoiceIn.summary.dueTotal')
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
|
@ -156,7 +156,7 @@ const cols = computed(() => [
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'InvoiceIns',
|
urlCreate: 'InvoiceIns',
|
||||||
title: t('globals.createInvoiceIn'),
|
title: t('globals.createInvoiceIn'),
|
||||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
onDataSaved: ({ id }) => tableRef.redirect(`${id}/basic-data`),
|
||||||
formInitialData: { companyFk: user.companyFk, issued: Date.vnNew() },
|
formInitialData: { companyFk: user.companyFk, issued: Date.vnNew() },
|
||||||
}"
|
}"
|
||||||
redirect="invoice-in"
|
redirect="invoice-in"
|
||||||
|
|
|
@ -56,8 +56,9 @@ async function checkToBook(id) {
|
||||||
componentProps: {
|
componentProps: {
|
||||||
title: t('Are you sure you want to book this invoice?'),
|
title: t('Are you sure you want to book this invoice?'),
|
||||||
message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
|
message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
|
||||||
|
promise: () => toBook(id),
|
||||||
},
|
},
|
||||||
}).onOk(() => toBook(id));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toBook(id) {
|
async function toBook(id) {
|
||||||
|
|
|
@ -58,7 +58,6 @@ invoiceIn:
|
||||||
bank: Bank
|
bank: Bank
|
||||||
foreignValue: Foreign value
|
foreignValue: Foreign value
|
||||||
dueTotal: Due day
|
dueTotal: Due day
|
||||||
noMatch: Do not match
|
|
||||||
code: Code
|
code: Code
|
||||||
net: Net
|
net: Net
|
||||||
stems: Stems
|
stems: Stems
|
||||||
|
@ -69,3 +68,4 @@ invoiceIn:
|
||||||
isBooked: Is booked
|
isBooked: Is booked
|
||||||
account: Ledger account
|
account: Ledger account
|
||||||
correctingFk: Rectificative
|
correctingFk: Rectificative
|
||||||
|
noMatch: No match with the vat({totalTaxableBase})
|
||||||
|
|
|
@ -67,3 +67,4 @@ invoiceIn:
|
||||||
isBooked: Contabilizada
|
isBooked: Contabilizada
|
||||||
account: Cuenta contable
|
account: Cuenta contable
|
||||||
correctingFk: Rectificativa
|
correctingFk: Rectificativa
|
||||||
|
noMatch: No cuadra con el iva({totalTaxableBase})
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script setup>
|
||||||
|
import ParkingDescriptor from './ParkingDescriptor.vue';
|
||||||
|
import ParkingSummary from './ParkingSummary.vue';
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<QPopupProxy style="max-width: 10px">
|
||||||
|
<ParkingDescriptor
|
||||||
|
v-if="$attrs.id"
|
||||||
|
v-bind="$attrs.id"
|
||||||
|
:summary="ParkingSummary"
|
||||||
|
:proxy-render="true"
|
||||||
|
/>
|
||||||
|
</QPopupProxy>
|
||||||
|
</template>
|
|
@ -21,6 +21,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
||||||
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
||||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
import VnDropdown from 'src/components/common/VnDropdown.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
@ -40,7 +41,7 @@ const ticket = computed(() => summary.value?.entity);
|
||||||
const editableStates = ref([]);
|
const editableStates = ref([]);
|
||||||
const ticketUrl = ref();
|
const ticketUrl = ref();
|
||||||
const grafanaUrl = 'https://grafana.verdnatura.es';
|
const grafanaUrl = 'https://grafana.verdnatura.es';
|
||||||
const stateBtnDropdownRef = ref();
|
|
||||||
const descriptorData = useArrayData('Ticket');
|
const descriptorData = useArrayData('Ticket');
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
@ -67,7 +68,6 @@ function isEditable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeState(value) {
|
async function changeState(value) {
|
||||||
stateBtnDropdownRef.value?.hide();
|
|
||||||
const formData = {
|
const formData = {
|
||||||
ticketFk: entityId.value,
|
ticketFk: entityId.value,
|
||||||
code: value,
|
code: value,
|
||||||
|
@ -113,25 +113,12 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #header-right>
|
<template #header-right>
|
||||||
<div>
|
<VnDropdown
|
||||||
<QBtnDropdown
|
:disable="!isEditable()"
|
||||||
ref="stateBtnDropdownRef"
|
:options="editableStates"
|
||||||
color="black"
|
option-value="code"
|
||||||
text-color="white"
|
@change-state="changeState"
|
||||||
:label="t('globals.changeState')"
|
/>
|
||||||
:disable="!isEditable()"
|
|
||||||
>
|
|
||||||
<VnSelect
|
|
||||||
:options="editableStates"
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="code"
|
|
||||||
hide-dropdown-icon
|
|
||||||
focus-on-mount
|
|
||||||
@update:model-value="changeState"
|
|
||||||
/>
|
|
||||||
</QBtnDropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
<TicketDescriptorMenu :ticket="entity" />
|
<TicketDescriptorMenu :ticket="entity" />
|
||||||
|
|
|
@ -89,6 +89,13 @@ const entriesTableColumns = computed(() => {
|
||||||
showValue: true,
|
showValue: true,
|
||||||
},
|
},
|
||||||
{ label: 'CC', field: 'cc', name: 'cc', align: 'left', showValue: true },
|
{ label: 'CC', field: 'cc', name: 'cc', align: 'left', showValue: true },
|
||||||
|
{
|
||||||
|
label: t('travel.summary.roundedCc'),
|
||||||
|
field: 'cc',
|
||||||
|
name: 'roundedCc',
|
||||||
|
align: 'left',
|
||||||
|
showValue: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Pallet',
|
label: 'Pallet',
|
||||||
field: 'pallet',
|
field: 'pallet',
|
||||||
|
@ -191,14 +198,15 @@ const entriesTotals = computed(() => {
|
||||||
freightValue: 0,
|
freightValue: 0,
|
||||||
packageValue: 0,
|
packageValue: 0,
|
||||||
cc: 0,
|
cc: 0,
|
||||||
|
roundedCc: 0,
|
||||||
pallet: 0,
|
pallet: 0,
|
||||||
m3: 0,
|
m3: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
entriesTableRows.value.forEach((row) => {
|
entriesTableRows.value.forEach((row) => {
|
||||||
for (const key in totals) {
|
for (const key in totals) {
|
||||||
if (key === 'cc') {
|
if (key === 'roundedCc') {
|
||||||
totals[key] += Math.ceil(row[key] || 0);
|
totals['roundedCc'] += Math.ceil(row['cc'] || 0);
|
||||||
} else {
|
} else {
|
||||||
totals[key] += row[key] || 0;
|
totals[key] += row[key] || 0;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +218,7 @@ const entriesTotals = computed(() => {
|
||||||
freight: toCurrency(totals.freightValue),
|
freight: toCurrency(totals.freightValue),
|
||||||
packageValue: toCurrency(totals.packageValue),
|
packageValue: toCurrency(totals.packageValue),
|
||||||
cc: totals.cc.toFixed(2),
|
cc: totals.cc.toFixed(2),
|
||||||
|
roundedCc: totals.roundedCc,
|
||||||
pallet: totals.pallet.toFixed(2),
|
pallet: totals.pallet.toFixed(2),
|
||||||
m3: totals.m3.toFixed(2),
|
m3: totals.m3.toFixed(2),
|
||||||
};
|
};
|
||||||
|
@ -374,6 +383,11 @@ onMounted(async () => {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #body-cell-roundedCc="{ col, value }">
|
||||||
|
<QTd>
|
||||||
|
{{ Math.ceil(value) || 0 }}
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
<template #body-cell-observation="{ value }">
|
<template #body-cell-observation="{ value }">
|
||||||
<QTd>
|
<QTd>
|
||||||
<QIcon name="insert_drive_file" color="primary" size="24px">
|
<QIcon name="insert_drive_file" color="primary" size="24px">
|
||||||
|
@ -390,6 +404,7 @@ onMounted(async () => {
|
||||||
<QTd class="text-bold">{{ entriesTotals.freight }}</QTd>
|
<QTd class="text-bold">{{ entriesTotals.freight }}</QTd>
|
||||||
<QTd class="text-bold">{{ entriesTotals.packageValue }}</QTd>
|
<QTd class="text-bold">{{ entriesTotals.packageValue }}</QTd>
|
||||||
<QTd class="text-bold">{{ entriesTotals.cc }}</QTd>
|
<QTd class="text-bold">{{ entriesTotals.cc }}</QTd>
|
||||||
|
<QTd class="text-bold">{{ entriesTotals.roundedCc }}</QTd>
|
||||||
<QTd class="text-bold">{{ entriesTotals.pallet }}</QTd>
|
<QTd class="text-bold">{{ entriesTotals.pallet }}</QTd>
|
||||||
<QTd class="text-bold">{{ entriesTotals.m3 }}</QTd>
|
<QTd class="text-bold">{{ entriesTotals.m3 }}</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const useDescriptorStore = defineStore('descriptorStore', () => {
|
||||||
const files = import.meta.glob(`/src/**/*DescriptorProxy.vue`);
|
const files = import.meta.glob(`/src/**/*DescriptorProxy.vue`);
|
||||||
const moduleParser = {
|
const moduleParser = {
|
||||||
account: 'user',
|
account: 'user',
|
||||||
client: 'customer',
|
customer: 'client',
|
||||||
};
|
};
|
||||||
for (const file in files) {
|
for (const file in files) {
|
||||||
const name = file.split('/').at(-1).slice(0, -19).toLowerCase();
|
const name = file.split('/').at(-1).slice(0, -19).toLowerCase();
|
||||||
|
|
|
@ -41,12 +41,12 @@ describe('InvoiceInList', () => {
|
||||||
cy.fillInForm({ ...mock }, { attr: 'data-cy' });
|
cy.fillInForm({ ...mock }, { attr: 'data-cy' });
|
||||||
cy.dataCy('FormModelPopup_save').click();
|
cy.dataCy('FormModelPopup_save').click();
|
||||||
cy.intercept('GET', /\/api\/InvoiceIns\/\d+\/getTotals$/).as('invoice');
|
cy.intercept('GET', /\/api\/InvoiceIns\/\d+\/getTotals$/).as('invoice');
|
||||||
cy.wait('@invoice').then(() =>
|
cy.wait('@invoice').then(() => {
|
||||||
cy.validateDescriptor({
|
cy.validateDescriptor({
|
||||||
title: mockInvoiceRef,
|
title: mockInvoiceRef,
|
||||||
listBox: { 0: '11/16/2001', 3: 'The farmer' },
|
listBox: { 0: '11/16/2001', 3: 'The farmer' },
|
||||||
}),
|
});
|
||||||
);
|
cy.dataCy('invoiceInBasicDataCompanyFk').should('have.value', 'ORN');
|
||||||
cy.get('[data-cy="vnLvCompany"]').should('contain.text', 'ORN');
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue