0
0
Fork 0

Create route autonomous

This commit is contained in:
Kevin Martinez 2024-02-01 23:08:59 -03:00
parent 988362ab69
commit e846582606
6 changed files with 575 additions and 11 deletions

View File

@ -889,7 +889,8 @@ export default {
basicData: 'Basic Data', basicData: 'Basic Data',
summary: 'Summary', summary: 'Summary',
tickets: 'Tickets', tickets: 'Tickets',
log: 'Log' log: 'Log',
autonomous: 'Autonomous',
}, },
cmr: { cmr: {
list: { list: {

View File

@ -944,6 +944,7 @@ export default {
summary: 'Summary', summary: 'Summary',
tickets: 'Tickets', tickets: 'Tickets',
log: 'Historial', log: 'Historial',
autonomous: 'Autónomos',
}, },
cmr: { cmr: {
list: { list: {

View File

@ -0,0 +1,15 @@
<script setup>
import InvoiceInDescriptor from "pages/InvoiceIn/Card/InvoiceInDescriptor.vue";
const $props = defineProps({
id: {
type: Number,
required: true,
},
});
</script>
<template>
<QPopupProxy>
<InvoiceInDescriptor v-if="$props.id" :id="$props.id" />
</QPopupProxy>
</template>

View File

@ -0,0 +1,237 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
const emit = defineEmits(['search']);
const agencyList = ref([]);
const agencyAgreementList = ref([]);
const supplierList = ref([]);
const exprBuilder = (param, value) => {
switch (param) {
case 'agencyModeFk':
return { 'a.agencyModeFk': value };
case 'supplierFk':
return { 'a.supplierName': value };
case 'routeFk':
return { 'a.routeFk': value };
case 'created':
case 'agencyFk':
case 'packages':
case 'm3':
case 'kmTotal':
case 'price':
case 'invoiceInFk':
return { [`a.${param}`]: value };
}
};
</script>
<template>
<FetchData
url="AgencyModes"
:filter="{ fields: ['id', 'name'] }"
sort-by="name ASC"
limit="30"
@on-fetch="(data) => (agencyList = data)"
auto-load
/>
<FetchData
url="Agencies"
:filter="{ fields: ['id', 'name'] }"
sort-by="name ASC"
limit="30"
@on-fetch="(data) => (agencyAgreementList = data)"
auto-load
/>
<FetchData
url="Suppliers"
:filter="{ fields: ['name'] }"
sort-by="name ASC"
limit="30"
@on-fetch="(data) => (supplierList = data)"
auto-load
/>
<VnFilterPanel
:data-key="props.dataKey"
:expr-builder="exprBuilder"
search-button
@search="emit('search')"
>
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params }">
<QList dense>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.routeFk" :label="t('ID')" is-outlined />
</QItemSection>
</QItem>
<QItem class="q-my-sm" v-if="agencyList">
<QItemSection>
<VnSelectFilter
:label="t('Agency route')"
v-model="params.agencyModeFk"
:options="agencyList"
option-value="id"
option-label="name"
dense
outlined
rounded
emit-value
map-options
use-input
is-clearable
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm" v-if="agencyAgreementList">
<QItemSection>
<VnSelectFilter
:label="t('Agency agreement')"
v-model="params.agencyFk"
:options="agencyAgreementList"
option-value="id"
option-label="name"
dense
outlined
rounded
emit-value
map-options
use-input
is-clearable
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm" v-if="supplierList">
<QItemSection>
<VnSelectFilter
:label="t('Autonomous')"
v-model="params.supplierFk"
:options="supplierList"
option-value="name"
option-label="name"
dense
outlined
rounded
emit-value
map-options
use-input
is-clearable
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInputDate
v-model="params.created"
:label="t('Date')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInputDate
v-model="params.from"
:label="t('From')"
is-outlined
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInputDate
v-model="params.to"
:label="t('To')"
is-outlined
is-clearable
/>
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.packages" :label="t('Packages')" is-outlined />
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.m3" :label="t('m3')" is-outlined />
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.kmTotal" :label="t('Km')" is-outlined />
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.price" :label="t('Price')" is-outlined />
</QItemSection>
</QItem>
<QItem class="q-my-sm">
<QItemSection>
<VnInput v-model="params.invoiceInFk" :label="t('Received')" is-outlined />
</QItemSection>
</QItem>
</QList>
</template>
</VnFilterPanel>
</template>
<i18n>
en:
params:
agencyModeFk: Agency route
m3:
from: From
to: To
date: Date
agencyFk: Agency agreement
packages: Packages
price: Price
invoiceInFk: Received
supplierFk: Autonomous
es:
params:
agencyModeFk: Agencia ruta
m3:
from: Desde
to: Hasta
date: Fecha
agencyFk: Agencia Acuerdo
packages: Bultos
price: Precio
invoiceInFk: Recibida
supplierFk: Autónomos
From: Desde
To: Hasta
Date: Fecha
Agency route: Agencia Ruta
Agency agreement: Agencia Acuerdo
Packages: Bultos
Price: Precio
Received: Recibida
Autonomous: Autónomos
</i18n>

View File

@ -0,0 +1,301 @@
<script setup>
import VnPaginate from 'components/ui/VnPaginate.vue';
import { useStateStore } from 'stores/useStateStore';
import { useI18n } from 'vue-i18n';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
import RouteSummaryDialog from 'pages/Route/Card/RouteSummaryDialog.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import RouteDescriptorProxy from 'pages/Route/Card/RouteDescriptorProxy.vue';
import InvoiceInDescriptorProxy from 'pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
import VnLv from 'components/ui/VnLv.vue';
import { useQuasar } from 'quasar';
import useNotify from "composables/useNotify";
import RouteAutonomousFilter from "pages/Route/Card/RouteAutonomousFilter.vue";
const stateStore = useStateStore();
const { t } = useI18n();
const quasar = useQuasar();
const { notify } = useNotify();
onMounted(() => (stateStore.rightDrawer = true));
onUnmounted(() => (stateStore.rightDrawer = false));
const selectedRows = ref([]);
const columns = computed(() => [
{
name: 'ID',
label: t('ID'),
field: (row) => row.routeFk,
sortable: true,
align: 'left',
},
{
name: 'date',
label: t('Date'),
field: (row) => toDate(row.created),
sortable: true,
align: 'left',
},
{
name: 'agency-route',
label: t('Agency route'),
field: (row) => row?.agencyModeName,
sortable: true,
align: 'left',
},
{
name: 'agency-agreement',
label: t('Agency agreement'),
field: (row) => row?.agencyAgreement,
sortable: true,
align: 'left',
},
{
name: 'packages',
label: t('Packages'),
field: (row) => dashIfEmpty(row.packages),
sortable: true,
align: 'left',
},
{
name: 'volume',
label: 'm³',
field: (row) => dashIfEmpty(row.m3),
sortable: true,
align: 'left',
},
{
name: 'km',
label: t('Km'),
field: (row) => dashIfEmpty(row?.kmTotal),
sortable: true,
align: 'left',
},
{
name: 'price',
label: t('Price'),
field: (row) => (row?.price ? toCurrency(row.price) : '-'),
sortable: true,
align: 'left',
},
{
name: 'received',
label: t('Received'),
field: (row) => row?.invoiceInFk,
sortable: true,
align: 'left',
},
{
name: 'autonomous',
label: t('Autonomous'),
field: (row) => row?.supplierName,
sortable: true,
align: 'left',
},
{
name: 'actions',
label: '',
sortable: false,
align: 'right',
},
]);
const refreshKey = ref(0);
const total = computed(() => selectedRows.value.reduce((item) => item?.price || 0, 0));
const openCreateInvoiceIn = () => {
const rowsToCreateInvoiceIn = selectedRows.value
.filter(
(agencyTerm) => agencyTerm.supplierFk === selectedRows.value?.[0].supplierFk
)
.map((agencyTerm) => ({
routeFk: agencyTerm.routeFk,
supplierFk: agencyTerm.supplierFk,
created: agencyTerm.created,
totalPrice: total.value,
}));
if (rowsToCreateInvoiceIn.length !== selectedRows.value.length) {
return notify(t('Two autonomous cannot be counted at the same time'), 'negative');
}
const params = JSON.stringify({
supplierName: selectedRows.value?.[0].supplierName,
rows: rowsToCreateInvoiceIn,
});
console.log(params);
};
function previewRoute(id) {
if (!id) {
return;
}
quasar.dialog({
component: RouteSummaryDialog,
componentProps: {
id,
},
});
}
</script>
<template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#searchbar">
<VnSearchbar
data-key="RouteAutonomousList"
:label="t('Search autonomous')"
:info="t('You can search by autonomous reference')"
/>
</Teleport>
<Teleport to="#actions-append">
<div class="row q-gutter-x-sm">
<QBtn
flat
@click="stateStore.toggleRightDrawer()"
round
dense
icon="menu"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.collapseMenu') }}
</QTooltip>
</QBtn>
</div>
</Teleport>
</template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">
<RouteAutonomousFilter data-key="RouteAutonomousList" />
</QScrollArea>
</QDrawer>
<QPage class="column items-center">
<div class="route-list">
<div class="q-pa-md">
<QCard class="vn-one q-py-sm q-px-lg">
<VnLv class="flex">
<template #label>
<span class="text-h6">{{ t('Total') }}</span>
</template>
<template #value>
<span class="text-h6 q-ml-md">{{ toCurrency(total) }}</span>
</template>
</VnLv>
</QCard>
</div>
<VnPaginate
:key="refreshKey"
data-key="RouteAutonomousList"
url="AgencyTerms/filter"
:limit="20"
auto-load
>
<template #body="{ rows }">
<div class="q-pa-md">
<QTable
v-model:selected="selectedRows"
:columns="columns"
:rows="rows"
flat
row-key="routeFk"
selection="multiple"
:rows-per-page-options="[0]"
hide-pagination
>
<template #body-cell-ID="props">
<QTd :props="props">
<span class="link">
{{ props.value }}
<RouteDescriptorProxy :id="props.value" />
</span>
</QTd>
</template>
<template #body-cell-received="props">
<QTd :props="props">
<span :class="props.value && 'link'">
{{ dashIfEmpty(props.value) }}
<InvoiceInDescriptorProxy
v-if="props.value"
:id="props.value"
/>
</span>
</QTd>
</template>
<template #body-cell-autonomous="props">
<QTd :props="props">
<span class="link">
{{ props.value }}
<SupplierDescriptorProxy
v-if="props.row?.supplierFk"
:id="props.row?.supplierFk"
/>
</span>
</QTd>
</template>
<template #body-cell-actions="props">
<QTd :props="props">
<div class="table-actions">
<QIcon
name="preview"
size="xs"
color="primary"
@click="previewRoute(props?.row?.routeFk)"
>
<QTooltip>{{ t('Preview') }}</QTooltip>
</QIcon>
</div>
</QTd>
</template>
</QTable>
</div>
</template>
</VnPaginate>
</div>
<QPageSticky :offset="[20, 20]" v-if="selectedRows?.length">
<QBtn
fab
icon="vn:invoice-in-create"
color="primary"
@click="openCreateInvoiceIn"
>
<QTooltip>
{{ t('Create invoiceIn') }}
</QTooltip>
</QBtn>
</QPageSticky>
</QPage>
</template>
<style lang="scss" scoped>
.route-list {
width: 100%;
}
.table-actions {
display: flex;
align-items: center;
gap: 12px;
i {
cursor: pointer;
}
}
</style>
<i18n>
es:
Search autonomous: Buscar autónomos
You can search by autonomous reference: Puedes buscar por referencia del autónomo
Create invoiceIn: Crear factura recibida
Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo
Date: Fecha
Agency route: Agencia Ruta
Agency agreement: Agencia Acuerdo
Packages: Bultos
Price: Precio
Received: Recibida
Autonomous: Autónomos
</i18n>

View File

@ -10,7 +10,7 @@ export default {
component: RouterView, component: RouterView,
redirect: { name: 'RouteMain' }, redirect: { name: 'RouteMain' },
menus: { menus: {
main: ['RouteList', 'CmrList'], main: ['RouteList', 'RouteAutonomous', 'CmrList'],
card: ['RouteBasicData', 'RouteTickets', 'RouteLog'], card: ['RouteBasicData', 'RouteTickets', 'RouteLog'],
}, },
children: [ children: [
@ -20,15 +20,6 @@ export default {
component: () => import('src/pages/Route/RouteMain.vue'), component: () => import('src/pages/Route/RouteMain.vue'),
redirect: { name: 'RouteList' }, redirect: { name: 'RouteList' },
children: [ children: [
{
path: 'cmr',
name: 'CmrList',
meta: {
title: 'cmrsList',
icon: 'fact_check',
},
component: () => import('src/pages/Route/Cmr/CmrList.vue'),
},
{ {
path: 'list', path: 'list',
name: 'RouteList', name: 'RouteList',
@ -46,6 +37,24 @@ export default {
}, },
component: () => import('src/pages/Route/Card/RouteForm.vue'), component: () => import('src/pages/Route/Card/RouteForm.vue'),
}, },
{
path: 'agency-term',
name: 'RouteAutonomous',
meta: {
title: 'autonomous',
icon: 'vn:agency-term',
},
component: () => import('src/pages/Route/RouteAutonomous.vue'),
},
{
path: 'cmr',
name: 'CmrList',
meta: {
title: 'cmrsList',
icon: 'fact_check',
},
component: () => import('src/pages/Route/Cmr/CmrList.vue'),
},
], ],
}, },
{ {