Compare commits

...

12 Commits

Author SHA1 Message Date
Alex Moreno 40568e183f fix: translation
gitea/salix-front/pipeline/pr-test This commit looks good Details
2024-11-24 11:37:58 +01:00
Alex Moreno a8ad48fae1 fix: translation
gitea/salix-front/pipeline/pr-test This commit looks good Details
2024-11-24 11:28:24 +01:00
Alex Moreno 34e00653f5 feat(Entry): add DescriptorMenu
gitea/salix-front/pipeline/pr-test This commit looks good Details
2024-11-24 11:21:59 +01:00
Alex Moreno ed3ad310c5 feat(Shelving): add DescriptorMenu 2024-11-24 11:16:08 +01:00
Alex Moreno b93633fc77 feat(Roadmap): add DescriptorMenu 2024-11-24 10:01:12 +01:00
Alex Moreno 0aa75043b8 feat(Route): add DescriptorMenu 2024-11-24 09:54:05 +01:00
Alex Moreno af32a4d512 feat(InvoiceOut): add DescriptorMenu 2024-11-24 09:49:00 +01:00
Alex Moreno 3506d2517a feat(Account): add DescriptorMenu 2024-11-24 09:45:32 +01:00
Alex Moreno 62ecc42a4b feat(ClaimSummary): add DescriptorMenu 2024-11-24 09:09:15 +01:00
Alex Moreno 752456915c feat(OrderSummary): add orderDescriptorMenu 2024-11-24 09:04:13 +01:00
Alex Moreno 51ed160e5e feat(ItemDescriptorMenu): create and use in descriptor and summary 2024-11-24 09:02:05 +01:00
Alex Moreno 6f7b83d593 feat(client and ticket): add moreOptions in summary 2024-11-22 15:30:43 +01:00
34 changed files with 208 additions and 129 deletions

View File

@ -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)"
> >

View File

@ -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">

View File

@ -5,6 +5,7 @@ import SkeletonSummary from 'components/ui/SkeletonSummary.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 { isDialogOpened } from 'src/filters'; import { isDialogOpened } from 'src/filters';
import VnMoreOptions from './VnMoreOptions.vue';
const props = defineProps({ const props = defineProps({
url: { url: {
@ -83,9 +84,14 @@ async function fetch() {
<slot name="header" :entity="entity" dense> <slot name="header" :entity="entity" dense>
<VnLv :label="`${entity.id} -`" :value="entity.name" /> <VnLv :label="`${entity.id} -`" :value="entity.name" />
</slot> </slot>
<slot name="header-right" :entity="entity"> <span class="row no-wrap">
<span></span> <slot name="header-right" :entity="entity" />
</slot> <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" />

View File

@ -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>

View File

@ -0,0 +1,6 @@
import axios from 'axios';
export default async (id) => {
const { data } = await axios.get(`Accounts/${id}/exists`);
return data.exists;
};

View File

@ -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,15 +31,13 @@ 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`"
@ -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>
<!-- falla id :id="entityId.value" collection="user" size="160x160" --> <!-- falla id :id="entityId.value" collection="user" size="160x160" -->
@ -91,7 +90,7 @@ const hasAccount = ref(false);
<QIcon <QIcon
color="primary" color="primary"
name="contact_mail" name="contact_mail"
v-if="entity.hasAccount" v-if="hasAccount"
flat flat
round round
size="sm" size="sm"

View File

@ -1,36 +1,36 @@
<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 useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import useHasAccount from 'src/composables/useHasAccount.js';
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 } = useNotify();
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;
@ -41,7 +41,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({

View File

@ -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 = [];

View File

@ -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,16 +31,6 @@ 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 () => {
const response = await axios.get(`MailForwards/${route.params.id}`); const response = await axios.get(`MailForwards/${route.params.id}`);
return response.data; return response.data;
@ -68,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;

View File

@ -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();
@ -30,13 +31,15 @@ const filter = {
<template> <template>
<CardSummary <CardSummary
data-key="AccountSummary" 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">

View File

@ -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

View File

@ -1,18 +1,18 @@
<script setup> <script setup>
import { computed, ref, onMounted } 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 VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue';
import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters'; import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters';
import CardSummary from 'components/ui/CardSummary.vue'; import CardSummary from 'components/ui/CardSummary.vue';
import { getUrl } from 'src/composables/getUrl';
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 VnLinkMail from 'src/components/ui/VnLinkMail.vue'; 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';
@ -71,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
@ -320,7 +323,7 @@ const sumRisk = ({ clientRisks }) => {
:value="entity.recommendedCredit" :value="entity.recommendedCredit"
/> />
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-max">
<VnTitle :text="t('Latest tickets')" /> <VnTitle :text="t('Latest tickets')" />
<CustomerSummaryTable /> <CustomerSummaryTable />
</QCard> </QCard>

View File

@ -10,6 +10,7 @@ import { toDate } from 'src/filters';
import { usePrintService } from 'composables/usePrintService'; 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: {
@ -68,9 +69,7 @@ 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" />
@ -154,7 +153,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

View File

@ -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>

View File

@ -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';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
@ -147,9 +148,8 @@ async function setEntryData(data) {
} }
const fetchEntryBuys = async () => { const fetchEntryBuys = async () => {
const { data } = await axios.get(`Entries/${entry.value.id}/getBuys`); const { data } = await axios.get(`Entries/${entry.value.id}/getBuys`);
if (data) entryBuys.value = data; if (data) entryBuys.value = data;
}; };
</script> </script>
@ -171,6 +171,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">
<router-link <router-link

View File

@ -247,7 +247,6 @@ onMounted(async () => {
<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

View File

@ -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

View File

@ -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

View File

@ -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')" />

View File

@ -6,13 +6,12 @@ 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: {
@ -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', {
@ -68,7 +65,7 @@ const setData = async (entity) => {
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>

View File

@ -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 }

View File

@ -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>

View File

@ -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,6 +44,9 @@ 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

View File

@ -373,5 +373,4 @@ const columns = computed(() => [
es: es:
New item: Nuevo artículo New item: Nuevo artículo
Preview: Vista previa Preview: Vista previa
Regularize stock: Regularizar stock
</i18n> </i18n>

View File

@ -205,3 +205,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

View File

@ -207,3 +207,4 @@ item:
achieved: 'Conseguido' achieved: 'Conseguido'
concept: 'Concepto' concept: 'Concepto'
state: 'Estado' state: 'Estado'
regularizeStock: Regularizar stock

View File

@ -89,9 +89,6 @@ const total = ref(null);
@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')"

View File

@ -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 './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

View File

@ -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',
}); });
} }

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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 = {
@ -45,6 +46,12 @@ const filter = {
<template #header="{ entity }"> <template #header="{ entity }">
<div>{{ entity.code }}</div> <div>{{ entity.code }}</div>
</template> </template>
<template #menu="{ entity }">
<ShelvingDescriptorMenu
:shelving="entity"
@on-remove="$refs.summary.fetch()"
/>
</template>
<template #body="{ entity }"> <template #body="{ entity }">
<QCard class="vn-one"> <QCard class="vn-one">
<RouterLink <RouterLink

View File

@ -113,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"
@ -132,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