Merge branch 'dev' into 7180_bug_supplierListScroll
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Javier Segarra 2024-04-18 06:06:01 +00:00
commit 817a8fcc71
8 changed files with 247 additions and 69 deletions

View File

@ -3,31 +3,29 @@ import { useRole } from './useRole';
import { useUserConfig } from './useUserConfig'; import { useUserConfig } from './useUserConfig';
import axios from 'axios'; import axios from 'axios';
import useNotify from './useNotify'; import useNotify from './useNotify';
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
const TOKEN = 'token';
export function useSession() { export function useSession() {
const { notify } = useNotify(); const { notify } = useNotify();
function getToken() { function getToken() {
const localToken = localStorage.getItem('token'); const localToken = localStorage.getItem(TOKEN);
const sessionToken = sessionStorage.getItem('token'); const sessionToken = sessionStorage.getItem(TOKEN);
return localToken || sessionToken || ''; return localToken || sessionToken || '';
} }
function getTokenMultimedia() { function getTokenMultimedia() {
const localTokenMultimedia = localStorage.getItem('token'); // Temporal const localTokenMultimedia = localStorage.getItem(TOKEN_MULTIMEDIA);
const sessionTokenMultimedia = sessionStorage.getItem('token'); // Temporal const sessionTokenMultimedia = sessionStorage.getItem(TOKEN_MULTIMEDIA);
return localTokenMultimedia || sessionTokenMultimedia || ''; return localTokenMultimedia || sessionTokenMultimedia || '';
} }
function setToken(data) { function setToken(data) {
if (data.keepLogin) { const storage = data.keepLogin ? localStorage : sessionStorage;
localStorage.setItem('token', data.token); storage.setItem(TOKEN, data.token);
localStorage.setItem('tokenMultimedia', data.tokenMultimedia); storage.setItem(TOKEN_MULTIMEDIA, data.tokenMultimedia);
} else {
sessionStorage.setItem('token', data.token);
sessionStorage.setItem('tokenMultimedia', data.tokenMultimedia);
}
} }
async function destroyToken(url, storage, key) { async function destroyToken(url, storage, key) {
if (storage.getItem(key)) { if (storage.getItem(key)) {
@ -71,8 +69,8 @@ export function useSession() {
} }
function isLoggedIn() { function isLoggedIn() {
const localToken = localStorage.getItem('token'); const localToken = localStorage.getItem(TOKEN);
const sessionToken = sessionStorage.getItem('token'); const sessionToken = sessionStorage.getItem(TOKEN);
return !!(localToken || sessionToken); return !!(localToken || sessionToken);
} }

View File

@ -1095,6 +1095,7 @@ item:
list: List list: List
diary: Diary diary: Diary
tags: Tags tags: Tags
wasteBreakdown: Waste breakdown
itemCreate: New item itemCreate: New item
descriptor: descriptor:
item: Item item: Item
@ -1123,6 +1124,13 @@ item:
stemMultiplier: Multiplier stemMultiplier: Multiplier
producer: Producer producer: Producer
landed: Landed landed: Landed
create:
name: Name
tag: Tag
priority: Priority
type: Type
intrastat: Intrastat
origin: Origin
components: components:
topbar: {} topbar: {}
userPanel: userPanel:

View File

@ -1094,6 +1094,7 @@ item:
list: Listado list: Listado
diary: Histórico diary: Histórico
tags: Etiquetas tags: Etiquetas
wasteBreakdown: Deglose de mermas
itemCreate: Nuevo artículo itemCreate: Nuevo artículo
descriptor: descriptor:
item: Artículo item: Artículo
@ -1122,6 +1123,13 @@ item:
stemMultiplier: Multiplicador stemMultiplier: Multiplicador
producer: Productor producer: Productor
landed: F. entrega landed: F. entrega
create:
name: Nombre
tag: Etiqueta
priority: Prioridad
type: Tipo
intrastat: Intrastat
origin: Origen
components: components:
topbar: {} topbar: {}
userPanel: userPanel:

View File

@ -268,16 +268,11 @@ const importBuys = () => {
const toggleGroupingMode = async (buy, mode) => { const toggleGroupingMode = async (buy, mode) => {
try { try {
const grouping = 1; const groupingMode = mode === 'grouping' ? mode : 'packing';
const packing = 2; const newGroupingMode = buy.groupingMode === groupingMode ? null : groupingMode;
const groupingMode = mode === 'grouping' ? grouping : packing;
const newGroupingMode = buy.groupingMode === groupingMode ? 0 : groupingMode;
const params = { const params = {
groupingMode: newGroupingMode, groupingMode: newGroupingMode,
}; };
await axios.patch(`Buys/${buy.id}`, params); await axios.patch(`Buys/${buy.id}`, params);
buy.groupingMode = newGroupingMode; buy.groupingMode = newGroupingMode;
} catch (err) { } catch (err) {
@ -287,9 +282,9 @@ const toggleGroupingMode = async (buy, mode) => {
const lockIconType = (groupingMode, mode) => { const lockIconType = (groupingMode, mode) => {
if (mode === 'packing') { if (mode === 'packing') {
return groupingMode === 2 ? 'lock' : 'lock_open'; return groupingMode === 'packing' ? 'lock' : 'lock_open';
} else { } else {
return groupingMode === 1 ? 'lock' : 'lock_open'; return groupingMode === 'grouping' ? 'lock' : 'lock_open';
} }
}; };
</script> </script>

View File

@ -0,0 +1 @@
<template>Item basic data</template>

View File

@ -1 +1,170 @@
<template>Item create view</template> <script setup>
import { reactive, ref, onBeforeMount } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import FetchData from 'components/FetchData.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import axios from 'axios';
const { t } = useI18n();
const router = useRouter();
const newItemForm = reactive({});
const originsOptions = ref([]);
const tagsOptions = ref([]);
const validPriorities = ref([]);
const itemTypesOptions = ref([]);
const intrastatsOptions = ref([]);
const fetchDefaultPriorityTag = async () => {
const filter = {
fields: ['defaultPriority', 'defaultTag', 'validPriorities'],
limit: 1,
};
const { data } = await axios.get(`ItemConfigs`, { filter });
if (!data) return;
const dataRow = data[0];
validPriorities.value = [...dataRow.validPriorities];
newItemForm.priority = dataRow.defaultPriority;
newItemForm.tag = dataRow.defaultTag;
};
const redirectToItemBasicData = (_, { id }) => {
router.push({ name: 'ItemBasicData', params: { id } });
};
onBeforeMount(async () => {
await fetchDefaultPriorityTag();
});
</script>
<template>
<FetchData
url="Origins"
@on-fetch="(data) => (originsOptions = data)"
:filter="{ order: 'name' }"
auto-load
/>
<FetchData
url="Tags"
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
@on-fetch="(data) => (tagsOptions = data)"
auto-load
/>
<FetchData
url="ItemTypes"
:filter="{
fields: ['id', 'code', 'categoryFk', 'name'],
include: 'category',
order: 'name ASC',
}"
@on-fetch="(data) => (itemTypesOptions = data)"
auto-load
/>
<FetchData
url="Intrastats"
:filter="{ fields: ['id', 'description'], order: 'description ASC' }"
@on-fetch="(data) => (intrastatsOptions = data)"
auto-load
/>
<QPage>
<VnSubToolbar />
<FormModel
url-create="Items/new"
model="item"
:form-initial-data="newItemForm"
observe-form-changes
@on-data-saved="redirectToItemBasicData"
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<VnInput
v-model="data.provisionalName"
:label="t('item.create.name')"
/>
<VnSelectFilter
:label="t('item.create.tag')"
v-model="data.tag"
:options="tagsOptions"
option-value="id"
option-label="name"
hide-selected
/>
<VnSelectFilter
:label="t('item.create.priority')"
v-model="data.priority"
:options="validPriorities"
option-value="priority"
option-label="priority"
hide-selected
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
:label="t('item.create.type')"
v-model="data.typeFk"
:options="itemTypesOptions"
option-label="name"
option-value="id"
hide-selected
>
<template #option="scope">
<QItem class="column" v-bind="scope.itemProps">
<QItemLabel class="row">
<span style="width: 3em">
{{ scope.opt?.code }}
</span>
<span>
{{ scope.opt?.name }}
</span>
</QItemLabel>
<QItemLabel v-if="scope.opt?.category" caption>
{{ scope.opt?.category?.name }}
</QItemLabel>
</QItem>
</template>
</VnSelectFilter>
<VnSelectFilter
:label="t('item.create.intrastat')"
v-model="data.intrastatFk"
:options="intrastatsOptions"
option-label="description"
option-value="id"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>
{{ scope.opt?.description }}
</QItemLabel>
<QItemLabel caption>
#{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelectFilter>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
:label="t('item.create.origin')"
v-model="data.originFk"
:options="originsOptions"
option-value="id"
option-label="name"
hide-selected
/>
</VnRow>
</template>
</FormModel>
</QPage>
</template>

View File

@ -1,10 +1,9 @@
<script setup> <script setup>
import { onMounted, ref, computed, onUpdated } from 'vue'; import { ref, computed, onUpdated } 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 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import { getUrl } from 'src/composables/getUrl';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import { dashIfEmpty } from 'src/filters'; import { dashIfEmpty } from 'src/filters';
import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue';
@ -28,12 +27,6 @@ const entityId = computed(() => $props.id || route.params.id);
const summaryRef = ref(); const summaryRef = ref();
const supplier = ref(); const supplier = ref();
const supplierUrl = ref();
onMounted(async () => {
await roleState.fetch();
supplierUrl.value = (await getUrl('supplier/')) + entityId.value;
});
async function setData(data) { async function setData(data) {
if (data) { if (data) {
@ -44,6 +37,10 @@ async function setData(data) {
const isAdministrative = computed(() => { const isAdministrative = computed(() => {
return roleState.hasAny(['administrative']); return roleState.hasAny(['administrative']);
}); });
function getUrl(section) {
return isAdministrative.value && `#/supplier/${entityId.value}/${section}`;
}
</script> </script>
<template> <template>
@ -58,15 +55,10 @@ const isAdministrative = computed(() => {
<template #body> <template #body>
<QCard class="vn-one"> <QCard class="vn-one">
<router-link <VnTitle
v-if="isAdministrative" :url="getUrl('basic-data')"
class="header link" :text="t('globals.summary.basicData')"
:to="{ name: 'SupplierBasicData', params: { id: entityId } }" />
>
{{ t('globals.summary.basicData') }}
<QIcon name="open_in_new" />
</router-link>
<span v-else> {{ t('globals.summary.basicData') }}</span>
<VnLv label="Id" :value="supplier.id" /> <VnLv label="Id" :value="supplier.id" />
<VnLv label="Alias" :value="supplier.nickname" /> <VnLv label="Alias" :value="supplier.nickname" />
<VnLv :label="t('supplier.summary.responsible')"> <VnLv :label="t('supplier.summary.responsible')">
@ -94,15 +86,10 @@ const isAdministrative = computed(() => {
/> />
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<router-link <VnTitle
v-if="isAdministrative" :url="getUrl('billing-data')"
class="header link" :text="t('supplier.summary.billingData')"
:to="{ name: 'SupplierBillingData', params: { id: entityId } }" />
>
{{ t('supplier.summary.billingData') }}
<QIcon name="open_in_new" />
</router-link>
<span v-else> {{ t('supplier.summary.billingData') }}</span>
<VnLv <VnLv
:label="t('supplier.summary.payMethod')" :label="t('supplier.summary.payMethod')"
:value="supplier.payMethod?.name" :value="supplier.payMethod?.name"
@ -117,15 +104,10 @@ const isAdministrative = computed(() => {
<VnLv :label="t('supplier.summary.account')" :value="supplier.account" /> <VnLv :label="t('supplier.summary.account')" :value="supplier.account" />
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<router-link <VnTitle
v-if="isAdministrative" :url="getUrl('fiscal-data')"
class="header link" :text="t('supplier.summary.fiscalData')"
:to="{ name: 'SupplierFiscalData', params: { id: entityId } }" />
>
{{ t('supplier.summary.fiscalData') }}
<QIcon name="open_in_new" />
</router-link>
<span v-else> {{ t('supplier.summary.fiscalData') }}</span>
<VnLv <VnLv
:label="t('supplier.summary.sageTaxType')" :label="t('supplier.summary.sageTaxType')"
:value="supplier.sageTaxType?.vat" :value="supplier.sageTaxType?.vat"
@ -152,15 +134,10 @@ const isAdministrative = computed(() => {
/> />
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<router-link <VnTitle
v-if="isAdministrative" :url="getUrl('fiscal-data')"
class="header link" :text="t('supplier.summary.fiscalAddress')"
:to="{ name: 'SupplierFiscalData', params: { id: entityId } }" />
>
{{ t('supplier.summary.fiscalAddress') }}
<QIcon name="open_in_new" />
</router-link>
<span v-else> {{ t('supplier.summary.fiscalAddress') }}</span>
<VnLv :label="t('supplier.summary.socialName')" :value="supplier.name" /> <VnLv :label="t('supplier.summary.socialName')" :value="supplier.name" />
<VnLv :label="t('supplier.summary.taxNumber')" :value="supplier.nif" /> <VnLv :label="t('supplier.summary.taxNumber')" :value="supplier.nif" />
<VnLv :label="t('supplier.summary.street')" :value="supplier.street" /> <VnLv :label="t('supplier.summary.street')" :value="supplier.street" />

View File

@ -10,8 +10,8 @@ export default {
component: RouterView, component: RouterView,
redirect: { name: 'ItemMain' }, redirect: { name: 'ItemMain' },
menus: { menus: {
main: ['ItemList'], main: ['ItemList', 'WasteBreakdown'],
card: [], card: ['ItemBasicData'],
}, },
children: [ children: [
{ {
@ -37,6 +37,19 @@ export default {
}, },
component: () => import('src/pages/Item/ItemCreate.vue'), component: () => import('src/pages/Item/ItemCreate.vue'),
}, },
{
path: 'waste-breakdown',
name: 'WasteBreakdown',
meta: {
title: 'wasteBreakdown',
icon: 'vn:claims',
},
beforeEnter: (to, from, next) => {
next({ name: 'ItemList' });
window.location.href =
'https://grafana.verdnatura.es/d/TTNXQAxVk';
},
},
], ],
}, },
{ {
@ -72,6 +85,15 @@ export default {
}, },
component: () => import('src/pages/Item/Card/ItemTags.vue'), component: () => import('src/pages/Item/Card/ItemTags.vue'),
}, },
{
path: 'basic-data',
name: 'ItemBasicData',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Item/Card/ItemBasicData.vue'),
},
], ],
}, },
], ],