Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 8316-parkingCardWithVnCardBeta
This commit is contained in:
commit
fd589ff798
|
@ -44,7 +44,7 @@ const onDataSaved = (data) => {
|
||||||
<FormModelPopup
|
<FormModelPopup
|
||||||
url-create="Items/regularize"
|
url-create="Items/regularize"
|
||||||
model="Items"
|
model="Items"
|
||||||
:title="t('Regularize stock')"
|
:title="t('item.regularizeStock')"
|
||||||
:form-initial-data="regularizeFormData"
|
:form-initial-data="regularizeFormData"
|
||||||
@on-data-saved="onDataSaved($event)"
|
@on-data-saved="onDataSaved($event)"
|
||||||
>
|
>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useArrayData } from 'composables/useArrayData';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import VnMoreOptions from './VnMoreOptions.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
|
@ -47,7 +48,6 @@ let store;
|
||||||
let entity;
|
let entity;
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
|
const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
|
||||||
const menuRef = ref();
|
|
||||||
defineExpose({ getData });
|
defineExpose({ getData });
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
@ -159,25 +159,11 @@ const toModule = computed(() =>
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<QBtn
|
<VnMoreOptions v-if="$slots.menu">
|
||||||
v-if="$slots.menu"
|
<template #menu="{ menuRef }">
|
||||||
color="white"
|
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
||||||
dense
|
</template>
|
||||||
flat
|
</VnMoreOptions>
|
||||||
icon="more_vert"
|
|
||||||
round
|
|
||||||
size="md"
|
|
||||||
data-cy="descriptor-more-opts"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
|
||||||
</QTooltip>
|
|
||||||
<QMenu :ref="menuRef">
|
|
||||||
<QList>
|
|
||||||
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
|
||||||
</QList>
|
|
||||||
</QMenu>
|
|
||||||
</QBtn>
|
|
||||||
</div>
|
</div>
|
||||||
<slot name="before" />
|
<slot name="before" />
|
||||||
<div class="body q-py-sm">
|
<div class="body q-py-sm">
|
||||||
|
@ -222,8 +208,8 @@ const toModule = computed(() =>
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss">
|
||||||
:deep(.body) {
|
.body {
|
||||||
background-color: var(--vn-section-color);
|
background-color: var(--vn-section-color);
|
||||||
.text-h5 {
|
.text-h5 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
@ -262,7 +248,9 @@ const toModule = computed(() =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
.title {
|
.title {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch, onBeforeMount, onMounted } from 'vue';
|
import { ref, computed, watch, onBeforeMount } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
|
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
|
||||||
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { isDialogOpened } from 'src/filters';
|
import { isDialogOpened } from 'src/filters';
|
||||||
import { useStateStore } from 'src/stores/useStateStore';
|
import VnMoreOptions from './VnMoreOptions.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
|
@ -40,7 +41,6 @@ const { store } = arrayData;
|
||||||
const entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
|
const entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
entity,
|
entity,
|
||||||
fetch,
|
fetch,
|
||||||
|
@ -52,9 +52,6 @@ onBeforeMount(async () => {
|
||||||
watch(props, async () => await fetch());
|
watch(props, async () => await fetch());
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
stateStore.rightDrawerChangeValue(false);
|
|
||||||
});
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
store.url = props.url;
|
store.url = props.url;
|
||||||
store.filter = props.filter ?? {};
|
store.filter = props.filter ?? {};
|
||||||
|
@ -64,6 +61,7 @@ async function fetch() {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="summary container">
|
<div class="summary container">
|
||||||
<QCard class="cardSummary">
|
<QCard class="cardSummary">
|
||||||
|
@ -84,11 +82,16 @@ async function fetch() {
|
||||||
<span v-else></span>
|
<span v-else></span>
|
||||||
</slot>
|
</slot>
|
||||||
<slot name="header" :entity="entity" dense>
|
<slot name="header" :entity="entity" dense>
|
||||||
{{ entity.id + ' - ' + entity.name }}
|
<VnLv :label="`${entity.id} -`" :value="entity.name" />
|
||||||
</slot>
|
|
||||||
<slot name="header-right" :entity="entity">
|
|
||||||
<span></span>
|
|
||||||
</slot>
|
</slot>
|
||||||
|
<span class="row no-wrap">
|
||||||
|
<slot name="header-right" :entity="entity" />
|
||||||
|
<VnMoreOptions v-if="$slots.menu && isDialogOpened()">
|
||||||
|
<template #menu="{ menuRef }">
|
||||||
|
<slot name="menu" :entity="entity" :menu-ref="menuRef" />
|
||||||
|
</template>
|
||||||
|
</VnMoreOptions>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="summaryBody row q-mb-md">
|
<div class="summaryBody row q-mb-md">
|
||||||
<slot name="body" :entity="entity" />
|
<slot name="body" :entity="entity" />
|
||||||
|
@ -97,6 +100,7 @@ async function fetch() {
|
||||||
</QCard>
|
</QCard>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.summary.container {
|
.summary.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<QBtn
|
||||||
|
color="white"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
icon="more_vert"
|
||||||
|
round
|
||||||
|
size="md"
|
||||||
|
data-cy="descriptor-more-opts"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ $t('components.cardDescriptor.moreOptions') }}
|
||||||
|
</QTooltip>
|
||||||
|
<QMenu ref="menuRef">
|
||||||
|
<QList>
|
||||||
|
<slot name="menu" :menu-ref="$refs.menuRef" />
|
||||||
|
</QList>
|
||||||
|
</QMenu>
|
||||||
|
</QBtn>
|
||||||
|
</template>
|
|
@ -0,0 +1,6 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default async (id) => {
|
||||||
|
const { data } = await axios.get(`Accounts/${id}/exists`);
|
||||||
|
return data.exists;
|
||||||
|
};
|
|
@ -1,13 +1,13 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import useCardDescription from 'src/composables/useCardDescription';
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
|
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
|
||||||
import VnImg from 'src/components/ui/VnImg.vue';
|
import VnImg from 'src/components/ui/VnImg.vue';
|
||||||
|
import useHasAccount from 'src/composables/useHasAccount.js';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -23,6 +23,7 @@ const entityId = computed(() => {
|
||||||
return $props.id || route.params.id;
|
return $props.id || route.params.id;
|
||||||
});
|
});
|
||||||
const data = ref(useCardDescription());
|
const data = ref(useCardDescription());
|
||||||
|
const hasAccount = ref();
|
||||||
const setData = (entity) => (data.value = useCardDescription(entity.nickname, entity.id));
|
const setData = (entity) => (data.value = useCardDescription(entity.nickname, entity.id));
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
|
@ -30,18 +31,16 @@ const filter = {
|
||||||
fields: ['id', 'nickname', 'name', 'role'],
|
fields: ['id', 'nickname', 'name', 'role'],
|
||||||
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
|
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
|
||||||
};
|
};
|
||||||
const hasAccount = ref(false);
|
|
||||||
|
onMounted(async () => {
|
||||||
|
hasAccount.value = await useHasAccount(entityId.value);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
:url="`Accounts/${entityId}/exists`"
|
|
||||||
auto-load
|
|
||||||
@on-fetch="(data) => (hasAccount = data.exists)"
|
|
||||||
/>
|
|
||||||
<CardDescriptor
|
<CardDescriptor
|
||||||
ref="descriptor"
|
ref="descriptor"
|
||||||
url="VnUsers/preview"
|
:url="`VnUsers/preview`"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
module="Account"
|
module="Account"
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
|
@ -50,7 +49,7 @@ const hasAccount = ref(false);
|
||||||
:subtitle="data.subtitle"
|
:subtitle="data.subtitle"
|
||||||
>
|
>
|
||||||
<template #menu>
|
<template #menu>
|
||||||
<AccountDescriptorMenu :has-account="hasAccount" />
|
<AccountDescriptorMenu :entity-id="entityId" />
|
||||||
</template>
|
</template>
|
||||||
<template #before>
|
<template #before>
|
||||||
<VnImg :id="entityId" collection="user" resolution="520x520" class="photo">
|
<VnImg :id="entityId" collection="user" resolution="520x520" class="photo">
|
||||||
|
@ -74,7 +73,7 @@ const hasAccount = ref(false);
|
||||||
<VnLv :label="t('account.card.nickname')" :value="entity.name" />
|
<VnLv :label="t('account.card.nickname')" :value="entity.name" />
|
||||||
<VnLv :label="t('account.card.role')" :value="entity.role.name" />
|
<VnLv :label="t('account.card.role')" :value="entity.role.name" />
|
||||||
</template>
|
</template>
|
||||||
<template #icons="{ entity }">
|
<template #actions="{ entity }">
|
||||||
<QCardActions class="q-gutter-x-md">
|
<QCardActions class="q-gutter-x-md">
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="!entity.active"
|
v-if="!entity.active"
|
||||||
|
@ -82,7 +81,7 @@ const hasAccount = ref(false);
|
||||||
name="vn:disabled"
|
name="vn:disabled"
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
size="xs"
|
size="sm"
|
||||||
class="fill-icon"
|
class="fill-icon"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('account.card.deactivated') }}</QTooltip>
|
<QTooltip>{{ t('account.card.deactivated') }}</QTooltip>
|
||||||
|
@ -93,7 +92,7 @@ const hasAccount = ref(false);
|
||||||
v-if="hasAccount"
|
v-if="hasAccount"
|
||||||
flat
|
flat
|
||||||
round
|
round
|
||||||
size="xs"
|
size="sm"
|
||||||
class="fill-icon"
|
class="fill-icon"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('account.card.enabled') }}</QTooltip>
|
<QTooltip>{{ t('account.card.enabled') }}</QTooltip>
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { computed, ref, toRefs } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import { useAcl } from 'src/composables/useAcl';
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
import VnChangePassword from 'src/components/common/VnChangePassword.vue';
|
import VnChangePassword from 'src/components/common/VnChangePassword.vue';
|
||||||
import { useQuasar } from 'quasar';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import useHasAccount from 'src/composables/useHasAccount.js';
|
||||||
import VnInputPassword from 'src/components/common/VnInputPassword.vue';
|
import VnInputPassword from 'src/components/common/VnInputPassword.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
hasAccount: {
|
entityId: {
|
||||||
type: Boolean,
|
type: Number,
|
||||||
default: false,
|
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { hasAccount } = toRefs($props);
|
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
const route = useRoute();
|
const { notify } = useNotify();
|
||||||
const { notify } = useQuasar();
|
|
||||||
const account = computed(() => useArrayData('AccountId').store.data[0]);
|
const account = computed(() => useArrayData('AccountId').store.data[0]);
|
||||||
account.value.hasAccount = hasAccount.value;
|
|
||||||
const entityId = computed(() => +route.params.id);
|
onMounted(async () => {
|
||||||
|
account.value.hasAccount = await useHasAccount($props.entityId);
|
||||||
|
});
|
||||||
|
|
||||||
async function updateStatusAccount(active) {
|
async function updateStatusAccount(active) {
|
||||||
if (active) {
|
if (active) {
|
||||||
await axios.post(`Accounts`, { id: entityId.value });
|
await axios.post(`Accounts`, { id: $props.entityId });
|
||||||
} else {
|
} else {
|
||||||
await axios.delete(`Accounts/${entityId.value}`);
|
await axios.delete(`Accounts/${$props.entityId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
account.value.hasAccount = active;
|
account.value.hasAccount = active;
|
||||||
|
@ -42,7 +42,7 @@ async function updateStatusAccount(active) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function updateStatusUser(active) {
|
async function updateStatusUser(active) {
|
||||||
await axios.patch(`VnUsers/${entityId.value}`, { active });
|
await axios.patch(`VnUsers/${$props.entityId}`, { active });
|
||||||
account.value.active = active;
|
account.value.active = active;
|
||||||
const status = active ? 'activate' : 'deactivate';
|
const status = active ? 'activate' : 'deactivate';
|
||||||
notify({
|
notify({
|
||||||
|
@ -105,6 +105,7 @@ async function sync() {
|
||||||
class="full-width"
|
class="full-width"
|
||||||
clearable
|
clearable
|
||||||
clear-icon="close"
|
clear-icon="close"
|
||||||
|
type="password"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnConfirm>
|
</VnConfirm>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import AccountMailAliasCreateForm from './AccountMailAliasCreateForm.vue';
|
||||||
import { useVnConfirm } from 'composables/useVnConfirm';
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import useHasAccount from 'src/composables/useHasAccount.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -50,16 +51,6 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const fetchAccountExistence = async () => {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`Accounts/${route.params.id}/exists`);
|
|
||||||
return data.exists;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching account existence', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteMailAlias = async (row) => {
|
const deleteMailAlias = async (row) => {
|
||||||
await axios.delete(`${urlPath}/${row.id}`);
|
await axios.delete(`${urlPath}/${row.id}`);
|
||||||
fetchMailAliases();
|
fetchMailAliases();
|
||||||
|
@ -79,7 +70,7 @@ const fetchMailAliases = async () => {
|
||||||
|
|
||||||
const getAccountData = async (reload = true) => {
|
const getAccountData = async (reload = true) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
hasAccount.value = await fetchAccountExistence();
|
hasAccount.value = await useHasAccount(route.params.id);
|
||||||
if (!hasAccount.value) {
|
if (!hasAccount.value) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
store.data = [];
|
store.data = [];
|
||||||
|
|
|
@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import useHasAccount from 'src/composables/useHasAccount';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -30,23 +31,9 @@ const hasDataChanged = computed(
|
||||||
initialData.value.hasData !== hasData.value
|
initialData.value.hasData !== hasData.value
|
||||||
);
|
);
|
||||||
|
|
||||||
const fetchAccountExistence = async () => {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`Accounts/${route.params.id}/exists`);
|
|
||||||
return data.exists;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching account existence', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchMailForwards = async () => {
|
const fetchMailForwards = async () => {
|
||||||
try {
|
const response = await axios.get(`MailForwards/${route.params.id}`);
|
||||||
const response = await axios.get(`MailForwards/${route.params.id}`);
|
return response.data;
|
||||||
return response.data;
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteMailForward = async () => {
|
const deleteMailForward = async () => {
|
||||||
|
@ -72,7 +59,7 @@ const setInitialData = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
initialData.value.account = route.params.id;
|
initialData.value.account = route.params.id;
|
||||||
formData.value.account = route.params.id;
|
formData.value.account = route.params.id;
|
||||||
hasAccount.value = await fetchAccountExistence(route.params.id);
|
hasAccount.value = await useHasAccount(route.params.id);
|
||||||
if (!hasAccount.value) {
|
if (!hasAccount.value) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
|
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -31,12 +32,14 @@ const filter = {
|
||||||
<template>
|
<template>
|
||||||
<CardSummary
|
<CardSummary
|
||||||
data-key="AccountId"
|
data-key="AccountId"
|
||||||
ref="AccountSummary"
|
|
||||||
url="VnUsers/preview"
|
url="VnUsers/preview"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="(data) => (account = data)"
|
@on-fetch="(data) => (account = data)"
|
||||||
>
|
>
|
||||||
<template #header>{{ account.id }} - {{ account.nickname }}</template>
|
<template #header>{{ account.id }} - {{ account.nickname }}</template>
|
||||||
|
<template #menu="">
|
||||||
|
<AccountDescriptorMenu :entity-id="entityId" />
|
||||||
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<QCardSection class="q-pa-none">
|
<QCardSection class="q-pa-none">
|
||||||
|
|
|
@ -19,6 +19,7 @@ import ClaimNotes from 'src/pages/Claim/Card/ClaimNotes.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
|
import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -228,6 +229,9 @@ function claimUrl(section) {
|
||||||
</QList>
|
</QList>
|
||||||
</QBtnDropdown>
|
</QBtnDropdown>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<ClaimDescriptorMenu :claim="entity.claim" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity: { claim, salesClaimed, developments } }">
|
<template #body="{ entity: { claim, salesClaimed, developments } }">
|
||||||
<QCard class="vn-one" v-if="$route.name != 'ClaimSummary'">
|
<QCard class="vn-one" v-if="$route.name != 'ClaimSummary'">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
|
|
@ -12,6 +12,7 @@ import VnLinkMail from 'src/components/ui/VnLinkMail.vue';
|
||||||
import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue';
|
import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import VnRow from 'src/components/ui/VnRow.vue';
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
|
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const grafanaUrl = 'https://grafana.verdnatura.es';
|
const grafanaUrl = 'https://grafana.verdnatura.es';
|
||||||
|
@ -70,6 +71,9 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
data-key="CustomerSummary"
|
data-key="CustomerSummary"
|
||||||
module-name="Customer"
|
module-name="Customer"
|
||||||
>
|
>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<CustomerDescriptorMenu :customer="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
@ -94,14 +98,13 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
:phone-number="entity.mobile"
|
:phone-number="entity.mobile"
|
||||||
:channel="entity.country?.saySimpleCountry?.channel"
|
:channel="entity.country?.saySimpleCountry?.channel"
|
||||||
class="q-ml-xs"
|
class="q-ml-xs"
|
||||||
:country="entity.country?.code"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :value="entity.email" copy
|
<VnLv :value="entity.email" copy
|
||||||
><template #label>
|
><template #label>
|
||||||
{{ t('globals.params.email') }}
|
{{ t('globals.params.email') }}
|
||||||
<VnLinkMail :email="entity.email"></VnLinkMail> </template
|
<VnLinkMail email="entity.email"></VnLinkMail> </template
|
||||||
></VnLv>
|
></VnLv>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('customer.summary.salesPerson')"
|
:label="t('customer.summary.salesPerson')"
|
||||||
|
@ -173,7 +176,7 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
:label="t('customer.summary.notifyByEmail')"
|
:label="t('customer.summary.notifyByEmail')"
|
||||||
:value="entity.isToBeMailed"
|
:value="entity.isToBeMailed"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('globals.isVies')" :value="entity.isVies" />
|
<VnLv :label="t('customer.summary.vies')" :value="entity.isVies" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
|
|
@ -247,8 +247,14 @@ function handleLocation(data, location) {
|
||||||
:label="t('Longitude')"
|
:label="t('Longitude')"
|
||||||
clearable
|
clearable
|
||||||
v-model="data.longitude"
|
v-model="data.longitude"
|
||||||
|
:decimal-places="7"
|
||||||
|
/>
|
||||||
|
<VnInputNumber
|
||||||
|
:label="t('Latitude')"
|
||||||
|
clearable
|
||||||
|
v-model="data.latitude"
|
||||||
|
:decimal-places="7"
|
||||||
/>
|
/>
|
||||||
<VnInputNumber :label="t('Latitude')" clearable v-model="data.latitude" />
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<h4 class="q-mb-xs">{{ t('Notes') }}</h4>
|
<h4 class="q-mb-xs">{{ t('Notes') }}</h4>
|
||||||
<VnRow
|
<VnRow
|
||||||
|
|
|
@ -7,9 +7,9 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
|
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
|
||||||
import { getUrl } from 'src/composables/getUrl';
|
import { getUrl } from 'src/composables/getUrl';
|
||||||
import filter from './EntryFilter.js';
|
import filter from './EntryFilter.js';
|
||||||
|
import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -21,7 +21,6 @@ const $props = defineProps({
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openReport } = usePrintService();
|
|
||||||
const entryDescriptorRef = ref(null);
|
const entryDescriptorRef = ref(null);
|
||||||
const url = ref();
|
const url = ref();
|
||||||
|
|
||||||
|
@ -52,10 +51,6 @@ const getEntryRedirectionFilter = (entry) => {
|
||||||
to,
|
to,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const showEntryReport = () => {
|
|
||||||
openReport(`Entries/${route.params.id}/entry-order-pdf`);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -68,14 +63,12 @@ const showEntryReport = () => {
|
||||||
data-key="Entry"
|
data-key="Entry"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
<QItem v-ripple clickable @click="showEntryReport(entity)">
|
<EntryDescriptorMenu :id="entity.id" />
|
||||||
<QItemSection>{{ t('Show entry report') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
|
<VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
|
||||||
<VnLv :label="t('globals.shipped')" :value="toDate(entity.travel?.shipped)" />
|
<VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" />
|
||||||
<VnLv :label="t('globals.landed')" :value="toDate(entity.travel?.landed)" />
|
<VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('globals.warehouseOut')"
|
:label="t('globals.warehouseOut')"
|
||||||
:value="entity.travel?.warehouseOut?.name"
|
:value="entity.travel?.warehouseOut?.name"
|
||||||
|
@ -154,7 +147,6 @@ es:
|
||||||
Supplier card: Ficha del proveedor
|
Supplier card: Ficha del proveedor
|
||||||
All travels with current agency: Todos los envíos con la agencia actual
|
All travels with current agency: Todos los envíos con la agencia actual
|
||||||
All entries with current supplier: Todas las entradas con el proveedor actual
|
All entries with current supplier: Todas las entradas con el proveedor actual
|
||||||
Show entry report: Ver informe del pedido
|
|
||||||
Go to module index: Ir al índice del modulo
|
Go to module index: Ir al índice del modulo
|
||||||
Inventory entry: Es inventario
|
Inventory entry: Es inventario
|
||||||
Virtual entry: Es una redada
|
Virtual entry: Es una redada
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup>
|
||||||
|
import { usePrintService } from 'composables/usePrintService';
|
||||||
|
|
||||||
|
const { openReport } = usePrintService();
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function showEntryReport() {
|
||||||
|
openReport(`Entries/${$props.id}/entry-order-pdf`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QItem v-ripple clickable @click="showEntryReport">
|
||||||
|
<QItemSection>{{ $t('entryList.list.showEntryReport') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
|
@ -12,6 +12,7 @@ import { getUrl } from 'src/composables/getUrl';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import FetchedTags from 'src/components/ui/FetchedTags.vue';
|
import FetchedTags from 'src/components/ui/FetchedTags.vue';
|
||||||
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
||||||
|
import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
|
||||||
import VnRow from 'src/components/ui/VnRow.vue';
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
|
||||||
|
@ -172,6 +173,9 @@ const fetchEntryBuys = async () => {
|
||||||
<template #header>
|
<template #header>
|
||||||
<span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
|
<span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<EntryDescriptorMenu :id="entity.id" />
|
||||||
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
@ -207,7 +211,10 @@ const fetchEntryBuys = async () => {
|
||||||
:label="t('entry.summary.travelAgency')"
|
:label="t('entry.summary.travelAgency')"
|
||||||
:value="entry.travel.agency?.name"
|
:value="entry.travel.agency?.name"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('globals.shipped')" :value="toDate(entry.travel.shipped)" />
|
<VnLv
|
||||||
|
:label="t('globals.shipped')"
|
||||||
|
:value="toDate(entry.travel.shipped)"
|
||||||
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('globals.warehouseOut')"
|
:label="t('globals.warehouseOut')"
|
||||||
:value="entry.travel.warehouseOut?.name"
|
:value="entry.travel.warehouseOut?.name"
|
||||||
|
|
|
@ -243,7 +243,6 @@ const columns = computed(() => [
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Inventory entry: Es inventario
|
|
||||||
Virtual entry: Es una redada
|
Virtual entry: Es una redada
|
||||||
Search entries: Buscar entradas
|
Search entries: Buscar entradas
|
||||||
You can search by entry reference: Puedes buscar por referencia de la entrada
|
You can search by entry reference: Puedes buscar por referencia de la entrada
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
entryList:
|
entryList:
|
||||||
list:
|
list:
|
||||||
inventoryEntry: Inventory entry
|
inventoryEntry: Inventory entry
|
||||||
|
showEntryReport: Show entry report
|
||||||
entryFilter:
|
entryFilter:
|
||||||
filter:
|
filter:
|
||||||
search: General search
|
search: General search
|
||||||
|
|
|
@ -4,6 +4,7 @@ You can search by entry reference: Puedes buscar por referencia de la entrada
|
||||||
entryList:
|
entryList:
|
||||||
list:
|
list:
|
||||||
inventoryEntry: Es inventario
|
inventoryEntry: Es inventario
|
||||||
|
showEntryReport: Ver informe del pedido
|
||||||
entryFilter:
|
entryFilter:
|
||||||
filter:
|
filter:
|
||||||
search: Búsqueda general
|
search: Búsqueda general
|
||||||
|
|
|
@ -1,60 +1,30 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, computed, onBeforeMount, capitalize } from 'vue';
|
import { ref, reactive, computed, onBeforeMount } from 'vue';
|
||||||
import { useRouter, onBeforeRouteUpdate } from 'vue-router';
|
import { useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { toCurrency, toDate } from 'src/filters';
|
import { toCurrency, toDate } from 'src/filters';
|
||||||
import { useAcl } from 'src/composables/useAcl';
|
|
||||||
import { downloadFile } from 'src/composables/downloadFile';
|
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
|
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import { useCapitalize } from 'src/composables/useCapitalize';
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import InvoiceInToBook from '../InvoiceInToBook.vue';
|
import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({ id: { type: Number, default: null } });
|
const $props = defineProps({ id: { type: Number, default: null } });
|
||||||
|
|
||||||
const { push, currentRoute } = useRouter();
|
const { push, currentRoute } = useRouter();
|
||||||
|
|
||||||
const quasar = useQuasar();
|
|
||||||
const { hasAny } = useAcl();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openReport, sendEmail } = usePrintService();
|
|
||||||
const arrayData = useArrayData();
|
|
||||||
|
|
||||||
const invoiceIn = computed(() => arrayData.store.data);
|
|
||||||
const cardDescriptorRef = ref();
|
const cardDescriptorRef = ref();
|
||||||
const correctionDialogRef = ref();
|
const correctionDialogRef = ref();
|
||||||
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
|
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
|
||||||
const totalAmount = ref();
|
const totalAmount = ref();
|
||||||
const currentAction = ref();
|
|
||||||
const config = ref();
|
const config = ref();
|
||||||
const cplusRectificationTypes = ref([]);
|
const cplusRectificationTypes = ref([]);
|
||||||
const siiTypeInvoiceIns = ref([]);
|
const siiTypeInvoiceIns = ref([]);
|
||||||
const invoiceCorrectionTypes = ref([]);
|
const invoiceCorrectionTypes = ref([]);
|
||||||
const actions = {
|
|
||||||
unbook: {
|
|
||||||
title: t('assertAction', { action: t('unbook') }),
|
|
||||||
action: toUnbook,
|
|
||||||
},
|
|
||||||
delete: {
|
|
||||||
title: t('assertAction', { action: t('delete') }),
|
|
||||||
action: deleteInvoice,
|
|
||||||
},
|
|
||||||
clone: {
|
|
||||||
title: t('assertAction', { action: t('clone') }),
|
|
||||||
action: cloneInvoice,
|
|
||||||
},
|
|
||||||
showPdf: { cb: showPdfInvoice },
|
|
||||||
sendPdf: { cb: sendPdfInvoiceConfirmation },
|
|
||||||
correct: { cb: () => correctionDialogRef.value.show() },
|
|
||||||
};
|
|
||||||
const filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -90,7 +60,7 @@ const routes = reactive({
|
||||||
return {
|
return {
|
||||||
name: 'InvoiceInList',
|
name: 'InvoiceInList',
|
||||||
query: {
|
query: {
|
||||||
table: JSON.stringify({ supplierFk: id }),
|
params: JSON.stringify({ supplierFk: id }),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -99,7 +69,7 @@ const routes = reactive({
|
||||||
return {
|
return {
|
||||||
name: 'InvoiceInList',
|
name: 'InvoiceInList',
|
||||||
query: {
|
query: {
|
||||||
table: JSON.stringify({ correctedFk: entityId.value }),
|
params: JSON.stringify({ correctedFk: entityId.value }),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -118,21 +88,21 @@ const routes = reactive({
|
||||||
const correctionFormData = reactive({
|
const correctionFormData = reactive({
|
||||||
invoiceReason: 2,
|
invoiceReason: 2,
|
||||||
invoiceType: 2,
|
invoiceType: 2,
|
||||||
invoiceClass: 8,
|
invoiceClass: 6,
|
||||||
});
|
});
|
||||||
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
|
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await setInvoiceCorrection(entityId.value);
|
await setInvoiceCorrection(entityId.value);
|
||||||
const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
|
const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
|
||||||
totalAmount.value = data.totalTaxableBase;
|
totalAmount.value = data.totalDueDay;
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
if (to.params.id !== from.params.id) {
|
if (to.params.id !== from.params.id) {
|
||||||
await setInvoiceCorrection(to.params.id);
|
await setInvoiceCorrection(to.params.id);
|
||||||
const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`);
|
const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`);
|
||||||
totalAmount.value = data.totalTaxableBase;
|
totalAmount.value = data.totalDueDay;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -153,94 +123,6 @@ async function setInvoiceCorrection(id) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDialog() {
|
|
||||||
quasar.dialog({
|
|
||||||
component: VnConfirm,
|
|
||||||
componentProps: {
|
|
||||||
title: t(currentAction.value.title),
|
|
||||||
promise: currentAction.value.action,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function toUnbook() {
|
|
||||||
const { data } = await axios.post(`InvoiceIns/${entityId.value}/toUnbook`);
|
|
||||||
const { isLinked, bookEntry, accountingEntries } = data;
|
|
||||||
|
|
||||||
const type = isLinked ? 'warning' : 'positive';
|
|
||||||
const message = isLinked
|
|
||||||
? t('isLinked', { bookEntry, accountingEntries })
|
|
||||||
: t('isNotLinked', { bookEntry });
|
|
||||||
|
|
||||||
quasar.notify({ type, message });
|
|
||||||
if (!isLinked) arrayData.store.data.isBooked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteInvoice() {
|
|
||||||
await axios.delete(`InvoiceIns/${entityId.value}`);
|
|
||||||
quasar.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: t('Invoice deleted'),
|
|
||||||
});
|
|
||||||
push({ path: '/invoice-in' });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function cloneInvoice() {
|
|
||||||
const { data } = await axios.post(`InvoiceIns/${entityId.value}/clone`);
|
|
||||||
quasar.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: t('Invoice cloned'),
|
|
||||||
});
|
|
||||||
push({ path: `/invoice-in/${data.id}/summary` });
|
|
||||||
}
|
|
||||||
|
|
||||||
const canEditProp = (props) =>
|
|
||||||
hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
|
|
||||||
|
|
||||||
const isAgricultural = () => {
|
|
||||||
if (!config.value) return false;
|
|
||||||
return (
|
|
||||||
invoiceIn.value?.supplier?.sageFarmerWithholdingFk ===
|
|
||||||
config?.value[0]?.sageWithholdingFk
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function showPdfInvoice() {
|
|
||||||
if (isAgricultural())
|
|
||||||
openReport(`InvoiceIns/${entityId.value}/invoice-in-pdf`, null, '_blank');
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendPdfInvoiceConfirmation() {
|
|
||||||
quasar.dialog({
|
|
||||||
component: SendEmailDialog,
|
|
||||||
componentProps: {
|
|
||||||
data: {
|
|
||||||
address: invoiceIn.value.supplier.contacts[0].email,
|
|
||||||
},
|
|
||||||
promise: sendPdfInvoice,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendPdfInvoice({ address }) {
|
|
||||||
if (!address)
|
|
||||||
quasar.notify({
|
|
||||||
type: 'negative',
|
|
||||||
message: t(`The email can't be empty`),
|
|
||||||
});
|
|
||||||
else
|
|
||||||
return sendEmail(`InvoiceIns/${entityId.value}/invoice-in-email`, {
|
|
||||||
recipientId: invoiceIn.value.supplier.id,
|
|
||||||
recipient: address,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerMenu(type) {
|
|
||||||
currentAction.value = actions[type];
|
|
||||||
if (currentAction.value.cb) currentAction.value.cb();
|
|
||||||
else openDialog(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
const createInvoiceInCorrection = async () => {
|
const createInvoiceInCorrection = async () => {
|
||||||
const { data: correctingId } = await axios.post(
|
const { data: correctingId } = await axios.post(
|
||||||
'InvoiceIns/corrective',
|
'InvoiceIns/corrective',
|
||||||
|
@ -262,7 +144,7 @@ const createInvoiceInCorrection = async () => {
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="siiTypeInvoiceIns"
|
url="SiiTypeInvoiceIns"
|
||||||
:where="{ code: { like: 'R%' } }"
|
:where="{ code: { like: 'R%' } }"
|
||||||
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
|
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
|
||||||
auto-load
|
auto-load
|
||||||
|
@ -281,87 +163,13 @@ const createInvoiceInCorrection = async () => {
|
||||||
title="supplierRef"
|
title="supplierRef"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
<InvoiceInToBook>
|
<InvoiceInDescriptorMenu :invoice="entity" />
|
||||||
<template #content="{ book }">
|
|
||||||
<QItem
|
|
||||||
v-if="!entity?.isBooked && canEditProp('toBook')"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="book(entityId)"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('To book') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</InvoiceInToBook>
|
|
||||||
<QItem
|
|
||||||
v-if="entity?.isBooked && canEditProp('toUnbook')"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('unbook')"
|
|
||||||
>
|
|
||||||
<QItemSection>
|
|
||||||
{{ t('To unbook') }}
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="canEditProp('deleteById')"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('delete')"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('Delete invoice') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="canEditProp('clone')"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('clone')"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('Clone invoice') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="isAgricultural()"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('showPdf')"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('Show agricultural receipt as PDF') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="isAgricultural()"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('sendPdf')"
|
|
||||||
>
|
|
||||||
<QItemSection
|
|
||||||
>{{ t('Send agricultural receipt as PDF') }}...</QItemSection
|
|
||||||
>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="!invoiceInCorrection.corrected"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="triggerMenu('correct')"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('Create rectificative invoice') }}...</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="entity.dmsFk"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="downloadFile(entity.dmsFk)"
|
|
||||||
>
|
|
||||||
<QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('InvoiceIn.list.issued')" :value="toDate(entity.issued)" />
|
<VnLv :label="t('invoiceIn.list.issued')" :value="toDate(entity.issued)" />
|
||||||
<VnLv
|
<VnLv :label="t('invoiceIn.summary.booked')" :value="toDate(entity.booked)" />
|
||||||
:label="t('InvoiceIn.summary.bookedDate')"
|
<VnLv :label="t('invoiceIn.list.amount')" :value="toCurrency(totalAmount)" />
|
||||||
:value="toDate(entity.booked)"
|
<VnLv :label="t('invoiceIn.list.supplier')">
|
||||||
/>
|
|
||||||
<VnLv :label="t('InvoiceIn.list.amount')" :value="toCurrency(totalAmount)" />
|
|
||||||
<VnLv :label="t('InvoiceIn.list.supplier')">
|
|
||||||
<template #value>
|
<template #value>
|
||||||
<span class="link">
|
<span class="link">
|
||||||
{{ entity?.supplier?.nickname }}
|
{{ entity?.supplier?.nickname }}
|
||||||
|
@ -378,7 +186,7 @@ const createInvoiceInCorrection = async () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
:to="routes.getSupplier(entity.supplierFk)"
|
:to="routes.getSupplier(entity.supplierFk)"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('InvoiceIn.list.supplier') }}</QTooltip>
|
<QTooltip>{{ t('invoiceIn.list.supplier') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
size="md"
|
size="md"
|
||||||
|
@ -394,7 +202,7 @@ const createInvoiceInCorrection = async () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
:to="routes.getTickets(entity.supplierFk)"
|
:to="routes.getTickets(entity.supplierFk)"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('InvoiceIn.descriptor.ticketList') }}</QTooltip>
|
<QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
v-if="
|
v-if="
|
||||||
|
@ -438,7 +246,7 @@ const createInvoiceInCorrection = async () => {
|
||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="`${capitalize(t('globals.class'))}`"
|
:label="`${useCapitalize(t('globals.class'))}`"
|
||||||
v-model="correctionFormData.invoiceClass"
|
v-model="correctionFormData.invoiceClass"
|
||||||
:options="siiTypeInvoiceIns"
|
:options="siiTypeInvoiceIns"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -448,27 +256,15 @@ const createInvoiceInCorrection = async () => {
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="`${capitalize(t('globals.type'))}`"
|
:label="`${useCapitalize(t('globals.type'))}`"
|
||||||
v-model="correctionFormData.invoiceType"
|
v-model="correctionFormData.invoiceType"
|
||||||
:options="cplusRectificationTypes"
|
:options="cplusRectificationTypes"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="description"
|
option-label="description"
|
||||||
:required="true"
|
:required="true"
|
||||||
>
|
/>
|
||||||
<template #option="{ opt }">
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel
|
|
||||||
>{{ opt.code }} -
|
|
||||||
{{ opt.description }}</QItemLabel
|
|
||||||
>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<div></div>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="`${capitalize(t('globals.reason'))}`"
|
:label="`${useCapitalize(t('globals.reason'))}`"
|
||||||
v-model="correctionFormData.invoiceReason"
|
v-model="correctionFormData.invoiceReason"
|
||||||
:options="invoiceCorrectionTypes"
|
:options="invoiceCorrectionTypes"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -512,31 +308,3 @@ const createInvoiceInCorrection = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries
|
|
||||||
isLinked: The entry {bookEntry} has been linked to Sage. Please contact administration for further information
|
|
||||||
assertAction: Are you sure you want to {action} this invoice?
|
|
||||||
es:
|
|
||||||
book: asentar
|
|
||||||
unbook: desasentar
|
|
||||||
delete: eliminar
|
|
||||||
clone: clonar
|
|
||||||
To book: Contabilizar
|
|
||||||
To unbook: Descontabilizar
|
|
||||||
Delete invoice: Eliminar factura
|
|
||||||
Invoice deleted: Factura eliminada
|
|
||||||
Clone invoice: Clonar factura
|
|
||||||
Invoice cloned: Factura clonada
|
|
||||||
Show agricultural receipt as PDF: Ver recibo agrícola como PDF
|
|
||||||
Send agricultural receipt as PDF: Enviar recibo agrícola como PDF
|
|
||||||
Are you sure you want to send it?: Estás seguro que quieres enviarlo?
|
|
||||||
Send PDF invoice: Enviar factura a PDF
|
|
||||||
Create rectificative invoice: Crear factura rectificativa
|
|
||||||
Rectificative invoice: Factura rectificativa
|
|
||||||
Original invoice: Factura origen
|
|
||||||
Entry: entrada
|
|
||||||
isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes
|
|
||||||
isLinked: El asiento {bookEntry} fue enlazado a Sage, por favor contacta con administración
|
|
||||||
assertAction: Estas seguro de querer {action} esta factura?
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, toRefs, reactive } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
|
import { downloadFile } from 'src/composables/downloadFile';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import { usePrintService } from 'composables/usePrintService';
|
||||||
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
|
||||||
|
import InvoiceInToBook from '../InvoiceInToBook.vue';
|
||||||
|
|
||||||
|
const { hasAny } = useAcl();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { openReport, sendEmail } = usePrintService();
|
||||||
|
const { push, currentRoute } = useRouter();
|
||||||
|
const $props = defineProps({
|
||||||
|
invoice: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { invoice } = toRefs($props);
|
||||||
|
const quasar = useQuasar();
|
||||||
|
const arrayData = useArrayData();
|
||||||
|
const currentAction = ref();
|
||||||
|
const config = ref();
|
||||||
|
const correctionDialogRef = ref();
|
||||||
|
const invoiceInCorrection = reactive({ correcting: [], corrected: null });
|
||||||
|
const entityId = computed(() => $props.invoice.id || +currentRoute.value.params.id);
|
||||||
|
const invoiceIn = computed(() => arrayData.store.data);
|
||||||
|
const actions = {
|
||||||
|
unbook: {
|
||||||
|
title: t('assertAction', { action: t('InvoiceIn.descriptorMenu.unbook') }),
|
||||||
|
action: toUnbook,
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
title: t('assertAction', { action: t('InvoiceIn.descriptorMenu.delete') }),
|
||||||
|
action: deleteInvoice,
|
||||||
|
},
|
||||||
|
clone: {
|
||||||
|
title: t('assertAction', { action: t('InvoiceIn.descriptorMenu.clone') }),
|
||||||
|
action: cloneInvoice,
|
||||||
|
},
|
||||||
|
showPdf: { cb: showPdfInvoice },
|
||||||
|
sendPdf: { cb: sendPdfInvoiceConfirmation },
|
||||||
|
correct: { cb: () => correctionDialogRef.value.show() },
|
||||||
|
};
|
||||||
|
const canEditProp = (props) =>
|
||||||
|
hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
|
||||||
|
|
||||||
|
function triggerMenu(type) {
|
||||||
|
currentAction.value = actions[type];
|
||||||
|
if (currentAction.value.cb) currentAction.value.cb();
|
||||||
|
else openDialog(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDialog() {
|
||||||
|
quasar.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t(currentAction.value.title),
|
||||||
|
promise: currentAction.value.action,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toUnbook() {
|
||||||
|
const { data } = await axios.post(`InvoiceIns/${entityId.value}/toUnbook`);
|
||||||
|
const { isLinked, bookEntry, accountingEntries } = data;
|
||||||
|
|
||||||
|
const type = isLinked ? 'warning' : 'positive';
|
||||||
|
const message = isLinked
|
||||||
|
? t('isLinked', { bookEntry })
|
||||||
|
: t('isNotLinked', { bookEntry, accountingEntries });
|
||||||
|
|
||||||
|
quasar.notify({ type, message });
|
||||||
|
if (!isLinked) arrayData.store.data.isBooked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteInvoice() {
|
||||||
|
await axios.delete(`InvoiceIns/${entityId.value}`);
|
||||||
|
quasar.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message: t('InvoiceIn.descriptorMenu.invoiceDeleted'),
|
||||||
|
});
|
||||||
|
push({ path: '/invoice-in' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cloneInvoice() {
|
||||||
|
const { data } = await axios.post(`InvoiceIns/${entityId.value}/clone`);
|
||||||
|
quasar.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message: t('InvoiceIn.descriptorMenu.invoiceCloned'),
|
||||||
|
});
|
||||||
|
push({ path: `/invoice-in/${data.id}/summary` });
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAgricultural = () => {
|
||||||
|
if (!config.value) return false;
|
||||||
|
return (
|
||||||
|
invoiceIn.value?.supplier?.sageFarmerWithholdingFk ===
|
||||||
|
config?.value[0]?.sageWithholdingFk
|
||||||
|
);
|
||||||
|
};
|
||||||
|
function showPdfInvoice() {
|
||||||
|
if (isAgricultural()) openReport(`InvoiceIns/${entityId.value}/invoice-in-pdf`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPdfInvoiceConfirmation() {
|
||||||
|
quasar.dialog({
|
||||||
|
component: SendEmailDialog,
|
||||||
|
componentProps: {
|
||||||
|
data: {
|
||||||
|
address: invoiceIn.value.supplier.contacts[0].email,
|
||||||
|
},
|
||||||
|
promise: sendPdfInvoice,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPdfInvoice({ address }) {
|
||||||
|
if (!address)
|
||||||
|
quasar.notify({
|
||||||
|
type: 'negative',
|
||||||
|
message: t(`The email can't be empty`),
|
||||||
|
});
|
||||||
|
else
|
||||||
|
return sendEmail(`InvoiceIns/${entityId.value}/invoice-in-email`, {
|
||||||
|
recipientId: invoiceIn.value.supplier.id,
|
||||||
|
recipient: address,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<InvoiceInToBook>
|
||||||
|
<template #content="{ book }">
|
||||||
|
<QItem
|
||||||
|
v-if="!invoice?.isBooked && canEditProp('toBook')"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="book(entityId)"
|
||||||
|
>
|
||||||
|
<QItemSection>{{ t('InvoiceIn.descriptorMenu.toBook') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</InvoiceInToBook>
|
||||||
|
<QItem
|
||||||
|
v-if="invoice?.isBooked && canEditProp('toUnbook')"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="triggerMenu('unbook')"
|
||||||
|
>
|
||||||
|
<QItemSection>
|
||||||
|
{{ t('InvoiceIn.descriptorMenu.toUnbook') }}
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
v-if="canEditProp('deleteById')"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="triggerMenu('InvoiceIn.descriptorMenu.delete')"
|
||||||
|
>
|
||||||
|
<QItemSection>{{ t('InvoiceIn.descriptorMenu.deleteInvoice') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem v-if="canEditProp('clone')" v-ripple clickable @click="triggerMenu('clone')">
|
||||||
|
<QItemSection>{{ t('InvoiceIn.descriptorMenu.cloneInvoice') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem v-if="isAgricultural()" v-ripple clickable @click="triggerMenu('showPdf')">
|
||||||
|
<QItemSection>{{
|
||||||
|
t('InvoiceIn.descriptorMenu.showAgriculturalPdf')
|
||||||
|
}}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem v-if="isAgricultural()" v-ripple clickable @click="triggerMenu('sendPdf')">
|
||||||
|
<QItemSection
|
||||||
|
>{{ t('InvoiceIn.descriptorMenu.sendAgriculturalPdf') }}...</QItemSection
|
||||||
|
>
|
||||||
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
v-if="!invoiceInCorrection.corrected"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="triggerMenu('correct')"
|
||||||
|
>
|
||||||
|
<QItemSection
|
||||||
|
>{{ t('InvoiceIn.descriptorMenu.createCorrective') }}...</QItemSection
|
||||||
|
>
|
||||||
|
</QItem>
|
||||||
|
<QItem v-if="invoice.dmsFk" v-ripple clickable @click="downloadFile(invoice.dmsFk)">
|
||||||
|
<QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries
|
||||||
|
isLinked: The entry has been linked to Sage. Please contact administration for further information
|
||||||
|
assertAction: Are you sure you want to {action} this invoice?
|
||||||
|
es:
|
||||||
|
isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes
|
||||||
|
isLinked: El asiento fue enlazado a Sage, por favor contacta con administración
|
||||||
|
assertAction: Estas seguro de querer {action} esta factura?
|
||||||
|
</i18n>
|
|
@ -10,6 +10,7 @@ import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import InvoiceIntoBook from '../InvoiceInToBook.vue';
|
import InvoiceIntoBook from '../InvoiceInToBook.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
|
||||||
|
|
||||||
const props = defineProps({ id: { type: [Number, String], default: 0 } });
|
const props = defineProps({ id: { type: [Number, String], default: 0 } });
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -200,6 +201,9 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
||||||
</template>
|
</template>
|
||||||
</InvoiceIntoBook>
|
</InvoiceIntoBook>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<InvoiceInDescriptorMenu :invoice="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<!--Basic Data-->
|
<!--Basic Data-->
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
|
|
@ -12,6 +12,26 @@ InvoiceIn:
|
||||||
amount: Amount
|
amount: Amount
|
||||||
descriptor:
|
descriptor:
|
||||||
ticketList: Ticket list
|
ticketList: Ticket list
|
||||||
|
descriptorMenu:
|
||||||
|
book: Book
|
||||||
|
unbook: Unbook
|
||||||
|
delete: Delete
|
||||||
|
clone: Clone
|
||||||
|
toBook: To book
|
||||||
|
toUnbook: To unbook
|
||||||
|
deleteInvoice: Delete invoice
|
||||||
|
invoiceDeleted: invoice deleted
|
||||||
|
cloneInvoice: Clone invoice
|
||||||
|
invoiceCloned: Invoice cloned
|
||||||
|
showAgriculturalPdf: Show agricultural receipt as PDF
|
||||||
|
sendAgriculturalPdf: Send agricultural receipt as PDF
|
||||||
|
checkSendInvoice: Are you sure you want to send it?
|
||||||
|
sendPdfInvoice: Send PDF invoice
|
||||||
|
createCorrective: Create rectificative invoice
|
||||||
|
correctiveInvoice: Rectificative invoice
|
||||||
|
originalInvoice: Original invoice
|
||||||
|
entry: Entry
|
||||||
|
emailEmpty: The email can't be empty
|
||||||
card:
|
card:
|
||||||
client: Client
|
client: Client
|
||||||
company: Company
|
company: Company
|
||||||
|
@ -50,4 +70,3 @@ invoicein:
|
||||||
params:
|
params:
|
||||||
account: Ledger account
|
account: Ledger account
|
||||||
correctingFk: Rectificative
|
correctingFk: Rectificative
|
||||||
|
|
|
@ -12,6 +12,26 @@ InvoiceIn:
|
||||||
amount: Importe
|
amount: Importe
|
||||||
descriptor:
|
descriptor:
|
||||||
ticketList: Listado de tickets
|
ticketList: Listado de tickets
|
||||||
|
descriptorMenu:
|
||||||
|
book: Asentar
|
||||||
|
unbook: Desasentar
|
||||||
|
delete: Eliminar
|
||||||
|
clone: Clonar
|
||||||
|
toBook: Contabilizar
|
||||||
|
toUnbook: Descontabilizar
|
||||||
|
deleteInvoice: Eliminar factura
|
||||||
|
invoiceDeleted: Factura eliminada
|
||||||
|
cloneInvoice: Clonar factura
|
||||||
|
invoiceCloned: Factura clonada
|
||||||
|
showAgriculturalPdf: Ver recibo agrícola como PDF
|
||||||
|
sendAgriculturalPdf: Enviar recibo agrícola como PDF
|
||||||
|
checkSendInvoice: ¿Estás seguro que quieres enviarlo?
|
||||||
|
sendPdfInvoice: Enviar factura a PDF
|
||||||
|
createCorrective: Crear factura rectificativa
|
||||||
|
correctiveInvoice: Factura rectificativa
|
||||||
|
originalInvoice: Factura origen
|
||||||
|
entry: Entrada
|
||||||
|
emailEmpty: El email no puede estar vacío
|
||||||
card:
|
card:
|
||||||
client: Cliente
|
client: Cliente
|
||||||
company: Empresa
|
company: Empresa
|
||||||
|
@ -47,4 +67,3 @@ invoicein:
|
||||||
params:
|
params:
|
||||||
account: Cuenta contable
|
account: Cuenta contable
|
||||||
correctingFk: Rectificativa
|
correctingFk: Rectificativa
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { getUrl } from 'src/composables/getUrl';
|
||||||
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
import InvoiceOutDescriptorMenu from './InvoiceOutDescriptorMenu.vue';
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
fetch();
|
fetch();
|
||||||
|
@ -113,6 +114,9 @@ const ticketsColumns = ref([
|
||||||
<template #header="{ entity: { invoiceOut } }">
|
<template #header="{ entity: { invoiceOut } }">
|
||||||
<div>{{ invoiceOut.ref }} - {{ invoiceOut.client?.socialName }}</div>
|
<div>{{ invoiceOut.ref }} - {{ invoiceOut.client?.socialName }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<InvoiceOutDescriptorMenu :invoice-out-data="entity.invoiceOut" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity: { invoiceOut } }">
|
<template #body="{ entity: { invoiceOut } }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle :text="t('globals.pageTitles.basicData')" />
|
<VnTitle :text="t('globals.pageTitles.basicData')" />
|
||||||
|
|
|
@ -6,17 +6,16 @@ import { useI18n } from 'vue-i18n';
|
||||||
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import RegularizeStockForm from 'components/RegularizeStockForm.vue';
|
|
||||||
import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
|
import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
|
||||||
import useCardDescription from 'src/composables/useCardDescription';
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { cloneItem } from 'src/pages/Item/composables/cloneItem';
|
import ItemDescriptorMenu from './ItemDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
type: [Number, String],
|
type: Number,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
@ -29,7 +28,7 @@ const $props = defineProps({
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
saleFk: {
|
saleFk: {
|
||||||
type: [Number, String],
|
type: Number,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
warehouseFk: {
|
warehouseFk: {
|
||||||
|
@ -38,7 +37,6 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { openCloneDialog } = cloneItem();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const warehouseConfig = ref(null);
|
const warehouseConfig = ref(null);
|
||||||
|
@ -46,7 +44,6 @@ const entityId = computed(() => {
|
||||||
return $props.id || route.params.id;
|
return $props.id || route.params.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const regularizeStockFormDialog = ref(null);
|
|
||||||
const mounted = ref();
|
const mounted = ref();
|
||||||
|
|
||||||
const arrayDataStock = useArrayData('descriptorStock', {
|
const arrayDataStock = useArrayData('descriptorStock', {
|
||||||
|
@ -61,14 +58,14 @@ onMounted(async () => {
|
||||||
const data = ref(useCardDescription());
|
const data = ref(useCardDescription());
|
||||||
const setData = async (entity) => {
|
const setData = async (entity) => {
|
||||||
if (!entity) return;
|
if (!entity) return;
|
||||||
data.value = useCardDescription(entity?.name, entity?.id);
|
data.value = useCardDescription(entity.name, entity.id);
|
||||||
await updateStock();
|
await updateStock();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getItemConfigs = async () => {
|
const getItemConfigs = async () => {
|
||||||
const { data } = await axios.get('ItemConfigs/findOne');
|
const { data } = await axios.get('ItemConfigs/findOne');
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
return (warehouseConfig.value = data.warehouseFk);
|
warehouseConfig.value = data.warehouseFk;
|
||||||
};
|
};
|
||||||
const updateStock = async () => {
|
const updateStock = async () => {
|
||||||
if (!mounted.value) return;
|
if (!mounted.value) return;
|
||||||
|
@ -89,10 +86,6 @@ const updateStock = async () => {
|
||||||
if (storeData?.itemFk == entityId.value) return;
|
if (storeData?.itemFk == entityId.value) return;
|
||||||
await stock.fetch({});
|
await stock.fetch({});
|
||||||
};
|
};
|
||||||
|
|
||||||
const openRegularizeStockForm = () => {
|
|
||||||
regularizeStockFormDialog.value.show();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -105,24 +98,12 @@ const openRegularizeStockForm = () => {
|
||||||
:url="`Items/${entityId}/getCard`"
|
:url="`Items/${entityId}/getCard`"
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
>
|
>
|
||||||
<template #menu="{}">
|
<template #menu>
|
||||||
<QItem v-ripple clickable @click="openRegularizeStockForm()">
|
<ItemDescriptorMenu
|
||||||
<QItemSection>
|
:entity-id="entityId"
|
||||||
{{ t('Regularize stock') }}
|
:warehouse-fk="warehouseFk"
|
||||||
<QDialog ref="regularizeStockFormDialog">
|
@regularized="updateStock"
|
||||||
<RegularizeStockForm
|
/>
|
||||||
:item-fk="entityId"
|
|
||||||
:warehouse-fk="warehouseFk"
|
|
||||||
@on-data-saved="updateStock()"
|
|
||||||
/>
|
|
||||||
</QDialog>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem v-ripple clickable @click="openCloneDialog(entityId)">
|
|
||||||
<QItemSection>
|
|
||||||
{{ t('globals.clone') }}
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
<template #before>
|
<template #before>
|
||||||
<ItemDescriptorImage
|
<ItemDescriptorImage
|
||||||
|
@ -191,7 +172,6 @@ const openRegularizeStockForm = () => {
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Regularize stock: Regularizar stock
|
|
||||||
Inactive article: Artículo inactivo
|
Inactive article: Artículo inactivo
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,6 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Regularize stock: Regularizar stock
|
|
||||||
All it's properties will be copied: Todas sus propiedades serán copiadas
|
All it's properties will be copied: Todas sus propiedades serán copiadas
|
||||||
Do you want to clone this item?: ¿Desea clonar este artículo?
|
Do you want to clone this item?: ¿Desea clonar este artículo?
|
||||||
warehouseText: Calculado sobre el almacén de { warehouseName }
|
warehouseText: Calculado sobre el almacén de { warehouseName }
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<script setup>
|
||||||
|
import RegularizeStockForm from 'components/RegularizeStockForm.vue';
|
||||||
|
import { cloneItem } from 'src/pages/Item/composables/cloneItem';
|
||||||
|
|
||||||
|
const { openCloneDialog } = cloneItem();
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
entityId: {
|
||||||
|
type: Number,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
warehouseFk: {
|
||||||
|
type: Number,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
defineEmits(['regularized']);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<QItem v-ripple clickable @click="$refs.regularizeStockFormDialog.show()">
|
||||||
|
<QItemSection>
|
||||||
|
{{ $t('item.regularizeStock') }}
|
||||||
|
<QDialog ref="regularizeStockFormDialog">
|
||||||
|
<RegularizeStockForm
|
||||||
|
:item-fk="entityId"
|
||||||
|
:warehouse-fk="warehouseFk"
|
||||||
|
@on-data-saved="$emit('regularized')"
|
||||||
|
/>
|
||||||
|
</QDialog>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem v-ripple clickable @click="openCloneDialog(entityId)">
|
||||||
|
<QItemSection>
|
||||||
|
{{ $t('globals.clone') }}
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.weekdaysBtn {
|
||||||
|
margin: 1%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -8,6 +8,7 @@ import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
|
import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
import ItemDescriptorMenu from './ItemDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -43,10 +44,13 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`;
|
||||||
<template #header="{ entity: { item } }">
|
<template #header="{ entity: { item } }">
|
||||||
{{ item.id }} - {{ item.name }}
|
{{ item.id }} - {{ item.name }}
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu>
|
||||||
|
<ItemDescriptorMenu :entity-id="entityId" :warehouse-fk="warehouseFk" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity: { item, tags, visible, available, botanical } }">
|
<template #body="{ entity: { item, tags, visible, available, botanical } }">
|
||||||
<QCard class="vn-one photo">
|
<QCard class="vn-one photo">
|
||||||
<ItemDescriptorImage
|
<ItemDescriptorImage
|
||||||
:entity-id="Number(entityId)"
|
:entity-id="entityId"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:available="available"
|
:available="available"
|
||||||
:show-edit-button="false"
|
:show-edit-button="false"
|
||||||
|
@ -89,7 +93,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`;
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="getUrl(entityId, 'basic-data')"
|
:url="getUrl(entityId, 'basic-data')"
|
||||||
:text="t('item.summary.basicData')"
|
:text="t('item.summary.otherData')"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('item.summary.intrastatCode')"
|
:label="t('item.summary.intrastatCode')"
|
||||||
|
|
|
@ -152,7 +152,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('item.list.category'),
|
label: t('item.list.category'),
|
||||||
|
@ -498,5 +498,4 @@ es:
|
||||||
Create Item: Crear artículo
|
Create Item: Crear artículo
|
||||||
You can search by id: Puedes buscar por id
|
You can search by id: Puedes buscar por id
|
||||||
Preview: Vista previa
|
Preview: Vista previa
|
||||||
Regularize stock: Regularizar stock
|
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -172,24 +172,22 @@ const changeQuantity = async (request) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
await axios.patch(`Sales/${request.saleFk}`, params);
|
await axios.patch(`Sales/${request.saleFk}`, params);
|
||||||
notify(t('globals.dataSaved'), 'positive');
|
}
|
||||||
confirmRequest(request);
|
await confirmRequest(request);
|
||||||
} else confirmRequest(request);
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
};
|
};
|
||||||
|
|
||||||
const confirmRequest = async (request) => {
|
const confirmRequest = async (request) => {
|
||||||
if (request.itemFk && request.saleQuantity) {
|
if (!request.itemFk || !request.saleQuantity) return;
|
||||||
const params = {
|
const params = {
|
||||||
itemFk: request.itemFk,
|
itemFk: request.itemFk,
|
||||||
quantity: request.saleQuantity,
|
quantity: request.saleQuantity,
|
||||||
attenderFk: request.attenderFk,
|
attenderFk: request.attenderFk,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data } = await axios.post(`TicketRequests/${request.id}/confirm`, params);
|
const { data } = await axios.post(`TicketRequests/${request.id}/confirm`, params);
|
||||||
request.itemDescription = data.concept;
|
request.itemDescription = data.concept;
|
||||||
request.isOk = true;
|
request.isOk = true;
|
||||||
notify(t('globals.dataSaved'), 'positive');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getState = (isOk) => {
|
const getState = (isOk) => {
|
||||||
|
|
|
@ -219,3 +219,4 @@ item:
|
||||||
minSalesQuantity: 'Cantidad mínima de venta'
|
minSalesQuantity: 'Cantidad mínima de venta'
|
||||||
genus: 'Genus'
|
genus: 'Genus'
|
||||||
specie: 'Specie'
|
specie: 'Specie'
|
||||||
|
regularizeStock: Regularize stock
|
||||||
|
|
|
@ -210,6 +210,7 @@ item:
|
||||||
minSalesQuantity: 'Cantidad mínima de venta'
|
minSalesQuantity: 'Cantidad mínima de venta'
|
||||||
genus: 'Genus'
|
genus: 'Genus'
|
||||||
specie: 'Specie'
|
specie: 'Specie'
|
||||||
|
regularizeStock: Regularizar stock
|
||||||
buyRequest:
|
buyRequest:
|
||||||
ticketId: 'ID Ticket'
|
ticketId: 'ID Ticket'
|
||||||
shipped: 'F. envío'
|
shipped: 'F. envío'
|
||||||
|
|
|
@ -9,7 +9,6 @@ import useCardDescription from 'src/composables/useCardDescription';
|
||||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue';
|
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
|
|
||||||
const DEFAULT_ITEMS = 0;
|
const DEFAULT_ITEMS = 0;
|
||||||
|
@ -94,9 +93,6 @@ const total = ref(0);
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
data-key="orderData"
|
data-key="orderData"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
|
||||||
<OrderDescriptorMenu :order="entity" />
|
|
||||||
</template>
|
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('globals.state')"
|
:label="t('globals.state')"
|
||||||
|
|
|
@ -12,6 +12,7 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
|
||||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
|
import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -91,6 +92,9 @@ async function handleConfirm() {
|
||||||
<QTooltip>{{ t('order.summary.confirmLines') }}</QTooltip>
|
<QTooltip>{{ t('order.summary.confirmLines') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<OrderDescriptorMenu :order="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
|
|
@ -52,7 +52,7 @@ async function actualizeVolume() {
|
||||||
const params = { isOk: true };
|
const params = { isOk: true };
|
||||||
await axios.post(`Routes/${routeId}/updateVolume`, params);
|
await axios.post(`Routes/${routeId}/updateVolume`, params);
|
||||||
quasar.notify({
|
quasar.notify({
|
||||||
message: t('globals.dataUpdated'),
|
message: t('globals.dataSaved'),
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
|
||||||
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
import RouteDescriptorMenu from './RouteDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -128,6 +129,9 @@ const ticketColumns = ref([
|
||||||
<template #header="{ entity }">
|
<template #header="{ entity }">
|
||||||
<span>{{ `${entity?.route.id} - ${entity?.route?.description}` }}</span>
|
<span>{{ `${entity?.route.id} - ${entity?.route?.description}` }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<RouteDescriptorMenu :route="entity.route" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-max">
|
<QCard class="vn-max">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
|
|
@ -10,6 +10,7 @@ import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import VnLinkPhone from 'components/ui/VnLinkPhone.vue';
|
import VnLinkPhone from 'components/ui/VnLinkPhone.vue';
|
||||||
|
import RoadmapDescriptorMenu from './RoadmapDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -86,6 +87,9 @@ const filter = {
|
||||||
<template #header="{ entity }">
|
<template #header="{ entity }">
|
||||||
<span>{{ `${entity?.id} - ${entity?.name}` }}</span>
|
<span>{{ `${entity?.id} - ${entity?.name}` }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<RoadmapDescriptorMenu :route="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useQuasar } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
shelving: {
|
shelving: {
|
||||||
|
@ -14,8 +15,11 @@ const $props = defineProps({
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const emit = defineEmits(['onRemove']);
|
||||||
|
|
||||||
function confirmRemove() {
|
function confirmRemove() {
|
||||||
quasar.dialog({
|
quasar.dialog({
|
||||||
component: VnConfirm,
|
component: VnConfirm,
|
||||||
|
@ -32,11 +36,12 @@ async function remove() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await axios.delete(`Shelvings/${$props.shelving.id}`);
|
await axios.delete(`Shelvings/${$props.shelving.id}`);
|
||||||
await router.push({ name: 'ShelvingList' });
|
if (route.name != 'ShelvingList') await router.push({ name: 'ShelvingList' });
|
||||||
quasar.notify({
|
quasar.notify({
|
||||||
message: t('globals.dataDeleted'),
|
message: t('globals.dataDeleted'),
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
});
|
});
|
||||||
|
emit('onRemove', {});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
import VnUserLink from 'components/ui/VnUserLink.vue';
|
import VnUserLink from 'components/ui/VnUserLink.vue';
|
||||||
|
import ShelvingDescriptorMenu from './ShelvingDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -14,7 +15,7 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const summary = ref({});
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
|
@ -43,7 +44,13 @@ const filter = {
|
||||||
data-key="ShelvingSummary"
|
data-key="ShelvingSummary"
|
||||||
>
|
>
|
||||||
<template #header="{ entity }">
|
<template #header="{ entity }">
|
||||||
<div>{{ entity.id }} - {{ entity.code }}</div>
|
<div>{{ entity.code }}</div>
|
||||||
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<ShelvingDescriptorMenu
|
||||||
|
:shelving="entity"
|
||||||
|
@on-remove="$refs.summary.fetch()"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
|
|
@ -96,7 +96,6 @@ function toTicketUrl(section) {
|
||||||
ref="summaryRef"
|
ref="summaryRef"
|
||||||
:url="`Tickets/${entityId}/summary`"
|
:url="`Tickets/${entityId}/summary`"
|
||||||
data-key="TicketSummary"
|
data-key="TicketSummary"
|
||||||
data-cy="ticketSummary"
|
|
||||||
>
|
>
|
||||||
<template #header-left>
|
<template #header-left>
|
||||||
<VnToSummary
|
<VnToSummary
|
||||||
|
@ -114,7 +113,7 @@ function toTicketUrl(section) {
|
||||||
{{ entity.nickname }}
|
{{ entity.nickname }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #header-right="{ entity }">
|
<template #header-right>
|
||||||
<div>
|
<div>
|
||||||
<QBtnDropdown
|
<QBtnDropdown
|
||||||
ref="stateBtnDropdownRef"
|
ref="stateBtnDropdownRef"
|
||||||
|
@ -133,18 +132,11 @@ function toTicketUrl(section) {
|
||||||
@update:model-value="changeState"
|
@update:model-value="changeState"
|
||||||
/>
|
/>
|
||||||
</QBtnDropdown>
|
</QBtnDropdown>
|
||||||
<QBtn color="white" dense flat icon="more_vert" round size="md">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
|
||||||
</QTooltip>
|
|
||||||
<QMenu>
|
|
||||||
<QList>
|
|
||||||
<TicketDescriptorMenu :ticket="entity" />
|
|
||||||
</QList>
|
|
||||||
</QMenu>
|
|
||||||
</QBtn>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<TicketDescriptorMenu :ticket="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
|
@ -258,7 +250,7 @@ function toTicketUrl(section) {
|
||||||
<QCard class="vn-one" v-if="entity.notes.length">
|
<QCard class="vn-one" v-if="entity.notes.length">
|
||||||
<VnTitle
|
<VnTitle
|
||||||
:url="toTicketUrl('observation')"
|
:url="toTicketUrl('observation')"
|
||||||
:text="t('globals.pageTitles.notes')"
|
:text="t('ticket.pageTitles.notes')"
|
||||||
/>
|
/>
|
||||||
<QVirtualScroll
|
<QVirtualScroll
|
||||||
:items="entity.notes"
|
:items="entity.notes"
|
||||||
|
|
|
@ -11,6 +11,7 @@ import FetchData from 'src/components/FetchData.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import { toDate, toCurrency } from 'src/filters';
|
import { toDate, toCurrency } from 'src/filters';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -242,7 +243,9 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
|
||||||
<template #header>
|
<template #header>
|
||||||
<span>{{ travel.id }} - {{ travel.ref }}</span>
|
<span>{{ travel.id }} - {{ travel.ref }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<TravelDescriptorMenuItems :travel="entity" />
|
||||||
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<QCardSection class="q-pa-none">
|
<QCardSection class="q-pa-none">
|
||||||
|
|
|
@ -6,11 +6,10 @@ import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
||||||
import VnChangePassword from 'src/components/common/VnChangePassword.vue';
|
import VnChangePassword from 'src/components/common/VnChangePassword.vue';
|
||||||
import { useState } from 'src/composables/useState';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VnImg from 'src/components/ui/VnImg.vue';
|
import VnImg from 'src/components/ui/VnImg.vue';
|
||||||
import EditPictureForm from 'components/EditPictureForm.vue';
|
import EditPictureForm from 'components/EditPictureForm.vue';
|
||||||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -28,8 +27,6 @@ const image = ref(null);
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const state = useState();
|
|
||||||
const user = state.getUser();
|
|
||||||
const showEditPhotoForm = ref(false);
|
const showEditPhotoForm = ref(false);
|
||||||
const toggleEditPictureForm = () => {
|
const toggleEditPictureForm = () => {
|
||||||
showEditPhotoForm.value = !showEditPhotoForm.value;
|
showEditPhotoForm.value = !showEditPhotoForm.value;
|
||||||
|
@ -45,18 +42,6 @@ const getIsExcluded = async () => {
|
||||||
workerExcluded.value = data.exists;
|
workerExcluded.value = data.exists;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleExcluded = async () => {
|
|
||||||
if (workerExcluded.value)
|
|
||||||
await axios.delete(`WorkerDisableExcludeds/${entityId.value}`);
|
|
||||||
else
|
|
||||||
await axios.post(`WorkerDisableExcludeds`, {
|
|
||||||
workerFk: entityId.value,
|
|
||||||
dated: new Date(),
|
|
||||||
});
|
|
||||||
|
|
||||||
workerExcluded.value = !workerExcluded.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePhotoUpdated = (evt = false) => {
|
const handlePhotoUpdated = (evt = false) => {
|
||||||
image.value.reload(evt);
|
image.value.reload(evt);
|
||||||
};
|
};
|
||||||
|
@ -72,25 +57,11 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
@on-fetch="getIsExcluded"
|
@on-fetch="getIsExcluded"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
<QItem v-ripple clickable @click="handleExcluded">
|
<WorkerDescriptorMenu
|
||||||
<QItemSection>
|
:worker="entity"
|
||||||
{{
|
:is-excluded="workerExcluded"
|
||||||
workerExcluded
|
@show-dialog="$refs.changePassRef.show"
|
||||||
? t('Click to allow the user to be disabled')
|
/>
|
||||||
: t('Click to exclude the user from getting disabled')
|
|
||||||
}}
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem
|
|
||||||
v-if="!entity.user.emailVerified && user.id != entity.id"
|
|
||||||
v-ripple
|
|
||||||
clickable
|
|
||||||
@click="$refs.changePassRef.show"
|
|
||||||
>
|
|
||||||
<QItemSection>
|
|
||||||
{{ t('globals.changePass') }}
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
<template #before>
|
<template #before>
|
||||||
<div class="relative-position">
|
<div class="relative-position">
|
||||||
|
@ -144,14 +115,10 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
:value="entity.user?.emailUser?.email"
|
:value="entity.user?.emailUser?.email"
|
||||||
copy
|
copy
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('worker.list.department')">
|
<VnLv
|
||||||
<template #value>
|
:label="t('worker.list.department')"
|
||||||
<span class="link" v-text="entity.department?.department?.name" />
|
:value="entity.department ? entity.department.department.name : null"
|
||||||
<DepartmentDescriptorProxy
|
/>
|
||||||
:id="entity.department?.department?.id"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VnLv>
|
|
||||||
<VnLv :value="entity.phone">
|
<VnLv :value="entity.phone">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ t('globals.phone') }}
|
{{ t('globals.phone') }}
|
||||||
|
@ -211,8 +178,6 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Go to client: Ir a cliente
|
|
||||||
Go to user: Ir al usuario
|
|
||||||
Click to allow the user to be disabled: Marcar para deshabilitar
|
Click to allow the user to be disabled: Marcar para deshabilitar
|
||||||
Click to exclude the user from getting disabled: Marcar para no deshabilitar
|
Click to exclude the user from getting disabled: Marcar para no deshabilitar
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref, toRefs } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
worker: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isExcluded: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const route = useRoute();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const state = useState();
|
||||||
|
const user = state.getUser();
|
||||||
|
const { worker } = toRefs($props);
|
||||||
|
const workerExcluded = ref($props.isExcluded);
|
||||||
|
const entityId = computed(() => {
|
||||||
|
return $props.worker.id || route.params.id;
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['show-dialog']);
|
||||||
|
const handleExcluded = async () => {
|
||||||
|
if (workerExcluded.value)
|
||||||
|
await axios.delete(`WorkerDisableExcludeds/${entityId.value}`);
|
||||||
|
else
|
||||||
|
await axios.post(`WorkerDisableExcludeds`, {
|
||||||
|
workerFk: entityId.value,
|
||||||
|
dated: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
workerExcluded.value = !workerExcluded.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showChangePasswordDialog = () => {
|
||||||
|
emit('show-dialog', true);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QItem v-ripple clickable @click="handleExcluded">
|
||||||
|
<QItemSection>
|
||||||
|
{{
|
||||||
|
workerExcluded
|
||||||
|
? t('Click to allow the user to be disabled')
|
||||||
|
: t('Click to exclude the user from getting disabled')
|
||||||
|
}}
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
v-if="!worker.user.emailVerified && user.id == worker.id"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="showChangePasswordDialog"
|
||||||
|
>
|
||||||
|
<QItemSection>
|
||||||
|
{{ t('globals.changePass') }}
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
|
@ -11,6 +11,7 @@ import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
|
import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
|
||||||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
|
import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
|
||||||
|
import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -42,6 +43,9 @@ onBeforeMount(async () => {
|
||||||
<template #header="{ entity }">
|
<template #header="{ entity }">
|
||||||
<div>{{ entity.id }} - {{ entity.firstName }} {{ entity.lastName }}</div>
|
<div>{{ entity.id }} - {{ entity.firstName }} {{ entity.lastName }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<WorkerDescriptorMenu :worker="entity" :is-excluded="workerExcluded" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity: worker }">
|
<template #body="{ entity: worker }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" />
|
<VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" />
|
||||||
|
|
|
@ -100,6 +100,16 @@ const agencyOptions = ref([]);
|
||||||
required="true"
|
required="true"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="data.priceOptimum"
|
||||||
|
:label="t('Price optimum')"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
required="true"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model="data.bonus"
|
v-model="data.bonus"
|
||||||
:label="t('Bonus')"
|
:label="t('Bonus')"
|
||||||
|
@ -107,8 +117,6 @@ const agencyOptions = ref([]);
|
||||||
min="0"
|
min="0"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Distribution point')"
|
:label="t('Distribution point')"
|
||||||
v-model="data.addressFk"
|
v-model="data.addressFk"
|
||||||
|
@ -152,6 +160,7 @@ es:
|
||||||
Traveling days: Dias de viaje
|
Traveling days: Dias de viaje
|
||||||
Closing: Cierre
|
Closing: Cierre
|
||||||
Price: Precio
|
Price: Precio
|
||||||
|
Price optimum: Precio óptimo
|
||||||
Bonus: Bonificación
|
Bonus: Bonificación
|
||||||
Inflation: Inflación
|
Inflation: Inflación
|
||||||
Volumetric: Volumétrico
|
Volumetric: Volumétrico
|
||||||
|
|
|
@ -182,13 +182,19 @@ onMounted(() => {
|
||||||
min="0"
|
min="0"
|
||||||
/>
|
/>
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model="eventInclusionFormData.bonus"
|
v-model="eventInclusionFormData.priceOptimum"
|
||||||
:label="t('zone.bonus')"
|
:label="t('list.priceOptimum')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
<VnInput
|
||||||
|
v-model="eventInclusionFormData.bonus"
|
||||||
|
:label="t('zone.bonus')"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model="eventInclusionFormData.m3Max"
|
v-model="eventInclusionFormData.m3Max"
|
||||||
:label="t('zone.m3Max')"
|
:label="t('zone.m3Max')"
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { getUrl } from 'src/composables/getUrl';
|
||||||
import { toCurrency } from 'filters/index';
|
import { toCurrency } from 'filters/index';
|
||||||
import { toTimeFormat } from 'src/filters/date';
|
import { toTimeFormat } from 'src/filters/date';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import ZoneDescriptorMenuItems from './ZoneDescriptorMenuItems.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -79,6 +80,9 @@ onMounted(async () => {
|
||||||
<template #header="{ entity }">
|
<template #header="{ entity }">
|
||||||
<div>#{{ entity.id }} - {{ entity.name }}</div>
|
<div>#{{ entity.id }} - {{ entity.name }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #menu="{ entity }">
|
||||||
|
<ZoneDescriptorMenuItems :zone="entity" />
|
||||||
|
</template>
|
||||||
<template #body="{ entity: zone }">
|
<template #body="{ entity: zone }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" />
|
<VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" />
|
||||||
|
|
|
@ -22,6 +22,7 @@ list:
|
||||||
agency: Agencia
|
agency: Agencia
|
||||||
close: Cierre
|
close: Cierre
|
||||||
price: Precio
|
price: Precio
|
||||||
|
priceOptimum: Precio óptimo
|
||||||
create: Crear zona
|
create: Crear zona
|
||||||
openSummary: Detalles
|
openSummary: Detalles
|
||||||
searchZone: Buscar zonas
|
searchZone: Buscar zonas
|
||||||
|
|
|
@ -10,7 +10,6 @@ const { notify } = useNotify();
|
||||||
|
|
||||||
export const useInvoiceOutGlobalStore = defineStore({
|
export const useInvoiceOutGlobalStore = defineStore({
|
||||||
id: 'invoiceOutGlobal',
|
id: 'invoiceOutGlobal',
|
||||||
|
|
||||||
state: () => ({
|
state: () => ({
|
||||||
initialDataLoading: true,
|
initialDataLoading: true,
|
||||||
formInitialData: {
|
formInitialData: {
|
||||||
|
@ -33,6 +32,7 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
nRequests: 0,
|
nRequests: 0,
|
||||||
nPdfs: 0,
|
nPdfs: 0,
|
||||||
totalPdfs: 0,
|
totalPdfs: 0,
|
||||||
|
formData: null,
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async init() {
|
async init() {
|
||||||
|
@ -93,8 +93,6 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
},
|
},
|
||||||
|
|
||||||
async makeInvoice(formData, clientsToInvoice) {
|
async makeInvoice(formData, clientsToInvoice) {
|
||||||
this.invoicing = true;
|
|
||||||
const promises = [];
|
|
||||||
try {
|
try {
|
||||||
this.printer = formData.printer;
|
this.printer = formData.printer;
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -119,11 +117,12 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
);
|
);
|
||||||
throw new Error("There aren't addresses to invoice");
|
throw new Error("There aren't addresses to invoice");
|
||||||
}
|
}
|
||||||
|
this.invoicing = false;
|
||||||
this.status = 'invoicing';
|
this.status = 'invoicing';
|
||||||
for (let index = 0; index < this.parallelism; index++) {
|
this.formData = formData;
|
||||||
promises.push(this.invoiceClient(formData, index));
|
this.addressIndex = 0;
|
||||||
}
|
this.errors = [];
|
||||||
await Promise.all(promises);
|
await this.invoiceClient();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.handleError(err);
|
this.handleError(err);
|
||||||
}
|
}
|
||||||
|
@ -182,45 +181,42 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async invoiceClient(formData, index) {
|
async invoiceClient() {
|
||||||
const address = this.addresses[index];
|
if (this.invoicing || this.nRequests >= this.parallelism) return;
|
||||||
|
const address = this.addresses[this.addressIndex];
|
||||||
|
|
||||||
if (!address || !this.status || this.status == 'stopping') {
|
if (!address || !this.status || this.status == 'stopping') {
|
||||||
this.status = 'stopping';
|
this.status = 'stopping';
|
||||||
this.invoicing = false;
|
this.invoicing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
this.invoicing = true;
|
||||||
const params = {
|
const params = {
|
||||||
clientId: address.clientId,
|
clientId: address.clientId,
|
||||||
addressId: address.id,
|
addressId: address.id,
|
||||||
invoiceDate: new Date(formData.invoiceDate),
|
invoiceDate: new Date(this.formData.invoiceDate),
|
||||||
maxShipped: new Date(formData.maxShipped),
|
maxShipped: new Date(this.formData.maxShipped),
|
||||||
companyFk: formData.companyFk,
|
companyFk: this.formData.companyFk,
|
||||||
serialType: formData.serialType,
|
serialType: this.formData.serialType,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.invoicing = true;
|
|
||||||
|
|
||||||
const { data } = await axios.post('InvoiceOuts/invoiceClient', params);
|
const { data } = await axios.post('InvoiceOuts/invoiceClient', params);
|
||||||
|
if (data) this.makePdfAndNotify(data, address);
|
||||||
if (data) await this.makePdfAndNotify(data, address);
|
|
||||||
this.isInvoicing = false;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err?.response?.status >= 400 && err?.response?.status < 500) {
|
if (err?.response?.status >= 400 && err?.response?.status < 500) {
|
||||||
this.invoiceClientError(address, err.response?.data?.error?.message);
|
this.invoiceClientError(address, err.response?.data?.error?.message);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.invoicing = false;
|
|
||||||
notify(
|
notify(
|
||||||
'invoiceOut.globalInvoices.errors.criticalInvoiceError',
|
'invoiceOut.globalInvoices.errors.criticalInvoiceError',
|
||||||
'negative'
|
'negative'
|
||||||
);
|
);
|
||||||
throw new Error('Critical invoicing error, process stopped');
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
this.invoicing = false;
|
||||||
this.addressIndex++;
|
this.addressIndex++;
|
||||||
if (this.status != 'stopping')
|
this.invoiceClient();
|
||||||
await this.invoiceClient(formData, this.addressIndex);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -231,9 +227,11 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
const params = { printerFk: this.printer };
|
const params = { printerFk: this.printer };
|
||||||
await axios.post(`InvoiceOuts/${invoiceId}/makePdfAndNotify`, params);
|
await axios.post(`InvoiceOuts/${invoiceId}/makePdfAndNotify`, params);
|
||||||
this.nPdfs++;
|
this.nPdfs++;
|
||||||
this.nRequests--;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.invoiceClientError(client, err.response?.data?.error?.message, true);
|
this.invoiceClientError(client, err.response?.data?.error?.message, true);
|
||||||
|
} finally {
|
||||||
|
this.nRequests--;
|
||||||
|
this.invoiceClient();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('InvoiceInCorrective', () => {
|
describe('InvoiceInCorrective', () => {
|
||||||
const createRectificative = '.q-menu > .q-list > :nth-child(6) > .q-item__section';
|
const createCorrective = '.q-menu > .q-list > :nth-child(6) > .q-item__section';
|
||||||
const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)';
|
const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)';
|
||||||
const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';
|
const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ describe('InvoiceInCorrective', () => {
|
||||||
|
|
||||||
cy.openActionsDescriptor();
|
cy.openActionsDescriptor();
|
||||||
|
|
||||||
cy.get(createRectificative).click();
|
cy.get(createCorrective).click();
|
||||||
cy.get(saveDialog).click();
|
cy.get(saveDialog).click();
|
||||||
cy.wait('@corrective').then((interception) => {
|
cy.wait('@corrective').then((interception) => {
|
||||||
const correctingId = interception.response.body;
|
const correctingId = interception.response.body;
|
||||||
|
|
Loading…
Reference in New Issue