@@ -64,6 +68,7 @@ const onDataSaved = (data) => {
{},
+ },
autoLoad: {
type: Boolean,
default: false,
@@ -61,6 +66,10 @@ const $props = defineProps({
type: Function,
default: null,
},
+ clearStoreOnUnmount: {
+ type: Boolean,
+ default: true,
+ },
saveFn: {
type: Function,
default: null,
@@ -109,7 +118,12 @@ onBeforeRouteLeave((to, from, next) => {
});
onUnmounted(() => {
- state.unset($props.model);
+ // Restauramos los datos originales en el store si se realizaron cambios en el formulario pero no se guardaron, evitando modificaciones erróneas.
+ if (hasChanges.value) {
+ state.set($props.model, originalData.value);
+ return;
+ }
+ if ($props.clearStoreOnUnmount) state.unset($props.model);
});
const isLoading = ref(false);
@@ -119,7 +133,19 @@ const hasChanges = ref(!$props.observeFormChanges);
const originalData = ref({ ...$props.formInitialData });
const formData = computed(() => state.get($props.model));
const formUrl = computed(() => $props.url);
-
+const defaultButtons = computed(() => ({
+ save: {
+ color: 'primary',
+ icon: 'restart_alt',
+ label: 'globals.save',
+ },
+ reset: {
+ color: 'primary',
+ icon: 'save',
+ label: 'globals.reset',
+ },
+ ...$props.defaultButtons,
+}));
const startFormWatcher = () => {
watch(
() => formData.value,
@@ -131,10 +157,6 @@ const startFormWatcher = () => {
);
};
-function tMobile(...args) {
- if (!quasar.platform.is.mobile) return t(...args);
-}
-
async function fetch() {
const { data } = await axios.get($props.url, {
params: { filter: JSON.stringify($props.filter) },
@@ -233,21 +255,21 @@ watch(formUrl, async () => {
diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index 04322a3c8..cc22c77db 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -42,8 +42,8 @@ const { t } = useI18n();
const closeButton = ref(null);
const isLoading = ref(false);
-const onDataSaved = (dataSaved) => {
- emit('onDataSaved', dataSaved);
+const onDataSaved = (formData, requestResponse) => {
+ emit('onDataSaved', formData, requestResponse);
closeForm();
};
@@ -59,7 +59,7 @@ const closeForm = () => {
:default-actions="false"
:url-create="urlCreate"
:model="model"
- @on-data-saved="onDataSaved($event)"
+ @on-data-saved="onDataSaved"
>
diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue
index 12366e174..17b8c2b7e 100644
--- a/src/components/NavBar.vue
+++ b/src/components/NavBar.vue
@@ -10,12 +10,12 @@ import UserPanel from 'components/UserPanel.vue';
import VnBreadcrumbs from './common/VnBreadcrumbs.vue';
const { t } = useI18n();
-const session = useSession();
const stateStore = useStateStore();
const quasar = useQuasar();
const state = useState();
const user = state.getUser();
-const token = session.getToken();
+const { getTokenMultimedia } = useSession();
+const token = getTokenMultimedia();
const appName = 'Lilium';
onMounted(() => stateStore.setMounted());
diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue
index 6037b6405..f134de495 100644
--- a/src/components/UserPanel.vue
+++ b/src/components/UserPanel.vue
@@ -48,7 +48,7 @@ const darkMode = computed({
});
const user = state.getUser();
-const token = session.getToken();
+const token = session.getTokenMultimedia();
const warehousesData = ref();
const companiesData = ref();
const accountBankData = ref();
@@ -161,7 +161,6 @@ console.log('userWarehouse', user.value.warehouseFk.name);
>
@{{ user.name }}
-
+import {useDialogPluginComponent} from 'quasar';
+import {useI18n} from 'vue-i18n';
+import {computed, ref} from 'vue';
+import VnInput from 'components/common/VnInput.vue';
+import axios from 'axios';
+import useNotify from "composables/useNotify";
+
+const MESSAGE_MAX_LENGTH = 160;
+
+const {t} = useI18n();
+const {notify} = useNotify();
+const props = defineProps({
+ title: {
+ type: String,
+ required: true,
+ },
+ url: {
+ type: String,
+ required: true,
+ },
+ destination: {
+ type: String,
+ required: true,
+ },
+ destinationFk: {
+ type: String,
+ required: true,
+ },
+ data: {
+ type: Object,
+ default: () => ({}),
+ },
+});
+
+const emit = defineEmits([...useDialogPluginComponent.emits, 'sent']);
+const {dialogRef, onDialogHide} = useDialogPluginComponent();
+
+const smsRules = [
+ (val) => (val && val.length > 0) || t("The message can't be empty"),
+ (val) =>
+ (val && new Blob([val]).size <= MESSAGE_MAX_LENGTH) ||
+ t("The message it's too long"),
+];
+
+const message = ref('');
+
+const charactersRemaining = computed(
+ () => MESSAGE_MAX_LENGTH - new Blob([message.value]).size
+);
+
+const charactersChipColor = computed(() => {
+ if (charactersRemaining.value < 0) {
+ return 'negative';
+ }
+ if (charactersRemaining.value <= 25) {
+ return 'warning';
+ }
+ return 'primary';
+});
+
+const onSubmit = async () => {
+ if (!props.destination) {
+ throw new Error(`The destination can't be empty`);
+ }
+
+ if (!message.value) {
+ throw new Error(`The message can't be empty`);
+ }
+
+ if (charactersRemaining.value < 0) {
+ throw new Error(`The message it's too long`);
+ }
+
+ const response = await axios.post(props.url, {
+ destination: props.destination,
+ destinationFk: props.destinationFk,
+ message: message.value,
+ ...props.data,
+ });
+
+ if (response.data) {
+ emit('sent', response.data);
+ notify('globals.smsSent', 'positive');
+ }
+ emit('ok', response.data);
+ emit('hide', response.data);
+};
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+ {{
+ t(
+ 'Special characters like accents counts as a multiple'
+ )
+ }}
+
+
+
+
+
+ {{ t('Characters remaining') }}:
+
+ {{ charactersRemaining }}
+
+
+
+
+
+ {{ t('globals.cancel') }}
+
+ {{ t('Send') }}
+
+
+
+
+
+
+
+
+es:
+ Message: Mensaje
+ Send: Enviar
+ Characters remaining: Carácteres restantes
+ Special characters like accents counts as a multiple: Carácteres especiales como los acentos cuentan como varios
+ The destination can't be empty: El destinatario no puede estar vacio
+ The message can't be empty: El mensaje no puede estar vacio
+ The message it's too long: El mensaje es demasiado largo
+
diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue
index d5c59517d..08255f8a5 100644
--- a/src/components/common/VnDms.vue
+++ b/src/components/common/VnDms.vue
@@ -27,6 +27,10 @@ const $props = defineProps({
type: Object,
default: null,
},
+ url: {
+ type: String,
+ default: null,
+ },
});
const warehouses = ref();
@@ -65,14 +69,15 @@ function mapperDms(data) {
}
function getUrl() {
+ if ($props.url) return $props.url;
if ($props.formInitialData) return 'dms/' + $props.formInitialData.id + '/updateFile';
return `${$props.model}/${route.params.id}/uploadFile`;
}
async function save() {
const body = mapperDms(dms.value);
- await axios.post(getUrl(), body[0], body[1]);
- emit('onDataSaved', body[1].params);
+ const response = await axios.post(getUrl(), body[0], body[1]);
+ emit('onDataSaved', body[1].params, response);
}
function defaultData() {
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 8a01e0bee..ec836f2cd 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -1,5 +1,5 @@
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 355a25109..bca014a19 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -59,6 +59,9 @@ const toggleForm = () => {
:name="actionIcon"
:size="actionIcon === 'add' ? 'xs' : 'sm'"
:class="['default-icon', { '--add-icon': actionIcon === 'add' }]"
+ :style="{
+ 'font-variation-settings': `'FILL' ${1}`,
+ }"
>
{{ tooltip }}
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index c53193e6f..01048c6de 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
import { useArrayData } from 'composables/useArrayData';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import { useState } from 'src/composables/useState';
const $props = defineProps({
url: {
@@ -35,6 +36,8 @@ const $props = defineProps({
default: null,
},
});
+
+const state = useState();
const slots = useSlots();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
@@ -64,6 +67,7 @@ async function getData() {
isLoading.value = true;
try {
const { data } = await arrayData.fetch({ append: false, updateRouter: false });
+ state.set($props.dataKey, data);
emit('onFetch', data);
} finally {
isLoading.value = false;
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
index aeca84c80..f7780670f 100644
--- a/src/components/ui/CardSummary.vue
+++ b/src/components/ui/CardSummary.vue
@@ -1,11 +1,10 @@
@@ -126,17 +134,17 @@ const showEntryReport = () => {
:value="entity.travel?.warehouseOut?.name"
/>
-
+
{{ t('Inventory entry') }}
-
+
{{ t('Virtual entry') }}
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index b6863f8f7..1cd2a6cd9 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -165,20 +165,27 @@ const fetchEntryBuys = async () => {
@on-fetch="(data) => setEntryData(data)"
>
-
+
{{ entry.id }} - {{ entry.supplier.nickname }}
-
-
+
@@ -192,37 +199,15 @@ const fetchEntryBuys = async () => {
:label="t('entry.summary.invoiceNumber')"
:value="entry.invoiceNumber"
/>
-
-
-
-
-
-
+
@@ -250,7 +235,7 @@ const fetchEntryBuys = async () => {
{
+
+
+
+
+
+
+
+
@@ -277,9 +296,9 @@ const fetchEntryBuys = async () => {
@@ -325,11 +344,8 @@ const fetchEntryBuys = async () => {
-
-
+
+
@@ -338,13 +354,7 @@ const fetchEntryBuys = async () => {
-
-
es:
- Travel data: 'Datos envío'
+ Travel data: Datos envío
diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue
index 217a25870..bbc4a16cf 100644
--- a/src/pages/Entry/EntryLatestBuys.vue
+++ b/src/pages/Entry/EntryLatestBuys.vue
@@ -20,8 +20,8 @@ import { dashIfEmpty } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
const router = useRouter();
-const session = useSession();
-const token = session.getToken();
+const { getTokenMultimedia } = useSession();
+const token = getTokenMultimedia();
const stateStore = useStateStore();
const { t } = useI18n();
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index e8eff584b..6f146e21a 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -74,7 +74,7 @@ onMounted(async () => {
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue
new file mode 100644
index 000000000..a36656c1d
--- /dev/null
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
index 73acc0ad1..c5c17fa87 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
@@ -95,7 +95,11 @@ const ticketsColumns = ref([
-
+
{{ invoiceOut.ref }} - {{ invoiceOut.client?.socialName }}
diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue
index 8c986e627..981de0632 100644
--- a/src/pages/Item/Card/ItemDescriptor.vue
+++ b/src/pages/Item/Card/ItemDescriptor.vue
@@ -41,7 +41,7 @@ const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
-const { getToken } = useSession();
+const { getTokenMultimedia } = useSession();
const state = useState();
const user = state.getUser();
@@ -79,7 +79,7 @@ onMounted(async () => {
});
const getItemAvatar = async () => {
- const token = getToken();
+ const token = getTokenMultimedia();
const timeStamp = `timestamp=${Date.now()}`;
image.value = `/api/Images/catalog/200x200/${entityId.value}/download?access_token=${token}&${timeStamp}`;
};
diff --git a/src/pages/Login/LoginMain.vue b/src/pages/Login/LoginMain.vue
index 9c469e611..f920854c6 100644
--- a/src/pages/Login/LoginMain.vue
+++ b/src/pages/Login/LoginMain.vue
@@ -30,8 +30,15 @@ async function onSubmit() {
const { data } = await axios.post('Accounts/login', params);
if (!data) return;
+ const {
+ data: { multimediaToken },
+ } = await axios.get('VnUsers/ShareToken', {
+ headers: { Authorization: data.token },
+ });
- await session.login(data.token, keepLogin.value);
+ if (!multimediaToken) return;
+
+ await session.login(data.token, multimediaToken.id, keepLogin.value);
quasar.notify({
message: t('login.loginSuccess'),
diff --git a/src/pages/Order/Card/OrderCatalogItem.vue b/src/pages/Order/Card/OrderCatalogItem.vue
index ee73bcffb..a197ceafc 100644
--- a/src/pages/Order/Card/OrderCatalogItem.vue
+++ b/src/pages/Order/Card/OrderCatalogItem.vue
@@ -11,8 +11,8 @@ import toCurrency from '../../../filters/toCurrency';
const DEFAULT_PRICE_KG = 0;
-const session = useSession();
-const token = session.getToken();
+const { getTokenMultimedia } = useSession();
+const token = getTokenMultimedia();
const { t } = useI18n();
defineProps({
diff --git a/src/pages/Order/OrderLines.vue b/src/pages/Order/OrderLines.vue
index a2ee42481..4b6c21c75 100644
--- a/src/pages/Order/OrderLines.vue
+++ b/src/pages/Order/OrderLines.vue
@@ -17,9 +17,9 @@ import axios from 'axios';
const route = useRoute();
const { t } = useI18n();
-const session = useSession();
+const { getTokenMultimedia } = useSession();
const quasar = useQuasar();
-const token = session.getToken();
+const token = getTokenMultimedia();
const orderSummary = ref({
total: null,
vat: null,
diff --git a/src/pages/Route/Card/RouteAutonomousFilter.vue b/src/pages/Route/Card/RouteAutonomousFilter.vue
new file mode 100644
index 000000000..ec30458ce
--- /dev/null
+++ b/src/pages/Route/Card/RouteAutonomousFilter.vue
@@ -0,0 +1,237 @@
+
+
+
+ (agencyList = data)"
+ auto-load
+ />
+ (agencyAgreementList = data)"
+ auto-load
+ />
+ (supplierList = data)"
+ auto-load
+ />
+
+
+
+ {{ t(`params.${tag.label}`) }}:
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+en:
+ params:
+ agencyModeFk: Agency route
+ m3: m³
+ from: From
+ to: To
+ date: Date
+ agencyFk: Agency agreement
+ packages: Packages
+ price: Price
+ invoiceInFk: Received
+ supplierFk: Autonomous
+es:
+ params:
+ agencyModeFk: Agencia ruta
+ m3: m³
+ 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
+
diff --git a/src/pages/Route/Card/RouteForm.vue b/src/pages/Route/Card/RouteForm.vue
index 604f04357..60693cbf1 100644
--- a/src/pages/Route/Card/RouteForm.vue
+++ b/src/pages/Route/Card/RouteForm.vue
@@ -11,12 +11,15 @@ import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
import axios from 'axios';
import VnInputTime from 'components/common/VnInputTime.vue';
+import RouteSearchbar from "pages/Route/Card/RouteSearchbar.vue";
+import {useStateStore} from "stores/useStateStore";
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
-const shelvingId = route.params?.id || null;
-const isNew = Boolean(!shelvingId);
+const stateStore = useStateStore();
+const shelvingId = ref(route.params?.id || null);
+const isNew = Boolean(!shelvingId.value);
const defaultInitialData = {
agencyModeFk: null,
created: null,
@@ -78,6 +81,11 @@ const onSave = (data, response) => {
+
+
+
+
+
{
(agencyList = data)"
auto-load
@@ -103,13 +111,13 @@ const onSave = (data, response) => {
auto-load
/>
@@ -131,7 +139,7 @@ const onSave = (data, response) => {
{{ opt.name }}
- {{ opt.nickname }},{{ opt.code }}
+ {{ opt.nickname }}, {{ opt.code }}
@@ -212,6 +220,8 @@ const onSave = (data, response) => {
@@ -230,4 +240,5 @@ es:
Hour finished: Hora fin
Description: Descripción
Is served: Se ha servido
+ Created: Creado
diff --git a/src/pages/Route/Card/RouteListTicketsDialog.vue b/src/pages/Route/Card/RouteListTicketsDialog.vue
new file mode 100644
index 000000000..ba07f859f
--- /dev/null
+++ b/src/pages/Route/Card/RouteListTicketsDialog.vue
@@ -0,0 +1,241 @@
+
+
+
+
+ (!value ? (selectedTicket = null) : null)"
+ class="confirmation-dialog"
+ >
+
+
+ {{ t('Unlink selected zone?') }}
+
+
+
+
+ {{ t('Unlink') }}
+
+
+
+
+
+
+
+ {{ t('Tickets to add') }}
+
+
+
+
+
+
+
+
+ {{ props.value }}
+
+
+
+
+
+
+
+ {{ props.value }}
+
+
+
+
+
+
+
+ {{
+ t('Unlink zone', {
+ zone: props?.row?.zone?.name,
+ agency: props?.row?.agencyMode?.name,
+ })
+ }}
+
+
+
+
+
+
+
+ {{ t('globals.cancel') }}
+
+ {{ t('globals.add') }}
+
+
+
+
+
+
+
+
+en:
+ Unlink zone: Unlink zone {zone} from agency {agency}
+es:
+ Tickets to add: Tickets a añadir
+ Client: Cliente
+ Province: Provincia
+ City: Población
+ PC: CP
+ Address: Dirección
+ Zone: Zona
+ Unlink zone: Desvincular zona {zone} de agencia {agency}
+ Unlink: Desvincular
+
diff --git a/src/pages/Route/Card/RouteSearchbar.vue b/src/pages/Route/Card/RouteSearchbar.vue
index 9ee4a602f..e3833d13c 100644
--- a/src/pages/Route/Card/RouteSearchbar.vue
+++ b/src/pages/Route/Card/RouteSearchbar.vue
@@ -9,6 +9,7 @@ const { t } = useI18n();
data-key="RouteList"
:label="t('Search route')"
:info="t('You can search by route reference')"
+ custom-route-redirect-name="RouteList"
/>
diff --git a/src/pages/Route/Card/RouteSummary.vue b/src/pages/Route/Card/RouteSummary.vue
index df4495d3a..304dc8a86 100644
--- a/src/pages/Route/Card/RouteSummary.vue
+++ b/src/pages/Route/Card/RouteSummary.vue
@@ -8,9 +8,10 @@ import VnLv from 'components/ui/VnLv.vue';
import { QIcon } from 'quasar';
import { dashIfEmpty, toCurrency, toDate, toHour } from 'src/filters';
import WorkerDescriptorProxy from 'pages/Worker/Card/WorkerDescriptorProxy.vue';
-import axios from 'axios';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
+import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
+import { openBuscaman } from 'src/utils/buscaman';
const $props = defineProps({
id: {
@@ -104,7 +105,7 @@ const ticketColumns = ref([
label: t('route.summary.ticket'),
field: (row) => row?.id,
sortable: false,
- align: 'right',
+ align: 'center',
},
{
name: 'observations',
@@ -114,30 +115,20 @@ const ticketColumns = ref([
align: 'left',
},
]);
-
-const openBuscaman = async (route, ticket) => {
- if (!route.vehicleFk) throw new Error(`The route doesn't have a vehicle`);
- const response = await axios.get(`Routes/${route.vehicleFk}/getDeliveryPoint`);
- if (!response.data)
- throw new Error(`The route's vehicle doesn't have a delivery point`);
-
- const address = `${response.data}+to:${ticket.postalCode} ${ticket.city} ${ticket.street}`;
- window.open(
- 'https://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=' +
- encodeURI(address),
- '_blank'
- );
-};
-
-
-
-
-
-
-
+
+
+
+
+
+
+
{{ `${entity?.route.id} - ${entity?.route?.description}` }}
@@ -207,9 +198,10 @@ const openBuscaman = async (route, ticket) => {
-
+
+
{
{{ value }}
@@ -237,7 +229,7 @@ const openBuscaman = async (route, ticket) => {
-
+
{{ value }}
diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue
index dc5602c1c..41908ec6c 100644
--- a/src/pages/Route/Cmr/CmrList.vue
+++ b/src/pages/Route/Cmr/CmrList.vue
@@ -12,8 +12,8 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
const stateStore = useStateStore();
const { t } = useI18n();
-const session = useSession();
-const token = session.getToken();
+const { getTokenMultimedia } = useSession();
+const token = getTokenMultimedia();
const selected = ref([]);
const columns = computed(() => [
@@ -91,6 +91,24 @@ function downloadPdfs() {
}
+
+
+
+
+
+
+ {{ t('globals.collapseMenu') }}
+
+
+
+
+
+import { useDialogPluginComponent } from 'quasar';
+import { useI18n } from 'vue-i18n';
+import { reactive, ref } from 'vue';
+import axios from 'axios';
+import FetchData from 'components/FetchData.vue';
+import RoadmapAddStopForm from 'pages/Route/Roadmap/RoadmapAddStopForm.vue';
+
+const emit = defineEmits([...useDialogPluginComponent.emits]);
+const { dialogRef, onDialogHide } = useDialogPluginComponent();
+
+const { t } = useI18n();
+const props = defineProps({
+ roadmapFk: {
+ type: Number,
+ required: true,
+ },
+});
+
+const isLoading = ref(false);
+const roadmapStopForm = reactive({
+ roadmapFk: Number(props.roadmapFk) || 0,
+ warehouseFk: null,
+ eta: new Date().toISOString(),
+ description: '',
+});
+
+const updateDefaultStop = (data) => {
+ const eta = new Date(data.etd);
+ eta.setDate(eta.getDate() + 1);
+ roadmapStopForm.eta = eta.toISOString();
+};
+
+const onSave = async () => {
+ isLoading.value = true;
+ try {
+ await axios.post('ExpeditionTrucks', { ...roadmapStopForm });
+ emit('ok');
+ } finally {
+ isLoading.value = false;
+ emit('hide');
+ }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Warehouse: Almacén
+ ETA date: Fecha ETA
+ ETA time: Hora ETA
+ Description: Descripción
+
diff --git a/src/pages/Route/Roadmap/RoadmapAddStopForm.vue b/src/pages/Route/Roadmap/RoadmapAddStopForm.vue
new file mode 100644
index 000000000..6793e4513
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapAddStopForm.vue
@@ -0,0 +1,104 @@
+
+
+ (warehouseList = data)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Warehouse: Almacén
+ ETA date: Fecha ETA
+ ETA hour: Hora ETA
+ Description: Descripción
+ Remove stop: Eliminar parada
+ Add stop: Añadir parada
+
diff --git a/src/pages/Route/Roadmap/RoadmapBasicData.vue b/src/pages/Route/Roadmap/RoadmapBasicData.vue
new file mode 100644
index 000000000..8b10f5e57
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapBasicData.vue
@@ -0,0 +1,143 @@
+
+
+
+ (supplierList = data)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ opt.id }} - {{ opt.nickname }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Roadmap: Troncal
+ ETD date: Fecha ETD
+ ETD hour: Hora ETD
+ Tractor plate: Matrícula tractor
+ Trailer plate: Matrícula trailer
+ Carrier: Transportista
+ Price: Precio
+ Driver name: Nombre del conductor
+ Phone: Teléfono
+ Observations: Observaciones
+
diff --git a/src/pages/Route/Roadmap/RoadmapCard.vue b/src/pages/Route/Roadmap/RoadmapCard.vue
new file mode 100644
index 000000000..d6b02824b
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapCard.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Route/Roadmap/RoadmapCreate.vue b/src/pages/Route/Roadmap/RoadmapCreate.vue
new file mode 100644
index 000000000..214983dd3
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapCreate.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Roadmap: Troncal
+ ETD date: Fecha ETD
+ ETD hour: Hora ETD
+
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptor.vue b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
new file mode 100644
index 000000000..3396ce3f1
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+ {{ dashIfEmpty(entity?.supplier?.nickname) }}
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Roadmap: Troncal
+ Carrier: Transportista
+
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptorMenu.vue b/src/pages/Route/Roadmap/RoadmapDescriptorMenu.vue
new file mode 100644
index 000000000..2c0099f28
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapDescriptorMenu.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+ {{ t('Delete roadmap') }}
+
+
+
+
+es:
+ Confirm deletion: Confirmar eliminación
+ Are you sure you want to delete this roadmap?: ¿Estás seguro de que quieres eliminar esta troncal?
+ Delete roadmap: Eliminar troncal
+
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptorProxy.vue b/src/pages/Route/Roadmap/RoadmapDescriptorProxy.vue
new file mode 100644
index 000000000..4e22ecd62
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapDescriptorProxy.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/src/pages/Route/Roadmap/RoadmapFilter.vue b/src/pages/Route/Roadmap/RoadmapFilter.vue
new file mode 100644
index 000000000..b3fb7bf34
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapFilter.vue
@@ -0,0 +1,183 @@
+
+
+
+ (supplierList = data)"
+ auto-load
+ />
+
+
+
+ {{ t(`params.${tag.label}`) }}:
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ opt.id }} - {{ opt.nickname }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+en:
+ params:
+ tractorPlate: Tractor Plate
+ trailerPlate: Trailer Plate
+ supplierFk: Carrier
+ price: Price
+ driverName: Driver name
+ phone: Phone
+ from: From
+ to: To
+es:
+ params:
+ tractorPlate: Matrícula del tractor
+ trailerPlate: Matrícula del trailer
+ supplierFk: Transportista
+ price: Precio
+ driverName: Nombre del conductor
+ phone: Teléfono
+ from: Desde
+ to: Hasta
+ From: Desde
+ To: Hasta
+ Tractor Plate: Matrícula del tractor
+ Trailer Plate: Matrícula del trailer
+ Carrier: Transportista
+ Price: Precio
+ Driver name: Nombre del conductor
+ Phone: Teléfono
+
diff --git a/src/pages/Route/Roadmap/RoadmapStops.vue b/src/pages/Route/Roadmap/RoadmapStops.vue
new file mode 100644
index 000000000..10d6e6066
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapStops.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('Remove stop') }}
+
+
+
+
+
+
+
+ {{ t('Add stop') }}
+
+
+
+
+
+
+
+
+
+es:
+ Warehouse: Almacén
+ ETA date: Fecha ETA
+ ETA hour: Hora ETA
+ Description: Descripción
+ Remove stop: Eliminar parada
+ Add stop: Añadir parada
+
diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue
new file mode 100644
index 000000000..446d381ec
--- /dev/null
+++ b/src/pages/Route/Roadmap/RoadmapSummary.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ `${entity?.id} - ${entity?.name}` }}
+
+
+
+
+
+
+ {{ dashIfEmpty(entity?.supplier?.nickname) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dashIfEmpty(entity?.phone) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ Carrier: Transportista
+ Tractor Plate: Matrícula tractor
+ Trailer Plate: Matrícula trailer
+ Phone: Teléfono
+ Worker: Trabajador
+ Observations: Observaciones
+ Stops: Paradas
+ Warehouse: Almacén
+ Go to stops: Ir a paradas
+ Add stop: Añadir parada
+
diff --git a/src/pages/Route/RouteAutonomous.vue b/src/pages/Route/RouteAutonomous.vue
new file mode 100644
index 000000000..6fd4d3f90
--- /dev/null
+++ b/src/pages/Route/RouteAutonomous.vue
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('globals.collapseMenu') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('Total') }}
+
+
+ {{ toCurrency(total) }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.value }}
+
+
+
+
+
+
+
+ {{ dashIfEmpty(props.value) }}
+
+
+
+
+
+
+
+ {{ props.value }}
+
+
+
+
+
+
+
+
+ {{ t('Preview') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('Create invoiceIn') }}
+
+
+
+
+
+
+
+
+
+
+
+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
+ Preview: Vista previa
+
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index 0b4aa6795..d308696e1 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -2,9 +2,8 @@
import VnPaginate from 'components/ui/VnPaginate.vue';
import { useStateStore } from 'stores/useStateStore';
import { useI18n } from 'vue-i18n';
-import { useQuasar } from 'quasar';
import { computed, onMounted, onUnmounted, ref } from 'vue';
-import { dashIfEmpty, toDate, toHour } from 'src/filters';
+import { dashIfEmpty, toHour } from 'src/filters';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import FetchData from 'components/FetchData.vue';
import { useValidator } from 'composables/useValidator';
@@ -16,12 +15,15 @@ import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
-import {useSession} from "composables/useSession";
+import { useSession } from 'composables/useSession';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
+import { useQuasar } from 'quasar';
const stateStore = useStateStore();
const { t } = useI18n();
const { validate } = useValidator();
+const quasar = useQuasar();
const session = useSession();
const { viewSummary } = useSummaryDialog();
@@ -35,7 +37,7 @@ const columns = computed(() => [
label: t('ID'),
field: (row) => row.id,
sortable: true,
- align: 'left',
+ align: 'center',
},
{
name: 'worker',
@@ -70,7 +72,7 @@ const columns = computed(() => [
label: 'm³',
field: (row) => dashIfEmpty(row.m3),
sortable: true,
- align: 'left',
+ align: 'center',
},
{
name: 'description',
@@ -113,24 +115,6 @@ const updateRoute = async (route) => {
}
};
-const updateVehicle = (row, vehicle) => {
- row.vehicleFk = vehicle.id;
- row.vehiclePlateNumber = vehicle.numberPlate;
- updateRoute(row);
-};
-
-const updateAgency = (row, agency) => {
- row.agencyModeFk = agency.id;
- row.agencyName = agency.name;
- updateRoute(row);
-};
-
-const updateWorker = (row, worker) => {
- row.workerFk = worker.id;
- row.workerUserName = worker.name;
- updateRoute(row);
-};
-
const confirmationDialog = ref(false);
const startingDate = ref(null);
@@ -144,21 +128,21 @@ const cloneRoutes = () => {
};
const showRouteReport = () => {
- const ids = selectedRows.value.map(row => row?.id)
- const idString = ids.join(',')
+ const ids = selectedRows.value.map((row) => row?.id);
+ const idString = ids.join(',');
let url;
if (selectedRows.value.length <= 1) {
- url = `api/Routes/${idString}/driver-route-pdf?access_token=${session.getToken()}`;
+ url = `api/Routes/${idString}/driver-route-pdf?access_token=${session.getTokenMultimedia()}`;
} else {
const params = new URLSearchParams({
- access_token: session.getToken(),
- id: idString
- })
+ access_token: session.getTokenMultimedia(),
+ id: idString,
+ });
url = `api/Routes/downloadZip?${params.toString()}`;
}
window.open(url, '_blank');
-}
+};
const markAsServed = () => {
selectedRows.value.forEach((row) => {
@@ -169,6 +153,20 @@ const markAsServed = () => {
refreshKey.value++;
startingDate.value = null;
};
+
+const openTicketsDialog = (id) => {
+ if (!id) {
+ return;
+ }
+ quasar
+ .dialog({
+ component: RouteListTicketsDialog,
+ componentProps: {
+ id,
+ },
+ })
+ .onOk(() => refreshKey.value++);
+};
@@ -278,199 +276,136 @@ const markAsServed = () => {
:rows-per-page-options="[0]"
hide-pagination
:pagination="{ sortBy: 'ID', descending: true }"
+ :no-data-label="t('globals.noResults')"
>
-
-
- {{ props.row?.workerUserName }}
- updateWorker(props.row, worker)
- "
+
+
+
- $event.target.select()"
- >
-
-
+
+
-
- {{ opt.name }}
- {{
- opt.nickname
- }}
-
-
-
-
-
+ {{ opt.name }}
+ {{
+ opt.nickname
+ }}
+
+
+
+
-
-
- {{ props.row?.agencyName }}
- updateAgency(props.row, agency)
- "
- >
- $event.target.select()"
- />
-
+
+
+
-
-
- {{ props.row?.vehiclePlateNumber }}
- updateVehicle(props.row, vehicle)
- "
- >
- $event.target.select()"
- />
-
+
+
+
-
-
- {{ toDate(props.row?.created) }}
-
- $event.target.select()"
- />
-
+
+
+
-
-
- {{ props.row?.description }}
-
- $event.target.select()"
- />
-
+
+
+
-
-
- {{ toHour(props.row.started) }}
-
- $event.target.select()"
- />
-
+
+
+
-
-
- {{ toHour(props.row.finished) }}
-
- $event.target.select()"
- />
-
+
+
+
-
+
{{ t('Add ticket') }}
@@ -485,6 +420,20 @@ const markAsServed = () => {
>
{{ t('Preview') }}
+
+
+ {{ t('Summary') }}
+
+
@@ -505,8 +454,13 @@ const markAsServed = () => {
+
+es:
+ Search roadmaps: Buscar troncales
+ You can search by roadmap reference: Puedes buscar por referencia de la troncal
+ Delete roadmap(s): Eliminar troncal(es)
+ Selected roadmaps will be removed: Las troncales seleccionadas serán eliminadas
+ Are you sure you want to continue?: ¿Seguro que quieres continuar?
+ The date can't be empty: La fecha no puede estar vacía
+ Clone Selected Routes: Clonar rutas seleccionadas
+ Create roadmap: Crear troncal
+ Roadmap: Troncal
+ Carrier: Transportista
+ Plate: Matrícula
+ Price: Precio
+ Observations: Observaciones
+ Preview: Vista previa
+
diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue
new file mode 100644
index 000000000..8410232c5
--- /dev/null
+++ b/src/pages/Route/RouteTickets.vue
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+ (routeEntity = data)"
+ auto-load
+ :url="`Routes/${route.params?.id}`"
+ :filter="{
+ fields: ['vehicleFk'],
+ }"
+ />
+
+
+
+ {{ t('Select the starting date') }}
+
+
+
+
+
+
+
+
+ {{ t('Clone') }}
+
+
+
+
+
+
+
+
+ {{ t('Sort routes') }}
+
+
+ {{ t('Open buscaman') }}
+
+
+ {{ t('Delete priority') }}
+
+
+ {{
+ t('Renumber all tickets in the order you see on the screen')
+ }}
+
+
+
+ {{ t('Send SMS to all clients') }}
+
+
+
+
+
(ticketList = data)"
+ >
+
+
+
+
+
+
+
+
+ {{ t('Assign highest priority') }}
+
+
+
+
+
+
+
+
+
+ {{ value }}
+ {{ t('Open buscaman') }}
+
+
+
+
+
+
+ {{ value }}
+
+
+
+
+
+
+
+ {{ value }}
+
+
+
+
+
+
+
+
+ {{ t('globals.remove') }}
+
+
+ {{ value }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('Add ticket') }}
+
+
+
+
+
+
+
+
+es:
+ Order: Orden
+ Street: Dirección fiscal
+ City: Población
+ PC: CP
+ Client: Cliente
+ Warehouse: Almacén
+ Packages: Bultos
+ Packaging: Encajado
+ Confirm removal from route: Quitar de la ruta
+ Are you sure you want to remove this ticket from the route?: ¿Seguro que quieres quitar este ticket de la ruta?
+ Sort routes: Ordenar rutas
+ Open buscaman: Abrir buscaman
+ Delete priority: Borrar orden
+ Renumber all tickets in the order you see on the screen: Renumerar todos los tickets con el orden que ves por pantalla
+ Assign highest priority: Asignar máxima prioridad
+ Send SMS to all clients: Mandar sms a todos los clientes de las rutas
+ Send SMS to the selected tickets: Enviar SMS a los tickets seleccionados
+ Add ticket: Añadir ticket
+
diff --git a/src/pages/Supplier/Card/SupplierAccounts.vue b/src/pages/Supplier/Card/SupplierAccounts.vue
index 302e03217..41df6adb9 100644
--- a/src/pages/Supplier/Card/SupplierAccounts.vue
+++ b/src/pages/Supplier/Card/SupplierAccounts.vue
@@ -18,13 +18,16 @@ const quasar = useQuasar();
const { notify } = useNotify();
const route = useRoute();
const { t } = useI18n();
+
+const bankEntitiesRef = ref(null);
const supplier = ref(null);
const supplierAccountRef = ref(null);
const wireTransferFk = ref(null);
const bankEntitiesOptions = ref([]);
-const onBankEntityCreated = (data) => {
- bankEntitiesOptions.value.push(data);
+const onBankEntityCreated = async (dataSaved, rowData) => {
+ await bankEntitiesRef.value.fetch();
+ rowData.bankEntityFk = dataSaved.id;
};
const onChangesSaved = () => {
@@ -63,6 +66,7 @@ onMounted(() => {
(bankEntitiesOptions = data)"
auto-load
@@ -114,13 +118,16 @@ onMounted(() => {
:label="t('worker.create.bankEntity')"
v-model="row.bankEntityFk"
:options="bankEntitiesOptions"
- option-label="name"
+ option-label="bic"
option-value="id"
hide-selected
>
+ onBankEntityCreated(requestResponse, row)
+ "
:show-entity-field="false"
/>
diff --git a/src/pages/Supplier/Card/SupplierAddresses.vue b/src/pages/Supplier/Card/SupplierAddresses.vue
index c6b08075f..735b50625 100644
--- a/src/pages/Supplier/Card/SupplierAddresses.vue
+++ b/src/pages/Supplier/Card/SupplierAddresses.vue
@@ -83,8 +83,13 @@ const redirectToUpdateView = (addressData) => {
- {{ t('supplier.list.newSupplier') }}
+ {{ t('New address') }}
+
+
+es:
+ New address: Nueva dirección
+
diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue
index bc50deb9b..01741dd77 100644
--- a/src/pages/Supplier/Card/SupplierBasicData.vue
+++ b/src/pages/Supplier/Card/SupplierBasicData.vue
@@ -26,6 +26,7 @@ const workersOptions = ref([]);
:url-update="`Suppliers/${route.params.id}`"
model="supplier"
auto-load
+ :clear-store-on-unmount="false"
>
diff --git a/src/pages/Supplier/Card/SupplierBillingData.vue b/src/pages/Supplier/Card/SupplierBillingData.vue
index bf5ccb115..26b6e5461 100644
--- a/src/pages/Supplier/Card/SupplierBillingData.vue
+++ b/src/pages/Supplier/Card/SupplierBillingData.vue
@@ -33,6 +33,7 @@ const formatPayDems = (data) => {
:url-update="`Suppliers/${route.params.id}`"
model="supplier"
auto-load
+ :clear-store-on-unmount="false"
>
diff --git a/src/pages/Supplier/Card/SupplierContacts.vue b/src/pages/Supplier/Card/SupplierContacts.vue
index d69b74a4c..3abe5a9cc 100644
--- a/src/pages/Supplier/Card/SupplierContacts.vue
+++ b/src/pages/Supplier/Card/SupplierContacts.vue
@@ -1,5 +1,5 @@
+
+
+ (deviceProductionsOptions = data)"
+ />
+ setCurrentPDA(data[0])"
+ />
+
+ setCurrentPDA(data)"
+ >
+
+
+
+
+ {{ currentPDA.description }}
+
+
+
+
+
+ {{ t('worker.pda.removePDA') }}
+
+
+
+
+
+
+
+
+
+ ID: {{ scope.opt?.id }}
+
+ {{ scope.opt?.modelFk }},
+ {{ scope.opt?.serialNumber }}
+
+
+
+
+
+
+
+
+
+
+
+es:
+ PDA deallocated: PDA desasignada
+
diff --git a/src/router/modules/Supplier.js b/src/router/modules/Supplier.js
index d341ddc25..379a2c2c2 100644
--- a/src/router/modules/Supplier.js
+++ b/src/router/modules/Supplier.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'suppliers',
icon: 'vn:supplier',
+ moduleName: 'Supplier',
},
component: RouterView,
redirect: { name: 'SupplierMain' },
diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js
index 0aa26cadf..65c714418 100644
--- a/src/router/modules/claim.js
+++ b/src/router/modules/claim.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'claims',
icon: 'vn:claims',
+ moduleName: 'Claim',
},
component: RouterView,
redirect: { name: 'ClaimMain' },
diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js
index 716b0fa6c..75188bd32 100644
--- a/src/router/modules/customer.js
+++ b/src/router/modules/customer.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'customers',
icon: 'vn:client',
+ moduleName: 'Customer',
},
component: RouterView,
redirect: { name: 'CustomerMain' },
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index 2f6c8cb4c..50a651af5 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'entries',
icon: 'vn:entry',
+ moduleName: 'Entry',
},
component: RouterView,
redirect: { name: 'EntryMain' },
diff --git a/src/router/modules/index.js b/src/router/modules/index.js
index 84a26798d..076605f24 100644
--- a/src/router/modules/index.js
+++ b/src/router/modules/index.js
@@ -13,6 +13,7 @@ import Travel from './travel';
import Order from './order';
import Department from './department';
import Entry from './entry';
+import roadmap from "./roadmap";
export default [
Item,
@@ -30,4 +31,5 @@ export default [
invoiceIn,
Department,
Entry,
+ roadmap
];
diff --git a/src/router/modules/invoiceIn.js b/src/router/modules/invoiceIn.js
index 01ed37036..869a3555a 100644
--- a/src/router/modules/invoiceIn.js
+++ b/src/router/modules/invoiceIn.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'invoiceIns',
icon: 'vn:invoice-in',
+ moduleName: 'InvoiceIn',
},
component: RouterView,
redirect: { name: 'InvoiceInMain' },
diff --git a/src/router/modules/invoiceOut.js b/src/router/modules/invoiceOut.js
index 084cf6ac3..386e04ed8 100644
--- a/src/router/modules/invoiceOut.js
+++ b/src/router/modules/invoiceOut.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'invoiceOuts',
icon: 'vn:invoice-out',
+ moduleName: 'InvoiceOut',
},
component: RouterView,
redirect: { name: 'InvoiceOutMain' },
diff --git a/src/router/modules/order.js b/src/router/modules/order.js
index 4599394cd..16d73281b 100644
--- a/src/router/modules/order.js
+++ b/src/router/modules/order.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'order',
icon: 'vn:basket',
+ moduleName: 'Order',
},
component: RouterView,
redirect: { name: 'OrderMain' },
diff --git a/src/router/modules/roadmap.js b/src/router/modules/roadmap.js
new file mode 100644
index 000000000..02edf94be
--- /dev/null
+++ b/src/router/modules/roadmap.js
@@ -0,0 +1,52 @@
+import { RouterView } from 'vue-router';
+
+export default {
+ path: '/route/roadmap',
+ name: 'Roadmap',
+ meta: {
+ title: 'roadmap',
+ icon: 'vn:troncales',
+ },
+ component: RouterView,
+ redirect: { name: 'RouteMain' },
+ menus: {
+ card: ['RoadmapBasicData', 'RoadmapStops'],
+ },
+ children: [
+ {
+ name: 'RouteRoadmapCard',
+ path: ':id',
+ component: () => import('src/pages/Route/Roadmap/RoadmapCard.vue'),
+ redirect: { name: 'RoadmapSummary' },
+ children: [
+ {
+ name: 'RoadmapSummary',
+ path: 'summary',
+ meta: {
+ title: 'summary',
+ icon: 'open_in_new',
+ },
+ component: () => import('pages/Route/Roadmap/RoadmapSummary.vue'),
+ },
+ {
+ name: 'RoadmapBasicData',
+ path: 'basic-data',
+ meta: {
+ title: 'basicData',
+ icon: 'vn:settings',
+ },
+ component: () => import('pages/Route/Roadmap/RoadmapBasicData.vue'),
+ },
+ {
+ name: 'RoadmapStops',
+ path: 'stops',
+ meta: {
+ title: 'stops',
+ icon: 'vn:lines',
+ },
+ component: () => import('pages/Route/Roadmap/RoadmapStops.vue'),
+ },
+ ],
+ },
+ ],
+};
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 614345913..099492981 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -6,12 +6,13 @@ export default {
meta: {
title: 'routes',
icon: 'vn:delivery',
+ moduleName: 'Route',
},
component: RouterView,
redirect: { name: 'RouteMain' },
menus: {
- main: ['RouteList', 'CmrList'],
- card: ['RouteBasicData'],
+ main: ['RouteList', 'RouteAutonomous', 'RouteRoadmap', 'CmrList'],
+ card: ['RouteBasicData', 'RouteTickets', 'RouteLog'],
},
children: [
{
@@ -20,15 +21,6 @@ export default {
component: () => import('src/pages/Route/RouteMain.vue'),
redirect: { name: 'RouteList' },
children: [
- {
- path: 'cmr',
- name: 'CmrList',
- meta: {
- title: 'cmrsList',
- icon: 'fact_check',
- },
- component: () => import('src/pages/Route/Cmr/CmrList.vue'),
- },
{
path: 'list',
name: 'RouteList',
@@ -46,6 +38,42 @@ export default {
},
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: 'roadmap',
+ name: 'RouteRoadmap',
+ meta: {
+ title: 'RouteRoadmap',
+ icon: 'vn:troncales',
+ },
+ component: () => import('src/pages/Route/RouteRoadmap.vue'),
+ },
+ {
+ path: 'roadmap/create',
+ name: 'RouteRoadmapCreate',
+ meta: {
+ title: 'RouteRoadmapCreate',
+ icon: 'vn:troncales',
+ },
+ component: () => import('src/pages/Route/Roadmap/RoadmapCreate.vue'),
+ },
+ {
+ path: 'cmr',
+ name: 'CmrList',
+ meta: {
+ title: 'cmrsList',
+ icon: 'fact_check',
+ },
+ component: () => import('src/pages/Route/Cmr/CmrList.vue'),
+ },
],
},
{
@@ -72,6 +100,24 @@ export default {
},
component: () => import('pages/Route/Card/RouteSummary.vue'),
},
+ {
+ path: 'tickets',
+ name: 'RouteTickets',
+ meta: {
+ title: 'tickets',
+ icon: 'vn:ticket',
+ },
+ component: () => import('src/pages/Route/RouteTickets.vue'),
+ },
+ {
+ path: 'log',
+ name: 'RouteLog',
+ meta: {
+ title: 'log',
+ icon: 'vn:History',
+ },
+ component: () => import('src/pages/Route/RouteLog.vue'),
+ },
],
},
],
diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js
index 494f286c3..d32c7d9f3 100644
--- a/src/router/modules/shelving.js
+++ b/src/router/modules/shelving.js
@@ -1,17 +1,18 @@
-import {RouterView} from "vue-router";
+import { RouterView } from 'vue-router';
export default {
path: '/shelving',
name: 'Shelving',
meta: {
title: 'shelving',
- icon: 'vn:inventory'
+ icon: 'vn:inventory',
+ moduleName: 'Shelving',
},
component: RouterView,
redirect: { name: 'ShelvingMain' },
menus: {
main: ['ShelvingList'],
- card: ['ShelvingBasicData', 'ShelvingLog']
+ card: ['ShelvingBasicData', 'ShelvingLog'],
},
children: [
{
@@ -51,8 +52,7 @@ export default {
meta: {
title: 'summary',
},
- component: () =>
- import('pages/Shelving/Card/ShelvingSummary.vue'),
+ component: () => import('pages/Shelving/Card/ShelvingSummary.vue'),
},
{
name: 'ShelvingBasicData',
@@ -75,6 +75,5 @@ export default {
},
],
},
- ]
+ ],
};
-
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index 73c441b4d..d6b714154 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'tickets',
icon: 'vn:ticket',
+ moduleName: 'Ticket',
},
component: RouterView,
redirect: { name: 'TicketMain' },
diff --git a/src/router/modules/travel.js b/src/router/modules/travel.js
index 792b393e4..2f1e2150e 100644
--- a/src/router/modules/travel.js
+++ b/src/router/modules/travel.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'travel',
icon: 'local_airport',
+ moduleName: 'Travel',
},
component: RouterView,
redirect: { name: 'TravelMain' },
diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js
index 238e482dd..6f9a4c819 100644
--- a/src/router/modules/wagon.js
+++ b/src/router/modules/wagon.js
@@ -6,6 +6,7 @@ export default {
meta: {
title: 'wagons',
icon: 'vn:trolley',
+ moduleName: 'Wagon',
},
component: RouterView,
redirect: { name: 'WagonMain' },
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index 27a6f19a9..1c722afe8 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -6,12 +6,13 @@ export default {
meta: {
title: 'workers',
icon: 'vn:worker',
+ moduleName: 'Worker',
},
component: RouterView,
redirect: { name: 'WorkerMain' },
menus: {
main: ['WorkerList', 'WorkerDepartment'],
- card: ['WorkerNotificationsManager'],
+ card: ['WorkerNotificationsManager', 'WorkerPda'],
departmentCard: ['BasicData'],
},
children: [
@@ -75,6 +76,15 @@ export default {
component: () =>
import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
},
+ {
+ name: 'WorkerPda',
+ path: 'pda',
+ meta: {
+ title: 'pda',
+ icon: 'phone_android',
+ },
+ component: () => import('src/pages/Worker/Card/WorkerPda.vue'),
+ },
],
},
],
diff --git a/src/router/routes.js b/src/router/routes.js
index d1027955f..32f43965f 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -13,6 +13,7 @@ import department from './modules/department';
import shelving from 'src/router/modules/shelving';
import order from 'src/router/modules/order';
import entry from 'src/router/modules/entry';
+import roadmap from "src/router/modules/roadmap";
const routes = [
{
@@ -66,6 +67,7 @@ const routes = [
supplier,
travel,
department,
+ roadmap,
entry,
{
path: '/:catchAll(.*)*',
diff --git a/src/utils/buscaman.js b/src/utils/buscaman.js
new file mode 100644
index 000000000..0778a21e8
--- /dev/null
+++ b/src/utils/buscaman.js
@@ -0,0 +1,22 @@
+import axios from 'axios';
+
+const BUSCAMAN_URL = 'https://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
+
+export async function openBuscaman(vehicleId, tickets) {
+ if (!vehicleId) throw new Error(`The route doesn't have a vehicle`);
+
+ const response = await axios.get(`Routes/${vehicleId}/getDeliveryPoint`);
+
+ if (!response.data) {
+ throw new Error(`The route's vehicle doesn't have a delivery point`);
+ }
+
+ let addresses = response.data;
+ tickets.forEach((ticket, index) => {
+ const previousLine = tickets[index - 1] ? tickets[index - 1].street : null;
+ if (previousLine !== tickets.street) {
+ addresses += `+to:${ticket.postalCode} ${ticket.city} ${ticket.street}`;
+ }
+ });
+ window.open(BUSCAMAN_URL + encodeURI(addresses), '_blank');
+}
diff --git a/test/vitest/__tests__/composables/useSession.spec.js b/test/vitest/__tests__/composables/useSession.spec.js
index 4f900aca6..f9f3dcb80 100644
--- a/test/vitest/__tests__/composables/useSession.spec.js
+++ b/test/vitest/__tests__/composables/useSession.spec.js
@@ -54,7 +54,8 @@ describe('session', () => {
expect(localStorage.getItem('token')).toEqual('tokenToBeGone');
expect(user.value).toEqual(previousUser);
- session.destroy();
+ vi.spyOn(axios, 'post').mockResolvedValue({ data: true });
+ await session.destroy();
user = state.getUser();
expect(localStorage.getItem('token')).toBeNull();
@@ -92,9 +93,10 @@ describe('session', () => {
});
const expectedToken = 'mySessionToken';
+ const expectedTokenMultimedia = 'mySessionTokenMultimedia';
const keepLogin = false;
- await session.login(expectedToken, keepLogin);
+ await session.login(expectedToken,expectedTokenMultimedia, keepLogin);
const roles = state.getRoles();
const localToken = localStorage.getItem('token');
@@ -104,7 +106,7 @@ describe('session', () => {
expect(localToken).toBeNull();
expect(sessionToken).toEqual(expectedToken);
- session.destroy(); // this clears token and user for any other test
+ await session.destroy(); // this clears token and user for any other test
});
it('should fetch the user roles and then set token in the localStorage', async () => {
@@ -114,9 +116,10 @@ describe('session', () => {
});
const expectedToken = 'myLocalToken';
+ const expectedTokenMultimedia = 'myLocalTokenMultimedia';
const keepLogin = true;
- await session.login(expectedToken, keepLogin);
+ await session.login(expectedToken, expectedTokenMultimedia, keepLogin);
const roles = state.getRoles();
const localToken = localStorage.getItem('token');
@@ -126,7 +129,7 @@ describe('session', () => {
expect(localToken).toEqual(expectedToken);
expect(sessionToken).toBeNull();
- session.destroy(); // this clears token and user for any other test
+ await session.destroy(); // this clears token and user for any other test
});
});
});
diff --git a/test/vitest/__tests__/pages/Login/Login.spec.js b/test/vitest/__tests__/pages/Login/Login.spec.js
index fadfc898f..6e2de9870 100644
--- a/test/vitest/__tests__/pages/Login/Login.spec.js
+++ b/test/vitest/__tests__/pages/Login/Login.spec.js
@@ -22,9 +22,9 @@ describe('Login', () => {
darkMode: false,
},
};
- vi.spyOn(axios, 'post').mockResolvedValue({ data: { token: 'token' } });
+ vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } });
vi.spyOn(axios, 'get').mockResolvedValue({
- data: { roles: [], user: expectedUser },
+ data: { roles: [], user: expectedUser , multimediaToken: {id:'multimediaToken' }},
});
vi.spyOn(vm.quasar, 'notify');
@@ -36,7 +36,7 @@ describe('Login', () => {
expect(vm.quasar.notify).toHaveBeenCalledWith(
expect.objectContaining({ type: 'positive' })
);
- vm.session.destroy();
+ await vm.session.destroy();
});
it('should not set the token into session if any error occurred', async () => {