working on create deliveryMan

This commit is contained in:
Alexandre Riera 2022-11-30 15:00:02 +01:00
parent d33da3cf3c
commit e499fd1511
11 changed files with 669 additions and 2 deletions

View File

@ -251,6 +251,47 @@ export default {
returnOfMaterial: 'Return of material authorization (RMA)',
},
},
route: {
pageTitles: {
routes: 'Routes',
deliveryManList: 'Delivery Men',
basicData: 'Basic Data',
deliveryManCreate: 'Create Delivery Man',
},
deliveryMan: {
list: {
deliveryMan: 'Delivery man',
supplier: 'Supplier',
id: 'ID',
minCost: 'Minimum cost',
minM3: 'M3',
agency: 'Agency',
},
basicData: {
supplier: 'Supplier',
id: 'ID',
minCost: 'Minimum cost',
minM3: 'M3',
agency: 'Agency',
},
card: {
supplier: 'Supplier',
id: 'ID',
minCost: 'Minimum cost',
minM3: 'M3',
agency: 'Agency',
},
summary: {
deliveryMan: 'Delivery man',
supplier: 'Supplier',
id: 'ID',
minCost: 'Minimum cost',
minM3: 'M3',
agency: 'Agency',
},
}
},
components: {
topbar: {},
userPanel: {

View File

@ -250,6 +250,47 @@ export default {
returnOfMaterial: 'Autorización de retorno de materiales (RMA)',
},
},
route: {
pageTitles: {
routes: 'Rutas',
deliveryManList: 'Repartidores',
basicData: 'Datos básicos',
deliveryManCreate: 'Crear Repartidor',
},
deliveryMan: {
list: {
deliveryMan: 'Repartidor',
supplier: 'Proveedor',
id: 'ID',
minCost: 'Coste mínimo',
minM3: 'Número de M3',
agency: 'Agencia',
},
basicData: {
supplier: 'Proveedor',
id: 'ID',
minCost: 'Coste mínimo',
minM3: 'Número de M3',
agency: 'Agencia',
},
card: {
supplier: 'Proveedor',
id: 'ID',
minCost: 'Coste mínimo',
minM3: 'Número de M3',
agency: 'Agencia',
},
summary: {
deliveryMan: 'Repartidor',
supplier: 'Proveedor',
id: 'ID',
minCost: 'Coste mínimo',
minM3: 'Número de M3',
agency: 'Agencia',
}
}
},
components: {
topbar: {},
userPanel: {

View File

@ -0,0 +1,115 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
const route = useRoute();
const { t } = useI18n();
const suppliers = ref([]);
const agencyModes = ref([]);
function setSuppliers(data) {
suppliers.value = data;
}
function setAgencyModes(data) {
agencyModes.value = data;
}
const filter = {
include: [
{
relation: 'deliveryManAgency',
scope: {
include: {
relation: 'agencyMode',
},
},
},
{
relation: 'supplier',
},
],
};
</script>
<template>
<fetch-data url="Suppliers" @on-fetch="setSuppliers" auto-load />
<fetch-data url="AgencyModes" @on-fetch="setAgencyModes" auto-load />
<div class="container">
<q-card>
<form-model :url="`DeliveryMans/${route.params.id}`" :filter="filter" model="deliveryMan">
<template #form="{ data, validate }">
<div class="row q-gutter-md q-mb-md">
<div class="col">
<q-input v-model="data.id" :label="t('route.deliveryMan.basicData.id')" disable />
</div>
<div class="col">
<q-select
v-model="data.supplierFk"
:options="suppliers"
option-value="id"
option-label="name"
emit-value
:label="t('route.deliveryMan.basicData.supplier')"
map-options
use-input
:rules="validate('deliveryMan.supplierFk')"
:input-debounce="0"
>
</q-select>
</div>
</div>
<div class="row q-gutter-md q-mb-md">
<div class="col">
<q-input
v-model="data.minCost"
:label="t('route.deliveryMan.basicData.minCost')"
:rules="validate('deliveryMan.minCost')"
/>
</div>
<div class="col">
<q-input
v-model="data.minM3"
:label="t('route.deliveryMan.basicData.minM3')"
:rules="validate('deliveryMan.minM3')"
/>
</div>
</div>
<div class="row q-gutter-md q-mb-md">
<div class="col">
<q-select
v-model="data.deliveryManAgency.agencyModeFk"
:options="agencyModes"
option-value="id"
option-label="name"
emit-value
:label="t('route.deliveryMan.basicData.agency')"
map-options
use-input
:rules="validate('deliveryMan.deliveryManAgency.agencyModeFk')"
:input-debounce="0"
>
</q-select>
</div>
</div>
</template>
</form-model>
</q-card>
</div>
</template>
<style lang="scss" scoped>
.container {
display: flex;
justify-content: center;
}
.q-card {
width: 800px;
}
</style>

View File

@ -0,0 +1,58 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useState } from 'composables/useState';
import DeliveryManDescriptor from './DeliveryManDescriptor.vue';
const { t } = useI18n();
const state = useState();
</script>
<template>
<q-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500">
<q-scroll-area class="fit">
<delivery-man-descriptor />
<q-separator />
<q-list>
<q-item :to="{ name: 'DeliveryManBasicData' }" clickable v-ripple>
<q-item-section avatar>
<q-icon name="vn:settings" />
</q-item-section>
<q-item-section>{{ t('route.pageTitles.basicData') }}</q-item-section>
</q-item>
</q-list>
</q-scroll-area>
</q-drawer>
<q-page-container>
<q-page class="q-pa-md">
<router-view></router-view>
</q-page>
</q-page-container>
</template>
<style lang="scss">
.q-scrollarea__content {
max-width: 100%;
}
</style>
<style lang="scss" scoped>
.descriptor {
max-width: 256px;
h5 {
margin: 0 15px;
}
.header {
display: flex;
justify-content: space-between;
}
.q-card__actions {
justify-content: center;
}
#descriptor-skeleton .q-card__actions {
justify-content: space-between;
}
}
</style>

View File

@ -0,0 +1,82 @@
<script setup>
import axios from 'axios';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
import { computed, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
onMounted(async () => {
await fetch();
});
const route = useRoute();
const { t } = useI18n();
const entityId = computed(() => {
return $props.id || route.params.id;
});
const deliveryMan = ref();
async function fetch() {
const filter = {
include: [
{
relation: 'deliveryManAgency',
scope: {
include: {
relation: 'agencyMode',
},
},
},
{
relation: 'supplier',
},
],
};
const options = { params: { filter } };
const { data } = await axios.get(`DeliveryMans/${entityId.value}`, options);
if (data) deliveryMan.value = data;
}
</script>
<template>
<skeleton-descriptor v-if="!deliveryMan" />
<card-descriptor v-if="deliveryMan" module="DeliveryMan" :data="deliveryMan">
<template #body>
<q-list>
<q-item>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.card.supplier') }}</q-item-label>
<q-item-label>{{ deliveryMan.supplier.name }}</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.card.agency') }}</q-item-label>
<q-item-label>{{ deliveryMan.deliveryManAgency.agencyMode.name }}</q-item-label>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.card.minCost') }}</q-item-label>
<q-item-label>{{ deliveryMan.minCost }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.card.minM3') }}</q-item-label>
<q-item-label>{{ deliveryMan.minM3 }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</template>
</card-descriptor>
</template>

View File

@ -0,0 +1,124 @@
<script setup>
import axios from 'axios';
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
import { computed, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
onMounted(() => fetch());
const route = useRoute();
const { t } = useI18n();
const $props = defineProps({
id: {
type: Number,
default: 0,
},
});
const entityId = computed(() => $props.id || route.params.id);
const filter = {
include: [
{
relation: 'deliveryManAgency',
scope: {
include: {
relation: 'agencyMode',
},
},
},
{
relation: 'supplier',
},
],
};
const deliveryMan = ref(null);
function fetch() {
const id = entityId.value;
axios
.get(`DeliveryMans/${id}`, {
params: {
filter,
},
})
.then(({ data }) => {
deliveryMan.value = data;
});
}
</script>
<template>
<div class="summary container">
<q-card>
<skeleton-summary v-if="!deliveryMan" />
<template v-if="deliveryMan">
<div class="header bg-primary q-pa-sm q-mb-md">
{{ t('route.deliveryMan.summary.deliveryMan') }} #{{ deliveryMan.id }}
</div>
<q-list>
<q-item>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.summary.supplier') }}</q-item-label>
<q-item-label>{{ deliveryMan.supplier.name }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.summary.agency') }}</q-item-label>
<q-item-label>{{ deliveryMan.deliveryManAgency.agencyMode.name }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.summary.minCost') }}</q-item-label>
<q-item-label>{{ deliveryMan.minCost }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.summary.minM3') }}</q-item-label>
<q-item-label>{{ deliveryMan.minM3 }}</q-item-label>
</q-item-section>
</q-item>
<q-item> </q-item>
</q-list>
</template>
</q-card>
</div>
</template>
<style lang="scss" scoped>
.container {
display: flex;
justify-content: center;
}
.q-card {
width: 100%;
max-width: 950px;
}
.summary {
.header {
text-align: center;
font-size: 18px;
}
#slider-container {
max-width: 80%;
margin: 0 auto;
.q-slider {
.q-slider__marker-labels:nth-child(1) {
transform: none;
}
.q-slider__marker-labels:nth-child(2) {
transform: none;
left: auto !important;
right: 0%;
}
}
}
}
.q-dialog .summary {
max-width: 1200px;
}
</style>

View File

@ -0,0 +1,44 @@
<script setup>
import axios from 'axios';
import { reactive } from 'vue';
const deliveryMan = reactive({
supplierFk: null,
agencyMode: null,
minCost: null,
minM3: null,
});
async function onSubmit() {
await axios.post('DeliveryMans', {
supplierFk: deliveryMan.supplierFk,
minCost: deliveryMan.minCost,
minM3: deliveryMan.minM3,
});
}
</script>
<template>
<q-page class="q-pa-md">
<q-card class="q-pa-md">
<q-banner v-if="hasChanges" class="text-white bg-warning">
<q-icon name="warning" size="md" class="q-mr-md" />
<span>{{ t('globals.changesToSave') }}</span>
</q-banner>
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md">
<q-input filled v-model="deliveryMan.minCost" label="Your name *" lazy-rules />
<div>
<q-btn label="Submit" type="submit" color="primary" />
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
</div>
</q-form>
</q-card>
</q-page>
</template>
<style lang="scss" scoped>
.card {
width: 100%;
max-width: 60em;
}
</style>

View File

@ -0,0 +1,78 @@
<script setup>
import Paginate from 'components/Paginate.vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
const { t } = useI18n();
const router = useRouter();
const filter = {
include: [
{
relation: 'deliveryManAgency',
scope: {
include: {
relation: 'agencyMode',
},
},
},
{
relation: 'supplier',
},
],
};
function navigate(id) {
router.push({ path: `/route/${id}` });
}
</script>
<template>
<q-page class="q-pa-md">
<paginate url="DeliveryMans" :filter="filter" sort-by="id DESC" auto-load>
<template #body="{ rows }">
<q-card class="card" v-for="row of rows" :key="row.id">
<q-item class="q-pa-none items-start cursor-pointer q-hoverable" v-ripple clickable>
<q-item-section class="q-pa-md" @click="navigate(row.id)">
<div class="text-h6 link">{{ t('route.deliveryMan.list.deliveryMan') }}</div>
<q-item-label caption>#{{ row.id }}</q-item-label>
<q-list>
<q-item class="q-pa-none">
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.list.supplier') }}</q-item-label>
<q-item-label>{{ row.supplier.name }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.list.minCost') }}</q-item-label>
<q-item-label>{{ row.minCost }}</q-item-label>
</q-item-section>
</q-item>
<q-item class="q-pa-none">
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.list.minM3') }}</q-item-label>
<q-item-label>{{ row.minM3 }}</q-item-label>
</q-item-section>
<q-item-section>
<q-item-label caption>{{ t('route.deliveryMan.list.agency') }}</q-item-label>
<q-item-label v-if="row.deliveryManAgency">{{
row.deliveryManAgency.agencyMode.name
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-item-section>
<q-separator vertical />
<q-card-actions vertical>
<q-btn flat round color="orange" icon="arrow_circle_right" @click="navigate(row.id)">
<q-tooltip>{{ t('components.smartCard.openCard') }}</q-tooltip>
</q-btn>
</q-card-actions>
</q-item>
</q-card>
</template>
</paginate>
<q-page-sticky position="bottom-right" :offset="[18, 18]">
<q-fab icon="person_add" direction="up" color="orange"> </q-fab>
</q-page-sticky>
</q-page>
</template>

View File

@ -0,0 +1,17 @@
<script setup>
import { useState } from 'src/composables/useState';
import LeftMenu from 'components/LeftMenu.vue';
const state = useState();
</script>
<template>
<q-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500">
<q-scroll-area class="fit text-grey-8">
<LeftMenu />
</q-scroll-area>
</q-drawer>
<q-page-container>
<router-view></router-view>
</q-page-container>
</template>

View File

@ -0,0 +1,65 @@
import { RouterView } from 'vue-router';
export default {
name: 'Route',
path: '/route',
meta: {
title: 'routes',
icon: 'vn:delivery'
},
component: RouterView,
redirect: { name: 'RouteMain' },
children: [
{
path: '',
name: 'RouteMain',
component: () => import('src/pages/Route/RouteMain.vue'),
redirect: { name: 'DeliveryManList' },
children: [
{
name: 'DeliveryManList',
path: 'deliveryMan/list',
meta: {
title: 'deliveryManList',
icon: 'person',
},
component: () => import('src/pages/Route/DeliveryManList.vue'),
},
{
name: 'DeliveryManCreate',
path: 'deliveryMan/create',
meta: {
title: 'deliveryManCreate',
icon: 'vn:addperson',
},
component: () => import('src/pages/Route/DeliveryManCreate.vue'),
},
]
},
{
name: 'DeliveryManCard',
path: ':id',
component: () => import('src/pages/Route/Card/DeliveryManCard.vue'),
redirect: { name: 'DeliveryManSummary' },
children: [
{
name: 'DeliveryManSummary',
path: 'deliveryMan/summary',
meta: {
title: 'summary',
},
component: () => import('src/pages/Route/Card/DeliveryManSummary.vue'),
},
{
name: 'DeliveryManBasicData',
path: 'deliveryMan/basic-data',
meta: {
title: 'basicData',
},
component: () => import('src/pages/Route/Card/DeliveryManBasicData.vue'),
},
]
},
]
};

View File

@ -1,6 +1,7 @@
import customer from './modules/customer';
import ticket from './modules/ticket';
import claim from './modules/claim';
import route from './modules/route';
const routes = [
{
@ -25,13 +26,14 @@ const routes = [
customer,
ticket,
claim,
route,
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('../pages/NotFound.vue'),
}
},
],
}
];
export default routes;
export default routes;