297 lines
9.4 KiB
Vue
297 lines
9.4 KiB
Vue
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { toDate } from 'src/filters';
|
|
import { getUrl } from 'src/composables/getUrl';
|
|
import { useQuasar } from 'quasar';
|
|
import { usePrintService } from 'composables/usePrintService';
|
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
|
import VnLv from 'src/components/ui/VnLv.vue';
|
|
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
|
import axios from 'axios';
|
|
|
|
const quasar = useQuasar();
|
|
const { push } = useRouter();
|
|
const { openReport } = usePrintService();
|
|
|
|
const $props = defineProps({
|
|
id: {
|
|
type: Number,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
});
|
|
|
|
const route = useRoute();
|
|
const { t } = useI18n();
|
|
const entryDescriptorRef = ref(null);
|
|
const url = ref();
|
|
const entryFilter = {
|
|
include: [
|
|
{
|
|
relation: 'travel',
|
|
scope: {
|
|
fields: ['id', 'landed', 'shipped', 'agencyModeFk', 'warehouseOutFk'],
|
|
include: [
|
|
{
|
|
relation: 'agency',
|
|
scope: {
|
|
fields: ['name'],
|
|
},
|
|
},
|
|
{
|
|
relation: 'warehouseOut',
|
|
scope: {
|
|
fields: ['name'],
|
|
},
|
|
},
|
|
{
|
|
relation: 'warehouseIn',
|
|
scope: {
|
|
fields: ['name'],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
relation: 'supplier',
|
|
scope: {
|
|
fields: ['id', 'nickname'],
|
|
},
|
|
},
|
|
],
|
|
};
|
|
const entityId = computed(() => {
|
|
return $props.id || route.params.id;
|
|
});
|
|
onMounted(async () => {
|
|
url.value = await getUrl('');
|
|
});
|
|
|
|
const getEntryRedirectionFilter = (entry) => {
|
|
let entryTravel = entry && entry.travel;
|
|
|
|
if (!entryTravel || !entryTravel.landed) return null;
|
|
|
|
const date = new Date(entryTravel.landed);
|
|
date.setHours(0, 0, 0, 0);
|
|
|
|
const from = new Date(date.getTime());
|
|
from.setDate(from.getDate() - 10);
|
|
|
|
const to = new Date(date.getTime());
|
|
to.setDate(to.getDate() + 10);
|
|
|
|
return JSON.stringify({
|
|
supplierFk: entry.supplierFk,
|
|
from,
|
|
to,
|
|
});
|
|
};
|
|
|
|
function showEntryReport() {
|
|
openReport(`Entries/${entityId.value}/entry-order-pdf`);
|
|
}
|
|
|
|
function showNotification(type, message) {
|
|
quasar.notify({
|
|
type: type,
|
|
message: t(message),
|
|
});
|
|
}
|
|
|
|
async function recalculateRates(entity) {
|
|
try {
|
|
const entryConfig = await axios.get('EntryConfigs/findOne');
|
|
if (entryConfig.data?.inventorySupplierFk === entity.supplierFk) {
|
|
showNotification(
|
|
'negative',
|
|
'Cannot recalculate prices because this is an inventory entry',
|
|
);
|
|
return;
|
|
}
|
|
|
|
await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
|
|
showNotification('positive', 'Entry prices recalculated');
|
|
} catch (error) {
|
|
showNotification('negative', 'Failed to recalculate rates');
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
async function cloneEntry() {
|
|
try {
|
|
const response = await axios.post(`Entries/${entityId.value}/cloneEntry`);
|
|
push({ path: `/entry/${response.data[0].vNewEntryFk}` });
|
|
showNotification('positive', 'Entry cloned');
|
|
} catch (error) {
|
|
showNotification('negative', 'Failed to clone entry');
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
async function deleteEntry() {
|
|
try {
|
|
await axios.post(`Entries/${entityId.value}/deleteEntry`);
|
|
push({ path: `/entry/list` });
|
|
showNotification('positive', 'Entry deleted');
|
|
} catch (error) {
|
|
showNotification('negative', 'Failed to delete entry');
|
|
console.error(error);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<CardDescriptor
|
|
ref="entryDescriptorRef"
|
|
module="Entry"
|
|
:url="`Entries/${entityId}`"
|
|
:userFilter="entryFilter"
|
|
title="supplier.nickname"
|
|
data-key="Entry"
|
|
width="lg-width"
|
|
>
|
|
<template #menu="{ entity }">
|
|
<QItem
|
|
v-ripple
|
|
clickable
|
|
@click="showEntryReport(entity)"
|
|
data-cy="show-entry-report"
|
|
>
|
|
<QItemSection>{{ t('Show entry report') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
v-ripple
|
|
clickable
|
|
@click="recalculateRates(entity)"
|
|
data-cy="recalculate-rates"
|
|
>
|
|
<QItemSection>{{ t('Recalculate rates') }}</QItemSection>
|
|
</QItem>
|
|
<QItem v-ripple clickable @click="cloneEntry(entity)" data-cy="clone-entry">
|
|
<QItemSection>{{ t('Clone') }}</QItemSection>
|
|
</QItem>
|
|
<QItem
|
|
v-ripple
|
|
clickable
|
|
@click="deleteEntry(entity)"
|
|
data-cy="delete-entry"
|
|
v-if="entity?.travelFk"
|
|
>
|
|
<QItemSection>{{ t('Delete') }}</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
<template #body="{ entity }">
|
|
<VnLv :label="t('Travel')">
|
|
<template #value>
|
|
<span class="link" v-if="entity?.travelFk">
|
|
{{ entity.travel?.agency?.name }}
|
|
{{ entity.travel?.warehouseOut?.code }} →
|
|
{{ entity.travel?.warehouseIn?.code }}
|
|
<TravelDescriptorProxy :id="entity?.travelFk" />
|
|
</span>
|
|
</template>
|
|
</VnLv>
|
|
<VnLv
|
|
:label="t('entry.summary.travelShipped')"
|
|
:value="toDate(entity.travel?.shipped)"
|
|
/>
|
|
<VnLv
|
|
:label="t('entry.summary.travelLanded')"
|
|
:value="toDate(entity.travel?.landed)"
|
|
/>
|
|
<VnLv :label="t('entry.summary.currency')" :value="entity?.currency?.code" />
|
|
<VnLv
|
|
:label="t('entry.summary.invoiceAmount')"
|
|
:value="entity?.invoiceAmount"
|
|
/>
|
|
<VnLv
|
|
:label="t('entry.summary.entryType')"
|
|
:value="entity?.entryType?.description"
|
|
/>
|
|
</template>
|
|
<template #icons="{ entity }">
|
|
<QCardActions class="q-gutter-x-md">
|
|
<QIcon
|
|
v-if="entity?.isExcludedFromAvailable"
|
|
name="vn:inventory"
|
|
color="primary"
|
|
size="xs"
|
|
>
|
|
<QTooltip>{{ t('Inventory entry') }}</QTooltip>
|
|
</QIcon>
|
|
<QIcon
|
|
v-if="entity?.travel?.daysInForward"
|
|
name="vn:net"
|
|
color="primary"
|
|
size="xs"
|
|
>
|
|
<QTooltip>
|
|
{{
|
|
t('globals.raid', {
|
|
daysInForward: entity?.travel?.daysInForward,
|
|
})
|
|
}}</QTooltip
|
|
>
|
|
</QIcon>
|
|
<QIcon
|
|
v-if="!entity?.travelFk"
|
|
name="vn:deletedTicket"
|
|
size="xs"
|
|
color="primary"
|
|
>
|
|
<QTooltip>{{ t('This entry is deleted') }}</QTooltip>
|
|
</QIcon>
|
|
</QCardActions>
|
|
</template>
|
|
<template #actions="{ entity }">
|
|
<QCardActions>
|
|
<QBtn
|
|
:to="`/supplier/${entity.supplier?.id}`"
|
|
size="md"
|
|
icon="vn:supplier"
|
|
color="primary"
|
|
>
|
|
<QTooltip>{{ t('Supplier card') }}</QTooltip>
|
|
</QBtn>
|
|
<QBtn
|
|
:to="{
|
|
name: 'EntryMain',
|
|
query: {
|
|
params: getEntryRedirectionFilter(entity),
|
|
},
|
|
}"
|
|
size="md"
|
|
icon="vn:entry"
|
|
color="primary"
|
|
>
|
|
<QTooltip>{{ t('All entries with current supplier') }}</QTooltip>
|
|
</QBtn>
|
|
</QCardActions>
|
|
</template>
|
|
</CardDescriptor>
|
|
</template>
|
|
<i18n>
|
|
es:
|
|
Travel: Envío
|
|
Supplier card: Ficha del proveedor
|
|
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
|
|
Show entry report: Ver informe del pedido
|
|
Inventory entry: Es inventario
|
|
Virtual entry: Es una redada
|
|
shipped: Enviado
|
|
landed: Recibido
|
|
This entry is deleted: Esta entrada está eliminada
|
|
Cannot recalculate prices because this is an inventory entry: No se pueden recalcular los precios porque es una entrada de inventario
|
|
Entry deleted: Entrada eliminada
|
|
Entry cloned: Entrada clonada
|
|
Entry prices recalculated: Precios de la entrada recalculados
|
|
Failed to recalculate rates: No se pudieron recalcular las tarifas
|
|
Failed to clone entry: No se pudo clonar la entrada
|
|
Failed to delete entry: No se pudo eliminar la entrada
|
|
</i18n>
|