forked from verdnatura/salix-front
Merge branch 'dev' into feature/TicketComponents
This commit is contained in:
commit
84462fe201
|
@ -52,7 +52,7 @@ const toggleMarkAll = (val) => {
|
||||||
|
|
||||||
const getConfig = async (url, filter) => {
|
const getConfig = async (url, filter) => {
|
||||||
const response = await axios.get(url, {
|
const response = await axios.get(url, {
|
||||||
params: { filter: filter },
|
params: { filter: JSON.stringify(filter) },
|
||||||
});
|
});
|
||||||
return response.data && response.data.length > 0 ? response.data[0] : null;
|
return response.data && response.data.length > 0 ? response.data[0] : null;
|
||||||
};
|
};
|
||||||
|
@ -60,7 +60,7 @@ const getConfig = async (url, filter) => {
|
||||||
const fetchViewConfigData = async () => {
|
const fetchViewConfigData = async () => {
|
||||||
try {
|
try {
|
||||||
const userConfigFilter = {
|
const userConfigFilter = {
|
||||||
where: { tableCode: $props.tableCode, userFk: user.id },
|
where: { tableCode: $props.tableCode, userFk: user.value.id },
|
||||||
};
|
};
|
||||||
const userConfig = await getConfig('UserConfigViews', userConfigFilter);
|
const userConfig = await getConfig('UserConfigViews', userConfigFilter);
|
||||||
|
|
||||||
|
@ -74,8 +74,14 @@ const fetchViewConfigData = async () => {
|
||||||
const defaultConfig = await getConfig('DefaultViewConfigs', defaultConfigFilter);
|
const defaultConfig = await getConfig('DefaultViewConfigs', defaultConfigFilter);
|
||||||
|
|
||||||
if (defaultConfig) {
|
if (defaultConfig) {
|
||||||
|
// Si el backend devuelve una configuración por defecto la usamos
|
||||||
setUserConfigViewData(defaultConfig.columns);
|
setUserConfigViewData(defaultConfig.columns);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// Si no hay configuración por defecto mostramos todas las columnas
|
||||||
|
const defaultColumns = {};
|
||||||
|
$props.allColumns.forEach((col) => (defaultColumns[col] = true));
|
||||||
|
setUserConfigViewData(defaultColumns);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.err('Error fetching config view data', err);
|
console.err('Error fetching config view data', err);
|
||||||
|
|
|
@ -39,7 +39,7 @@ const arrayData = useArrayData(props.dataKey, {
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
|
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
|
||||||
await arrayData.fetch({ append: false });
|
await arrayData.fetch({ append: false, updateRouter: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
if (props.baseUrl) {
|
if (props.baseUrl) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
|
||||||
import OrderCatalogItemDialog from 'pages/Order/Card/OrderCatalogItemDialog.vue';
|
import OrderCatalogItemDialog from 'pages/Order/Card/OrderCatalogItemDialog.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
|
|
||||||
import toCurrency from '../../../filters/toCurrency';
|
import { toCurrency } from 'filters/index';
|
||||||
|
|
||||||
const DEFAULT_PRICE_KG = 0;
|
const DEFAULT_PRICE_KG = 0;
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
isCatalog: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const dialog = ref(null);
|
const dialog = ref(null);
|
||||||
|
@ -28,7 +32,7 @@ const dialog = ref(null);
|
||||||
<QCard class="card shadow-6">
|
<QCard class="card shadow-6">
|
||||||
<div class="img-wrapper">
|
<div class="img-wrapper">
|
||||||
<VnImg :id="item.id" zoom-size="lg" class="image" />
|
<VnImg :id="item.id" zoom-size="lg" class="image" />
|
||||||
<div v-if="item.hex" class="item-color-container">
|
<div v-if="item.hex && isCatalog" class="item-color-container">
|
||||||
<div
|
<div
|
||||||
class="item-color"
|
class="item-color"
|
||||||
:style="{ backgroundColor: `#${item.hex}` }"
|
:style="{ backgroundColor: `#${item.hex}` }"
|
||||||
|
@ -50,11 +54,12 @@ const dialog = ref(null);
|
||||||
</template>
|
</template>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<p>
|
<p v-if="isCatalog">
|
||||||
{{ item.available }} {{ t('to') }}
|
{{ item.available }} {{ t('to') }}
|
||||||
{{ toCurrency(item.price) }}
|
{{ toCurrency(item.price) }}
|
||||||
</p>
|
</p>
|
||||||
<QIcon name="add_circle" class="icon">
|
<slot name="price" />
|
||||||
|
<QIcon v-if="isCatalog" name="add_circle" class="icon">
|
||||||
<QTooltip>{{ t('globals.add') }}</QTooltip>
|
<QTooltip>{{ t('globals.add') }}</QTooltip>
|
||||||
<QPopupProxy ref="dialog">
|
<QPopupProxy ref="dialog">
|
||||||
<OrderCatalogItemDialog
|
<OrderCatalogItemDialog
|
|
@ -112,9 +112,7 @@ async function search(evt) {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
const filter = { ...userParams.value };
|
const filter = { ...userParams.value };
|
||||||
store.userParamsChanged = true;
|
store.userParamsChanged = true;
|
||||||
store.filter.skip = 0;
|
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||||
store.skip = 0;
|
|
||||||
store.page = 1;
|
|
||||||
const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
|
const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
|
||||||
userParams.value = newParams;
|
userParams.value = newParams;
|
||||||
|
|
||||||
|
@ -138,9 +136,7 @@ async function reload() {
|
||||||
async function clearFilters() {
|
async function clearFilters() {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
store.userParamsChanged = true;
|
store.userParamsChanged = true;
|
||||||
store.filter.skip = 0;
|
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||||
store.skip = 0;
|
|
||||||
store.page = 1;
|
|
||||||
// Filtrar los params no removibles
|
// Filtrar los params no removibles
|
||||||
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
||||||
$props.unremovableParams.includes(param)
|
$props.unremovableParams.includes(param)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, watch } from 'vue';
|
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
|
|
||||||
|
@ -95,6 +95,8 @@ onMounted(async () => {
|
||||||
mounted.value = true;
|
mounted.value = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => arrayData.reset());
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
() => {
|
() => {
|
||||||
|
@ -118,8 +120,7 @@ const addFilter = async (filter, params) => {
|
||||||
|
|
||||||
async function fetch(params) {
|
async function fetch(params) {
|
||||||
useArrayData(props.dataKey, params);
|
useArrayData(props.dataKey, params);
|
||||||
store.filter.skip = 0;
|
arrayData.reset(['filter.skip', 'skip']);
|
||||||
store.skip = 0;
|
|
||||||
await arrayData.fetch({ append: false });
|
await arrayData.fetch({ append: false });
|
||||||
if (!store.hasMoreData) {
|
if (!store.hasMoreData) {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
|
|
@ -103,8 +103,7 @@ async function search() {
|
||||||
const staticParams = Object.entries(store.userParams).filter(
|
const staticParams = Object.entries(store.userParams).filter(
|
||||||
([key, value]) => value && (props.staticParams || []).includes(key)
|
([key, value]) => value && (props.staticParams || []).includes(key)
|
||||||
);
|
);
|
||||||
store.skip = 0;
|
arrayData.reset(['skip', 'page']);
|
||||||
store.page = 1;
|
|
||||||
|
|
||||||
if (props.makeFetch)
|
if (props.makeFetch)
|
||||||
await arrayData.applyFilter({
|
await arrayData.applyFilter({
|
||||||
|
|
|
@ -18,7 +18,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setOptions();
|
setOptions();
|
||||||
store.skip = 0;
|
arrayDataStore.reset(['skip']);
|
||||||
|
|
||||||
const query = route.query;
|
const query = route.query;
|
||||||
const searchUrl = store.searchUrl;
|
const searchUrl = store.searchUrl;
|
||||||
if (query[searchUrl]) {
|
if (query[searchUrl]) {
|
||||||
|
@ -84,8 +85,12 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(filter, store.userFilter, exprFilter);
|
Object.assign(filter, store.userFilter, exprFilter);
|
||||||
Object.assign(store.filter, filter);
|
let where;
|
||||||
const params = { filter: store.filter };
|
if (filter?.where || store.filter?.where)
|
||||||
|
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
||||||
|
Object.assign(filter, store.filter);
|
||||||
|
filter.where = where;
|
||||||
|
const params = { filter };
|
||||||
|
|
||||||
Object.assign(params, userParams);
|
Object.assign(params, userParams);
|
||||||
params.filter.skip = store.skip;
|
params.filter.skip = store.skip;
|
||||||
|
@ -126,6 +131,10 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
delete store[option];
|
delete store[option];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset(opts = []) {
|
||||||
|
if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function cancelRequest() {
|
function cancelRequest() {
|
||||||
if (canceller) {
|
if (canceller) {
|
||||||
canceller.abort();
|
canceller.abort();
|
||||||
|
@ -143,21 +152,20 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addFilter({ filter, params }) {
|
async function addFilter({ filter, params }) {
|
||||||
if (filter) store.userFilter = Object.assign(store.userFilter, filter);
|
if (filter) store.filter = filter;
|
||||||
|
|
||||||
let userParams = { ...store.userParams, ...params };
|
let userParams = { ...store.userParams, ...params };
|
||||||
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
||||||
|
|
||||||
store.userParams = userParams;
|
store.userParams = userParams;
|
||||||
store.skip = 0;
|
arrayDataStore.reset(['skip', 'filter.skip', 'page']);
|
||||||
store.filter.skip = 0;
|
|
||||||
store.page = 1;
|
|
||||||
await fetch({ append: false });
|
await fetch({ append: false });
|
||||||
return { filter, params };
|
return { filter, params };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addFilterWhere(where) {
|
async function addFilterWhere(where) {
|
||||||
const storedFilter = { ...store.userFilter };
|
const storedFilter = { ...store.filter };
|
||||||
if (!storedFilter?.where) storedFilter.where = {};
|
if (!storedFilter?.where) storedFilter.where = {};
|
||||||
where = { ...storedFilter.where, ...where };
|
where = { ...storedFilter.where, ...where };
|
||||||
await addFilter({ filter: { where } });
|
await addFilter({ filter: { where } });
|
||||||
|
@ -187,7 +195,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
store.page += 1;
|
store.page += 1;
|
||||||
|
|
||||||
await fetch({ append: true });
|
await fetch({ append: true });
|
||||||
updateStateParams();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
async function refresh() {
|
||||||
|
@ -241,5 +248,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
updateStateParams,
|
updateStateParams,
|
||||||
isLoading,
|
isLoading,
|
||||||
deleteOption,
|
deleteOption,
|
||||||
|
reset,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,11 +550,13 @@ ticket:
|
||||||
observation: Notes
|
observation: Notes
|
||||||
ticketAdvance: Advance tickets
|
ticketAdvance: Advance tickets
|
||||||
futureTickets: Future tickets
|
futureTickets: Future tickets
|
||||||
|
expedition: Expedition
|
||||||
purchaseRequest: Purchase request
|
purchaseRequest: Purchase request
|
||||||
weeklyTickets: Weekly tickets
|
weeklyTickets: Weekly tickets
|
||||||
services: Service
|
services: Service
|
||||||
tracking: Tracking
|
tracking: Tracking
|
||||||
components: Components
|
components: Components
|
||||||
|
pictures: Pictures
|
||||||
list:
|
list:
|
||||||
nickname: Nickname
|
nickname: Nickname
|
||||||
state: State
|
state: State
|
||||||
|
|
|
@ -548,11 +548,13 @@ ticket:
|
||||||
observation: Notas
|
observation: Notas
|
||||||
ticketAdvance: Adelantar tickets
|
ticketAdvance: Adelantar tickets
|
||||||
futureTickets: Tickets a futuro
|
futureTickets: Tickets a futuro
|
||||||
|
expedition: Expedición
|
||||||
purchaseRequest: Petición de compra
|
purchaseRequest: Petición de compra
|
||||||
weeklyTickets: Tickets programados
|
weeklyTickets: Tickets programados
|
||||||
services: Servicios
|
services: Servicios
|
||||||
tracking: Estados
|
tracking: Estados
|
||||||
components: Componentes
|
components: Componentes
|
||||||
|
pictures: Fotos
|
||||||
list:
|
list:
|
||||||
nickname: Alias
|
nickname: Alias
|
||||||
state: Estado
|
state: Estado
|
||||||
|
|
|
@ -408,7 +408,6 @@ function handleLocation(data, location) {
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
redirect="customer"
|
redirect="customer"
|
||||||
auto-load
|
auto-load
|
||||||
:disable-option="{ card: true }"
|
|
||||||
>
|
>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<VnLocation
|
<VnLocation
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useRoute } from 'vue-router';
|
||||||
import { onMounted, onUnmounted, ref } from 'vue';
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||||
import OrderCatalogItem from 'pages/Order/Card/OrderCatalogItem.vue';
|
import CatalogItem from 'components/ui/CatalogItem.vue';
|
||||||
import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue';
|
import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -77,7 +77,12 @@ function extractValueTags(items) {
|
||||||
<div v-if="rows && !rows?.length" class="no-result">
|
<div v-if="rows && !rows?.length" class="no-result">
|
||||||
{{ t('globals.noResults') }}
|
{{ t('globals.noResults') }}
|
||||||
</div>
|
</div>
|
||||||
<OrderCatalogItem v-for="row in rows" :key="row.id" :item="row" />
|
<CatalogItem
|
||||||
|
v-for="row in rows"
|
||||||
|
:key="row.id"
|
||||||
|
:item="row"
|
||||||
|
is-catalog
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</VnPaginate>
|
</VnPaginate>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
ticket: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
withRoute: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
selectedExpeditions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const router = useRouter();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
const newTicketFormData = reactive({});
|
||||||
|
|
||||||
|
const createTicket = async () => {
|
||||||
|
try {
|
||||||
|
const expeditionIds = $props.selectedExpeditions.map(
|
||||||
|
(expedition) => expedition.id
|
||||||
|
);
|
||||||
|
const params = {
|
||||||
|
clientId: $props.ticket.clientFk,
|
||||||
|
landed: newTicketFormData.landed,
|
||||||
|
warehouseId: $props.ticket.warehouseFk,
|
||||||
|
addressId: $props.ticket.addressFk,
|
||||||
|
agencyModeId: $props.ticket.agencyModeFk,
|
||||||
|
routeId: newTicketFormData.routeFk,
|
||||||
|
expeditionIds: expeditionIds,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await axios.post('Expeditions/moveExpeditions', params);
|
||||||
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
|
router.push({ name: 'TicketSummary', params: { id: data.id } });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FormModelPopup
|
||||||
|
model="expeditionNewTicket"
|
||||||
|
:form-initial-data="newTicketFormData"
|
||||||
|
:save-fn="createTicket"
|
||||||
|
>
|
||||||
|
<template #form-inputs="{ data }">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<VnInputDate :label="t('expedition.landed')" v-model="data.landed" />
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<VnInput
|
||||||
|
v-if="withRoute"
|
||||||
|
:label="t('expedition.routeId')"
|
||||||
|
v-model="data.routeFk"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
</template>
|
||||||
|
</FormModelPopup>
|
||||||
|
</template>
|
|
@ -0,0 +1,474 @@
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, computed, onUnmounted, reactive, watch } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
|
import TicketEditManaProxy from './TicketEditMana.vue';
|
||||||
|
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
|
||||||
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
|
import ExpeditionNewTicket from './ExpeditionNewTicket.vue';
|
||||||
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { toCurrency, toPercentage } from 'src/filters';
|
||||||
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const stateStore = useStateStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
|
const editPriceProxyRef = ref(null);
|
||||||
|
const newTicketDialogRef = ref(null);
|
||||||
|
const logsTableDialogRef = ref(null);
|
||||||
|
|
||||||
|
const expeditionsLogsData = ref([]);
|
||||||
|
const selectedExpeditions = ref([]);
|
||||||
|
const allColumnNames = ref([]);
|
||||||
|
const visibleColumns = ref([]);
|
||||||
|
const newTicketWithRoute = ref(false);
|
||||||
|
const itemsOptions = ref([]);
|
||||||
|
|
||||||
|
const exprBuilder = (param, value) => {
|
||||||
|
switch (param) {
|
||||||
|
case 'expeditionFk':
|
||||||
|
return { id: value };
|
||||||
|
case 'packageItemName':
|
||||||
|
return { packagingItemFk: value };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const expeditionsFilter = computed(() => ({
|
||||||
|
where: { ticketFk: route.params.id },
|
||||||
|
order: ['created DESC'],
|
||||||
|
}));
|
||||||
|
|
||||||
|
const expeditionsArrayData = useArrayData('ticketExpeditions', {
|
||||||
|
url: 'Expeditions/filter',
|
||||||
|
filter: expeditionsFilter.value,
|
||||||
|
exprBuilder: exprBuilder,
|
||||||
|
});
|
||||||
|
const expeditionsStore = expeditionsArrayData.store;
|
||||||
|
const ticketExpeditions = computed(() => expeditionsStore.data);
|
||||||
|
|
||||||
|
const ticketArrayData = useArrayData('ticketData');
|
||||||
|
const ticketStore = ticketArrayData.store;
|
||||||
|
const ticketData = computed(() => ticketStore.data);
|
||||||
|
|
||||||
|
const refetchExpeditions = async () => {
|
||||||
|
await expeditionsArrayData.applyFilter({
|
||||||
|
params: { filter: JSON.stringify(expeditionsFilter.value) },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.params.id,
|
||||||
|
async () => await refetchExpeditions(),
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const params = reactive({});
|
||||||
|
|
||||||
|
const applyColumnFilter = async (col) => {
|
||||||
|
try {
|
||||||
|
const paramKey = col.columnFilter?.filterParamKey || col.field;
|
||||||
|
params[paramKey] = col.columnFilter.filterValue;
|
||||||
|
await expeditionsArrayData.addFilter({ params });
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error applying column filter', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInputEvents = (col) => {
|
||||||
|
return col.columnFilter.type === 'select'
|
||||||
|
? { 'update:modelValue': () => applyColumnFilter(col) }
|
||||||
|
: {
|
||||||
|
'keyup.enter': () => applyColumnFilter(col),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = computed(() => [
|
||||||
|
{
|
||||||
|
label: t('expedition.id'),
|
||||||
|
name: 'id',
|
||||||
|
field: 'id',
|
||||||
|
align: 'left',
|
||||||
|
sortable: true,
|
||||||
|
columnFilter: {
|
||||||
|
component: VnInput,
|
||||||
|
type: 'text',
|
||||||
|
filterParamKey: 'expeditionFk',
|
||||||
|
filterValue: null,
|
||||||
|
event: getInputEvents,
|
||||||
|
attrs: {
|
||||||
|
dense: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.item'),
|
||||||
|
name: 'item',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: {
|
||||||
|
component: VnInput,
|
||||||
|
type: 'text',
|
||||||
|
filterParamKey: 'packageItemName',
|
||||||
|
filterValue: null,
|
||||||
|
event: getInputEvents,
|
||||||
|
attrs: {
|
||||||
|
dense: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.name'),
|
||||||
|
name: 'name',
|
||||||
|
field: 'packageItemName',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: {
|
||||||
|
component: VnSelect,
|
||||||
|
type: 'select',
|
||||||
|
filterValue: null,
|
||||||
|
event: getInputEvents,
|
||||||
|
attrs: {
|
||||||
|
options: itemsOptions.value,
|
||||||
|
'option-value': 'id',
|
||||||
|
'option-label': 'name',
|
||||||
|
dense: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.packageType'),
|
||||||
|
name: 'packageType',
|
||||||
|
field: 'freightItemName',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: {
|
||||||
|
component: VnInput,
|
||||||
|
type: 'text',
|
||||||
|
// filterParamKey: 'expeditionFk',
|
||||||
|
filterValue: null,
|
||||||
|
event: getInputEvents,
|
||||||
|
attrs: {
|
||||||
|
dense: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.counter'),
|
||||||
|
name: 'counter',
|
||||||
|
field: 'counter',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.externalId'),
|
||||||
|
name: 'externalId',
|
||||||
|
field: 'externalId',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.created'),
|
||||||
|
name: 'created',
|
||||||
|
field: 'created',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
format: (value) => toDateTimeFormat(value),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.state'),
|
||||||
|
name: 'state',
|
||||||
|
field: 'state',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
name: 'history',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const logTableColumns = computed(() => [
|
||||||
|
{
|
||||||
|
label: t('expedition.state'),
|
||||||
|
name: 'state',
|
||||||
|
field: 'state',
|
||||||
|
align: 'left',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.name'),
|
||||||
|
name: 'name',
|
||||||
|
align: 'name',
|
||||||
|
columnFilter: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('expedition.created'),
|
||||||
|
name: 'created',
|
||||||
|
field: 'created',
|
||||||
|
align: 'left',
|
||||||
|
columnFilter: null,
|
||||||
|
format: (value) => toDateTimeFormat(value),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const showNewTicketDialog = (withRoute = false) => {
|
||||||
|
newTicketWithRoute.value = withRoute;
|
||||||
|
newTicketDialogRef.value.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteExpedition = async () => {
|
||||||
|
try {
|
||||||
|
const expeditionIds = selectedExpeditions.value.map(
|
||||||
|
(expedition) => expedition.id
|
||||||
|
);
|
||||||
|
const params = { expeditionIds };
|
||||||
|
await axios.post('Expeditions/deleteExpeditions', params);
|
||||||
|
await refetchExpeditions();
|
||||||
|
selectedExpeditions.value = [];
|
||||||
|
notify(t('expedition.expeditionRemoved'), 'positive');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showLog = async (expedition) => {
|
||||||
|
await getExpeditionState(expedition);
|
||||||
|
logsTableDialogRef.value.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExpeditionState = async (expedition) => {
|
||||||
|
try {
|
||||||
|
const filter = {
|
||||||
|
where: { expeditionFk: expedition.id },
|
||||||
|
order: ['created DESC'],
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await axios.get(`ExpeditionStates/filter`, {
|
||||||
|
params: { filter: JSON.stringify(filter) },
|
||||||
|
});
|
||||||
|
expeditionsLogsData.value = data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
stateStore.rightDrawer = true;
|
||||||
|
const filteredColumns = columns.value.filter((col) => col.name !== 'history');
|
||||||
|
allColumnNames.value = filteredColumns.map((col) => col.name);
|
||||||
|
// await expeditionsArrayData.fetch({ append: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
url="Items"
|
||||||
|
auto-load
|
||||||
|
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
|
||||||
|
@on-fetch="(data) => (itemsOptions = data)"
|
||||||
|
/>
|
||||||
|
<VnSubToolbar>
|
||||||
|
<template #st-data>
|
||||||
|
<TableVisibleColumns
|
||||||
|
:all-columns="allColumnNames"
|
||||||
|
table-code="expeditionIndex"
|
||||||
|
labels-traductions-path="expedition"
|
||||||
|
@on-config-saved="visibleColumns = [...$event, 'history']"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #st-actions>
|
||||||
|
<QBtnGroup push class="q-gutter-x-sm" flat>
|
||||||
|
<QBtnDropdown
|
||||||
|
ref="btnDropdownRef"
|
||||||
|
color="primary"
|
||||||
|
:label="t('expedition.move')"
|
||||||
|
:disable="!selectedExpeditions.length"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<QTooltip>{{ t('Select lines to see the options') }}</QTooltip>
|
||||||
|
</template>
|
||||||
|
<QList>
|
||||||
|
<QItem
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
v-ripple
|
||||||
|
@click="showNewTicketDialog(false)"
|
||||||
|
>
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
t('expedition.newTicketWithoutRoute')
|
||||||
|
}}</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
v-ripple
|
||||||
|
@click="showNewTicketDialog(true)"
|
||||||
|
>
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
t('expedition.newTicketWithRoute')
|
||||||
|
}}</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</QList>
|
||||||
|
</QBtnDropdown>
|
||||||
|
<QBtn
|
||||||
|
:disable="!selectedExpeditions.length"
|
||||||
|
icon="delete"
|
||||||
|
color="primary"
|
||||||
|
@click="
|
||||||
|
openConfirmationModal(
|
||||||
|
'',
|
||||||
|
t('expedition.removeExpeditionSubtitle'),
|
||||||
|
deleteExpedition
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</QBtnGroup>
|
||||||
|
</template>
|
||||||
|
</VnSubToolbar>
|
||||||
|
|
||||||
|
<QTable
|
||||||
|
:rows="ticketExpeditions"
|
||||||
|
:columns="columns"
|
||||||
|
row-key="id"
|
||||||
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
selection="multiple"
|
||||||
|
v-model:selected="selectedExpeditions"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
:no-data-label="t('globals.noResults')"
|
||||||
|
>
|
||||||
|
<template #top-row="{ cols }">
|
||||||
|
<QTr>
|
||||||
|
<QTd />
|
||||||
|
<QTd v-for="(col, index) in cols" :key="index" style="max-width: 100px">
|
||||||
|
<component
|
||||||
|
:is="col.columnFilter.component"
|
||||||
|
v-if="col.columnFilter"
|
||||||
|
v-model="col.columnFilter.filterValue"
|
||||||
|
v-bind="col.columnFilter.attrs"
|
||||||
|
v-on="col.columnFilter.event(col)"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</QTr>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-item="{ row }">
|
||||||
|
<QTd auto-width @click.stop>
|
||||||
|
<QBtn flat color="primary">{{ row.packagingItemFk }}</QBtn>
|
||||||
|
<ItemDescriptorProxy :id="row.packagingItemFk" />
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-available="{ row }">
|
||||||
|
<QTd @click.stop>
|
||||||
|
<QBadge :color="row.available < 0 ? 'alert' : 'transparent'" dense>
|
||||||
|
{{ row.available }}
|
||||||
|
</QBadge>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #body-cell-price="{ row }">
|
||||||
|
<QTd>
|
||||||
|
<template v-if="isTicketEditable && row.id">
|
||||||
|
<QBtn flat color="primary" dense @click="onOpenEditPricePopover(row)">
|
||||||
|
{{ toCurrency(row.price) }}
|
||||||
|
</QBtn>
|
||||||
|
<TicketEditManaProxy
|
||||||
|
ref="editPriceProxyRef"
|
||||||
|
:mana="mana"
|
||||||
|
:new-price="getNewPrice"
|
||||||
|
@save="updatePrice(row)"
|
||||||
|
>
|
||||||
|
<VnInput
|
||||||
|
v-model.number="edit.price"
|
||||||
|
:label="t('ticketSale.price')"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TicketEditManaProxy>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ toCurrency(row.price) }}</span>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-discount="{ row }">
|
||||||
|
<QTd>
|
||||||
|
<template v-if="!isLocked && row.id">
|
||||||
|
<QBtn
|
||||||
|
flat
|
||||||
|
color="primary"
|
||||||
|
dense
|
||||||
|
@click="onOpenEditDiscountPopover(row)"
|
||||||
|
>
|
||||||
|
{{ toPercentage(row.discount / 100) }}
|
||||||
|
</QBtn>
|
||||||
|
<TicketEditManaProxy
|
||||||
|
:mana="mana"
|
||||||
|
:new-price="getNewPrice"
|
||||||
|
@save="changeDiscount(row)"
|
||||||
|
>
|
||||||
|
<VnInput
|
||||||
|
v-model.number="edit.discount"
|
||||||
|
:label="t('ticketSale.discount')"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TicketEditManaProxy>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-history="{ row }">
|
||||||
|
<QTd>
|
||||||
|
<QBtn
|
||||||
|
@click.stop="showLog(row)"
|
||||||
|
color="primary"
|
||||||
|
icon="history"
|
||||||
|
size="md"
|
||||||
|
flat
|
||||||
|
>
|
||||||
|
<QTooltip class="text-no-wrap">
|
||||||
|
{{ t('expedition.historyAction') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QBtn>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
<QDialog ref="newTicketDialogRef" transition-show="scale" transition-hide="scale">
|
||||||
|
<ExpeditionNewTicket
|
||||||
|
:ticket="ticketData"
|
||||||
|
:with-route="newTicketWithRoute"
|
||||||
|
:selected-expeditions="selectedExpeditions"
|
||||||
|
/>
|
||||||
|
</QDialog>
|
||||||
|
<QDialog ref="logsTableDialogRef" transition-show="scale" transition-hide="scale">
|
||||||
|
<QTable
|
||||||
|
ref="tableRef"
|
||||||
|
data-key="TicketExpeditionLog"
|
||||||
|
:rows="expeditionsLogsData"
|
||||||
|
:columns="logTableColumns"
|
||||||
|
class="q-pa-sm"
|
||||||
|
>
|
||||||
|
<template #body-cell-name="{ row }">
|
||||||
|
<QTd auto-width>
|
||||||
|
<QBtn flat dense color="primary">{{ row.name }}</QBtn>
|
||||||
|
<WorkerDescriptorProxy :id="row.workerFk" />
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</QDialog>
|
||||||
|
</template>
|
|
@ -0,0 +1,60 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import CatalogItem from 'components/ui/CatalogItem.vue';
|
||||||
|
|
||||||
|
import { toCurrency } from 'filters/index';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
const salesFilter = {
|
||||||
|
include: {
|
||||||
|
relation: 'item',
|
||||||
|
scope: {
|
||||||
|
field: ['name', 'image'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: { ticketFk: route.params.id },
|
||||||
|
};
|
||||||
|
const sales = ref([]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
ref="salesRef"
|
||||||
|
url="sales"
|
||||||
|
:filter="salesFilter"
|
||||||
|
@on-fetch="(data) => (sales = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<div class="pictures-list">
|
||||||
|
<CatalogItem v-for="(sale, index) in sales" :key="index" :item="sale.item">
|
||||||
|
<template #price>
|
||||||
|
<div class="q-mt-md full-width row justify-between items-center">
|
||||||
|
<span class="text-h6">{{ sale.quantity }}</span>
|
||||||
|
<span>{{ t('by') }}</span>
|
||||||
|
<span class="text-h6">{{ toCurrency(sale?.price) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CatalogItem>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pictures-list {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
by: por
|
||||||
|
</i18n>
|
|
@ -774,6 +774,5 @@ es:
|
||||||
Continue anyway?: ¿Continuar de todas formas?
|
Continue anyway?: ¿Continuar de todas formas?
|
||||||
You are going to delete lines of the ticket: Vas a eliminar lineas del ticket
|
You are going to delete lines of the ticket: Vas a eliminar lineas del ticket
|
||||||
Add item: Añadir artículo
|
Add item: Añadir artículo
|
||||||
Select lines to see the options: Selecciona líneas para ver las opciones
|
|
||||||
Transfer lines: Transferir líneas
|
Transfer lines: Transferir líneas
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -93,6 +93,25 @@ futureTickets:
|
||||||
moveTicketSuccess: Tickets moved successfully!
|
moveTicketSuccess: Tickets moved successfully!
|
||||||
searchInfo: Search future tickets by date
|
searchInfo: Search future tickets by date
|
||||||
futureTicket: Future tickets
|
futureTicket: Future tickets
|
||||||
|
expedition:
|
||||||
|
id: Expedition
|
||||||
|
item: Item
|
||||||
|
name: Name
|
||||||
|
packageType: Package type
|
||||||
|
counter: Counter
|
||||||
|
externalId: externalId
|
||||||
|
created: Created
|
||||||
|
state: State
|
||||||
|
historyAction: Status log
|
||||||
|
newTicketWithRoute: New ticket with route
|
||||||
|
newTicketWithoutRoute: New ticket without route
|
||||||
|
landed: Landed
|
||||||
|
routeId: Route id
|
||||||
|
deleteExpedition: Delete expedition
|
||||||
|
expeditionRemoved: Expedition removed
|
||||||
|
removeExpeditionSubtitle: Are you sure you want to delete this expedition?
|
||||||
|
worker: Worker
|
||||||
|
move: Move
|
||||||
basicData:
|
basicData:
|
||||||
next: Next
|
next: Next
|
||||||
back: Back
|
back: Back
|
||||||
|
|
|
@ -182,5 +182,25 @@ components:
|
||||||
theoricalCost: Porte teórico
|
theoricalCost: Porte teórico
|
||||||
totalPrice: Precio total
|
totalPrice: Precio total
|
||||||
packages: Bultos
|
packages: Bultos
|
||||||
|
expedition:
|
||||||
|
id: Expedición
|
||||||
|
item: Artículo
|
||||||
|
name: Nombre
|
||||||
|
packageType: Package type
|
||||||
|
counter: Contador
|
||||||
|
externalId: externalId
|
||||||
|
created: Fecha creación
|
||||||
|
state: Estado
|
||||||
|
historyAction: Historial de estados
|
||||||
|
newTicketWithRoute: Nuevo ticket con ruta
|
||||||
|
newTicketWithoutRoute: Nuevo ticket sin ruta
|
||||||
|
landed: F. entrega
|
||||||
|
routeId: Id ruta
|
||||||
|
deleteExpedition: Eliminar expedición
|
||||||
|
expeditionRemoved: Expedición eliminada
|
||||||
|
removeExpeditionSubtitle: ¿Está seguro de eliminar esta expedición?
|
||||||
|
worker: Trabajador
|
||||||
|
move: Mover
|
||||||
Search ticket: Buscar tickets
|
Search ticket: Buscar tickets
|
||||||
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
You can search by ticket id or alias: Puedes buscar por id o alias del ticket
|
||||||
|
Select lines to see the options: Selecciona líneas para ver las opciones
|
||||||
|
|
|
@ -65,7 +65,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
|
||||||
:subtitle="data.subtitle"
|
:subtitle="data.subtitle"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
data-key="travelData"
|
data-key="travelData"
|
||||||
:summary="$attrs"
|
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
>
|
>
|
||||||
<template #menu="{ entity }">
|
<template #menu="{ entity }">
|
||||||
|
|
|
@ -71,6 +71,7 @@ const columns = computed(() => [
|
||||||
url: 'agencyModes',
|
url: 'agencyModes',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
|
format: (row) => row.agencyModeName,
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
|
@ -112,7 +113,10 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'warehouses',
|
url: 'warehouses',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
},
|
},
|
||||||
|
format: (row) => row.warehouseInName,
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
|
@ -129,6 +133,7 @@ const columns = computed(() => [
|
||||||
url: 'warehouses',
|
url: 'warehouses',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
|
format: (row) => row.warehouseOutName,
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
|
@ -196,7 +201,6 @@ const columns = computed(() => [
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
auto-load
|
auto-load
|
||||||
redirect="travel"
|
redirect="travel"
|
||||||
:right-search="false"
|
|
||||||
:is-editable="false"
|
:is-editable="false"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -14,15 +14,17 @@ export default {
|
||||||
main: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
|
main: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
|
||||||
card: [
|
card: [
|
||||||
'TicketBasicData',
|
'TicketBasicData',
|
||||||
'TicketBoxing',
|
'TicketPurchaseRequest',
|
||||||
'TicketSms',
|
|
||||||
'TicketSale',
|
'TicketSale',
|
||||||
'TicketLog',
|
'TicketLog',
|
||||||
'TicketPurchaseRequest',
|
'TicketExpedition',
|
||||||
'TicketService',
|
'TicketService',
|
||||||
'TicketTracking',
|
|
||||||
'TicketVolume',
|
'TicketVolume',
|
||||||
'TicketNotes',
|
'TicketNotes',
|
||||||
|
'TicketTracking',
|
||||||
|
'TicketBoxing',
|
||||||
|
'TicketSms',
|
||||||
|
'TicketPicture',
|
||||||
'TicketComponents',
|
'TicketComponents',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -71,8 +73,8 @@ export default {
|
||||||
component: () => import('src/pages/Ticket/TicketFuture.vue'),
|
component: () => import('src/pages/Ticket/TicketFuture.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'advance',
|
|
||||||
name: 'TicketAdvance',
|
name: 'TicketAdvance',
|
||||||
|
path: 'advance',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'ticketAdvance',
|
title: 'ticketAdvance',
|
||||||
icon: 'keyboard_double_arrow_left',
|
icon: 'keyboard_double_arrow_left',
|
||||||
|
@ -144,32 +146,31 @@ export default {
|
||||||
component: () => import('src/pages/Ticket/Card/TicketLog.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketLog.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'boxing',
|
path: 'picture',
|
||||||
name: 'TicketBoxing',
|
name: 'TicketPicture',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'boxing',
|
title: 'pictures',
|
||||||
icon: 'vn:package',
|
icon: 'vn:photo',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketPicture.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sms',
|
path: 'picture',
|
||||||
name: 'TicketSms',
|
name: 'TicketPicture',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'sms',
|
title: 'pictures',
|
||||||
icon: 'sms',
|
icon: 'vn:photo',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketPicture.vue'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'service',
|
path: 'observation',
|
||||||
name: 'TicketService',
|
name: 'TicketNotes',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'services',
|
title: 'notes',
|
||||||
icon: 'vn:services',
|
icon: 'vn:notes',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketService.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketNotes.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'volume',
|
path: 'volume',
|
||||||
|
@ -190,13 +191,40 @@ export default {
|
||||||
component: () => import('src/pages/Ticket/Card/TicketComponents.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketComponents.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'observation',
|
path: 'expedition',
|
||||||
name: 'TicketNotes',
|
name: 'TicketExpedition',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'notes',
|
title: 'expedition',
|
||||||
icon: 'vn:notes',
|
icon: 'vn:package',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Ticket/Card/TicketNotes.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketExpedition.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'service',
|
||||||
|
name: 'TicketService',
|
||||||
|
meta: {
|
||||||
|
title: 'services',
|
||||||
|
icon: 'vn:services',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/Card/TicketService.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'boxing',
|
||||||
|
name: 'TicketBoxing',
|
||||||
|
meta: {
|
||||||
|
title: 'boxing',
|
||||||
|
icon: 'science',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'sms',
|
||||||
|
name: 'TicketSms',
|
||||||
|
meta: {
|
||||||
|
title: 'sms',
|
||||||
|
icon: 'sms',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,13 +3,7 @@ import { defineStore } from 'pinia';
|
||||||
|
|
||||||
export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
||||||
const state = ref({});
|
const state = ref({});
|
||||||
|
const defaultOpts = {
|
||||||
function get(key) {
|
|
||||||
return state.value[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function set(key) {
|
|
||||||
state.value[key] = {
|
|
||||||
filter: {},
|
filter: {},
|
||||||
userFilter: {},
|
userFilter: {},
|
||||||
userParams: {},
|
userParams: {},
|
||||||
|
@ -17,7 +11,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
||||||
limit: 10,
|
limit: 10,
|
||||||
skip: 0,
|
skip: 0,
|
||||||
order: '',
|
order: '',
|
||||||
data: ref(),
|
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
userParamsChanged: false,
|
userParamsChanged: false,
|
||||||
exprBuilder: null,
|
exprBuilder: null,
|
||||||
|
@ -25,15 +18,41 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
||||||
navigate: null,
|
navigate: null,
|
||||||
page: 1,
|
page: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function get(key) {
|
||||||
|
return state.value[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(key) {
|
||||||
|
state.value[key] = getDefaultState();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear(key) {
|
function clear(key) {
|
||||||
delete state.value[key];
|
delete state.value[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset(key, opts = []) {
|
||||||
|
if (!opts.length) state.value[key] = getDefaultState();
|
||||||
|
else
|
||||||
|
opts.forEach((opt) => {
|
||||||
|
if (opt.includes('.')) {
|
||||||
|
const [parent, child] = opt.split('.');
|
||||||
|
state.value[key][parent][child] = defaultOpts[child];
|
||||||
|
} else if (Object.hasOwn(state.value[key], opt))
|
||||||
|
state.value[key][opt] = defaultOpts[opt];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultState() {
|
||||||
|
return Object.assign(JSON.parse(JSON.stringify(defaultOpts)), {
|
||||||
|
data: ref(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
get,
|
get,
|
||||||
set,
|
set,
|
||||||
clear,
|
clear,
|
||||||
|
reset,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
describe('WagonTypeCreate', () => {
|
describe('EntryDms', () => {
|
||||||
const entryId = 1;
|
const entryId = 1;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
describe('WagonTypeCreate', () => {
|
// describe('WagonTypeCreate', () => {
|
||||||
beforeEach(() => {
|
// beforeEach(() => {
|
||||||
cy.viewport(1920, 1080);
|
// cy.viewport(1920, 1080);
|
||||||
cy.login('customer');
|
// cy.login('customer');
|
||||||
cy.visit(`/#/entry/my`, {
|
// cy.visit(`/#/entry/my`, {
|
||||||
onBeforeLoad(win) {
|
// onBeforeLoad(win) {
|
||||||
cy.stub(win, 'open');
|
// cy.stub(win, 'open');
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
cy.waitForElement('.q-page', 6000);
|
// cy.waitForElement('.q-page', 6000);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should create edit and remove new dms', () => {
|
// it('should create edit and remove new dms', () => {
|
||||||
cy.get(
|
// cy.get(
|
||||||
'[to="/null/2"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon'
|
// '[to="/null/2"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon'
|
||||||
).click();
|
// ).click();
|
||||||
cy.get('.q-card__actions > .q-btn').click();
|
// cy.get('.q-card__actions > .q-btn').click();
|
||||||
cy.window().its('open').should('be.called');
|
// cy.window().its('open').should('be.called');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -239,5 +239,5 @@ Cypress.Commands.add('validateContent', (selector, expectedValue) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('openActionsDescriptor', () => {
|
Cypress.Commands.add('openActionsDescriptor', () => {
|
||||||
cy.get('.descriptor > .header > .q-btn').click();
|
cy.get('.header > :nth-child(3) > .q-btn__content > .q-icon').click();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue