@@ -18,7 +28,7 @@ defineProps({ row: { type: Object, required: true } });
{{ $t('salesTicketsTable.componentLack') }}
-
+
{{ $t('ticket.summary.hasItemDelay') }}
-
+
{{ $t('salesTicketsTable.hasItemLost') }}
{{ $t('salesTicketsTable.notVisible') }}
-
+
{{ $t('ticketList.rounding') }}
{{ $t('salesTicketsTable.purchaseRequest') }}
-
+
{{ $t('salesTicketsTable.noVerifiedData') }}
-
+
{{ $t('salesTicketsTable.clientFrozen') }}
-
+
{{ $t('salesTicketsTable.tooLittle') }}
diff --git a/src/components/__tests__/UserPanel.spec.js b/src/components/__tests__/UserPanel.spec.js
index 9e449745a..b6da8b058 100644
--- a/src/components/__tests__/UserPanel.spec.js
+++ b/src/components/__tests__/UserPanel.spec.js
@@ -1,65 +1,63 @@
-import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
+import { vi, describe, expect, it, beforeEach, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import UserPanel from 'src/components/UserPanel.vue';
import axios from 'axios';
import { useState } from 'src/composables/useState';
-vi.mock('src/utils/quasarLang', () => ({
- default: vi.fn(),
-}));
-
describe('UserPanel', () => {
- let wrapper;
- let vm;
- let state;
+ let wrapper;
+ let vm;
+ let state;
- beforeEach(() => {
- wrapper = createWrapper(UserPanel, {});
- state = useState();
- state.setUser({
- id: 115,
- name: 'itmanagement',
- nickname: 'itManagementNick',
- lang: 'en',
- darkMode: false,
- companyFk: 442,
- warehouseFk: 1,
+ beforeEach(() => {
+ wrapper = createWrapper(UserPanel, {});
+ state = useState();
+ state.setUser({
+ id: 115,
+ name: 'itmanagement',
+ nickname: 'itManagementNick',
+ lang: 'en',
+ darkMode: false,
+ companyFk: 442,
+ warehouseFk: 1,
+ });
+ wrapper = wrapper.wrapper;
+ vm = wrapper.vm;
});
- wrapper = wrapper.wrapper;
- vm = wrapper.vm;
- });
- afterEach(() => {
- vi.clearAllMocks();
- });
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
- it('should fetch warehouses data on mounted', async () => {
- const fetchData = wrapper.findComponent({ name: 'FetchData' });
- expect(fetchData.props('url')).toBe('Warehouses');
- expect(fetchData.props('autoLoad')).toBe(true);
- });
+ it('should fetch warehouses data on mounted', async () => {
+ const fetchData = wrapper.findComponent({ name: 'FetchData' });
+ expect(fetchData.props('url')).toBe('Warehouses');
+ expect(fetchData.props('autoLoad')).toBe(true);
+ });
- it('should toggle dark mode correctly and update preferences', async () => {
- await vm.saveDarkMode(true);
- expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
- expect(vm.user.darkMode).toBe(true);
- await vm.updatePreferences();
- expect(vm.darkMode).toBe(true);
- });
+ it('should toggle dark mode correctly and update preferences', async () => {
+ await vm.saveDarkMode(true);
+ expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
+ expect(vm.user.darkMode).toBe(true);
+ vm.updatePreferences();
+ expect(vm.darkMode).toBe(true);
+ });
- it('should change user language and update preferences', async () => {
- const userLanguage = 'es';
- await vm.saveLanguage(userLanguage);
- expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
- expect(vm.user.lang).toBe(userLanguage);
- await vm.updatePreferences();
- expect(vm.locale).toBe(userLanguage);
- });
+ it('should change user language and update preferences', async () => {
+ const userLanguage = 'es';
+ await vm.saveLanguage(userLanguage);
+ expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
+ expect(vm.user.lang).toBe(userLanguage);
+ vm.updatePreferences();
+ expect(vm.locale).toBe(userLanguage);
+ });
- it('should update user data', async () => {
- const key = 'name';
- const value = 'itboss';
- await vm.saveUserData(key, value);
- expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
- });
-});
\ No newline at end of file
+ it('should update user data', async () => {
+ const key = 'name';
+ const value = 'itboss';
+ await vm.saveUserData(key, value);
+ expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', {
+ [key]: value,
+ });
+ });
+});
diff --git a/src/components/ui/VnDescriptor.vue b/src/components/ui/VnDescriptor.vue
index 994233eb0..69fd5af6b 100644
--- a/src/components/ui/VnDescriptor.vue
+++ b/src/components/ui/VnDescriptor.vue
@@ -6,6 +6,7 @@ import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { useRoute, useRouter } from 'vue-router';
import { useClipboard } from 'src/composables/useClipboard';
import VnMoreOptions from './VnMoreOptions.vue';
+import { getValueFromPath } from 'src/composables/getValueFromPath';
const entity = defineModel({ type: Object, default: null });
const $props = defineProps({
@@ -56,18 +57,6 @@ const routeName = computed(() => {
return `${routeName}Summary`;
});
-function getValueFromPath(path) {
- if (!path) return;
- const keys = path.toString().split('.');
- let current = entity.value;
-
- for (const key of keys) {
- if (current[key] === undefined) return undefined;
- else current = current[key];
- }
- return current;
-}
-
function copyIdText(id) {
copyText(id, {
component: {
@@ -170,10 +159,10 @@ const toModule = computed(() => {
- {{ getValueFromPath(title) ?? title }}
+ {{ getValueFromPath(entity, title) ?? title }}
{
class="subtitle"
:data-cy="`${$attrs['data-cy'] ?? 'vnDescriptor'}_subtitle`"
>
- #{{ getValueFromPath(subtitle) ?? entity.id }}
+ #{{ getValueFromPath(entity, subtitle) ?? entity.id }}
[
headerClass: 'horizontal-separator',
hidden: true,
},
+ {
+ label: t('globals.agency'),
+ name: 'agency',
+ field: 'agency',
+ align: 'left',
+ sortable: true,
+ headerClass: 'horizontal-separator',
+ columnFilter: false,
+ },
{
label: t('advanceTickets.preparation'),
name: 'preparation',
@@ -85,7 +106,6 @@ const ticketColumns = computed(() => [
align: 'left',
sortable: true,
headerClass: 'horizontal-separator',
- columnFilter: false,
},
{
align: 'left',
@@ -110,10 +130,17 @@ const ticketColumns = computed(() => [
},
{
align: 'left',
- label: t('advanceTickets.futureId'),
- name: 'futureId',
+ label: '',
+ name: 'problems',
headerClass: 'vertical-separator horizontal-separator',
columnClass: 'vertical-separator',
+ hidden: true,
+ },
+ {
+ align: 'left',
+ label: t('advanceTickets.futureId'),
+ name: 'futureId',
+ headerClass: 'horizontal-separator',
},
{
align: 'left',
@@ -242,7 +269,7 @@ const requestComponentUpdate = async (ticket, isWithoutNegatives) => {
return { query, params };
};
-const moveTicketsAdvance = async () => {
+async function moveTicketsAdvance() {
let ticketsToMove = [];
for (const ticket of selectedTickets.value) {
if (!ticket.id) {
@@ -267,7 +294,7 @@ const moveTicketsAdvance = async () => {
vnTableRef.value.reload();
selectedTickets.value = [];
if (ticketsToMove.length) notify(t('advanceTickets.moveTicketSuccess'), 'positive');
-};
+}
const progressLength = ref(0);
const progressPercentage = computed(() => {
@@ -290,7 +317,7 @@ const progressAdd = () => {
}
};
-const splitTickets = async () => {
+async function splitTickets() {
try {
showProgressDialog.value = true;
for (const ticket of selectedTickets.value) {
@@ -310,7 +337,7 @@ const splitTickets = async () => {
} finally {
vnTableRef.value.reload();
}
-};
+}
const resetProgressData = () => {
if (cancelProgress.value) cancelProgress.value = false;
@@ -326,6 +353,32 @@ const handleCloseProgressDialog = () => {
const handleCancelProgress = () => (cancelProgress.value = true);
+const confirmAction = (action) => {
+ openConfirmationModal(actions[action].title, false, actions[action].cb, null, {
+ component: QTable,
+ props: {
+ columns: [
+ {
+ align: 'left',
+ label: t('advanceTickets.destination'),
+ name: 'id',
+ field: (row) => row.id,
+ },
+ {
+ align: 'left',
+ label: t('advanceTickets.origin'),
+ name: 'futureId',
+ field: (row) => row.futureId,
+ },
+ ],
+ rows: selectedTickets.value,
+ class: 'full-width',
+ dense: true,
+ flat: true,
+ },
+ });
+};
+
watch(
() => vnTableRef.value.tableRef?.$el,
($el) => {
@@ -399,15 +452,7 @@ watch(
color="primary"
class="q-mr-sm"
:disable="!selectedTickets.length"
- @click.stop="
- openConfirmationModal(
- t('advanceTickets.advanceTicketTitle'),
- t(`advanceTickets.advanceTitleSubtitle`, {
- selectedTickets: selectedTickets.length,
- }),
- moveTicketsAdvance,
- )
- "
+ @click.stop="confirmAction('advance')"
>
{{ t('advanceTickets.advanceTickets') }}
@@ -417,15 +462,7 @@ watch(
icon="alt_route"
color="primary"
:disable="!selectedTickets.length"
- @click.stop="
- openConfirmationModal(
- t('advanceTickets.advanceWithoutNegativeTitle'),
- t(`advanceTickets.advanceWithoutNegativeSubtitle`, {
- selectedTickets: selectedTickets.length,
- }),
- splitTickets,
- )
- "
+ @click.stop="confirmAction('advanceWithoutNegative')"
>
{{ t('advanceTickets.advanceTicketsWithoutNegatives') }}
@@ -454,9 +491,9 @@ watch(
}"
v-model:selected="selectedTickets"
:pagination="{ rowsPerPage: 0 }"
- :no-data-label="t('globals.noResults')"
+ :no-data-label="$t('globals.noResults')"
:right-search="false"
- :order="['futureTotalWithVat ASC']"
+ :order="['futureTotalWithVat ASC']"
auto-load
:disable-option="{ card: true }"
>
@@ -522,6 +559,9 @@ watch(
{{ toCurrency(row.totalWithVat || 0) }}
+
+
+
{{ row.futureId }}
diff --git a/src/pages/Ticket/TicketAdvanceFilter.vue b/src/pages/Ticket/TicketAdvanceFilter.vue
index f065eaf2e..a88d06300 100644
--- a/src/pages/Ticket/TicketAdvanceFilter.vue
+++ b/src/pages/Ticket/TicketAdvanceFilter.vue
@@ -10,7 +10,7 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
import axios from 'axios';
import { onMounted } from 'vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
const { t, te } = useI18n();
const props = defineProps({
dataKey: {
@@ -122,18 +122,20 @@ onMounted(async () => await getItemPackingTypes());
-
@@ -166,11 +168,12 @@ onMounted(async () => await getItemPackingTypes());
-
@@ -194,8 +197,8 @@ es:
Vertical: Vertical
iptInfo: Encajado
params:
- dateFuture: fecha origen
- dateToAdvance: Fecha destino
+ dateFuture: F. origen
+ dateToAdvance: F. destino
futureIpt: IPT Origen
ipt: IPT destino
isFullMovable: 100% movible