forked from verdnatura/salix-front
Merge branch 'feature/EntrySubmodules' of https://gitea.verdnatura.es/hyervoni/salix-front-mindshore into feature/ms-141-EntrySubmoduleNotes
This commit is contained in:
commit
5d9e48c979
|
@ -1,7 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'update:options']);
|
const emit = defineEmits(['update:modelValue', 'update:options', 'keyup.enter']);
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
@ -32,6 +32,10 @@ const styleAttrs = computed(() => {
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onEnterPress = () => {
|
||||||
|
emit('keyup.enter');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -41,6 +45,7 @@ const styleAttrs = computed(() => {
|
||||||
v-bind="{ ...$attrs, ...styleAttrs }"
|
v-bind="{ ...$attrs, ...styleAttrs }"
|
||||||
type="text"
|
type="text"
|
||||||
:class="{ required: $attrs.required }"
|
:class="{ required: $attrs.required }"
|
||||||
|
@keyup.enter="onEnterPress()"
|
||||||
>
|
>
|
||||||
<template v-if="$slots.prepend" #prepend>
|
<template v-if="$slots.prepend" #prepend>
|
||||||
<slot name="prepend" />
|
<slot name="prepend" />
|
||||||
|
|
|
@ -261,9 +261,11 @@ export default {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
entries: 'Entries',
|
entries: 'Entries',
|
||||||
list: 'List',
|
list: 'List',
|
||||||
createEntry: 'New entry',
|
|
||||||
summary: 'Summary',
|
summary: 'Summary',
|
||||||
create: 'Create',
|
basicData: 'Basic data',
|
||||||
|
buys: 'Buys',
|
||||||
|
notes: 'Notes',
|
||||||
|
log: 'Log',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
newEntry: 'New entry',
|
newEntry: 'New entry',
|
||||||
|
@ -303,6 +305,35 @@ export default {
|
||||||
buyingValue: 'Buying value',
|
buyingValue: 'Buying value',
|
||||||
import: 'Import',
|
import: 'Import',
|
||||||
pvp: 'PVP',
|
pvp: 'PVP',
|
||||||
|
item: 'Item',
|
||||||
|
},
|
||||||
|
basicData: {
|
||||||
|
supplier: 'Supplier',
|
||||||
|
travel: 'Travel',
|
||||||
|
reference: 'Reference',
|
||||||
|
invoiceNumber: 'Invoice number',
|
||||||
|
company: 'Company',
|
||||||
|
currency: 'Currency',
|
||||||
|
commission: 'Commission',
|
||||||
|
observation: 'Observation',
|
||||||
|
ordered: 'Ordered',
|
||||||
|
confirmed: 'Confirmed',
|
||||||
|
booked: 'Booked',
|
||||||
|
raid: 'Raid',
|
||||||
|
excludedFromAvailable: 'Inventory',
|
||||||
|
},
|
||||||
|
buys: {
|
||||||
|
groupingPrice: 'Grouping price',
|
||||||
|
packingPrice: 'Packing price',
|
||||||
|
reference: 'Reference',
|
||||||
|
observations: 'Observations',
|
||||||
|
item: 'Item',
|
||||||
|
description: 'Description',
|
||||||
|
size: 'Size',
|
||||||
|
packing: 'Packing',
|
||||||
|
grouping: 'Grouping',
|
||||||
|
buyingValue: 'Buying value',
|
||||||
|
packagingFk: 'Box',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ticket: {
|
ticket: {
|
||||||
|
|
|
@ -261,7 +261,10 @@ export default {
|
||||||
entries: 'Entradas',
|
entries: 'Entradas',
|
||||||
list: 'Listado',
|
list: 'Listado',
|
||||||
summary: 'Resumen',
|
summary: 'Resumen',
|
||||||
create: 'Crear',
|
basicData: 'Datos básicos',
|
||||||
|
buys: 'Compras',
|
||||||
|
notes: 'Notas',
|
||||||
|
log: 'Historial',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
newEntry: 'Nueva entrada',
|
newEntry: 'Nueva entrada',
|
||||||
|
@ -301,6 +304,35 @@ export default {
|
||||||
buyingValue: 'Coste',
|
buyingValue: 'Coste',
|
||||||
import: 'Importe',
|
import: 'Importe',
|
||||||
pvp: 'PVP',
|
pvp: 'PVP',
|
||||||
|
item: 'Artículo',
|
||||||
|
},
|
||||||
|
basicData: {
|
||||||
|
supplier: 'Proveedor',
|
||||||
|
travel: 'Envío',
|
||||||
|
reference: 'Referencia',
|
||||||
|
invoiceNumber: 'Núm. factura',
|
||||||
|
company: 'Empresa',
|
||||||
|
currency: 'Moneda',
|
||||||
|
observation: 'Observación',
|
||||||
|
commission: 'Comisión',
|
||||||
|
ordered: 'Pedida',
|
||||||
|
confirmed: 'Confirmado',
|
||||||
|
booked: 'Asentado',
|
||||||
|
raid: 'Redada',
|
||||||
|
excludedFromAvailable: 'Inventario',
|
||||||
|
},
|
||||||
|
buys: {
|
||||||
|
groupingPrice: 'Precio grouping',
|
||||||
|
packingPrice: 'Precio packing',
|
||||||
|
reference: 'Referencia',
|
||||||
|
observations: 'Observaciónes',
|
||||||
|
item: 'Artículo',
|
||||||
|
description: 'Descripción',
|
||||||
|
size: 'Medida',
|
||||||
|
packing: 'Packing',
|
||||||
|
grouping: 'Grouping',
|
||||||
|
buyingValue: 'Coste',
|
||||||
|
packagingFk: 'Embalaje',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ticket: {
|
ticket: {
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import FormModel from 'components/FormModel.vue';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||||
|
|
||||||
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const suppliersOptions = ref([]);
|
||||||
|
const travelsOptions = ref([]);
|
||||||
|
const companiesOptions = ref([]);
|
||||||
|
const currenciesOptions = ref([]);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
url="Suppliers"
|
||||||
|
:filter="{ fields: ['id', 'nickname'] }"
|
||||||
|
order="nickname"
|
||||||
|
@on-fetch="(data) => (suppliersOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
url="Travels/filter"
|
||||||
|
:filter="{ fields: ['id', 'warehouseInName'] }"
|
||||||
|
order="id"
|
||||||
|
@on-fetch="(data) => (travelsOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
ref="companiesRef"
|
||||||
|
url="Companies"
|
||||||
|
:filter="{ fields: ['id', 'code'] }"
|
||||||
|
order="code"
|
||||||
|
@on-fetch="(data) => (companiesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
ref="currenciesRef"
|
||||||
|
url="Currencies"
|
||||||
|
:filter="{ fields: ['id', 'code'] }"
|
||||||
|
order="code"
|
||||||
|
@on-fetch="(data) => (currenciesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FormModel
|
||||||
|
:url="`Entries/${route.params.id}`"
|
||||||
|
:url-update="`Entries/${route.params.id}`"
|
||||||
|
model="entry"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
|
<template #form="{ data }">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('entry.basicData.supplier')"
|
||||||
|
v-model="data.supplierFk"
|
||||||
|
:options="suppliersOptions"
|
||||||
|
option-value="id"
|
||||||
|
option-label="nickname"
|
||||||
|
hide-selected
|
||||||
|
:required="true"
|
||||||
|
map-options
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{ scope.opt?.nickname }}, {{ scope.opt?.id }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelectFilter>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('entry.basicData.travel')"
|
||||||
|
v-model="data.travelFk"
|
||||||
|
:options="travelsOptions"
|
||||||
|
option-value="id"
|
||||||
|
option-label="warehouseInName"
|
||||||
|
map-options
|
||||||
|
hide-selected
|
||||||
|
:required="true"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel
|
||||||
|
>{{ scope.opt?.agencyModeName }} -
|
||||||
|
{{ scope.opt?.warehouseInName }} ({{
|
||||||
|
toDate(scope.opt?.shipped)
|
||||||
|
}}) → {{ scope.opt?.warehouseOutName }} ({{
|
||||||
|
toDate(scope.opt?.landed)
|
||||||
|
}})</QItemLabel
|
||||||
|
>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelectFilter>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnInput
|
||||||
|
v-model="data.reference"
|
||||||
|
:label="t('entry.basicData.reference')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnInput
|
||||||
|
v-model="data.invoiceNumber"
|
||||||
|
:label="t('entry.basicData.invoiceNumber')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('entry.basicData.company')"
|
||||||
|
v-model="data.companyFk"
|
||||||
|
:options="companiesOptions"
|
||||||
|
option-value="id"
|
||||||
|
option-label="code"
|
||||||
|
map-options
|
||||||
|
hide-selected
|
||||||
|
:required="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('entry.basicData.currency')"
|
||||||
|
v-model="data.currencyFk"
|
||||||
|
:options="currenciesOptions"
|
||||||
|
option-value="id"
|
||||||
|
option-label="code"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QInput
|
||||||
|
:label="t('entry.basicData.commission')"
|
||||||
|
v-model="data.commission"
|
||||||
|
type="number"
|
||||||
|
autofocus
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput
|
||||||
|
:label="t('entry.basicData.observation')"
|
||||||
|
type="textarea"
|
||||||
|
v-model="data.observation"
|
||||||
|
fill-input
|
||||||
|
autogrow
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QCheckbox
|
||||||
|
v-model="data.isOrdered"
|
||||||
|
:label="t('entry.basicData.ordered')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QCheckbox
|
||||||
|
v-model="data.isConfirmed"
|
||||||
|
:label="t('entry.basicData.confirmed')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QCheckbox
|
||||||
|
v-model="data.isExcludedFromAvailable"
|
||||||
|
:label="t('entry.basicData.excludedFromAvailable')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QCheckbox
|
||||||
|
v-model="data.isBooked"
|
||||||
|
:label="t('entry.basicData.booked')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
</template>
|
||||||
|
</FormModel>
|
||||||
|
</template>
|
|
@ -0,0 +1,407 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||||
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||||
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { toCurrency } from 'src/filters';
|
||||||
|
import axios from 'axios';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
|
||||||
|
const quasar = useQuasar();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const stateStore = useStateStore();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
const rowsSelected = ref([]);
|
||||||
|
const entryBuysPaginateRef = ref(null);
|
||||||
|
const packagingsOptions = ref(null);
|
||||||
|
|
||||||
|
const tableColumnComponents = computed(() => ({
|
||||||
|
item: {
|
||||||
|
component: () => 'span',
|
||||||
|
props: () => {},
|
||||||
|
event: () => ({}),
|
||||||
|
},
|
||||||
|
quantity: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
class: 'input-number',
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
packagingFk: {
|
||||||
|
component: () => VnSelectFilter,
|
||||||
|
props: () => ({
|
||||||
|
'option-value': 'id',
|
||||||
|
'option-label': 'id',
|
||||||
|
'emit-value': true,
|
||||||
|
'map-options': true,
|
||||||
|
'use-input': true,
|
||||||
|
'hide-selected': true,
|
||||||
|
options: packagingsOptions.value,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'update:modelValue': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
stickers: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
class: 'input-number',
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
weight: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
packing: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
grouping: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
buyingValue: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
price2: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
price3: {
|
||||||
|
component: () => VnInput,
|
||||||
|
props: (col) => ({
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
label: col.label,
|
||||||
|
}),
|
||||||
|
event: (props) => ({
|
||||||
|
'keyup.enter': () => saveChange(props.row),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
import: {
|
||||||
|
component: () => 'span',
|
||||||
|
props: () => {},
|
||||||
|
event: () => ({}),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const entriesTableColumns = computed(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('entry.summary.item'),
|
||||||
|
field: 'id',
|
||||||
|
name: 'item',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.quantity'),
|
||||||
|
field: 'quantity',
|
||||||
|
name: 'quantity',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.package'),
|
||||||
|
field: 'packagingFk',
|
||||||
|
name: 'packagingFk',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.stickers'),
|
||||||
|
field: 'stickers',
|
||||||
|
name: 'stickers',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.weight'),
|
||||||
|
field: 'weight',
|
||||||
|
name: 'weight',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.packing'),
|
||||||
|
field: 'packing',
|
||||||
|
name: 'packing',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.grouping'),
|
||||||
|
field: 'grouping',
|
||||||
|
name: 'grouping',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.buyingValue'),
|
||||||
|
field: 'buyingValue',
|
||||||
|
name: 'buyingValue',
|
||||||
|
align: 'left',
|
||||||
|
format: (value) => toCurrency(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.groupingPrice'),
|
||||||
|
field: 'price2',
|
||||||
|
name: 'price2',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.packingPrice'),
|
||||||
|
field: 'price3',
|
||||||
|
name: 'price3',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.summary.import'),
|
||||||
|
name: 'import',
|
||||||
|
align: 'left',
|
||||||
|
format: (_, row) => toCurrency(row.buyingValue * row.quantity),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
const saveChange = async (rowData) => {
|
||||||
|
await axios.patch(`Buys/${rowData.id}`, rowData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openRemoveDialog = async () => {
|
||||||
|
quasar
|
||||||
|
.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t('Confirm deletion'),
|
||||||
|
message:
|
||||||
|
rowsSelected.value.length > 1
|
||||||
|
? t('Are you sure you want to delete this buys?')
|
||||||
|
: t('Are you sure you want to delete this buy?'),
|
||||||
|
data: rowsSelected.value,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.onOk(async () => {
|
||||||
|
try {
|
||||||
|
await deleteBuys();
|
||||||
|
const notifyMessage =
|
||||||
|
rowsSelected.value.length > 1 ? t('Buys deleted') : t('Buy deleted');
|
||||||
|
notify(notifyMessage, 'positive');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error deleting buys');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteBuys = async () => {
|
||||||
|
await axios.post('Buys/deleteBuys', { buys: rowsSelected.value });
|
||||||
|
entryBuysPaginateRef.value.fetch();
|
||||||
|
};
|
||||||
|
|
||||||
|
const importBuys = () => {
|
||||||
|
router.push({ name: 'EntryBuysImport' });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
ref="expensesRef"
|
||||||
|
url="Packagings"
|
||||||
|
:filter="{ fields: ['id'], where: { freightItemFk: true }, order: 'id ASC' }"
|
||||||
|
auto-load
|
||||||
|
@on-fetch="(data) => (packagingsOptions = data)"
|
||||||
|
/>
|
||||||
|
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
||||||
|
<QBtnGroup push style="column-gap: 10px">
|
||||||
|
<slot name="moreBeforeActions" />
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.remove')"
|
||||||
|
color="primary"
|
||||||
|
icon="delete"
|
||||||
|
flat
|
||||||
|
@click="openRemoveDialog()"
|
||||||
|
:disable="!rowsSelected?.length"
|
||||||
|
:title="t('globals.remove')"
|
||||||
|
/>
|
||||||
|
</QBtnGroup>
|
||||||
|
</Teleport>
|
||||||
|
<VnPaginate
|
||||||
|
ref="entryBuysPaginateRef"
|
||||||
|
data-key="EntryBuys"
|
||||||
|
:url="`Entries/${route.params.id}/getBuys`"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
|
<template #body="{ rows }">
|
||||||
|
<QTable
|
||||||
|
:rows="rows"
|
||||||
|
:columns="entriesTableColumns"
|
||||||
|
selection="multiple"
|
||||||
|
row-key="id"
|
||||||
|
hide-bottom
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
:grid="$q.screen.lt.md"
|
||||||
|
v-model:selected="rowsSelected"
|
||||||
|
>
|
||||||
|
<template #body="props">
|
||||||
|
<QTr>
|
||||||
|
<QTd>
|
||||||
|
<QCheckbox v-model="props.selected" />
|
||||||
|
</QTd>
|
||||||
|
<QTd v-for="col in props.cols" :key="col.name">
|
||||||
|
<component
|
||||||
|
:is="tableColumnComponents[col.name].component()"
|
||||||
|
v-bind="tableColumnComponents[col.name].props(col)"
|
||||||
|
v-model="props.row[col.field]"
|
||||||
|
v-on="tableColumnComponents[col.name].event(props)"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="col.name === 'item' || col.name === 'import'"
|
||||||
|
>
|
||||||
|
{{ col.value }}
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
</QTd>
|
||||||
|
</QTr>
|
||||||
|
<QTr no-hover>
|
||||||
|
<QTd />
|
||||||
|
<QTd>
|
||||||
|
<span>{{ props.row.item.itemType.code }}</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd>
|
||||||
|
<span>{{ props.row.item.id }}</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd>
|
||||||
|
<span>{{ props.row.item.size }}</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd>
|
||||||
|
<span>{{ toCurrency(props.row.item.minPrice) }}</span>
|
||||||
|
</QTd>
|
||||||
|
<QTd colspan="7">
|
||||||
|
<span>{{ props.row.item.concept }}</span>
|
||||||
|
<span v-if="props.row.item.subName" class="subName">
|
||||||
|
{{ props.row.item.subName }}
|
||||||
|
</span>
|
||||||
|
<fetched-tags :item="props.row.item" :max-length="5" />
|
||||||
|
</QTd>
|
||||||
|
</QTr>
|
||||||
|
<!-- Esta última row es utilizada para agregar un espaciado y así marcar una diferencia visual entre los diferentes buys -->
|
||||||
|
<QTr v-if="props.rowIndex !== rows.length - 1" class="separation-row">
|
||||||
|
<QTd colspan="12" style="height: 24px" />
|
||||||
|
</QTr>
|
||||||
|
</template>
|
||||||
|
<template #item="props">
|
||||||
|
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
||||||
|
<QCard bordered flat>
|
||||||
|
<QCardSection>
|
||||||
|
<QCheckbox v-model="props.selected" dense />
|
||||||
|
</QCardSection>
|
||||||
|
<QSeparator />
|
||||||
|
<QList dense>
|
||||||
|
<QItem v-for="col in props.cols" :key="col.name">
|
||||||
|
<component
|
||||||
|
:is="tableColumnComponents[col.name].component()"
|
||||||
|
v-bind="
|
||||||
|
tableColumnComponents[col.name].props(col)
|
||||||
|
"
|
||||||
|
v-model="props.row[col.field]"
|
||||||
|
v-on="
|
||||||
|
tableColumnComponents[col.name].event(props)
|
||||||
|
"
|
||||||
|
class="full-width"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
col.name === 'item' ||
|
||||||
|
col.name === 'import'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ col.label + ': ' + col.value }}
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
</QItem>
|
||||||
|
</QList>
|
||||||
|
</QCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</template>
|
||||||
|
</VnPaginate>
|
||||||
|
<QPageSticky :offset="[20, 20]">
|
||||||
|
<QBtn fab icon="upload" color="primary" @click="importBuys()" />
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Import buys') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QPageSticky>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.separation-row {
|
||||||
|
background-color: var(--vn-gray) !important;
|
||||||
|
}
|
||||||
|
.grid-style-transition {
|
||||||
|
transition: transform 0.28s, background-color 0.28s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
Import buys: Importar compras
|
||||||
|
Buy deleted: Compra eliminada
|
||||||
|
Buys deleted: Compras eliminadas
|
||||||
|
Confirm deletion: Confirmar eliminación
|
||||||
|
Are you sure you want to delete this buy?: Seguro que quieres eliminar esta compra?
|
||||||
|
Are you sure you want to delete this buys?: Seguro que quieres eliminar estas compras?
|
||||||
|
</i18n>
|
|
@ -0,0 +1,281 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
|
||||||
|
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import axios from 'axios';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { toCurrency } from 'filters/index';
|
||||||
|
|
||||||
|
const stateStore = useStateStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
const importData = ref({
|
||||||
|
file: null,
|
||||||
|
invoice: null,
|
||||||
|
buys: [],
|
||||||
|
observation: null,
|
||||||
|
ref: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const lastItemBuysOptions = ref([]);
|
||||||
|
const packagingsOptions = ref([]);
|
||||||
|
|
||||||
|
const columns = computed(() => [
|
||||||
|
{
|
||||||
|
label: t('entry.buys.item'),
|
||||||
|
name: 'item',
|
||||||
|
field: 'itemFk',
|
||||||
|
options: lastItemBuysOptions.value,
|
||||||
|
optionValue: 'id',
|
||||||
|
optionLabel: 'name',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.description'),
|
||||||
|
name: 'description',
|
||||||
|
field: 'description',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.size'),
|
||||||
|
name: 'size',
|
||||||
|
field: 'size',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.packing'),
|
||||||
|
name: 'packing',
|
||||||
|
field: 'packing',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.grouping'),
|
||||||
|
name: 'grouping',
|
||||||
|
field: 'grouping',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.buyingValue'),
|
||||||
|
name: 'buyingValue',
|
||||||
|
field: 'buyingValue',
|
||||||
|
align: 'left',
|
||||||
|
format: (val) => toCurrency(val),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.packagingFk'),
|
||||||
|
name: 'packagingFk',
|
||||||
|
field: 'packagingFk',
|
||||||
|
options: packagingsOptions.value,
|
||||||
|
optionValue: 'id',
|
||||||
|
optionLabel: 'id',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const onFileChange = (e) => {
|
||||||
|
importData.value.file = e;
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => fillData(e.target.result);
|
||||||
|
reader.readAsText(importData.value.file);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fillData = async (rawData) => {
|
||||||
|
const data = JSON.parse(rawData);
|
||||||
|
const [invoice] = data.invoices;
|
||||||
|
|
||||||
|
importData.value.observation = invoice.tx_awb;
|
||||||
|
const companyName = invoice.tx_company;
|
||||||
|
const boxes = invoice.boxes;
|
||||||
|
const buys = [];
|
||||||
|
|
||||||
|
for (let box of boxes) {
|
||||||
|
const boxVolume = box.nu_length * box.nu_width * box.nu_height;
|
||||||
|
for (let product of box.products) {
|
||||||
|
const packing = product.nu_stems_bunch * product.nu_bunches;
|
||||||
|
buys.push({
|
||||||
|
description: product.nm_product,
|
||||||
|
companyName: companyName,
|
||||||
|
size: product.nu_length,
|
||||||
|
packing: packing,
|
||||||
|
grouping: product.nu_stems_bunch,
|
||||||
|
buyingValue: parseFloat(product.mny_rate_stem),
|
||||||
|
volume: boxVolume,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const boxesId = boxes.map((box) => box.id_box);
|
||||||
|
importData.value.ref = boxesId.join(', ');
|
||||||
|
await fetchBuys(buys);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchBuys = async (buys) => {
|
||||||
|
try {
|
||||||
|
const params = { buys };
|
||||||
|
const { data } = await axios.post(
|
||||||
|
`Entries/${route.params.id}/importBuysPreview`,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
importData.value.buys = data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error fetching buys');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const params = importData.value;
|
||||||
|
const hasAnyEmptyRow = params.buys.some((buy) => {
|
||||||
|
return buy.itemFk === null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasAnyEmptyRow) {
|
||||||
|
notify(t('Some of the imported buys does not have an item'), 'negative');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await axios.post(`Entries/${route.params.id}/importBuys`, params);
|
||||||
|
notify('globals.dataSaved', 'positive');
|
||||||
|
redirectToBuysView();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error importing buys', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const redirectToBuysView = () => {
|
||||||
|
router.push({ name: 'EntryBuys' });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
:url="`Entries/${route.params.id}/lastItemBuys`"
|
||||||
|
:filter="{ fields: ['id', 'name'] }"
|
||||||
|
order="id DESC"
|
||||||
|
@on-fetch="(data) => (lastItemBuysOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
url="Packagings"
|
||||||
|
:filter="{ fields: ['id'], where: { isBox: true } }"
|
||||||
|
order="id ASC"
|
||||||
|
@on-fetch="(data) => (packagingsOptions = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<QForm>
|
||||||
|
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
||||||
|
<div>
|
||||||
|
<QBtnGroup push class="q-gutter-x-sm">
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.cancel')"
|
||||||
|
color="primary"
|
||||||
|
icon="restart_alt"
|
||||||
|
flat
|
||||||
|
@click="redirectToBuysView()"
|
||||||
|
/>
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.save')"
|
||||||
|
color="primary"
|
||||||
|
icon="save"
|
||||||
|
type="submit"
|
||||||
|
:disable="!importData.file"
|
||||||
|
@click="onSubmit()"
|
||||||
|
/>
|
||||||
|
</QBtnGroup>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
<QCard class="q-pa-lg">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QFile
|
||||||
|
label="Standard"
|
||||||
|
:multiple="false"
|
||||||
|
v-model="importData.file"
|
||||||
|
@update:model-value="onFileChange($event)"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<QIcon name="vn:attach" class="cursor-pointer">
|
||||||
|
<QTooltip>{{ t('Select a file') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</template>
|
||||||
|
</QFile>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<div v-if="importData.file">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnInput
|
||||||
|
:label="t('entry.buys.reference')"
|
||||||
|
v-model="importData.ref"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnInput
|
||||||
|
:label="t('entry.buys.observations')"
|
||||||
|
v-model="importData.observation"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
|
<QTable
|
||||||
|
:columns="columns"
|
||||||
|
:rows="importData.buys"
|
||||||
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
|
hide-pagination
|
||||||
|
>
|
||||||
|
<template #body-cell-item="{ row, col }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<VnSelectFilter
|
||||||
|
v-model="row[col.field]"
|
||||||
|
:options="col.options"
|
||||||
|
:option-value="col.optionValue"
|
||||||
|
:option-label="col.optionLabel"
|
||||||
|
hide-selected
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.id }} -
|
||||||
|
{{ scope.opt?.name }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelectFilter>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-packagingFk="{ row, col }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<VnSelectFilter
|
||||||
|
v-model="row[col.field]"
|
||||||
|
:options="col.options"
|
||||||
|
:option-value="col.optionValue"
|
||||||
|
:option-label="col.optionLabel"
|
||||||
|
hide-selected
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</VnRow>
|
||||||
|
</div>
|
||||||
|
</QCard>
|
||||||
|
</QForm>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
Select a file: Selecciona un fichero
|
||||||
|
Some of the imported buys does not have an item: Algunas de las compras importadas no tienen un artículo
|
||||||
|
</i18n>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<script setup>
|
||||||
|
import VnLog from 'src/components/common/VnLog.vue';
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VnLog model="Entry" url="/EntryLogs"></VnLog>
|
||||||
|
</template>
|
|
@ -0,0 +1 @@
|
||||||
|
<template>Entry Notes</template>
|
|
@ -39,47 +39,30 @@ onMounted(async () => {
|
||||||
const tableColumnComponents = {
|
const tableColumnComponents = {
|
||||||
quantity: {
|
quantity: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
},
|
},
|
||||||
stickers: {
|
stickers: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
packagingFk: {
|
packagingFk: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
weight: {
|
weight: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
packing: {
|
packing: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
grouping: {
|
grouping: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
buyingValue: {
|
buyingValue: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
pvp: {
|
pvp: {
|
||||||
component: () => 'span',
|
component: () => 'span',
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,10 +297,7 @@ const fetchEntryBuys = async () => {
|
||||||
<QTr no-hover>
|
<QTr no-hover>
|
||||||
<QTd v-for="col in cols" :key="col.name">
|
<QTd v-for="col in cols" :key="col.name">
|
||||||
<component
|
<component
|
||||||
:is="tableColumnComponents[col.name].component(props)"
|
:is="tableColumnComponents[col.name].component()"
|
||||||
v-bind="tableColumnComponents[col.name].props(props)"
|
|
||||||
@click="tableColumnComponents[col.name].event(props)"
|
|
||||||
class="col-content"
|
|
||||||
>
|
>
|
||||||
<template
|
<template
|
||||||
v-if="
|
v-if="
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default {
|
||||||
redirect: { name: 'EntryMain' },
|
redirect: { name: 'EntryMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['EntryList'],
|
main: ['EntryList'],
|
||||||
card: [],
|
card: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryLog'],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,47 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Entry/Card/EntrySummary.vue'),
|
component: () => import('src/pages/Entry/Card/EntrySummary.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'basic-data',
|
||||||
|
name: 'EntryBasicData',
|
||||||
|
meta: {
|
||||||
|
title: 'basicData',
|
||||||
|
icon: 'vn:settings',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Entry/Card/EntryBasicData.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'buys',
|
||||||
|
name: 'EntryBuys',
|
||||||
|
meta: {
|
||||||
|
title: 'buys',
|
||||||
|
icon: 'vn:lines',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Entry/Card/EntryBuys.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'buys/import',
|
||||||
|
name: 'EntryBuysImport',
|
||||||
|
component: () => import('src/pages/Entry/Card/EntryBuysImport.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'notes',
|
||||||
|
name: 'EntryNotes',
|
||||||
|
meta: {
|
||||||
|
title: 'notes',
|
||||||
|
icon: 'vn:notes',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Entry/Card/EntryNotes.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'log',
|
||||||
|
name: 'EntryLog',
|
||||||
|
meta: {
|
||||||
|
title: 'log',
|
||||||
|
icon: 'vn:History',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Entry/Card/EntryLog.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue