From 168201c755f50cefb633598e5488a88bf48068d9 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 15 Jul 2024 12:25:54 +0200 Subject: [PATCH 001/207] refs #7283 itemList table --- src/pages/Item/ItemList.vue | 477 +++++------------------------------- 1 file changed, 68 insertions(+), 409 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index f1e3629cd..334ef2604 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -3,114 +3,48 @@ import { onMounted, ref, computed, reactive, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; -import FetchData from 'components/FetchData.vue'; -import FetchedTags from 'components/ui/FetchedTags.vue'; -import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import ItemDescriptorProxy from '../Item/Card/ItemDescriptorProxy.vue'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; -import ItemSummary from '../Item/Card/ItemSummary.vue'; -import VnPaginate from 'components/ui/VnPaginate.vue'; -import ItemListFilter from './ItemListFilter.vue'; - +import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDateFormat } from 'src/filters/date.js'; import { dashIfEmpty } from 'src/filters'; -import { useSummaryDialog } from 'src/composables/useSummaryDialog'; -import { useVnConfirm } from 'composables/useVnConfirm'; import axios from 'axios'; -import RightMenu from 'src/components/common/RightMenu.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -import VnImg from 'src/components/ui/VnImg.vue'; const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); -const { viewSummary } = useSummaryDialog(); -const { openConfirmationModal } = useVnConfirm(); +const tableRef = ref(); -const paginateRef = ref(null); -const itemTypesOptions = ref([]); -const originsOptions = ref([]); -const buyersOptions = ref([]); -const intrastatOptions = ref([]); -const itemCategoriesOptions = ref([]); -const visibleColumns = ref([]); -const allColumnNames = ref([]); - -const exprBuilder = (param, value) => { - switch (param) { - case 'category': - return { 'ic.name': value }; - case 'buyerFk': - return { 'it.workerFk': value }; - case 'grouping': - return { 'b.grouping': value }; - case 'packing': - return { 'b.packing': value }; - case 'origin': - return { 'ori.code': value }; - case 'typeFk': - return { 'i.typeFk': value }; - case 'intrastat': - return { 'intr.description': value }; - case 'name': - return { 'i.name': { like: `%${value}%` } }; - case 'producer': - return { 'pr.name': { like: `%${value}%` } }; - case 'id': - case 'size': - case 'subname': - case 'isActive': - case 'weightByPiece': - case 'stemMultiplier': - case 'stems': - return { [`i.${param}`]: value }; - } +const itemFilter = { + include: [ + { + relation: 'trainingCourseType', + scope: { + fields: ['id', 'name'], + }, + }, + { + relation: 'trainingCenter', + scope: { + fields: ['id', 'name'], + }, + }, + ], }; - -const params = reactive({ isFloramondo: false, isActive: true }); - -const applyColumnFilter = async (col) => { - try { - const paramKey = col.columnFilter?.filterParamKey || col.field; - params[paramKey] = col.columnFilter.filterValue; - await paginateRef.value.addFilter(null, 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: '', name: 'picture', align: 'left', - columnFilter: null, }, { label: t('item.list.id'), name: 'id', field: 'id', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, + isId: true, + chip: { + condition: () => true, }, }, { @@ -118,101 +52,41 @@ const columns = computed(() => [ field: 'grouping', name: 'grouping', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, - format: (val) => dashIfEmpty(val), }, { label: t('item.list.packing'), field: 'packing', name: 'packing', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, - format: (val) => dashIfEmpty(val), }, { label: t('globals.description'), field: 'name', name: 'description', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, + create: true, }, { label: t('item.list.stems'), field: 'stems', name: 'stems', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, }, { label: t('item.list.size'), field: 'size', name: 'size', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, }, { label: t('item.list.typeName'), field: 'typeName', name: 'typeName', align: 'left', - sortable: true, - columnFilter: { - component: VnSelect, - filterParamKey: 'typeFk', - type: 'select', - filterValue: null, - event: getInputEvents, - attrs: { - options: itemTypesOptions.value, - 'option-value': 'id', - 'option-label': 'name', - dense: true, - }, + component: 'select', + attrs: { + url: 'ItemType', + fields: ['id', 'name'], }, }, @@ -221,18 +95,10 @@ const columns = computed(() => [ field: 'category', name: 'category', align: 'left', - sortable: true, - columnFilter: { - component: VnSelect, - type: 'select', - filterValue: null, - event: getInputEvents, - attrs: { - options: itemCategoriesOptions.value, - 'option-value': 'name', - 'option-label': 'name', - dense: true, - }, + component: 'select', + attrs: { + url: 'ItemCategory', + fields: ['id', 'name'], }, }, @@ -241,18 +107,10 @@ const columns = computed(() => [ field: 'intrastat', name: 'intrastat', align: 'left', - sortable: true, - columnFilter: { - component: VnSelect, - type: 'select', - filterValue: null, - event: getInputEvents, - attrs: { - options: intrastatOptions.value, - 'option-value': 'description', - 'option-label': 'description', - dense: true, - }, + component: 'select', + attrs: { + url: 'Intrastat', + fields: ['id', 'description'], }, }, { @@ -260,18 +118,10 @@ const columns = computed(() => [ field: 'origin', name: 'origin', align: 'left', - sortable: true, - columnFilter: { - component: VnSelect, - type: 'select', - filterValue: null, - event: getInputEvents, - attrs: { - options: originsOptions.value, - 'option-value': 'code', - 'option-label': 'code', - dense: true, - }, + component: 'select', + attrs: { + url: 'Origin', + fields: ['id', 'name'], }, }, { @@ -279,36 +129,13 @@ const columns = computed(() => [ field: 'userName', name: 'userName', align: 'left', - sortable: true, - columnFilter: { - component: VnSelect, - filterParamKey: 'buyerFk', - type: 'select', - filterValue: null, - event: getInputEvents, - attrs: { - options: buyersOptions.value, - 'option-value': 'id', - 'option-label': 'nickname', - dense: true, - }, - }, }, { label: t('item.list.weightByPiece'), field: 'weightByPiece', name: 'weightByPiece', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, + component: 'input', format: (val) => dashIfEmpty(val), }, { @@ -316,16 +143,7 @@ const columns = computed(() => [ field: 'stemMultiplier', name: 'stemMultiplier', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, - }, + component: 'input', format: (val) => dashIfEmpty(val), }, { @@ -333,40 +151,26 @@ const columns = computed(() => [ field: 'isActive', name: 'isActive', align: 'left', - sortable: true, - columnFilter: null, + component: 'checkbox', }, { label: t('item.list.producer'), field: 'producer', name: 'producer', align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, + component: 'select', + attrs: { + url: 'Producer', + fields: ['id', 'name'], }, - format: (val) => dashIfEmpty(val), }, { label: t('item.list.landed'), field: 'landed', name: 'landed', align: 'left', - sortable: true, + component: 'date', format: (val) => dashIfEmpty(toDateFormat(val)), - columnFilter: null, - }, - { - label: '', - name: 'actions', - align: 'left', - columnFilter: null, }, ]); @@ -388,49 +192,11 @@ const cloneItem = async (itemFk) => { } }; -onMounted(async () => { - stateStore.rightDrawer = true; - const filteredColumns = columns.value.filter( - (col) => col.name !== 'picture' && col.name !== 'actions' - ); - allColumnNames.value = filteredColumns.map((col) => col.name); -}); - onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> - <FetchData - url="ItemTypes" - :filter="{ fields: ['id', 'name'], order: 'name ASC' }" - auto-load - @on-fetch="(data) => (itemTypesOptions = data)" - /> - <FetchData - url="ItemCategories" - :filter="{ fields: ['name'], order: 'name ASC' }" - auto-load - @on-fetch="(data) => (itemCategoriesOptions = data)" - /> - <FetchData - url="Intrastats" - :filter="{ fields: ['description'], order: 'description ASC' }" - auto-load - @on-fetch="(data) => (intrastatOptions = data)" - /> - <FetchData - url="Origins" - :filter="{ fields: ['code'], order: 'code ASC' }" - auto-load - @on-fetch="(data) => (originsOptions = data)" - /> - <FetchData - url="TicketRequests/getItemTypeWorker" - :filter="{ fields: ['id', 'nickname'], order: 'nickname ASC' }" - auto-load - @on-fetch="(data) => (buyersOptions = data)" - /> - <VnSubToolbar> + <!-- <VnSubToolbar> <template #st-data> <TableVisibleColumns :all-columns="allColumnNames" @@ -439,135 +205,28 @@ onUnmounted(() => (stateStore.rightDrawer = false)); @on-config-saved="visibleColumns = ['picture', ...$event, 'actions']" /> </template> - </VnSubToolbar> - <RightMenu> - <template #right-panel> - <ItemListFilter data-key="ItemList" /> - </template> - </RightMenu> - <QPage class="column items-center q-pa-md"> - <VnPaginate - ref="paginateRef" - data-key="ItemList" - url="Items/filter" - :order="['isActive DESC', 'name', 'id']" - :limit="12" - :expr-builder="exprBuilder" - :user-params="params" - :keep-opts="['userParams']" - :offset="50" - auto-load - > - <template #body="{ rows }"> - <QTable - :rows="rows" - :columns="columns" - row-key="id" - :pagination="{ rowsPerPage: 0 }" - class="full-width q-mt-md" - :visible-columns="visibleColumns" - :no-data-label="t('globals.noResults')" - @row-click="(_, row) => redirectToItemSummary(row.id)" - > - <template #top-row="{ cols }"> - <QTr> - <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-picture="{ row }"> - <QTd> - <VnImg - size="50x50" - :id="row.id" - height="50px" - width="50px" - class="image" - /> - </QTd> - </template> - <template #body-cell-id="{ row }"> - <QTd @click.stop> - <QBtn flat color="primary"> - {{ row.id }} - </QBtn> - <ItemDescriptorProxy :id="row.id" /> - </QTd> - </template> - <template #body-cell-userName="{ row }"> - <QTd @click.stop> - <QBtn flat color="primary" dense> - {{ row.userName }} - </QBtn> - <WorkerDescriptorProxy :id="row.buyerFk" /> - </QTd> - </template> - <template #body-cell-description="{ row }"> - <QTd class="col"> - <span>{{ row.name }} {{ row.subName }}</span> - <FetchedTags :item="row" :max-length="6" /> - </QTd> - </template> - <template #body-cell-isActive="{ row }"> - <QTd> - <QCheckbox :model-value="!!row.isActive" disable /> - </QTd> - </template> - <template #body-cell-actions="{ row }"> - <QTd> - <QIcon - @click.stop=" - openConfirmationModal( - t(`All it's properties will be copied`), - t('Do you want to clone this item?'), - () => cloneItem(row.id) - ) - " - class="q-ml-sm" - color="primary" - name="vn:clone" - size="sm" - > - <QTooltip> - {{ t('globals.clone') }} - </QTooltip> - </QIcon> - <QIcon - @click.stop="viewSummary(row.id, ItemSummary)" - class="q-ml-md" - color="primary" - name="preview" - size="sm" - > - <QTooltip class="text-no-wrap"> - {{ t('Preview') }} - </QTooltip> - </QIcon> - </QTd> - </template> - </QTable> - </template> - </VnPaginate> - - <QPageSticky :offset="[20, 20]"> - <QBtn @click="redirectToItemCreate()" color="primary" fab icon="add" /> - <QTooltip class="text-no-wrap"> - {{ t('New item') }} - </QTooltip> - </QPageSticky> - </QPage> + </VnSubToolbar> --> + <VnTable + ref="tableRef" + data-key="ItemList" + url="Items" + url-create="Items" + save-url="Items/crud" + :create="{ + urlCreate: 'Items', + title: 'Create Item', + onDataSaved: () => tableRef.redirect(), + formInitialData: { + editorFk: entityId, + }, + }" + order="id ASC" + :columns="columns" + auto-load + :right-search="false" + :is-editable="false" + :use-model="true" + /> </template> <i18n> From 16b5b5d9a1111f31a8c07f53272a8f6f77ae71ba Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 15 Jul 2024 13:48:59 +0200 Subject: [PATCH 002/207] refs #7283 filter --- src/pages/Item/ItemList.vue | 64 +++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 334ef2604..4c49f068f 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -1,30 +1,39 @@ <script setup> import { onMounted, ref, computed, reactive, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; +import { useRouter, useRoute } from 'vue-router'; +import VnImg from 'src/components/ui/VnImg.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; -import { toDateFormat } from 'src/filters/date.js'; +import { toDate } from 'src/filters'; import { dashIfEmpty } from 'src/filters'; import axios from 'axios'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; +const entityId = computed(() => route.params.id); const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); const tableRef = ref(); +const route = useRoute(); const itemFilter = { include: [ { - relation: 'trainingCourseType', + relation: 'itemType', scope: { fields: ['id', 'name'], }, }, { - relation: 'trainingCenter', + relation: 'intrastat', + scope: { + fields: ['id', 'description'], + }, + }, + { + relation: 'origin', scope: { fields: ['id', 'name'], }, @@ -34,8 +43,18 @@ const itemFilter = { const columns = computed(() => [ { label: '', - name: 'picture', + name: 'image', align: 'left', + columnField: { + component: VnImg, + attrs: (id) => { + return { + id, + width: '50px', + }; + }, + }, + columnFilter: false, }, { label: t('item.list.id'), @@ -88,6 +107,10 @@ const columns = computed(() => [ url: 'ItemType', fields: ['id', 'name'], }, + columnField: { + component: null, + }, + create: true, }, { @@ -100,6 +123,9 @@ const columns = computed(() => [ url: 'ItemCategory', fields: ['id', 'name'], }, + columnField: { + component: null, + }, }, { @@ -112,6 +138,10 @@ const columns = computed(() => [ url: 'Intrastat', fields: ['id', 'description'], }, + columnField: { + component: null, + }, + create: true, }, { label: t('item.list.origin'), @@ -123,6 +153,10 @@ const columns = computed(() => [ url: 'Origin', fields: ['id', 'name'], }, + columnField: { + component: null, + }, + create: true, }, { label: t('item.list.userName'), @@ -136,7 +170,9 @@ const columns = computed(() => [ name: 'weightByPiece', align: 'left', component: 'input', - format: (val) => dashIfEmpty(val), + columnField: { + component: null, + }, }, { label: t('item.list.stemMultiplier'), @@ -144,7 +180,9 @@ const columns = computed(() => [ name: 'stemMultiplier', align: 'left', component: 'input', - format: (val) => dashIfEmpty(val), + columnField: { + component: null, + }, }, { label: t('item.list.isActive'), @@ -163,6 +201,9 @@ const columns = computed(() => [ url: 'Producer', fields: ['id', 'name'], }, + columnField: { + component: null, + }, }, { label: t('item.list.landed'), @@ -170,7 +211,10 @@ const columns = computed(() => [ name: 'landed', align: 'left', component: 'date', - format: (val) => dashIfEmpty(toDateFormat(val)), + columnField: { + component: null, + }, + format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)), }, ]); @@ -209,9 +253,10 @@ onUnmounted(() => (stateStore.rightDrawer = false)); <VnTable ref="tableRef" data-key="ItemList" - url="Items" + url="Items/filter" url-create="Items" save-url="Items/crud" + :filter="itemFilter" :create="{ urlCreate: 'Items', title: 'Create Item', @@ -223,6 +268,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); order="id ASC" :columns="columns" auto-load + redirect="Item" :right-search="false" :is-editable="false" :use-model="true" From afbcd2ebda00ec2487ebc090940f83405ce54f1f Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 15 Jul 2024 14:31:33 +0200 Subject: [PATCH 003/207] refs #7283 item filters --- src/pages/Item/ItemList.vue | 14 ++-- src/pages/Item/ItemTypeList.vue | 140 ++++++++++++++++++++------------ 2 files changed, 91 insertions(+), 63 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 4c49f068f..e2c5f4bb3 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -7,9 +7,7 @@ import VnImg from 'src/components/ui/VnImg.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; -import { dashIfEmpty } from 'src/filters'; import axios from 'axios'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; const entityId = computed(() => route.params.id); const router = useRouter(); @@ -104,7 +102,7 @@ const columns = computed(() => [ align: 'left', component: 'select', attrs: { - url: 'ItemType', + url: 'ItemTypes', fields: ['id', 'name'], }, columnField: { @@ -112,7 +110,6 @@ const columns = computed(() => [ }, create: true, }, - { label: t('item.list.category'), field: 'category', @@ -120,14 +117,13 @@ const columns = computed(() => [ align: 'left', component: 'select', attrs: { - url: 'ItemCategory', + url: 'ItemCategories', fields: ['id', 'name'], }, columnField: { component: null, }, }, - { label: t('item.list.intrastat'), field: 'intrastat', @@ -135,7 +131,7 @@ const columns = computed(() => [ align: 'left', component: 'select', attrs: { - url: 'Intrastat', + url: 'Intrastats', fields: ['id', 'description'], }, columnField: { @@ -150,7 +146,7 @@ const columns = computed(() => [ align: 'left', component: 'select', attrs: { - url: 'Origin', + url: 'Origins', fields: ['id', 'name'], }, columnField: { @@ -198,7 +194,7 @@ const columns = computed(() => [ align: 'left', component: 'select', attrs: { - url: 'Producer', + url: 'Producers', fields: ['id', 'name'], }, columnField: { diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 125672d60..c02f9bb43 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -1,20 +1,13 @@ <script setup> import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; - -import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; -import ItemTypeSummary from 'src/pages/ItemType/Card/ItemTypeSummary.vue'; -import ItemTypeFilter from 'src/pages/ItemType/ItemTypeFilter.vue'; +import { ref, computed } from 'vue'; import ItemTypeSearchbar from '../ItemType/ItemTypeSearchbar.vue'; -import { useSummaryDialog } from 'src/composables/useSummaryDialog'; -import RightMenu from 'src/components/common/RightMenu.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; const router = useRouter(); const { t } = useI18n(); -const { viewSummary } = useSummaryDialog(); - +const tableRef = ref(); const redirectToItemTypeSummary = (id) => { router.push({ name: 'ItemTypeSummary', params: { id } }); }; @@ -56,52 +49,91 @@ const exprBuilder = (param, value) => { } } }; + +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + isId: true, + cardVisible: true, + }, + { + align: 'left', + name: 'code', + label: t('code'), + isTitle: true, + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'name', + label: t('name'), + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'worker', + label: t('worker'), + create: true, + component: 'select', + attrs: { + url: 'Workers', + fields: ['id', 'firstName'], + }, + cardVisible: true, + }, + { + align: 'left', + name: 'ItemCategory', + label: t('ItemCategory'), + create: true, + component: 'select', + attrs: { + url: 'ItemCategories', + fields: ['id', 'name'], + }, + cardVisible: true, + }, + { + align: 'left', + name: 'Temperature', + label: t('Temperature'), + create: true, + component: 'select', + attrs: { + url: 'Temperatures', + fields: ['id', 'name'], + }, + cardVisible: true, + }, +]); </script> <template> <ItemTypeSearchbar /> - <RightMenu> - <template #right-panel> - <ItemTypeFilter data-key="ItemTypeList" /> - </template> - </RightMenu> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - data-key="ItemTypeList" - url="ItemTypes" - :order="['name']" - auto-load - :expr-builder="exprBuilder" - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :key="row.id" - :title="row.code" - @click="redirectToItemTypeSummary(row.id)" - :id="row.id" - > - <template #list-items> - <VnLv :label="t('Name')" :value="row.name" /> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, ItemTypeSummary)" - color="primary" - type="submit" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - </QPage> - <QPageSticky :offset="[20, 20]"> - <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" /> - <QTooltip> - {{ t('New item type') }} - </QTooltip> - </QPageSticky> + <VnTable + ref="tableRef" + data-key="ItemTypeList" + :url="`ItemTypes`" + :url-create="`ItemTypes`" + save-url="ItemTypes/crud" + :filter="courseFilter" + :create="{ + urlCreate: 'ItemTypes', + title: 'Create ItemTypes', + onDataSaved: () => tableRef.reload(), + formInitialData: { + workerFk: entityId, + }, + }" + order="id DESC" + :columns="columns" + auto-load + :right-search="false" + :is-editable="false" + :use-model="true" + /> </template> From daf99f47306f2ae346e9fd023bce9e8b8c222c7b Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 15 Jul 2024 15:00:43 +0200 Subject: [PATCH 004/207] refs #7283 itemRequestList --- src/pages/Item/ItemRequest.vue | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index ae6638953..10cb6c2a6 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -18,6 +18,7 @@ import useNotify from 'src/composables/useNotify.js'; import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js'; import axios from 'axios'; import RightMenu from 'src/components/common/RightMenu.vue'; +import { toDate } from 'src/filters'; const { t } = useI18n(); const { notify } = useNotify(); @@ -46,21 +47,28 @@ const columns = computed(() => [ name: 'id', field: 'id', align: 'left', - sortable: true, + isId: true, + chip: { + condition: () => true, + }, + cardVisible: true, }, { label: t('item.buyRequest.shipped'), field: 'shipped', name: 'shipped', align: 'left', - sortable: true, + component: 'date', + columnField: { + component: null, + }, + format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.shipped)), }, { label: t('globals.description'), field: 'description', name: 'description', align: 'left', - sortable: true, }, { label: t('item.buyRequest.requester'), @@ -80,29 +88,31 @@ const columns = computed(() => [ field: 'price', name: 'price', align: 'left', - sortable: true, - format: (val) => toCurrency(val), + format: (row) => toCurrency(row.price), }, { label: t('item.buyRequest.attender'), field: 'attender', name: 'attender', align: 'left', - sortable: true, + attrs: { + url: 'Workers', + fields: ['id', 'firstName'], + }, }, { label: t('item.buyRequest.item'), field: 'item', name: 'item', align: 'left', - sortable: true, + component: 'input', }, { label: t('item.buyRequest.achieved'), field: 'achieved', name: 'achieved', align: 'left', - sortable: true, + component: 'input', }, { label: t('item.buyRequest.concept'), From b7ba8eec3da2524c3fc2834dc2e4ffb64dbfc20d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 08:24:57 +0200 Subject: [PATCH 005/207] refs #7283 fix searchbar --- src/pages/Item/ItemList.vue | 41 +++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index e2c5f4bb3..17a62c5b9 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -3,11 +3,12 @@ import { onMounted, ref, computed, reactive, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter, useRoute } from 'vue-router'; import VnImg from 'src/components/ui/VnImg.vue'; - +import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; import axios from 'axios'; +import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; const entityId = computed(() => route.params.id); const router = useRouter(); @@ -212,16 +213,21 @@ const columns = computed(() => [ }, format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)), }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('Clone item'), + icon: 'vn:clone', + action: cloneItem, + isPrimary: true, + }, + ], + }, ]); -const redirectToItemCreate = () => { - router.push({ name: 'ItemCreate' }); -}; - -const redirectToItemSummary = (id) => { - router.push({ name: 'ItemSummary', params: { id } }); -}; - const cloneItem = async (itemFk) => { try { const { data } = await axios.post(`Items/${itemFk}/clone`); @@ -236,16 +242,11 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> - <!-- <VnSubToolbar> - <template #st-data> - <TableVisibleColumns - :all-columns="allColumnNames" - table-code="itemsIndex" - labels-traductions-path="item.list" - @on-config-saved="visibleColumns = ['picture', ...$event, 'actions']" - /> - </template> - </VnSubToolbar> --> + <VnSearchbar + data-key="ItemList" + :label="t('Search Item')" + :info="t('You can search by id')" + /> <VnTable ref="tableRef" data-key="ItemList" @@ -265,7 +266,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); :columns="columns" auto-load redirect="Item" - :right-search="false" + :right-search="true" :is-editable="false" :use-model="true" /> From 85b030c7bc07fa7e2abf7e1c7e0d969c7000322d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 08:31:04 +0200 Subject: [PATCH 006/207] refs #7283 view summary --- src/pages/Item/ItemList.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 17a62c5b9..0e444254f 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -9,8 +9,10 @@ import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; import axios from 'axios'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; +import { useSummaryDialog } from 'src/composables/useSummaryDialog'; const entityId = computed(() => route.params.id); +const { viewSummary } = useSummaryDialog(); const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); @@ -224,6 +226,11 @@ const columns = computed(() => [ action: cloneItem, isPrimary: true, }, + { + title: t('view Summary'), + icon: 'preview', + action: (row) => viewSummary(row.id), + }, ], }, ]); From cce1d891fb67b738a45d6f3d59cbcda6dd1dde5d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 08:48:50 +0200 Subject: [PATCH 007/207] refs #7283 fix viewSummary --- src/pages/Item/ItemList.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 0e444254f..273374150 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -10,6 +10,7 @@ import { toDate } from 'src/filters'; import axios from 'axios'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; +import ItemSummary from '../Item/Card/ItemSummary.vue'; const entityId = computed(() => route.params.id); const { viewSummary } = useSummaryDialog(); @@ -229,7 +230,7 @@ const columns = computed(() => [ { title: t('view Summary'), icon: 'preview', - action: (row) => viewSummary(row.id), + action: (row) => viewSummary(row.id, ItemSummary), }, ], }, From 339f6e810bf87a9115691c69f447b43988b08e2d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 10:34:00 +0200 Subject: [PATCH 008/207] refs #7283 fix descriptorproxy --- src/pages/Item/ItemList.vue | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 273374150..6893d55a1 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -11,6 +11,7 @@ import axios from 'axios'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import ItemSummary from '../Item/Card/ItemSummary.vue'; +import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; const entityId = computed(() => route.params.id); const { viewSummary } = useSummaryDialog(); @@ -277,7 +278,14 @@ onUnmounted(() => (stateStore.rightDrawer = false)); :right-search="true" :is-editable="false" :use-model="true" - /> + > + <template #column-userName="{ row }"> + <span class="link" @click.stop> + {{ row.userName }} + <WorkerDescriptorProxy :id="row.buyerFk" /> + </span> + </template> + </VnTable> </template> <i18n> From f29d873ed42abad1c45d641a51aa02bc2ab02db1 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 12:15:39 +0200 Subject: [PATCH 009/207] refs #7283 fix request --- src/pages/Item/ItemRequest.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 10cb6c2a6..e5faff6b2 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -120,13 +120,13 @@ const columns = computed(() => [ name: 'concept', align: 'left', sortable: true, + component: 'input', }, { label: t('item.buyRequest.state'), field: 'state', name: 'state', align: 'left', - sortable: true, }, { label: '', @@ -252,7 +252,6 @@ onBeforeMount(() => { <TicketDescriptorProxy :id="row.ticketFk" /> </QTd> </template> - <template #body-cell-shipped="{ row }"> <QTd> <QBadge From 86ae827fda7a8c45b346fdfaa490225b10039cbd Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 16 Jul 2024 13:48:32 +0200 Subject: [PATCH 010/207] refs #7283 clone --- src/pages/Item/ItemList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 6893d55a1..c44438087 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -239,7 +239,7 @@ const columns = computed(() => [ const cloneItem = async (itemFk) => { try { - const { data } = await axios.post(`Items/${itemFk}/clone`); + const { data } = await axios.post(`Items/${itemFk.id}/clone`); if (!data) return; router.push({ name: 'ItemTags', params: { id: data.id } }); } catch (err) { From 4d394a98a4f3d2b23bd580fcbe0a0186892e9b0c Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 22 Jul 2024 08:24:59 +0200 Subject: [PATCH 011/207] refs #7283 fix yml list basicData --- src/i18n/locale/en.yml | 21 +++++++++++- src/i18n/locale/es.yml | 21 +++++++++++- src/pages/Item/Card/ItemBasicData.vue | 47 ++++++++++++++++----------- src/pages/Item/ItemList.vue | 1 - 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 2f1209a3a..a3d7362b3 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -246,7 +246,6 @@ globals: mailForwarding: Mail forwarding mailAlias: Mail alias privileges: Privileges - labeler: Labeler created: Created worker: Worker now: Now @@ -1194,6 +1193,26 @@ item: stemMultiplier: Multiplier producer: Producer landed: Landed + basicData: + type: Type + reference: Reference + relevancy: Relevancy + stems: Stems + multiplier: Multiplier + generic: Generic + intrastat: Intrastat + expense: Expense + weightByPiece: Weight/Piece + boxUnits: Units/Box + recycledPlastic: Recycled Plastic + nonRecycledPlastic: Non recycled plastic + isActive: Active + hasKgPrice: Price in kg + isFragile: Fragile + isFragileTooltip: Is shown at website, app that this item cannot travel (wreath, palms, ...) + isPhotoRequested: Do photo + isPhotoRequestedTooltip: This item does need a photo + description: Description fixedPrice: itemId: Item ID groupingPrice: Grouping price diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index c5c4fab66..71b2c5919 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -248,7 +248,6 @@ globals: components: Componentes pictures: Fotos packages: Bultos - labeler: Etiquetas created: Fecha creación worker: Trabajador now: Ahora @@ -1175,6 +1174,26 @@ item: stemMultiplier: Multiplicador producer: Productor landed: F. entrega + basicData: + type: Tipo + reference: Referencia + relevancy: Relevancia + stems: Tallos + multiplier: Multiplicador + generic: Genérico + intrastat: Intrastat + expense: Gasto + weightByPiece: Peso (gramos)/tallo + boxUnits: Unidades/caja + recycledPlastic: Plastico reciclado + nonRecycledPlastic: Plático no reciclado + isActive: Activo + hasKgPrice: Precio en kg + isFragile: Frágil + isFragileTooltip: Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...) + isPhotoRequested: Hacer foto + isPhotoRequestedTooltip: Este artículo necesita una foto + description: Descripción fixedPrice: itemId: ID Artículo groupingPrice: Precio grouping diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue index eb486f551..07242635b 100644 --- a/src/pages/Item/Card/ItemBasicData.vue +++ b/src/pages/Item/Card/ItemBasicData.vue @@ -73,7 +73,7 @@ const onIntrastatCreated = (response, formData) => { <template #form="{ data }"> <VnRow class="row q-gutter-md q-mb-md"> <VnSelect - :label="t('basicData.type')" + :label="t('item.basicData.type')" v-model="data.typeFk" :options="itemTypesOptions" option-value="id" @@ -92,17 +92,20 @@ const onIntrastatCreated = (response, formData) => { </QItem> </template> </VnSelect> - <VnInput :label="t('basicData.reference')" v-model="data.comment" /> - <VnInput :label="t('basicData.relevancy')" v-model="data.relevancy" /> + <VnInput :label="t('item.basicData.reference')" v-model="data.comment" /> + <VnInput + :label="t('item.basicData.relevancy')" + v-model="data.relevancy" + /> </VnRow> <VnRow class="row q-gutter-md q-mb-md"> - <VnInput :label="t('basicData.stems')" v-model="data.stems" /> + <VnInput :label="t('item.basicData.stems')" v-model="data.stems" /> <VnInput - :label="t('basicData.multiplier')" + :label="t('item.basicData.multiplier')" v-model="data.stemMultiplier" /> <VnSelectDialog - :label="t('basicData.generic')" + :label="t('item.basicData.generic')" v-model="data.genericFk" :options="itemsWithNameOptions" option-value="id" @@ -129,7 +132,7 @@ const onIntrastatCreated = (response, formData) => { </VnRow> <VnRow class="row q-gutter-md q-mb-md"> <VnSelectDialog - :label="t('basicData.intrastat')" + :label="t('item.basicData.intrastat')" v-model="data.intrastatFk" :options="intrastatsOptions" option-value="id" @@ -156,7 +159,7 @@ const onIntrastatCreated = (response, formData) => { </VnSelectDialog> <div class="col"> <VnSelect - :label="t('basicData.expense')" + :label="t('item.basicData.expense')" v-model="data.expenseFk" :options="expensesOptions" option-value="id" @@ -168,61 +171,67 @@ const onIntrastatCreated = (response, formData) => { </VnRow> <VnRow class="row q-gutter-md q-mb-md"> <VnInput - :label="t('basicData.weightByPiece')" + :label="t('item.basicData.weightByPiece')" v-model.number="data.weightByPiece" :min="0" type="number" /> <VnInput - :label="t('basicData.boxUnits')" + :label="t('item.basicData.boxUnits')" v-model.number="data.packingOut" :min="0" type="number" /> <VnInput - :label="t('basicData.recycledPlastic')" + :label="t('item.basicData.recycledPlastic')" v-model.number="data.recycledPlastic" :min="0" type="number" /> <VnInput - :label="t('basicData.nonRecycledPlastic')" + :label="t('item.basicData.nonRecycledPlastic')" v-model.number="data.nonRecycledPlastic" :min="0" type="number" /> </VnRow> <VnRow class="row q-gutter-md q-mb-md"> - <QCheckbox v-model="data.isActive" :label="t('basicData.isActive')" /> - <QCheckbox v-model="data.hasKgPrice" :label="t('basicData.hasKgPrice')" /> + <QCheckbox + v-model="data.isActive" + :label="t('item.basicData.isActive')" + /> + <QCheckbox + v-model="data.hasKgPrice" + :label="t('item.basicData.hasKgPrice')" + /> <div> <QCheckbox v-model="data.isFragile" - :label="t('basicData.isFragile')" + :label="t('item.basicData.isFragile')" class="q-mr-sm" /> <QIcon name="info" class="cursor-pointer" size="xs"> <QTooltip max-width="300px"> - {{ t('basicData.isFragileTooltip') }} + {{ t('item.basicData.isFragileTooltip') }} </QTooltip> </QIcon> </div> <div> <QCheckbox v-model="data.isPhotoRequested" - :label="t('basicData.isPhotoRequested')" + :label="t('item.basicData.isPhotoRequested')" class="q-mr-sm" /> <QIcon name="info" class="cursor-pointer" size="xs"> <QTooltip> - {{ t('basicData.isPhotoRequestedTooltip') }} + {{ t('item.basicData.isPhotoRequestedTooltip') }} </QTooltip> </QIcon> </div> </VnRow> <VnRow> <VnInput - :label="t('basicData.description')" + :label="t('item.basicData.description')" type="textarea" v-model="data.description" fill-input diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index c44438087..169ee93d6 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -226,7 +226,6 @@ const columns = computed(() => [ title: t('Clone item'), icon: 'vn:clone', action: cloneItem, - isPrimary: true, }, { title: t('view Summary'), From f678c6304313cbc6d976c9df21f7f0e33c958dac Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 22 Jul 2024 13:35:41 +0200 Subject: [PATCH 012/207] refs #7283 request --- src/i18n/locale/en.yml | 2 +- src/pages/Item/ItemList.vue | 6 +---- src/pages/Item/ItemRequest.vue | 40 +++++++++++++++++----------------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index a3d7362b3..33862f766 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -1235,7 +1235,7 @@ item: requester: 'Requester' requested: 'Requested' price: 'Price' - attender: 'Atender' + attender: 'Attender' item: 'Item' achieved: 'Achieved' concept: 'Concept' diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 169ee93d6..2532a6df2 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -1,9 +1,8 @@ <script setup> -import { onMounted, ref, computed, reactive, onUnmounted } from 'vue'; +import { ref, computed, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter, useRoute } from 'vue-router'; import VnImg from 'src/components/ui/VnImg.vue'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; @@ -245,8 +244,6 @@ const cloneItem = async (itemFk) => { console.error('Error cloning item', err); } }; - -onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> @@ -274,7 +271,6 @@ onUnmounted(() => (stateStore.rightDrawer = false)); :columns="columns" auto-load redirect="Item" - :right-search="true" :is-editable="false" :use-model="true" > diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index e5faff6b2..ed6f623aa 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -1,24 +1,14 @@ <script setup> import { ref, computed, onMounted, onBeforeMount, watch } from 'vue'; import { useI18n } from 'vue-i18n'; -import FetchData from 'components/FetchData.vue'; -import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; -import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import ItemRequestDenyForm from './ItemRequestDenyForm.vue'; -import ItemRequestFilter from './ItemRequestFilter.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; -import VnSelect from 'components/common/VnSelect.vue'; import { useStateStore } from 'stores/useStateStore'; import { useArrayData } from 'composables/useArrayData'; -import { toDateFormat } from 'src/filters/date'; import { toCurrency } from 'filters/index'; import useNotify from 'src/composables/useNotify.js'; -import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js'; import axios from 'axios'; -import RightMenu from 'src/components/common/RightMenu.vue'; import { toDate } from 'src/filters'; +import VnTable from 'components/VnTable/VnTable.vue'; const { t } = useI18n(); const { notify } = useNotify(); @@ -72,16 +62,15 @@ const columns = computed(() => [ }, { label: t('item.buyRequest.requester'), - name: 'requester', + field: 'requesterName', + name: 'requesterFk', align: 'left', - sortable: true, }, { label: t('item.buyRequest.requested'), field: 'quantity', name: 'requested', align: 'left', - sortable: true, }, { label: t('item.buyRequest.price'), @@ -95,10 +84,6 @@ const columns = computed(() => [ field: 'attender', name: 'attender', align: 'left', - attrs: { - url: 'Workers', - fields: ['id', 'firstName'], - }, }, { label: t('item.buyRequest.item'), @@ -218,7 +203,7 @@ onBeforeMount(() => { </script> <template> - <FetchData + <!-- <FetchData url="Workers" :filter="{ where: { role: 'buyer' } }" order="id" @@ -350,7 +335,22 @@ onBeforeMount(() => { @on-data-saved="onDenyAccept" /> </QDialog> - </QPage> + </QPage> --> + <VnTable + ref="tableRef" + data-key="itemRequest" + url="ticketRequests" + order="id DESC" + :columns="columns" + auto-load + > + <template #column-attender="{ row }"> + <span class="link" @click.stop> + {{ row.attenderFk }} + <WorkerDescriptorProxy :id="row.attenderFk" /> + </span> + </template> + </VnTable> </template> <i18n> From b668d07e2dc4fb453efcd1050abbc0f6fd570687 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 1 Aug 2024 13:20:33 +0200 Subject: [PATCH 013/207] refs #7283 fetchedTags --- src/pages/Item/ItemList.vue | 46 +++++++++++++++++++++++----------- src/pages/Item/ItemRequest.vue | 17 ++++++++++--- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 2532a6df2..a3b70372f 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -7,6 +7,7 @@ import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; import axios from 'axios'; +import FetchedTags from 'src/components/ui/FetchedTags.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import ItemSummary from '../Item/Card/ItemSummary.vue'; @@ -43,21 +44,21 @@ const itemFilter = { ], }; const columns = computed(() => [ - { - label: '', - name: 'image', - align: 'left', - columnField: { - component: VnImg, - attrs: (id) => { - return { - id, - width: '50px', - }; - }, - }, - columnFilter: false, - }, + // { + // label: '', + // name: 'image', + // align: 'left', + // columnField: { + // component: VnImg, + // attrs: (id) => { + // return { + // id, + // width: '50px', + // }; + // }, + // }, + // columnFilter: false, + // }, { label: t('item.list.id'), name: 'id', @@ -280,9 +281,24 @@ const cloneItem = async (itemFk) => { <WorkerDescriptorProxy :id="row.buyerFk" /> </span> </template> + <template #column-description="{ row }"> + <div class="row column full-width justify-between items-start"> + {{ row?.name }} + <div v-if="row?.subName" class="subName"> + {{ row?.subName.toUpperCase() }} + </div> + </div> + <FetchedTags :item="row" :max-length="6" /> + </template> </VnTable> </template> +<style lang="scss" scoped> +.subName { + text-transform: uppercase; + color: var(--vn-label-color); +} +</style> <i18n> es: New item: Nuevo artículo diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index ed6f623aa..0389ba864 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -13,7 +13,6 @@ import VnTable from 'components/VnTable/VnTable.vue'; const { t } = useI18n(); const { notify } = useNotify(); const stateStore = useStateStore(); -const workersOptions = ref([]); let filterParams = ref({}); const denyFormRef = ref(null); const denyRequestId = ref(null); @@ -91,6 +90,7 @@ const columns = computed(() => [ name: 'item', align: 'left', component: 'input', + visible: false, }, { label: t('item.buyRequest.achieved'), @@ -98,6 +98,7 @@ const columns = computed(() => [ name: 'achieved', align: 'left', component: 'input', + visible: false, }, { label: t('item.buyRequest.concept'), @@ -106,6 +107,7 @@ const columns = computed(() => [ align: 'left', sortable: true, component: 'input', + visible: false, }, { label: t('item.buyRequest.state'), @@ -114,10 +116,17 @@ const columns = computed(() => [ align: 'left', }, { + align: 'right', label: '', - name: 'action', - align: 'left', - columnFilter: null, + name: 'tableActions', + actions: [ + { + title: t('Client ticket list'), + icon: 'thumb_down', + action: onDenyAccept, + isPrimary: true, + }, + ], }, ]); From fe78de0c4761772593a3e714c69894f36651e696 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 5 Aug 2024 11:49:06 +0200 Subject: [PATCH 014/207] refs #7283 fixedPrices --- src/pages/Item/ItemFixedPrice.vue | 325 +++++++----------------------- 1 file changed, 70 insertions(+), 255 deletions(-) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 2ecd1f21b..41f2bac2f 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -1,7 +1,7 @@ <script setup> import { onMounted, ref, reactive, computed, onUnmounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; - +import { toDate } from 'src/filters'; import FetchData from 'components/FetchData.vue'; import FetchedTags from 'components/ui/FetchedTags.vue'; import VnInput from 'src/components/common/VnInput.vue'; @@ -10,7 +10,7 @@ import VnInputDate from 'src/components/common/VnInputDate.vue'; import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue'; import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; - +import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { dashIfEmpty } from 'src/filters'; import { useVnConfirm } from 'composables/useVnConfirm'; @@ -27,7 +27,7 @@ const { t } = useI18n(); const { openConfirmationModal } = useVnConfirm(); const state = useState(); const { notify } = useNotify(); - +const tableRef = ref(); const editTableCellDialogRef = ref(null); const user = state.getUser(); const fixedPrices = ref([]); @@ -111,86 +111,81 @@ const defaultColumnAttrs = { const columns = computed(() => [ { label: t('item.fixedPrice.itemId'), - name: 'itemId', - field: 'itemFk', - ...defaultColumnAttrs, - columnFilter: { - ...defaultColumnFilter, + name: 'itemFk', + align: 'left', + isId: true, + chip: { + condition: () => true, }, }, { label: t('globals.description'), - field: 'name', name: 'description', - ...defaultColumnAttrs, - columnFilter: { - ...defaultColumnFilter, - }, + align: 'left', + create: true, }, { label: t('item.fixedPrice.groupingPrice'), - field: 'rate2', - name: 'groupingPrice', - ...defaultColumnAttrs, - columnFilter: { - ...defaultColumnFilter, - }, - format: (val) => toCurrency(val), + name: 'rate2', + align: 'left', + create: true, }, { label: t('item.fixedPrice.packingPrice'), - field: 'rate3', - name: 'packingPrice', - ...defaultColumnAttrs, - columnFilter: { - ...defaultColumnFilter, - }, - format: (val) => dashIfEmpty(val), + name: 'rate3', + align: 'left', + create: true, }, { label: t('item.fixedPrice.minPrice'), - field: 'minPrice', name: 'minPrice', - ...defaultColumnAttrs, - columnFilter: { - ...defaultColumnFilter, - }, + align: 'left', + create: true, }, { label: t('item.fixedPrice.started'), - field: 'started', name: 'started', - ...defaultColumnAttrs, - columnFilter: null, + align: 'left', + create: true, + format: (row) => toDate(row.started), }, { label: t('item.fixedPrice.ended'), - field: 'ended', name: 'ended', - ...defaultColumnAttrs, - columnFilter: null, + align: 'left', + create: true, + format: (row) => toDate(row.ended), }, - { label: t('item.fixedPrice.warehouse'), - field: 'warehouseFk', - name: 'warehouse', - ...defaultColumnAttrs, + name: 'warehouseFk', columnFilter: { - component: VnSelect, - type: 'select', - filterValue: null, - event: getColumnInputEvents, + component: 'select', attrs: { - options: warehousesOptions.value, - 'option-value': 'id', - 'option-label': 'name', - dense: true, + url: 'Warehouses', + optionValue: 'id', + optionLabel: 'name', }, }, + component: 'select', + attrs: { + url: 'Warehouses', + fields: ['id', 'name'], + }, + disable: false, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('Delete'), + icon: 'delete', + }, + ], }, - { name: 'deleteAction', align: 'center' }, ]); const editTableFieldsOptions = [ @@ -364,212 +359,32 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> - <FetchData - url="Warehouses" - :filter="{ order: ['name'] }" + <VnTable + ref="tableRef" + data-key="ItemFixedPrices" + url="FixedPrices/filter" + :create="{ + urlCreate: 'PriceFixed', + title: 'Create Item', + onDataSaved: () => tableRef.redirect(), + formInitialData: {}, + }" + order="id ASC" + :columns="columns" auto-load - @on-fetch="(data) => onWarehousesFetched(data)" - /> - <RightMenu> - <template #right-panel> - <ItemFixedPriceFilter - data-key="ItemFixedPrices" - :warehouses-options="warehousesOptions" - /> + :is-editable="false" + :use-model="true" + > + <template #column-description="{ row }"> + <div class="row column full-width justify-between items-start"> + {{ row?.description }} + <div v-if="row?.description" class="subName"> + {{ row?.subName.toUpperCase() }} + </div> + </div> + <FetchedTags :item="row" :max-length="6" /> </template> - </RightMenu> - <QPage class="column items-center q-pa-md"> - <QTable - :rows="fixedPrices" - :columns="columns" - row-key="id" - selection="multiple" - v-model:selected="rowsSelected" - :pagination="{ rowsPerPage: 0 }" - class="full-width q-mt-md" - :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-itemId="props"> - <QTd> - <VnSelect - url="Items/withName" - hide-selected - option-label="id" - option-value="id" - v-model="props.row.itemFk" - v-on="getRowUpdateInputEvents(props, true, 'select')" - > - <template #option="scope"> - <QItem v-bind="scope.itemProps"> - <QItemSection> - <QItemLabel> #{{ scope.opt?.id }} </QItemLabel> - <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel> - </QItemSection> - </QItem> - </template> - </VnSelect> - </QTd> - </template> - <template #body-cell-description="{ row }"> - <QTd class="col"> - <span class="link"> - {{ row.name }} - </span> - <ItemDescriptorProxy :id="row.itemFk" /> - <FetchedTags :item="row" :max-length="6" /> - </QTd> - </template> - <template #body-cell-groupingPrice="props"> - <QTd class="col"> - <VnInput - v-model.number="props.row.rate2" - v-on="getRowUpdateInputEvents(props)" - > - <template #append>€</template> - </VnInput> - </QTd> - </template> - <template #body-cell-packingPrice="props"> - <QTd class="col"> - <VnInput - v-model.number="props.row.rate3" - v-on="getRowUpdateInputEvents(props)" - > - <template #append>€</template> - </VnInput> - </QTd> - </template> - <template #body-cell-minPrice="props"> - <QTd class="col"> - <div class="row"> - <QCheckbox - class="col" - :model-value="props.row.hasMinPrice" - @update:model-value="updateMinPrice($event, props)" - :false-value="0" - :true-value="1" - :toggle-indeterminate="false" - /> - <VnInput - class="col" - :disable="!props.row.hasMinPrice" - v-model.number="props.row.minPrice" - v-on="getRowUpdateInputEvents(props)" - type="number" - /> - </div> - </QTd> - </template> - <template #body-cell-started="props"> - <QTd class="col" style="min-width: 160px"> - <VnInputDate - v-model="props.row.started" - v-on="getRowUpdateInputEvents(props, false, 'date')" - v-bind=" - isBigger(props.row.started) - ? { 'bg-color': 'warning', 'is-outlined': true } - : {} - " - /> - </QTd> - </template> - <template #body-cell-ended="props"> - <QTd class="col" style="min-width: 150px"> - <VnInputDate - v-model="props.row.ended" - v-on="getRowUpdateInputEvents(props, false, 'date')" - v-bind=" - isLower(props.row.ended) - ? { 'bg-color': 'warning', 'is-outlined': true } - : {} - " - /> - </QTd> - </template> - <template #body-cell-warehouse="props"> - <QTd class="col"> - <VnSelect - :options="warehousesOptions" - hide-selected - option-label="name" - option-value="id" - v-model="props.row.warehouseFk" - v-on="getRowUpdateInputEvents(props, false, 'select')" - /> - </QTd> - </template> - <template #body-cell-deleteAction="{ row, rowIndex }"> - <QTd class="col"> - <QIcon - name="delete" - size="sm" - class="cursor-pointer fill-icon-on-hover" - color="primary" - @click.stop=" - openConfirmationModal( - t('This row will be removed'), - t('Do you want to clone this item?'), - () => removePrice(row.id, rowIndex) - ) - " - > - <QTooltip class="text-no-wrap"> - {{ t('Delete') }} - </QTooltip> - </QIcon> - </QTd> - </template> - <template #bottom-row> - <QTd align="center"> - <QIcon - @click.stop="addRow()" - class="fill-icon-on-hover" - color="primary" - name="add_circle" - size="sm" - > - <QTooltip> - {{ t('Add fixed price') }} - </QTooltip> - </QIcon> - </QTd> - </template> - </QTable> - <QPageSticky v-if="rowsSelected.length" :offset="[20, 20]"> - <QBtn @click="openEditTableCellDialog()" color="primary" fab icon="edit" /> - <QTooltip> - {{ t('Edit fixed price(s)') }} - </QTooltip> - </QPageSticky> - <QDialog ref="editTableCellDialogRef"> - <EditTableCellValueForm - edit-url="FixedPrices/editFixedPrice" - :rows="rowsSelected" - :fields-options="editTableFieldsOptions" - @on-data-saved="onEditCellDataSaved()" - /> - </QDialog> - </QPage> + </VnTable> </template> <i18n> From 6ca8ede946356c0d3b04cf57671e583f349f7f2b Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 7 Aug 2024 09:53:42 +0200 Subject: [PATCH 015/207] refs #7283 item request --- src/pages/Item/ItemRequest.vue | 28 ++++++++-------------------- src/pages/Item/ItemTypeList.vue | 3 +++ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 0389ba864..8791a575f 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -33,8 +33,7 @@ watch( const columns = computed(() => [ { label: t('item.buyRequest.ticketId'), - name: 'id', - field: 'id', + name: 'ticketFk', align: 'left', isId: true, chip: { @@ -44,7 +43,6 @@ const columns = computed(() => [ }, { label: t('item.buyRequest.shipped'), - field: 'shipped', name: 'shipped', align: 'left', component: 'date', @@ -61,57 +59,46 @@ const columns = computed(() => [ }, { label: t('item.buyRequest.requester'), - field: 'requesterName', - name: 'requesterFk', + name: 'requesterName', align: 'left', }, { label: t('item.buyRequest.requested'), - field: 'quantity', - name: 'requested', + name: 'saleQuantity', align: 'left', }, { label: t('item.buyRequest.price'), - field: 'price', name: 'price', align: 'left', format: (row) => toCurrency(row.price), }, { label: t('item.buyRequest.attender'), - field: 'attender', - name: 'attender', + name: 'attenderName', align: 'left', }, { label: t('item.buyRequest.item'), - field: 'item', name: 'item', align: 'left', component: 'input', - visible: false, }, { label: t('item.buyRequest.achieved'), - field: 'achieved', name: 'achieved', align: 'left', component: 'input', - visible: false, }, { label: t('item.buyRequest.concept'), - field: 'concept', name: 'concept', align: 'left', sortable: true, component: 'input', - visible: false, }, { label: t('item.buyRequest.state'), - field: 'state', name: 'state', align: 'left', }, @@ -123,7 +110,7 @@ const columns = computed(() => [ { title: t('Client ticket list'), icon: 'thumb_down', - action: onDenyAccept, + action: showDenyRequestForm, isPrimary: true, }, ], @@ -348,14 +335,15 @@ onBeforeMount(() => { <VnTable ref="tableRef" data-key="itemRequest" - url="ticketRequests" + url="ticketRequests/filter" order="id DESC" :columns="columns" + :is-editable="false" auto-load > <template #column-attender="{ row }"> <span class="link" @click.stop> - {{ row.attenderFk }} + {{ row }} <WorkerDescriptorProxy :id="row.attenderFk" /> </span> </template> diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index c02f9bb43..5ebbec62b 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -84,6 +84,7 @@ const columns = computed(() => [ fields: ['id', 'firstName'], }, cardVisible: true, + visible: false, }, { align: 'left', @@ -96,6 +97,7 @@ const columns = computed(() => [ fields: ['id', 'name'], }, cardVisible: true, + visible: false, }, { align: 'left', @@ -108,6 +110,7 @@ const columns = computed(() => [ fields: ['id', 'name'], }, cardVisible: true, + visible: false, }, ]); </script> From 589ee629cfbfc3c2b79c32ecef9ff47f30d33c00 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 13 Aug 2024 12:45:30 +0200 Subject: [PATCH 016/207] refs #7283 fix conflicts --- src/pages/Item/ItemFixedPrice.vue | 255 +++++++++--------------------- src/pages/Item/ItemRequest.vue | 15 +- 2 files changed, 89 insertions(+), 181 deletions(-) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 41f2bac2f..56ad7a17d 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -2,25 +2,15 @@ import { onMounted, ref, reactive, computed, onUnmounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { toDate } from 'src/filters'; -import FetchData from 'components/FetchData.vue'; import FetchedTags from 'components/ui/FetchedTags.vue'; import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import VnInputDate from 'src/components/common/VnInputDate.vue'; -import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue'; -import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; -import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; -import { dashIfEmpty } from 'src/filters'; import { useVnConfirm } from 'composables/useVnConfirm'; import { useState } from 'src/composables/useState'; -import { toCurrency } from 'filters/index'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import { useArrayData } from 'composables/useArrayData'; -import { isLower, isBigger } from 'src/filters/date.js'; -import RightMenu from 'src/components/common/RightMenu.vue'; const stateStore = useStateStore(); const { t } = useI18n(); @@ -75,39 +65,6 @@ watch( (data) => onFixedPricesFetched(data) ); -const applyColumnFilter = async (col) => { - try { - const paramKey = col.columnFilter?.filterParamKey || col.field; - params[paramKey] = col.columnFilter.filterValue; - await arrayData.addFilter({ params }); - } catch (err) { - console.error('Error applying column filter', err); - } -}; - -const getColumnInputEvents = (col) => { - return col.columnFilter.type === 'select' - ? { 'update:modelValue': () => applyColumnFilter(col) } - : { - 'keyup.enter': () => applyColumnFilter(col), - }; -}; - -const defaultColumnFilter = { - component: VnInput, - type: 'text', - filterValue: null, - event: getColumnInputEvents, - attrs: { - dense: true, - }, -}; - -const defaultColumnAttrs = { - align: 'left', - sortable: true, -}; - const columns = computed(() => [ { label: t('item.fixedPrice.itemId'), @@ -127,12 +84,14 @@ const columns = computed(() => [ { label: t('item.fixedPrice.groupingPrice'), name: 'rate2', + component: 'input', align: 'left', create: true, }, { label: t('item.fixedPrice.packingPrice'), name: 'rate3', + component: 'input', align: 'left', create: true, }, @@ -140,6 +99,7 @@ const columns = computed(() => [ { label: t('item.fixedPrice.minPrice'), name: 'minPrice', + component: 'input', align: 'left', create: true, }, @@ -188,70 +148,14 @@ const columns = computed(() => [ }, ]); -const editTableFieldsOptions = [ - { - field: 'rate2', - label: t('item.fixedPrice.groupingPrice'), - component: 'input', - attrs: { - type: 'number', - }, - }, - { - field: 'rate3', - label: t('item.fixedPrice.packingPrice'), - component: 'input', - attrs: { - type: 'number', - }, - }, - { - field: 'minPrice', - label: t('item.fixedPrice.minPrice'), - component: 'input', - attrs: { - type: 'number', - }, - }, - { - field: 'hasMinPrice', - label: t('item.fixedPrice.hasMinPrice'), - component: 'checkbox', - attrs: { - 'false-value': 0, - 'true-value': 1, - }, - }, - { - field: 'started', - label: t('item.fixedPrice.started'), - component: 'date', - }, - { - field: 'ended', - label: t('item.fixedPrice.ended'), - component: 'date', - }, - { - field: 'warehouseFk', - label: t('item.fixedPrice.warehouse'), - component: 'select', - attrs: { - options: [], - 'option-label': 'name', - 'option-value': 'id', - }, - }, -]; - -const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => { - return inputType === 'text' - ? { - 'keyup.enter': () => upsertPrice(props, resetMinPrice), - blur: () => upsertPrice(props, resetMinPrice), - } - : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) }; -}; +// const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => { +// return inputType === 'text' +// ? { +// 'keyup.enter': () => upsertPrice(props, resetMinPrice), +// blur: () => upsertPrice(props, resetMinPrice), +// } +// : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) }; +// }; const validations = (row, rowIndex, col) => { const isNew = !row.id; @@ -281,81 +185,73 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => { } }; -const addRow = () => { - if (!fixedPrices.value || fixedPrices.value.length === 0) { - fixedPrices.value = []; +// const addRow = () => { +// if (!fixedPrices.value || fixedPrices.value.length === 0) { +// fixedPrices.value = []; - const today = Date.vnNew(); - const millisecsInDay = 86400000; - const daysInWeek = 7; - const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay); +// const today = Date.vnNew(); +// const millisecsInDay = 86400000; +// const daysInWeek = 7; +// const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay); - const newPrice = { - started: today, - ended: nextWeek, - hasMinPrice: 0, - }; +// const newPrice = { +// started: today, +// ended: nextWeek, +// hasMinPrice: 0, +// }; - fixedPricesOriginalData.value.push({ ...newPrice }); - fixedPrices.value.push({ ...newPrice }); - return; - } +// fixedPricesOriginalData.value.push({ ...newPrice }); +// fixedPrices.value.push({ ...newPrice }); +// return; +// } - const lastItemCopy = JSON.parse( - JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1]) - ); - delete lastItemCopy.id; - fixedPricesOriginalData.value.push(lastItemCopy); - fixedPrices.value.push(lastItemCopy); -}; +// const lastItemCopy = JSON.parse( +// JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1]) +// ); +// delete lastItemCopy.id; +// fixedPricesOriginalData.value.push(lastItemCopy); +// fixedPrices.value.push(lastItemCopy); +// }; -const openEditTableCellDialog = () => { - editTableCellDialogRef.value.show(); -}; +// const openEditTableCellDialog = () => { +// editTableCellDialogRef.value.show(); +// }; -const onEditCellDataSaved = async () => { - rowsSelected.value = []; - await fetchFixedPrices(); -}; +// const onEditCellDataSaved = async () => { +// rowsSelected.value = []; +// await fetchFixedPrices(); +// }; -const onWarehousesFetched = (data) => { - warehousesOptions.value = data; - // Actualiza las 'options' del elemento con field 'warehouseFk' en 'editTableFieldsOptions'. - const warehouseField = editTableFieldsOptions.find( - (field) => field.field === 'warehouseFk' - ); - warehouseField.attrs.options = data; -}; +// const onWarehousesFetched = (data) => { +// warehousesOptions.value = data; +// // Actualiza las 'options' del elemento con field 'warehouseFk' en 'editTableFieldsOptions'. +// const warehouseField = editTableFieldsOptions.find( +// (field) => field.field === 'warehouseFk' +// ); +// warehouseField.attrs.options = data; +// }; -const removePrice = async (id, rowIndex) => { - try { - await axios.delete(`FixedPrices/${id}`); - fixedPrices.value.splice(rowIndex, 1); - fixedPricesOriginalData.value.splice(rowIndex, 1); - notify(t('globals.dataSaved'), 'positive'); - } catch (err) { - console.error('Error removing price', err); - } -}; +// const removePrice = async (id, rowIndex) => { +// try { +// await axios.delete(`FixedPrices/${id}`); +// fixedPrices.value.splice(rowIndex, 1); +// fixedPricesOriginalData.value.splice(rowIndex, 1); +// notify(t('globals.dataSaved'), 'positive'); +// } catch (err) { +// console.error('Error removing price', err); +// } +// }; -const updateMinPrice = async (value, props) => { - // El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice - // Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado - props.row.hasMinPrice = value; - await upsertPrice({ - row: props.row, - col: { field: 'hasMinPrice' }, - rowIndex: props.rowIndex, - }); -}; - -onMounted(async () => { - stateStore.rightDrawer = true; - params.warehouseFk = user.value.warehouseFk; - await fetchFixedPrices(); -}); - -onUnmounted(() => (stateStore.rightDrawer = false)); +// const updateMinPrice = async (value, props) => { +// // El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice +// // Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado +// props.row.hasMinPrice = value; +// await upsertPrice({ +// row: props.row, +// col: { field: 'hasMinPrice' }, +// rowIndex: props.rowIndex, +// }); +// }; </script> <template> @@ -372,13 +268,13 @@ onUnmounted(() => (stateStore.rightDrawer = false)); order="id ASC" :columns="columns" auto-load - :is-editable="false" + :is-editable="true" :use-model="true" > <template #column-description="{ row }"> <div class="row column full-width justify-between items-start"> - {{ row?.description }} - <div v-if="row?.description" class="subName"> + {{ row?.name }} + <div v-if="row?.subName" class="subName"> {{ row?.subName.toUpperCase() }} </div> </div> @@ -386,7 +282,12 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </template> </VnTable> </template> - +<style lang="scss" scoped> +.subName { + text-transform: uppercase; + color: var(--vn-label-color); +} +</style> <i18n> es: Add fixed price: Añadir precio fijado diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 8791a575f..f67f7eda2 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -100,6 +100,7 @@ const columns = computed(() => [ { label: t('item.buyRequest.state'), name: 'state', + action: (row) => getState(row.isOk), align: 'left', }, { @@ -146,7 +147,6 @@ const confirmRequest = async (request) => { `TicketRequests/${request.id}/confirm`, params ); - request.itemDescription = data.concept; request.isOk = true; notify(t('globals.dataSaved'), 'positive'); @@ -338,15 +338,22 @@ onBeforeMount(() => { url="ticketRequests/filter" order="id DESC" :columns="columns" - :is-editable="false" + :is-editable="true" auto-load > - <template #column-attender="{ row }"> + <template #column-attenderName="{ row }"> <span class="link" @click.stop> - {{ row }} + {{ row.attenderName }} <WorkerDescriptorProxy :id="row.attenderFk" /> </span> </template> + + <template #column-requesterName="{ row }"> + <span class="link" @click.stop> + {{ row.requesterName }} + <WorkerDescriptorProxy :id="row.requesterFk" /> + </span> + </template> </VnTable> </template> From 1df089cef78e6728c764d7d72cc015b573f44f66 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 14 Aug 2024 15:50:13 +0200 Subject: [PATCH 017/207] refs #7283 fix itemFixedPrice --- src/pages/Item/ItemFixedPrice.vue | 65 ++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 56ad7a17d..30eb8544e 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -1,9 +1,10 @@ <script setup> -import { onMounted, ref, reactive, computed, onUnmounted, watch } from 'vue'; +import { ref, reactive, computed, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { toDate } from 'src/filters'; +import { useQuasar } from 'quasar'; import FetchedTags from 'components/ui/FetchedTags.vue'; -import VnInput from 'src/components/common/VnInput.vue'; +import { useRoute } from 'vue-router'; import VnTable from 'components/VnTable/VnTable.vue'; import { useStateStore } from 'stores/useStateStore'; import { useVnConfirm } from 'composables/useVnConfirm'; @@ -11,20 +12,30 @@ import { useState } from 'src/composables/useState'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import { useArrayData } from 'composables/useArrayData'; +import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; +import VnConfirm from 'components/ui/VnConfirm.vue'; -const stateStore = useStateStore(); +const route = useRoute(); const { t } = useI18n(); const { openConfirmationModal } = useVnConfirm(); const state = useState(); const { notify } = useNotify(); const tableRef = ref(); -const editTableCellDialogRef = ref(null); +const quasar = useQuasar(); const user = state.getUser(); const fixedPrices = ref([]); const fixedPricesOriginalData = ref([]); const warehousesOptions = ref([]); const rowsSelected = ref([]); +// function localUserData() { +// state.setUser(user.value); +// } + +// const userLocal = localUserData(); +// console.log('localUserData', userLocal); + +console.log('user', user.value.warehouseFk); const exprBuilder = (param, value) => { switch (param) { case 'name': @@ -80,6 +91,10 @@ const columns = computed(() => [ name: 'description', align: 'left', create: true, + columnCreate: { + component: 'select', + url: 'Items', + }, }, { label: t('item.fixedPrice.groupingPrice'), @@ -109,6 +124,9 @@ const columns = computed(() => [ align: 'left', create: true, format: (row) => toDate(row.started), + columnCreate: { + component: 'date', + }, }, { label: t('item.fixedPrice.ended'), @@ -116,6 +134,9 @@ const columns = computed(() => [ align: 'left', create: true, format: (row) => toDate(row.ended), + columnCreate: { + component: 'date', + }, }, { label: t('item.fixedPrice.warehouse'), @@ -148,6 +169,27 @@ const columns = computed(() => [ }, ]); +function confirmRemove(row) { + quasar.dialog({ + component: VnConfirm, + componentProps: { + title: t('confirmDeletion'), + message: t('confirmDeletionMessage'), + promise: () => remove(row), + }, + }); +} + +async function remove(item) { + await axios.post('FixedPrices/filter', { + rows: [item.id], + }); + quasar.notify({ + message: t('globals.dataDeleted'), + type: 'positive', + }); + tableRef.value.reload(); +} // const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => { // return inputType === 'text' // ? { @@ -213,15 +255,6 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => { // fixedPrices.value.push(lastItemCopy); // }; -// const openEditTableCellDialog = () => { -// editTableCellDialogRef.value.show(); -// }; - -// const onEditCellDataSaved = async () => { -// rowsSelected.value = []; -// await fetchFixedPrices(); -// }; - // const onWarehousesFetched = (data) => { // warehousesOptions.value = data; // // Actualiza las 'options' del elemento con field 'warehouseFk' en 'editTableFieldsOptions'. @@ -259,6 +292,7 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => { ref="tableRef" data-key="ItemFixedPrices" url="FixedPrices/filter" + :filter="{ where: { warehouseFk: user.warehouseFk } }" :create="{ urlCreate: 'PriceFixed', title: 'Create Item', @@ -273,7 +307,10 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => { > <template #column-description="{ row }"> <div class="row column full-width justify-between items-start"> - {{ row?.name }} + <span class="link" @click.stop> + {{ row?.name }} + <ItemDescriptorProxy class="link" :id="row.itemFk" /> + </span> <div v-if="row?.subName" class="subName"> {{ row?.subName.toUpperCase() }} </div> From 12a5d6cec035b72deaa3c9f316d0f329d5411081 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 19 Aug 2024 17:05:00 +0200 Subject: [PATCH 018/207] fix: refs #7283 css --- src/components/VnTable/VnTable.vue | 7 ++++--- src/pages/Item/ItemRequest.vue | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 6c77d44df..69c4739bf 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -486,11 +486,12 @@ defineExpose({ :icon="btn.icon" class="q-px-sm" flat - :class=" + :class="[ btn.isPrimary ? 'text-primary-light' - : 'color-vn-text ' - " + : 'color-vn-text ', + btn.class, + ]" :style="`visibility: ${ (btn.show && btn.show(row)) ?? true ? 'visible' diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index f67f7eda2..65c0aaae1 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -111,6 +111,7 @@ const columns = computed(() => [ { title: t('Client ticket list'), icon: 'thumb_down', + class: 'fill-icon', action: showDenyRequestForm, isPrimary: true, }, From bae0b4de351f43a65de5b6ef05fbdaa9cd525d7c Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 22 Aug 2024 10:38:15 +0200 Subject: [PATCH 019/207] fix: itemBotanical --- src/pages/Item/Card/ItemBotanical.vue | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue index 416c7f78b..88d251c47 100644 --- a/src/pages/Item/Card/ItemBotanical.vue +++ b/src/pages/Item/Card/ItemBotanical.vue @@ -13,7 +13,6 @@ import CreateSpecieForm from './CreateSpecieForm.vue'; const route = useRoute(); const { t } = useI18n(); -const itemBotanicalsRef = ref(null); const itemGenusOptions = ref([]); const itemSpeciesOptions = ref([]); const itemBotanicals = ref([]); @@ -31,22 +30,19 @@ const onSpecieCreated = (response, formData) => { const entityId = computed(() => { return route.params.id; }); -onMounted(async () => { - itemBotanicalsForm.itemFk = entityId.value; - itemBotanicals.value = await itemBotanicalsRef.value.fetch(); - if (itemBotanicals.value.length > 0) - Object.assign(itemBotanicalsForm, itemBotanicals.value[0]); -}); +// onMounted(async () => { +// itemBotanicalsForm.itemFk = entityId.value; +// // itemBotanicals.value = await itemBotanicalsRef.value.fetch(); +// if (itemBotanicals.value.length > 0) +// Object.assign(itemBotanicalsForm, itemBotanicals.value[0]); +// }); +async function handleItemBotanical(data) { + itemBotanicalsForm = data; + // if (data.length > 0) Object.assign(itemBotanicalsForm, itemBotanicals.value[0]); +} </script> <template> - <FetchData - ref="itemBotanicalsRef" - url="ItemBotanicals" - :filter="{ - where: { itemFk: entityId }, - }" - @on-fetch="(data) => (itemBotanicals = data)" - /> + <!-- <FetchData ref="itemBotanicalsRef" @on-fetch="(data) => (itemBotanicals = data)" /> --> <FetchData url="Genera" :filter="{ fields: ['id', 'name'], order: 'name ASC' }" @@ -60,11 +56,14 @@ onMounted(async () => { auto-load /> <FormModel + url="ItemBotanicals" url-update="ItemBotanicals" - model="entry" + model="item" auto-load - :form-initial-data="itemBotanicalsForm" - :clear-store-on-unmount="false" + :filter="{ + where: { itemFk: entityId }, + }" + @on-fetch="handleItemBotanical" > <template #form="{ data }"> <VnRow> From 2ef56f9f9730c0cbc8c287531ad12363a9f4c447 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 27 Aug 2024 08:00:07 +0200 Subject: [PATCH 020/207] refs #7283 fixedPrice --- src/pages/Item/ItemFixedPrice.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 30eb8544e..05a8545c8 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -292,6 +292,7 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => { ref="tableRef" data-key="ItemFixedPrices" url="FixedPrices/filter" + save-url="FixedPrices/crud" :filter="{ where: { warehouseFk: user.warehouseFk } }" :create="{ urlCreate: 'PriceFixed', From 6de59c64194c4aec32294575a531dda73d5d8b0d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 27 Aug 2024 14:39:21 +0200 Subject: [PATCH 021/207] refs #7283 itemRequestFixed --- src/pages/Item/ItemFixedPrice.vue | 1 + src/pages/Item/ItemList.vue | 2 ++ src/pages/Item/ItemRequest.vue | 31 +++++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 05a8545c8..7ba4984e7 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -164,6 +164,7 @@ const columns = computed(() => [ { title: t('Delete'), icon: 'delete', + isPrimary: true, }, ], }, diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index a3b70372f..2f3d20390 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -226,11 +226,13 @@ const columns = computed(() => [ title: t('Clone item'), icon: 'vn:clone', action: cloneItem, + isPrimary: true, }, { title: t('view Summary'), icon: 'preview', action: (row) => viewSummary(row.id, ItemSummary), + isPrimary: true, }, ], }, diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 65c0aaae1..0d641f8e2 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -9,7 +9,8 @@ import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import { toDate } from 'src/filters'; import VnTable from 'components/VnTable/VnTable.vue'; - +import VnInput from 'src/components/common/VnInput.vue'; +import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; const { t } = useI18n(); const { notify } = useNotify(); const stateStore = useStateStore(); @@ -64,7 +65,7 @@ const columns = computed(() => [ }, { label: t('item.buyRequest.requested'), - name: 'saleQuantity', + name: 'quantity', align: 'left', }, { @@ -100,7 +101,7 @@ const columns = computed(() => [ { label: t('item.buyRequest.state'), name: 'state', - action: (row) => getState(row.isOk), + format: (row) => getState(row.isOk), align: 'left', }, { @@ -333,11 +334,12 @@ onBeforeMount(() => { /> </QDialog> </QPage> --> + <VnSubToolbar /> <VnTable ref="tableRef" data-key="itemRequest" url="ticketRequests/filter" - order="id DESC" + order="shippedDate ASC, isOk ASC" :columns="columns" :is-editable="true" auto-load @@ -355,6 +357,27 @@ onBeforeMount(() => { <WorkerDescriptorProxy :id="row.requesterFk" /> </span> </template> + + <template #column-item="{ row }"> + <span @click.stop disabled="row.isOk != null"> + <VnInput type="number" v-model="row.item" fill-input /> + </span> + </template> + <template #column-achieved="{ row }"> + <span @click.stop disabled="!request.itemFk || request.isOk != null"> + <VnInput + type="number" + v-model="row.achieved" + fill-input + @keyup.enter="changeQuantity(row)" + /> + </span> + </template> + <template #column-concept="{ row }"> + <span @click.stop disabled="row.isOk != null"> + {{ row.itemDescription }} + </span> + </template> </VnTable> </template> From cd1b5f56f711ad8a0b0c3141c085f03897f36f8c Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 28 Aug 2024 11:35:57 +0200 Subject: [PATCH 022/207] refs #7283 column-action --- src/pages/Item/ItemRequest.vue | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 0d641f8e2..41248afbb 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -110,7 +110,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('Client ticket list'), + title: t('Deny Request'), icon: 'thumb_down', class: 'fill-icon', action: showDenyRequestForm, @@ -378,6 +378,32 @@ onBeforeMount(() => { {{ row.itemDescription }} </span> </template> + <template #column-action="{ row, rowIndex }"> + <QTd> + <QIcon + v-if="row.response?.length" + name="insert_drive_file" + color="primary" + size="sm" + > + <QTooltip> + {{ row.response }} + </QTooltip> + </QIcon> + <QIcon + v-if="row.isOk == null" + name="thumb_down" + color="primary" + size="sm" + class="fill-icon" + @click="showDenyRequestForm(row.id, rowIndex)" + > + <QTooltip> + {{ t('Discard') }} + </QTooltip> + </QIcon> + </QTd> + </template> </VnTable> </template> From e4aec1773b74c002913bf60f807c07ca39a873f5 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 29 Aug 2024 12:38:57 +0200 Subject: [PATCH 023/207] refs #7283 itemRequest fix deny --- src/pages/Item/ItemRequest.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 41248afbb..0e59a16c4 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -7,6 +7,7 @@ import { useArrayData } from 'composables/useArrayData'; import { toCurrency } from 'filters/index'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; +import ItemRequestDenyForm from './ItemRequestDenyForm.vue'; import { toDate } from 'src/filters'; import VnTable from 'components/VnTable/VnTable.vue'; import VnInput from 'src/components/common/VnInput.vue'; @@ -26,6 +27,10 @@ const arrayData = useArrayData('ItemRequests', { }); const store = arrayData.store; +const userParams = { + state: 'pending', +}; + watch( () => store.data, (value) => (itemRequestsOptions.value = value) @@ -174,7 +179,9 @@ const onDenyAccept = (_, responseData) => { itemRequestsOptions.value[denyRequestIndex.value].isOk = responseData.isOk; itemRequestsOptions.value[denyRequestIndex.value].attenderFk = responseData.attenderFk; + console.log('itemRequestsOptions: ', itemRequestsOptions.value); itemRequestsOptions.value[denyRequestIndex.value].response = responseData.response; + console.log('itemRequestsOptions.value', itemRequestsOptions.value); denyRequestId.value = null; denyRequestIndex.value = null; }; @@ -341,8 +348,10 @@ onBeforeMount(() => { url="ticketRequests/filter" order="shippedDate ASC, isOk ASC" :columns="columns" + :user-params="userParams" :is-editable="true" auto-load + :disable-option="{ card: true }" > <template #column-attenderName="{ row }"> <span class="link" @click.stop> @@ -378,7 +387,7 @@ onBeforeMount(() => { {{ row.itemDescription }} </span> </template> - <template #column-action="{ row, rowIndex }"> + <template #column-tableActions="{ row, rowIndex }"> <QTd> <QIcon v-if="row.response?.length" @@ -405,6 +414,9 @@ onBeforeMount(() => { </QTd> </template> </VnTable> + <QDialog ref="denyFormRef" transition-show="scale" transition-hide="scale"> + <ItemRequestDenyForm :request-id="denyRequestId" @on-data-saved="onDenyAccept" /> + </QDialog> </template> <i18n> From 388036a2eb589b6475132e630ee555147938b4a6 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 2 Sep 2024 09:19:49 +0200 Subject: [PATCH 024/207] refs #7283 itemRequest fix --- src/pages/Item/ItemRequest.vue | 146 ++------------------------------- 1 file changed, 7 insertions(+), 139 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 0e59a16c4..10ed237b4 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -208,140 +208,6 @@ onBeforeMount(() => { </script> <template> - <!-- <FetchData - url="Workers" - :filter="{ where: { role: 'buyer' } }" - order="id" - @on-fetch="(data) => (workersOptions = data)" - auto-load - /> - <VnSearchbar - data-key="ItemRequests" - url="TicketRequests/filter" - :label="t('globals.search')" - :info="t('You can search by Id or alias')" - :redirect="false" - /> - <RightMenu> - <template #right-panel> - <ItemRequestFilter data-key="ItemRequests" /> - </template> - </RightMenu> - <QPage class="column items-center q-pa-md"> - <QTable - :rows="itemRequestsOptions" - :columns="columns" - row-key="id" - :pagination="{ rowsPerPage: 0 }" - class="full-width q-mt-md" - :no-data-label="t('globals.noResults')" - > - <template #body-cell-id="{ row }"> - <QTd> - <QBtn flat color="primary"> {{ row.ticketFk }}</QBtn> - <TicketDescriptorProxy :id="row.ticketFk" /> - </QTd> - </template> - <template #body-cell-shipped="{ row }"> - <QTd> - <QBadge - v-if="getDateQBadgeColor(row.shipped)" - :color="getDateQBadgeColor(row.shipped)" - text-color="black" - class="q-ma-none" - dense - style="font-size: 14px" - > - {{ toDateFormat(row.shipped) }} - </QBadge> - <span v-else>{{ toDateFormat(row.shipped) }}</span> - </QTd> - </template> - <template #body-cell-requester="{ row }"> - <QTd> - <QBtn flat dense color="primary"> {{ row.requesterName }}</QBtn> - <WorkerDescriptorProxy :id="row.requesterFk" /> - </QTd> - </template> - <template #body-cell-attender="{ row }"> - <QTd> - <VnSelect - v-model="row.attenderFk" - :options="workersOptions" - hide-selected - option-label="firstName" - option-value="id" - dense - /> - </QTd> - </template> - <template #body-cell-item="{ row }"> - <QTd> - <VnInput - v-model.number="row.itemFk" - type="number" - :disable="row.isOk != null" - dense - /> - </QTd> - </template> - <template #body-cell-achieved="{ row }"> - <QTd> - <VnInput - v-model.number="row.saleQuantity" - @blur="changeQuantity(row)" - type="number" - :disable="!row.itemFk || row.isOk != null" - dense - /> - </QTd> - </template> - <template #body-cell-concept="{ row }"> - <QTd> - <QBtn flat dense color="primary"> {{ row.itemDescription }}</QBtn> - <ItemDescriptorProxy :id="row.itemFk" /> - </QTd> - </template> - <template #body-cell-state="{ row }"> - <QTd> - <span>{{ getState(row.isOk) }}</span> - </QTd> - </template> - <template #body-cell-action="{ row, rowIndex }"> - <QTd> - <QIcon - v-if="row.response?.length" - name="insert_drive_file" - color="primary" - size="sm" - > - <QTooltip> - {{ row.response }} - </QTooltip> - </QIcon> - <QIcon - v-if="row.isOk == null" - name="thumb_down" - color="primary" - size="sm" - class="fill-icon" - @click="showDenyRequestForm(row.id, rowIndex)" - > - <QTooltip> - {{ t('Discard') }} - </QTooltip> - </QIcon> - </QTd> - </template> - </QTable> - <QDialog ref="denyFormRef" transition-show="scale" transition-hide="scale"> - <ItemRequestDenyForm - :request-id="denyRequestId" - @on-data-saved="onDenyAccept" - /> - </QDialog> - </QPage> --> - <VnSubToolbar /> <VnTable ref="tableRef" data-key="itemRequest" @@ -368,17 +234,19 @@ onBeforeMount(() => { </template> <template #column-item="{ row }"> - <span @click.stop disabled="row.isOk != null"> - <VnInput type="number" v-model="row.item" fill-input /> + <span> + <VnInput v-model.number="row.itemFk" dense /> </span> </template> <template #column-achieved="{ row }"> - <span @click.stop disabled="!request.itemFk || request.isOk != null"> + <span> <VnInput type="number" - v-model="row.achieved" - fill-input + v-model.number="row.saleQuantity" + :disable="!row.itemFk || row.isOk != null" + @blur="changeQuantity(row)" @keyup.enter="changeQuantity(row)" + dense /> </span> </template> From 3bf3e8eeaa4c93dd2c8a737d5a95fb0528abbe50 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 2 Sep 2024 11:08:50 +0200 Subject: [PATCH 025/207] refs #7283 itemRequest fix deny --- src/pages/Item/ItemRequest.vue | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 10ed237b4..8273c5c91 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -112,16 +112,7 @@ const columns = computed(() => [ { align: 'right', label: '', - name: 'tableActions', - actions: [ - { - title: t('Deny Request'), - icon: 'thumb_down', - class: 'fill-icon', - action: showDenyRequestForm, - isPrimary: true, - }, - ], + name: 'denyOptions', }, ]); @@ -171,7 +162,9 @@ const getState = (isOk) => { const showDenyRequestForm = (requestId, rowIndex) => { denyRequestId.value = requestId; + console.log('denyRequestId.value: ', denyRequestId.value); denyRequestIndex.value = rowIndex; + console.log('denyRequestIndex.value: ', denyRequestIndex.value); denyFormRef.value.show(); }; @@ -255,8 +248,8 @@ onBeforeMount(() => { {{ row.itemDescription }} </span> </template> - <template #column-tableActions="{ row, rowIndex }"> - <QTd> + <template #column-denyOptions="{ row, rowIndex }"> + <QTd class="sticky no-padding"> <QIcon v-if="row.response?.length" name="insert_drive_file" From 488dc74c1f07c9314dc14618765c7250191ae72d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 2 Sep 2024 12:14:23 +0200 Subject: [PATCH 026/207] refs #7283 itemRequest fix reload --- src/pages/Item/ItemRequest.vue | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 8273c5c91..4062f8538 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -1,5 +1,5 @@ <script setup> -import { ref, computed, onMounted, onBeforeMount, watch } from 'vue'; +import { ref, computed, onMounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import { useStateStore } from 'stores/useStateStore'; @@ -11,7 +11,6 @@ import ItemRequestDenyForm from './ItemRequestDenyForm.vue'; import { toDate } from 'src/filters'; import VnTable from 'components/VnTable/VnTable.vue'; import VnInput from 'src/components/common/VnInput.vue'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; const { t } = useI18n(); const { notify } = useNotify(); const stateStore = useStateStore(); @@ -31,6 +30,7 @@ const userParams = { state: 'pending', }; +const tableRef = ref(); watch( () => store.data, (value) => (itemRequestsOptions.value = value) @@ -162,9 +162,7 @@ const getState = (isOk) => { const showDenyRequestForm = (requestId, rowIndex) => { denyRequestId.value = requestId; - console.log('denyRequestId.value: ', denyRequestId.value); denyRequestIndex.value = rowIndex; - console.log('denyRequestIndex.value: ', denyRequestIndex.value); denyFormRef.value.show(); }; @@ -172,32 +170,16 @@ const onDenyAccept = (_, responseData) => { itemRequestsOptions.value[denyRequestIndex.value].isOk = responseData.isOk; itemRequestsOptions.value[denyRequestIndex.value].attenderFk = responseData.attenderFk; - console.log('itemRequestsOptions: ', itemRequestsOptions.value); itemRequestsOptions.value[denyRequestIndex.value].response = responseData.response; - console.log('itemRequestsOptions.value', itemRequestsOptions.value); denyRequestId.value = null; denyRequestIndex.value = null; + tableRef.value.reload(); }; onMounted(async () => { await arrayData.fetch({ append: false }); stateStore.rightDrawer = true; }); - -onBeforeMount(() => { - const today = Date.vnNew(); - today.setHours(0, 0, 0, 0); - - const nextWeek = Date.vnNew(); - nextWeek.setHours(23, 59, 59, 59); - nextWeek.setDate(nextWeek.getDate() + 7); - - filterParams.value = { - from: today, - to: nextWeek, - state: 'pending', - }; -}); </script> <template> From 04c8481b51e70f3062d7d0a997bdab2fece7c98a Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 12 Sep 2024 07:43:12 +0200 Subject: [PATCH 027/207] refs #7283 fix itemFixed --- src/pages/Item/ItemFixedPrice.vue | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 29b886e25..d91b5189e 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -1,6 +1,5 @@ <script setup> import { onMounted, ref, reactive, onUnmounted, nextTick, computed } from 'vue'; -import { ref, reactive, computed, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import FetchedTags from 'components/ui/FetchedTags.vue'; @@ -27,15 +26,12 @@ import { QCheckbox } from 'quasar'; const quasar = useQuasar(); const stateStore = useStateStore(); -const route = useRoute(); const { t } = useI18n(); const { openConfirmationModal } = useVnConfirm(); const state = useState(); const { notify } = useNotify(); const tableRef = ref(); const editTableCellDialogRef = ref(null); -const tableRef = ref(); -const quasar = useQuasar(); const user = state.getUser(); const fixedPrices = ref([]); const warehousesOptions = ref([]); @@ -129,6 +125,7 @@ const columns = computed(() => [ }, { label: t('item.fixedPrice.started'), + field: 'started', name: 'started', format: ({ started }) => toDate(started), cardVisible: true, @@ -144,6 +141,7 @@ const columns = computed(() => [ }, { label: t('item.fixedPrice.ended'), + field: 'ended', name: 'ended', ...defaultColumnAttrs, cardVisible: true, @@ -157,6 +155,7 @@ const columns = computed(() => [ columnClass: 'expand', format: (row) => toDate(row.ended), }, + { label: t('item.fixedPrice.warehouse'), field: 'warehouseFk', @@ -223,18 +222,17 @@ const editTableFieldsOptions = [ label: t('item.fixedPrice.ended'), component: 'date', }, -]; - -function confirmRemove(row) { - quasar.dialog({ - component: VnConfirm, - componentProps: { - title: t('confirmDeletion'), - message: t('confirmDeletionMessage'), - promise: () => remove(row), + { + field: 'warehouseFk', + label: t('item.fixedPrice.warehouse'), + component: 'select', + attrs: { + options: [], + 'option-label': 'name', + 'option-value': 'id', }, - }), -}; + }, +]; const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => { return inputType === 'text' ? { From 039a8d1d02e1ca30a2dd6701a60b7211b3de01cd Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 12 Sep 2024 09:32:41 +0200 Subject: [PATCH 028/207] refs #7283 fix items --- src/i18n/locale/en.yml | 2 ++ src/i18n/locale/es.yml | 2 ++ src/pages/Item/Card/ItemCard.vue | 2 +- src/pages/Item/ItemList.vue | 49 ++++++++++++-------------------- src/pages/Item/ItemRequest.vue | 2 +- 5 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 6546b78c4..37d1e3726 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -1022,6 +1022,8 @@ travel: travelFileDescription: 'Travel id { travelId }' file: File item: + searchbar: + label: Search item descriptor: item: Item buyer: Buyer diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 79e66b5f7..0c0447b78 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -1007,6 +1007,8 @@ travel: travelFileDescription: 'Id envío { travelId }' file: Fichero item: + searchbar: + label: Buscar artículo descriptor: item: Artículo buyer: Comprador diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue index 1162327c1..4cf1372cc 100644 --- a/src/pages/Item/Card/ItemCard.vue +++ b/src/pages/Item/Card/ItemCard.vue @@ -12,7 +12,7 @@ import ItemListFilter from '../ItemListFilter.vue'; search-data-key="ItemList" :searchbar-props="{ url: 'Items/filter', - label: 'searchbar.labelr', + label: 'item.searchbar.label', info: 'searchbar.info', }" /> diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 2f3d20390..c31302bba 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -44,25 +44,24 @@ const itemFilter = { ], }; const columns = computed(() => [ - // { - // label: '', - // name: 'image', - // align: 'left', - // columnField: { - // component: VnImg, - // attrs: (id) => { - // return { - // id, - // width: '50px', - // }; - // }, - // }, - // columnFilter: false, - // }, + { + label: '', + name: 'image', + align: 'left', + columnField: { + component: VnImg, + attrs: (id) => { + return { + id, + width: '50px', + }; + }, + }, + columnFilter: false, + }, { label: t('item.list.id'), name: 'id', - field: 'id', align: 'left', isId: true, chip: { @@ -71,38 +70,35 @@ const columns = computed(() => [ }, { label: t('item.list.grouping'), - field: 'grouping', name: 'grouping', align: 'left', }, { label: t('item.list.packing'), - field: 'packing', name: 'packing', align: 'left', }, { label: t('globals.description'), - field: 'name', name: 'description', align: 'left', create: true, + columnFilter: { + name: 'description', + }, }, { label: t('item.list.stems'), - field: 'stems', name: 'stems', align: 'left', }, { label: t('item.list.size'), - field: 'size', name: 'size', align: 'left', }, { label: t('item.list.typeName'), - field: 'typeName', name: 'typeName', align: 'left', component: 'select', @@ -117,7 +113,6 @@ const columns = computed(() => [ }, { label: t('item.list.category'), - field: 'category', name: 'category', align: 'left', component: 'select', @@ -131,7 +126,6 @@ const columns = computed(() => [ }, { label: t('item.list.intrastat'), - field: 'intrastat', name: 'intrastat', align: 'left', component: 'select', @@ -146,7 +140,6 @@ const columns = computed(() => [ }, { label: t('item.list.origin'), - field: 'origin', name: 'origin', align: 'left', component: 'select', @@ -161,13 +154,11 @@ const columns = computed(() => [ }, { label: t('item.list.userName'), - field: 'userName', name: 'userName', align: 'left', }, { label: t('item.list.weightByPiece'), - field: 'weightByPiece', name: 'weightByPiece', align: 'left', component: 'input', @@ -177,7 +168,6 @@ const columns = computed(() => [ }, { label: t('item.list.stemMultiplier'), - field: 'stemMultiplier', name: 'stemMultiplier', align: 'left', component: 'input', @@ -187,14 +177,12 @@ const columns = computed(() => [ }, { label: t('item.list.isActive'), - field: 'isActive', name: 'isActive', align: 'left', component: 'checkbox', }, { label: t('item.list.producer'), - field: 'producer', name: 'producer', align: 'left', component: 'select', @@ -208,7 +196,6 @@ const columns = computed(() => [ }, { label: t('item.list.landed'), - field: 'landed', name: 'landed', align: 'left', component: 'date', diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index be0a9c2e8..4bf45fe4c 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -188,7 +188,7 @@ onMounted(async () => { ref="tableRef" data-key="itemRequest" url="ticketRequests/filter" - order="shippedDate ASC, isOk ASC" + order="shipped ASC, isOk ASC" :columns="columns" :user-params="userParams" :is-editable="true" From 68a2ac385f6638d0b23168f085984b2d8b40d313 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 12 Sep 2024 11:36:02 +0200 Subject: [PATCH 029/207] refs #7283 fix items images --- src/pages/Item/ItemList.vue | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index c31302bba..ca00a6502 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -50,9 +50,9 @@ const columns = computed(() => [ align: 'left', columnField: { component: VnImg, - attrs: (id) => { + attrs: ({ row }) => { return { - id, + id: row.id, width: '50px', }; }, @@ -102,9 +102,11 @@ const columns = computed(() => [ name: 'typeName', align: 'left', component: 'select', - attrs: { - url: 'ItemTypes', - fields: ['id', 'name'], + columnFilter: { + attrs: { + url: 'ItemTypes', + fields: ['name'], + }, }, columnField: { component: null, From 050d8ae208329f51e38f3e3acb79fe4c8e8a991a Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 12 Sep 2024 11:43:37 +0200 Subject: [PATCH 030/207] refs #7283 fix items error get images --- src/pages/Item/ItemList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index ca00a6502..bed30725b 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -52,7 +52,7 @@ const columns = computed(() => [ component: VnImg, attrs: ({ row }) => { return { - id: row.id, + id: row?.id, width: '50px', }; }, From 1916c6e4bf0b3b161b9c1ccaf6d554d5e5c2c83b Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 16 Sep 2024 14:29:39 +0200 Subject: [PATCH 031/207] refs #7283 itemFilters --- src/pages/Item/ItemList.vue | 50 ++++++++++++++++++++++++---------- src/pages/Item/ItemRequest.vue | 11 ++++++-- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index bed30725b..b6668edea 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -84,7 +84,7 @@ const columns = computed(() => [ align: 'left', create: true, columnFilter: { - name: 'description', + name: 'search', }, }, { @@ -103,9 +103,10 @@ const columns = computed(() => [ align: 'left', component: 'select', columnFilter: { + name: 'typeFk', attrs: { url: 'ItemTypes', - fields: ['name'], + fields: ['id', 'name'], }, }, columnField: { @@ -118,9 +119,12 @@ const columns = computed(() => [ name: 'category', align: 'left', component: 'select', - attrs: { - url: 'ItemCategories', - fields: ['id', 'name'], + columnFilter: { + name: 'categoryFk', + attrs: { + url: 'ItemCategories', + fields: ['id', 'name'], + }, }, columnField: { component: null, @@ -131,9 +135,15 @@ const columns = computed(() => [ name: 'intrastat', align: 'left', component: 'select', - attrs: { - url: 'Intrastats', - fields: ['id', 'description'], + columnFilter: { + name: 'description', + attrs: { + url: 'Intrastats', + optionValue: 'description', + optionLabel: 'description', + }, + inWhere: true, + alias: 'intr', }, columnField: { component: null, @@ -145,9 +155,15 @@ const columns = computed(() => [ name: 'origin', align: 'left', component: 'select', - attrs: { - url: 'Origins', - fields: ['id', 'name'], + columnFilter: { + name: 'id', + attrs: { + url: 'Origins', + optionValue: 'id', + optionLabel: 'code', + }, + inWhere: true, + alias: 'ori', }, columnField: { component: null, @@ -158,6 +174,14 @@ const columns = computed(() => [ label: t('item.list.userName'), name: 'userName', align: 'left', + columnFilter: { + name: 'workerFk', + attrs: { + url: 'Users', + optionValue: 'id', + optionLabel: 'userName', + }, + }, }, { label: t('item.list.weightByPiece'), @@ -249,8 +273,6 @@ const cloneItem = async (itemFk) => { data-key="ItemList" url="Items/filter" url-create="Items" - save-url="Items/crud" - :filter="itemFilter" :create="{ urlCreate: 'Items', title: 'Create Item', @@ -264,7 +286,7 @@ const cloneItem = async (itemFk) => { auto-load redirect="Item" :is-editable="false" - :use-model="true" + :filer="itemFilter" > <template #column-userName="{ row }"> <span class="link" @click.stop> diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 4bf45fe4c..1a1d98211 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -57,45 +57,51 @@ const columns = computed(() => [ component: null, }, format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.shipped)), + columnClass: 'shrink', }, { label: t('globals.description'), field: 'description', name: 'description', align: 'left', + columnClass: 'expand', }, { label: t('item.buyRequest.requester'), name: 'requesterName', - align: 'left', + columnClass: 'shrink', }, { label: t('item.buyRequest.requested'), name: 'quantity', - align: 'left', + columnClass: 'shrink', }, { label: t('item.buyRequest.price'), name: 'price', align: 'left', format: (row) => toCurrency(row.price), + columnClass: 'shrink', }, { label: t('item.buyRequest.attender'), name: 'attenderName', align: 'left', + columnClass: 'shrink', }, { label: t('item.buyRequest.item'), name: 'item', align: 'left', component: 'input', + columnClass: 'expand', }, { label: t('item.buyRequest.achieved'), name: 'achieved', align: 'left', component: 'input', + columnClass: 'shrink', }, { label: t('item.buyRequest.concept'), @@ -103,6 +109,7 @@ const columns = computed(() => [ align: 'left', sortable: true, component: 'input', + columnClass: 'expand', }, { label: t('item.buyRequest.state'), From db783e15384163fdb7221afae2fc4e509e0c4c52 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 17 Sep 2024 15:03:30 +0200 Subject: [PATCH 032/207] refs #7283 item Descriptor --- src/composables/useArrayData.js | 1 + src/pages/Item/Card/ItemDescriptor.vue | 70 ++++++------- src/pages/Item/Card/ItemDescriptorImage.vue | 8 +- src/pages/Item/Card/ItemDiary.vue | 110 +++++++++++--------- 4 files changed, 98 insertions(+), 91 deletions(-) diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 651bcefb0..6671632b3 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -246,6 +246,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { } function updateStateParams() { + if (!route) return; const newUrl = { path: route.path, query: { ...(route.query ?? {}) } }; newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter); diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index baac0c608..a14ee1446 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -14,6 +14,7 @@ import useCardDescription from 'src/composables/useCardDescription'; import { getUrl } from 'src/composables/getUrl'; import axios from 'axios'; import { dashIfEmpty } from 'src/filters'; +import { useArrayData } from 'src/composables/useArrayData'; const $props = defineProps({ id: { @@ -49,58 +50,49 @@ const entityId = computed(() => { }); const regularizeStockFormDialog = ref(null); -const available = ref(null); -const visible = ref(null); const salixUrl = ref(); +const mounted = ref(); + +const arrayDataStock = useArrayData('descriptorStock', { + url: `Items/${entityId.value}/getVisibleAvailable`, +}); onMounted(async () => { - salixUrl.value = await getUrl(''); + salixUrl.value = await getUrl('getVisibleAvailable'); await getItemConfigs(); - await updateStock(); + mounted.value = true; }); const data = ref(useCardDescription()); const setData = async (entity) => { - try { - if (!entity) return; - data.value = useCardDescription(entity.name, entity.id); - await updateStock(); - } catch (err) { - console.error('Error item'); - } + if (!entity) return; + data.value = useCardDescription(entity.name, entity.id); + await updateStock(); }; const getItemConfigs = async () => { - try { - const { data } = await axios.get('ItemConfigs/findOne'); - if (!data) return; - return (warehouseConfig.value = data.warehouseFk); - } catch (err) { - console.error('Error item'); - } + const { data } = await axios.get('ItemConfigs/findOne'); + if (!data) return; + return (warehouseConfig.value = data.warehouseFk); }; const updateStock = async () => { - try { - available.value = null; - visible.value = null; + if (!mounted.value) return; + await getItemConfigs(); - const params = { - warehouseFk: $props.warehouseFk, - dated: $props.dated, - }; + const params = { + warehouseFk: $props.warehouseFk ?? warehouseConfig.value, + dated: $props.dated, + }; - await getItemConfigs(); - if (!params.warehouseFk) { - params.warehouseFk = warehouseConfig.value; - } - const { data } = await axios.get(`Items/${entityId.value}/getVisibleAvailable`, { - params, - }); - available.value = data.available; - visible.value = data.visible; - } catch (err) { - console.error('Error updating stock'); - } + if (!params.warehouseFk) return; + + const stock = useArrayData('descriptorStock', { + url: `Items/${entityId.value}/getVisibleAvailable`, + userParams: params, + }); + const storeData = stock.store.data; + if (storeData?.itemFk == entityId.value) return; + await stock.fetch({}); }; const openRegularizeStockForm = () => { @@ -163,8 +155,8 @@ const openCloneDialog = async () => { <template #before> <ItemDescriptorImage :entity-id="entityId" - :visible="visible" - :available="available" + :visible="arrayDataStock.store.data?.visible" + :available="arrayDataStock.store.data?.available" /> </template> <template #body="{ entity }"> diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue index a4ef22ce3..b035a630a 100644 --- a/src/pages/Item/Card/ItemDescriptorImage.vue +++ b/src/pages/Item/Card/ItemDescriptorImage.vue @@ -32,6 +32,10 @@ const editPhotoFormDialog = ref(null); const showEditPhotoForm = ref(false); const warehouseName = ref(null); +onMounted(async () => { + getItemConfigs(); +}); + const toggleEditPictureForm = () => { showEditPhotoForm.value = !showEditPhotoForm.value; }; @@ -56,10 +60,6 @@ const getWarehouseName = async (warehouseFk) => { warehouseName.value = data.name; }; -onMounted(async () => { - getItemConfigs(); -}); - const handlePhotoUpdated = (evt = false) => { image.value.reload(evt); }; diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue index 68633caa2..a36b6a246 100644 --- a/src/pages/Item/Card/ItemDiary.vue +++ b/src/pages/Item/Card/ItemDiary.vue @@ -17,6 +17,7 @@ import { toDateFormat } from 'src/filters/date.js'; import { dashIfEmpty } from 'src/filters'; import { date } from 'quasar'; import { useState } from 'src/composables/useState'; +import { useArrayData } from 'src/composables/useArrayData'; import axios from 'axios'; const { t } = useI18n(); @@ -37,6 +38,33 @@ const warehouseFk = ref(null); const _showWhatsBeforeInventory = ref(false); const inventoriedDate = ref(null); +const originTypeMap = { + entry: { + descriptor: EntryDescriptorProxy, + icon: 'vn:entry', + color: 'green', + }, + ticket: { + descriptor: TicketDescriptorProxy, + icon: 'vn:ticket', + color: 'red', + }, + order: { + descriptor: OrderDescriptorProxy, + icon: 'vn:basket', + color: 'yellow', + }, +}; + +const entityTypeMap = { + client: { + descriptor: CustomerDescriptorProxy, + }, + supplier: { + descriptor: SupplierDescriptorProxy, + }, +}; + const columns = computed(() => [ { name: 'claim', @@ -105,6 +133,28 @@ const showWhatsBeforeInventory = computed({ }, }); +onMounted(async () => { + today.value.setHours(0, 0, 0, 0); + if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk; + else if (user.value) warehouseFk.value = user.value.warehouseFk; + itemsBalanceFilter.where.warehouseFk = warehouseFk.value; + const { data } = await axios.get('Configs/findOne'); + inventoriedDate.value = data.inventoried; + await fetchItemBalances(); + await scrollToToday(); + await updateWarehouse(warehouseFk.value); +}); + +onUnmounted(() => (stateStore.rightDrawer = false)); + +watch( + () => router.currentRoute.value.params.id, + (newId) => { + itemsBalanceFilter.where.itemFk = newId; + itemBalancesRef.value.fetch(); + } +); + const fetchItemBalances = async () => await itemBalancesRef.value.fetch(); const getBadgeAttrs = (_date) => { @@ -131,53 +181,15 @@ const formatDateForAttribute = (dateValue) => { return dateValue; }; -const originTypeMap = { - entry: { - descriptor: EntryDescriptorProxy, - icon: 'vn:entry', - color: 'green', - }, - ticket: { - descriptor: TicketDescriptorProxy, - icon: 'vn:ticket', - color: 'red', - }, - order: { - descriptor: OrderDescriptorProxy, - icon: 'vn:basket', - color: 'yellow', - }, -}; - -const entityTypeMap = { - client: { - descriptor: CustomerDescriptorProxy, - }, - supplier: { - descriptor: SupplierDescriptorProxy, - }, -}; - -onMounted(async () => { - today.value.setHours(0, 0, 0, 0); - if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk; - else if (user.value) warehouseFk.value = user.value.warehouseFk; - itemsBalanceFilter.where.warehouseFk = warehouseFk.value; - const { data } = await axios.get('Configs/findOne'); - inventoriedDate.value = data.inventoried; - await fetchItemBalances(); - await scrollToToday(); -}); - -onUnmounted(() => (stateStore.rightDrawer = false)); - -watch( - () => router.currentRoute.value.params.id, - (newId) => { - itemsBalanceFilter.where.itemFk = newId; - itemBalancesRef.value.fetch(); - } -); +async function updateWarehouse(warehouseFk) { + const stock = useArrayData('descriptorStock', { + userParams: { + warehouseFk, + }, + }); + await stock.fetch({}); + stock.store.data.itemFk = route.params.id +} </script> <template> @@ -203,7 +215,9 @@ watch( option-value="id" dense v-model="itemsBalanceFilter.where.warehouseFk" - @update:model-value="fetchItemBalances" + @update:model-value=" + (value) => fetchItemBalances() && updateWarehouse(value) + " class="q-mr-lg" /> <QCheckbox From 716d018121026767ecd2e9b5b1f47dffa349a028 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Fri, 20 Sep 2024 14:20:26 +0200 Subject: [PATCH 033/207] refs #72983 fix filters --- src/pages/Item/ItemList.vue | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index b6668edea..48fe3280e 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -54,6 +54,7 @@ const columns = computed(() => [ return { id: row?.id, width: '50px', + zoomResolution: '1600x900', }; }, }, @@ -72,11 +73,19 @@ const columns = computed(() => [ label: t('item.list.grouping'), name: 'grouping', align: 'left', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { label: t('item.list.packing'), name: 'packing', align: 'left', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { label: t('globals.description'), @@ -91,11 +100,19 @@ const columns = computed(() => [ label: t('item.list.stems'), name: 'stems', align: 'left', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { label: t('item.list.size'), name: 'size', align: 'left', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { label: t('item.list.typeName'), From 54015fb6bfbf975a7fed3150cf82de904df56d63 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 1 Oct 2024 08:44:08 +0200 Subject: [PATCH 034/207] refs #7283 fix itemMigration --- src/pages/Item/ItemRequest.vue | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 1a1d98211..7fbeccbf9 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -117,6 +117,15 @@ const columns = computed(() => [ format: (row) => getState(row.isOk), align: 'left', }, + { + align: 'left', + name: 'daysOnward', + label: t('item.buyRequest.daysOnward'), + visible: false, + columnFilter: { + inWhere: false, + }, + }, { align: 'right', label: '', @@ -238,6 +247,17 @@ onMounted(async () => { {{ row.itemDescription }} </span> </template> + <template #moreFilterPanel="{ params }"> + <VnInputNumber + :label="t('params.scopeDays')" + v-model.number="params.scopeDays" + @keyup.enter="(evt) => handleScopeDays(evt.target.value)" + @remove="handleScopeDays()" + class="q-px-xs q-pr-lg" + filled + dense + /> + </template> <template #column-denyOptions="{ row, rowIndex }"> <QTd class="sticky no-padding"> <QIcon From 55ddc8644f0450091f49ce96d4ef1ad2d3988a68 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 2 Oct 2024 12:51:33 +0200 Subject: [PATCH 035/207] refs #7283 fix itemMigration list filters --- src/pages/Item/ItemList.vue | 8 +++++++- src/pages/Item/ItemRequest.vue | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 48fe3280e..ad2c2e238 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -208,6 +208,9 @@ const columns = computed(() => [ columnField: { component: null, }, + columnFilter: { + inWhere: true, + }, }, { label: t('item.list.stemMultiplier'), @@ -217,11 +220,14 @@ const columns = computed(() => [ columnField: { component: null, }, + columnFilter: { + inWhere: true, + }, }, { label: t('item.list.isActive'), name: 'isActive', - align: 'left', + align: 'center', component: 'checkbox', }, { diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 7fbeccbf9..0eba6f9a4 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -29,6 +29,7 @@ const store = arrayData.store; const userParams = { state: 'pending', + daysOnward: 7, }; const tableRef = ref(); @@ -120,7 +121,7 @@ const columns = computed(() => [ { align: 'left', name: 'daysOnward', - label: t('item.buyRequest.daysOnward'), + label: t('travel.travelList.tableVisibleColumns.daysOnward'), visible: false, columnFilter: { inWhere: false, From 419d3d2d45b16d268da452d06fbc1aadfeb03707 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Thu, 10 Oct 2024 07:20:33 +0200 Subject: [PATCH 036/207] fix: refs #6896 fixed module problems --- src/components/ui/VnFilterPanel.vue | 12 ++- src/components/ui/VnSearchbar.vue | 2 + src/i18n/locale/en.yml | 2 + src/i18n/locale/es.yml | 4 +- src/pages/Order/Card/OrderCatalog.vue | 6 +- src/pages/Order/Card/OrderCatalogFilter.vue | 88 +++++++------------- src/pages/Order/Card/OrderDescriptor.vue | 10 +-- src/pages/Order/Card/OrderDescriptorMenu.vue | 7 +- src/pages/Order/Card/OrderLines.vue | 3 +- src/pages/Order/Card/OrderSummary.vue | 27 ++++++ 10 files changed, 87 insertions(+), 74 deletions(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 43d634ad9..242c4220d 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -185,6 +185,9 @@ async function remove(key) { } function formatValue(value) { + if (typeof value === 'object') { + return value; + } if (typeof value === 'boolean') return value ? t('Yes') : t('No'); if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value); @@ -193,6 +196,13 @@ function formatValue(value) { function sanitizer(params) { for (const [key, value] of Object.entries(params)) { + if (key == 'and') { + value.forEach((andValue) => { + params = { ...params, ...andValue }; + }); + delete params[key]; + } + if (value && typeof value === 'object') { const param = Object.values(value)[0]; if (typeof param == 'string') params[key] = param.replaceAll('%', ''); @@ -211,7 +221,7 @@ function sanitizer(params) { icon="search" @click="search()" ></QBtn> - <QForm @submit="search" id="filterPanelForm" @keyup.enter="search()"> + <QForm @submit="search(true)" id="filterPanelForm" @keyup.enter="search(true)"> <QList dense> <QItem class="q-mt-xs"> <QItemSection top> diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index dc6d4751c..fc292e980 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -9,6 +9,7 @@ import { useStateStore } from 'src/stores/useStateStore'; const quasar = useQuasar(); const { t } = useI18n(); const state = useStateStore(); +const emit = defineEmits(['on-search']); const props = defineProps({ dataKey: { @@ -118,6 +119,7 @@ async function search() { delete filter.params.search; } await arrayData.applyFilter(filter); + emit('on-search', store.data); } </script> <template> diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 6235447fe..e24926092 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -705,6 +705,8 @@ order: quantity: Quantity price: Price amount: Amount + confirm: Confirm + confirmLines: Confirm lines department: pageTitles: basicData: Basic data diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 6076af5d9..648868fcb 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -679,13 +679,15 @@ order: vat: IVA state: Estado alias: Alias - items: Items + items: Artículos orderTicketList: Tickets del pedido details: Detalles item: Item quantity: Cantidad price: Precio amount: Monto + confirm: Confirmar + confirmLines: Confirmar lineas shelving: list: parking: Parking diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue index b13e8661d..110ea48af 100644 --- a/src/pages/Order/Card/OrderCatalog.vue +++ b/src/pages/Order/Card/OrderCatalog.vue @@ -86,11 +86,8 @@ function extractValueTags(items) { <div class="full-width"> <VnPaginate data-key="OrderCatalogList" - url="Orders/CatalogFilter" - :limit="50" - :user-params="catalogParams" - @on-fetch="extractTags" :update-router="false" + @on-change="extractTags" > <template #body="{ rows }"> <div class="catalog-list"> @@ -102,6 +99,7 @@ function extractValueTags(items) { :key="row.id" :item="row" is-catalog + class="fill-icon" /> </div> </template> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 6de43e86a..9c713e77e 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -1,12 +1,11 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed, ref, onMounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; -import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; @@ -48,6 +47,15 @@ const orderWayList = ref([ const orderBySelected = ref('relevancy DESC, name'); const orderWaySelected = ref('ASC'); +const routeQuery = JSON.parse(route?.query.params ?? '{}'); +const params = ref({}); + +onMounted(() => { + const filter = routeQuery.filter; + params.value = JSON.parse(filter ?? '{}')?.where ?? {}; + if (Object.keys(params.value).length > 0) vnFilterPanelRef.value.search(); +}); + const createValue = (val, done) => { if (val.length > 2) { if (!tagOptions.value.includes(val)) { @@ -61,19 +69,15 @@ const resetCategory = () => { typeList.value = null; }; -const clearFilter = (key) => { - if (key === 'categoryFk') { +const selectCategory = (category, search) => { + if (!params.value?.filter) params.value.filter = { where: {} }; + const where = params.value.filter.where; + if (where.categoryFk === category?.id) { resetCategory(); - } -}; - -const selectCategory = (params, category, search) => { - if (params.categoryFk === category?.id) { - resetCategory(); - params.categoryFk = null; + where.categoryFk = null; } else { selectedCategoryFk.value = category?.id; - params.categoryFk = category?.id; + where.categoryFk = category?.id; loadTypes(category?.id); } search(); @@ -103,17 +107,6 @@ const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); -function exprBuilder(param, value) { - switch (param) { - case 'categoryFk': - case 'typeFk': - return { [param]: value }; - case 'search': - if (/^\d+$/.test(value)) return { 'i.id': value }; - else return { 'i.name': { like: `%${value}%` } }; - } -} - const applyTagFilter = (params, search) => { if (!tagValues.value?.length) { params.tagGroups = null; @@ -138,15 +131,6 @@ const applyTagFilter = (params, search) => { tagValues.value = [{}]; }; -const removeTagChip = (selection, params, search) => { - if (params.tagGroups) { - params.tagGroups = (params.tagGroups || []).filter( - (value) => value !== selection - ); - } - search(); -}; - const setCategoryList = (data) => { categoryList.value = (data || []) .filter((category) => category.display) @@ -178,12 +162,11 @@ function addOrder(value, field, params) { <VnFilterPanel ref="vnFilterPanelRef" :data-key="props.dataKey" - :hidden-tags="['orderFk', 'orderBy']" - :un-removable-params="['orderFk', 'orderBy']" - :expr-builder="exprBuilder" - :custom-tags="['tagGroups']" - @remove="clearFilter" + v-model="params" :redirect="false" + :hidden-tags="['orderFk', 'orderBy', 'filter', 'search', 'or', 'and']" + :un-removable-params="['orderFk', 'orderBy']" + :disable-submit-event="true" > <template #tags="{ tag, formatFn }"> <strong v-if="tag.label === 'categoryFk'"> @@ -192,30 +175,17 @@ function addOrder(value, field, params) { <strong v-else-if="tag.label === 'typeFk'"> {{ t(selectedType?.name || '') }} </strong> + <div v-else-if="tag.label === 'tagGroups'" class="q-gutter-x-xs"> + <strong v-if="JSON.parse(tag.value).tagSelection.name" + >{{ JSON.parse(tag.value).tagSelection?.name }}: + </strong> + <span>{{ JSON.parse(tag.value).values[0].value }}</span> + </div> <div v-else class="q-gutter-x-xs"> <strong>{{ t(`params.${tag.label}`) }}: </strong> <span>{{ formatFn(tag.value) }}</span> </div> </template> - <template #customTags="{ tags: customTags, params, searchFn }"> - <template v-for="tag in customTags" :key="tag.label"> - <template v-if="tag.label === 'tagGroups'"> - <VnFilterPanelChip - v-for="chip in tag.value" - :key="chip" - removable - @remove="removeTagChip(chip, params, searchFn)" - > - <strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong> - <span>{{ - (JSON.parse(chip).values || []) - .map((item) => item.value) - .join(' | ') - }}</span> - </VnFilterPanelChip> - </template> - </template> - </template> <template #body="{ params, searchFn }"> <QItem class="category-filter q-mt-md"> <div @@ -226,7 +196,7 @@ function addOrder(value, field, params) { <QIcon :name="category.icon" class="category-icon" - @click="selectCategory(params, category, searchFn)" + @click="selectCategory(category, searchFn)" > <QTooltip> {{ t(category.name) }} @@ -320,7 +290,7 @@ function addOrder(value, field, params) { > <FetchData v-if="selectedTag" - :url="`Tags/${selectedTag}/filterValue`" + :url="`Tags/${selectedTag.id}/filterValue`" limit="30" auto-load @on-fetch="(data) => (tagOptions = data)" @@ -343,7 +313,7 @@ function addOrder(value, field, params) { @update:model-value="applyTagFilter(params, searchFn)" /> <VnSelect - v-else-if="selectedTag === 1" + v-else-if="selectedTag.id === 1" :label="t('params.value')" v-model="value.value" :options="tagOptions || []" diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue index a035971b0..74c8d8bed 100644 --- a/src/pages/Order/Card/OrderDescriptor.vue +++ b/src/pages/Order/Card/OrderDescriptor.vue @@ -71,10 +71,6 @@ const getConfirmationValue = (isConfirmed) => { }; const total = ref(null); - -function ticketFilter(order) { - return JSON.stringify({ id: order.id }); -} </script> <template> @@ -126,7 +122,11 @@ function ticketFilter(order) { color="primary" :to="{ name: 'TicketList', - query: { table: ticketFilter(entity) }, + query: { + table: JSON.stringify({ + orderFk: entity.id, + }), + }, }" > <QTooltip>{{ t('order.summary.orderTicketList') }}</QTooltip> diff --git a/src/pages/Order/Card/OrderDescriptorMenu.vue b/src/pages/Order/Card/OrderDescriptorMenu.vue index 2695da4e5..461efa22f 100644 --- a/src/pages/Order/Card/OrderDescriptorMenu.vue +++ b/src/pages/Order/Card/OrderDescriptorMenu.vue @@ -23,8 +23,8 @@ function confirmRemove() { .dialog({ component: VnConfirm, componentProps: { - title: t('globals.confirmDeletion'), - message: t('confirmDeletionMessage'), + title: t('You are going to delete this order'), + message: t('Continue anyway?'), promise: remove, }, }) @@ -57,5 +57,6 @@ en: es: deleteOrder: Eliminar pedido confirmDeletionMessage: Seguro que quieres eliminar este pedido? - + You are going to delete this order: El pedido se eliminará + Continue anyway?: ¿Continuar de todos modos? </i18n> diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue index 175c956e1..0d00e04ed 100644 --- a/src/pages/Order/Card/OrderLines.vue +++ b/src/pages/Order/Card/OrderLines.vue @@ -168,7 +168,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('Delete'), + title: t('Remove item'), icon: 'delete', show: (row) => !row.order.isConfirmed, action: (row) => confirmRemove(row), @@ -397,4 +397,5 @@ es: confirmDeletion: Confirmar eliminación, confirmDeletionMessage: Seguro que quieres eliminar este artículo? confirm: Confirmar + Remove item: Eliminar artículo </i18n> diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index 60358f744..9bc89ad28 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -2,7 +2,10 @@ import { computed, ref } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; +import { useQuasar } from 'quasar'; +import axios from 'axios'; import { dashIfEmpty, toCurrency, toDateHourMinSec } from 'src/filters'; +import { useArrayData } from 'composables/useArrayData'; import VnLv from 'components/ui/VnLv.vue'; import CardSummary from 'components/ui/CardSummary.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -21,6 +24,9 @@ const $props = defineProps({ }); const entityId = computed(() => $props.id || route.params.id); +const summary = ref(); +const quasar = useQuasar(); +const descriptorData = useArrayData('orderData'); const detailsColumns = ref([ { name: 'item', @@ -49,6 +55,16 @@ const detailsColumns = ref([ field: (row) => toCurrency(row?.quantity * row?.price), }, ]); + +async function confirmOrder() { + await axios.post(`Orders/${route.params.id}/confirm`); + quasar.notify({ + message: t('globals.confirm'), + type: 'positive', + }); + summary.value.fetch({}); + descriptorData.fetch({}); +} </script> <template> @@ -62,6 +78,17 @@ const detailsColumns = ref([ {{ t('order.summary.basket') }} #{{ entity?.id }} - {{ entity?.client?.name }} ({{ entity?.clientFk }}) </template> + <template #header-right> + <QBtn + flat + text-color="white" + :disabled="isConfirmed" + :label="t('order.summary.confirm')" + @click="confirmOrder()" + > + <QTooltip>{{ t('order.summary.confirmLines') }}</QTooltip> + </QBtn> + </template> <template #body="{ entity }"> <QCard class="vn-one"> <VnTitle From d7210837959ca94189a78071a8145d5509af419d Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Thu, 10 Oct 2024 08:43:33 +0200 Subject: [PATCH 037/207] fix: filter panel --- src/components/ui/VnFilterPanel.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 242c4220d..f042c6481 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -221,7 +221,7 @@ function sanitizer(params) { icon="search" @click="search()" ></QBtn> - <QForm @submit="search(true)" id="filterPanelForm" @keyup.enter="search(true)"> + <QForm @submit="search()" id="filterPanelForm" @keyup.enter="search(true)"> <QList dense> <QItem class="q-mt-xs"> <QItemSection top> From f16707756e99cd64e798e6190bf03845b82520a5 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 9 Oct 2024 00:40:21 +0200 Subject: [PATCH 038/207] fix: change type vnput --- src/pages/Ticket/Card/TicketCreateRequest.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Ticket/Card/TicketCreateRequest.vue b/src/pages/Ticket/Card/TicketCreateRequest.vue index ffe009516..d6e757afe 100644 --- a/src/pages/Ticket/Card/TicketCreateRequest.vue +++ b/src/pages/Ticket/Card/TicketCreateRequest.vue @@ -56,6 +56,7 @@ const attendersOptions = ref([]); v-model="data.price" :label="t('purchaseRequest.price')" type="number" + step="0.01" min="0" /> </VnRow> From 3d5d2673452f4aa1e584fa333f12bcfc83e1f52f Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 10 Oct 2024 09:29:12 +0200 Subject: [PATCH 039/207] revert: commit --- src/components/ui/VnFilterPanel.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index f042c6481..66e9df5f5 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -221,7 +221,7 @@ function sanitizer(params) { icon="search" @click="search()" ></QBtn> - <QForm @submit="search()" id="filterPanelForm" @keyup.enter="search(true)"> + <QForm @submit="search" id="filterPanelForm" @keyup.enter.prevent="search(true)"> <QList dense> <QItem class="q-mt-xs"> <QItemSection top> From 787ce2fc48d28728fcc27aa1df73705d02508188 Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Mon, 14 Oct 2024 09:33:00 +0200 Subject: [PATCH 040/207] feat: refs #7006 itemTypeLog added --- src/pages/ItemType/Card/ItemTypeBasicData.vue | 1 + src/pages/ItemType/Card/ItemTypeLog.vue | 7 +++++++ src/pages/ItemType/locale/en.yml | 1 + src/pages/ItemType/locale/es.yml | 1 + src/router/modules/itemType.js | 11 ++++++++++- 5 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/pages/ItemType/Card/ItemTypeLog.vue diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/ItemType/Card/ItemTypeBasicData.vue index 51e24272d..deaf4a5fe 100644 --- a/src/pages/ItemType/Card/ItemTypeBasicData.vue +++ b/src/pages/ItemType/Card/ItemTypeBasicData.vue @@ -73,6 +73,7 @@ const temperaturesOptions = ref([]); option-label="name" hide-selected /> + <VnInput v-model="data.life" :label="t('shared.life')" /> </VnRow> </template> </FormModel> diff --git a/src/pages/ItemType/Card/ItemTypeLog.vue b/src/pages/ItemType/Card/ItemTypeLog.vue new file mode 100644 index 000000000..b3f7a6597 --- /dev/null +++ b/src/pages/ItemType/Card/ItemTypeLog.vue @@ -0,0 +1,7 @@ +<script setup> +import VnLog from 'src/components/common/VnLog.vue'; +</script> + +<template> + <VnLog model="ItemType" url="/ItemTypeLogs"></VnLog> +</template> diff --git a/src/pages/ItemType/locale/en.yml b/src/pages/ItemType/locale/en.yml index 7889418ea..4b203bd68 100644 --- a/src/pages/ItemType/locale/en.yml +++ b/src/pages/ItemType/locale/en.yml @@ -4,6 +4,7 @@ shared: worker: Worker category: Category temperature: Temperature + life: Life summary: id: id life: Life diff --git a/src/pages/ItemType/locale/es.yml b/src/pages/ItemType/locale/es.yml index 9a94dceb6..43699c332 100644 --- a/src/pages/ItemType/locale/es.yml +++ b/src/pages/ItemType/locale/es.yml @@ -4,6 +4,7 @@ shared: worker: Trabajador category: Reino temperature: Temperatura + life: Vida summary: id: id code: Código diff --git a/src/router/modules/itemType.js b/src/router/modules/itemType.js index 8064c41ff..0fd3797e6 100644 --- a/src/router/modules/itemType.js +++ b/src/router/modules/itemType.js @@ -12,7 +12,7 @@ export default { redirect: { name: 'ItemTypeList' }, menus: { main: [], - card: ['ItemTypeBasicData'], + card: ['ItemTypeBasicData', 'ItemTypeLog'], }, children: [ { @@ -40,6 +40,15 @@ export default { component: () => import('src/pages/ItemType/Card/ItemTypeBasicData.vue'), }, + { + path: 'log', + name: 'ItemTypeLog', + meta: { + title: 'log', + icon: 'vn:History', + }, + component: () => import('src/pages/ItemType/Card/ItemTypeLog.vue'), + }, ], }, ], From f2cb0111eb6a5ceb1232da91f5190b5610c2e81d Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 16 Oct 2024 14:45:33 +0200 Subject: [PATCH 041/207] fix: refs #7283 fix image --- src/pages/Item/ItemList.vue | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index ad2c2e238..6c7b7eaed 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -1,10 +1,9 @@ <script setup> -import { ref, computed, onUnmounted } from 'vue'; +import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter, useRoute } from 'vue-router'; import VnImg from 'src/components/ui/VnImg.vue'; import VnTable from 'components/VnTable/VnTable.vue'; -import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters'; import axios from 'axios'; import FetchedTags from 'src/components/ui/FetchedTags.vue'; @@ -16,7 +15,6 @@ const entityId = computed(() => route.params.id); const { viewSummary } = useSummaryDialog(); const router = useRouter(); -const stateStore = useStateStore(); const { t } = useI18n(); const tableRef = ref(); const route = useRoute(); @@ -53,8 +51,8 @@ const columns = computed(() => [ attrs: ({ row }) => { return { id: row?.id, - width: '50px', zoomResolution: '1600x900', + zoom: true, }; }, }, @@ -116,9 +114,13 @@ const columns = computed(() => [ }, { label: t('item.list.typeName'), - name: 'typeName', + name: 'typeFk', align: 'left', component: 'select', + attrs: { + url: 'ItemTypes', + fields: ['id', 'name'], + }, columnFilter: { name: 'typeFk', attrs: { @@ -152,6 +154,11 @@ const columns = computed(() => [ name: 'intrastat', align: 'left', component: 'select', + attrs: { + url: 'Intrastats', + optionValue: 'description', + optionLabel: 'description', + }, columnFilter: { name: 'description', attrs: { @@ -159,7 +166,6 @@ const columns = computed(() => [ optionValue: 'description', optionLabel: 'description', }, - inWhere: true, alias: 'intr', }, columnField: { @@ -172,6 +178,11 @@ const columns = computed(() => [ name: 'origin', align: 'left', component: 'select', + attrs: { + url: 'Origins', + optionValue: 'id', + optionLabel: 'code', + }, columnFilter: { name: 'id', attrs: { From 16ef5d372296ef2a5609ea319edb162c30337dc5 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 17 Oct 2024 08:30:45 +0200 Subject: [PATCH 042/207] fix: refs #7306 clean warning --- src/pages/Customer/Card/CustomerUnpaid.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/Customer/Card/CustomerUnpaid.vue b/src/pages/Customer/Card/CustomerUnpaid.vue index ad00cbf59..6fa5b7f01 100644 --- a/src/pages/Customer/Card/CustomerUnpaid.vue +++ b/src/pages/Customer/Card/CustomerUnpaid.vue @@ -2,10 +2,9 @@ import { computed, onBeforeMount, ref, watch, nextTick } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; - import VnInputDate from 'components/common/VnInputDate.vue'; import VnInput from 'src/components/common/VnInput.vue'; - +import VnRow from 'components/ui/VnRow.vue'; import axios from 'axios'; import useNotify from 'src/composables/useNotify'; import { useStateStore } from 'stores/useStateStore'; From 608e6c717ab6748238446eb8c06f700a09790a01 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 17 Oct 2024 09:34:48 +0200 Subject: [PATCH 043/207] fix: refs #7310 clean warning --- src/pages/Travel/Card/TravelThermographs.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue index 6d83581ee..e4a060889 100644 --- a/src/pages/Travel/Card/TravelThermographs.vue +++ b/src/pages/Travel/Card/TravelThermographs.vue @@ -19,7 +19,7 @@ const router = useRouter(); const { t } = useI18n(); const { notify } = useNotify(); -const thermographPaginateRef = ref(null); +const thermographPaginateRef = ref(); const warehouses = ref([]); const thermographFilter = { @@ -137,7 +137,6 @@ const removeThermograph = async (id) => { data-key="TravelThermographs" url="TravelThermographs" :filter="thermographFilter" - :params="{ travelFk: id }" auto-load > <template #body="{ rows }"> From 58e88f605c8f4138c835c13c671eec195e65b1bd Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Fri, 18 Oct 2024 08:04:52 +0200 Subject: [PATCH 044/207] refactor: refs #7132 delete duplicate translations' keys --- .../InvoiceIn/Card/InvoiceInDescriptor.vue | 6 +- src/pages/InvoiceIn/Card/InvoiceInSummary.vue | 10 +-- src/pages/InvoiceIn/InvoiceInCreate.vue | 2 +- src/pages/InvoiceIn/InvoiceInList.vue | 4 +- src/pages/InvoiceIn/locale/en.yml | 7 -- src/pages/InvoiceIn/locale/es.yml | 6 -- src/pages/InvoiceOut/locale/es.yml | 21 +++--- src/pages/Item/Card/CreateIntrastatForm.vue | 2 +- src/pages/Item/Card/ItemDiary.vue | 2 +- src/pages/Item/Card/ItemLastEntries.vue | 8 +-- src/pages/Item/Card/ItemTags.vue | 2 +- src/pages/Item/locale/en.yml | 7 -- src/pages/Item/locale/es.yml | 7 -- src/pages/ItemType/locale/es.yml | 5 -- src/pages/Monitor/MonitorOrders.vue | 4 +- src/pages/Monitor/Ticket/MonitorTickets.vue | 6 +- src/pages/Monitor/locale/en.yml | 5 -- src/pages/Monitor/locale/es.yml | 5 -- .../Card/BasicData/TicketBasicDataForm.vue | 18 ++--- src/pages/Ticket/Card/ExpeditionNewTicket.vue | 2 +- src/pages/Ticket/Card/TicketComponents.vue | 24 +++---- src/pages/Ticket/Card/TicketCreateRequest.vue | 9 +-- .../Ticket/Card/TicketCreateServiceType.vue | 2 +- .../Ticket/Card/TicketCreateTracking.vue | 4 +- src/pages/Ticket/Card/TicketExpedition.vue | 6 +- src/pages/Ticket/Card/TicketNotes.vue | 2 +- src/pages/Ticket/Card/TicketPackage.vue | 2 +- .../Ticket/Card/TicketPurchaseRequest.vue | 21 +++--- src/pages/Ticket/Card/TicketSale.vue | 16 ++--- src/pages/Ticket/Card/TicketSaleTracking.vue | 20 +++--- src/pages/Ticket/Card/TicketService.vue | 6 +- src/pages/Ticket/Card/TicketTracking.vue | 6 +- src/pages/Ticket/Card/TicketTransfer.vue | 14 ++-- src/pages/Ticket/Card/TicketVolume.vue | 6 +- src/pages/Ticket/TicketAdvance.vue | 2 +- src/pages/Ticket/TicketFuture.vue | 24 +++---- src/pages/Ticket/TicketWeekly.vue | 6 +- src/pages/Ticket/locale/en.yml | 65 ------------------- src/pages/Ticket/locale/es.yml | 64 ------------------ src/pages/Zone/Card/ZoneCreateWarehouse.vue | 2 +- src/pages/Zone/Card/ZoneDescriptor.vue | 10 +-- .../Zone/Card/ZoneEventExclusionForm.vue | 4 +- .../Zone/Card/ZoneEventInclusionForm.vue | 16 ++--- src/pages/Zone/Card/ZoneEventsPanel.vue | 14 ++-- src/pages/Zone/Card/ZoneLocations.vue | 2 +- src/pages/Zone/Card/ZoneSummary.vue | 14 ++-- src/pages/Zone/Card/ZoneWarehouses.vue | 6 +- src/pages/Zone/ZoneClosingTable.vue | 12 ++-- src/pages/Zone/ZoneCreate.vue | 14 ++-- src/pages/Zone/ZoneDeliveryPanel.vue | 4 +- src/pages/Zone/ZoneFilterPanel.vue | 6 +- src/pages/Zone/ZoneList.vue | 4 +- src/pages/Zone/ZoneUpcoming.vue | 4 +- src/pages/Zone/locale/en.yml | 50 ++------------ src/pages/Zone/locale/es.yml | 53 ++------------- 55 files changed, 189 insertions(+), 454 deletions(-) diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue index 9bc4856a8..92f3fffca 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue @@ -355,10 +355,10 @@ const createInvoiceInCorrection = async () => { </QItem> </template> <template #body="{ entity }"> - <VnLv :label="t('invoiceIn.card.issued')" :value="toDate(entity.issued)" /> + <VnLv :label="t('invoiceIn.list.issued')" :value="toDate(entity.issued)" /> <VnLv :label="t('invoiceIn.summary.booked')" :value="toDate(entity.booked)" /> - <VnLv :label="t('invoiceIn.card.amount')" :value="toCurrency(totalAmount)" /> - <VnLv :label="t('invoiceIn.summary.supplier')"> + <VnLv :label="t('invoiceIn.list.amount')" :value="toCurrency(totalAmount)" /> + <VnLv :label="t('invoiceIn.list.supplier')"> <template #value> <span class="link"> {{ entity?.supplier?.nickname }} diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue index 801a04342..08fc11f69 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue @@ -95,7 +95,7 @@ const dueDayColumns = ref([ }, { name: 'amount', - label: 'invoiceIn.summary.amount', + label: 'invoiceIn.list.amount', field: (row) => row.amount, format: (value) => toCurrency(value), sortable: true, @@ -123,7 +123,7 @@ const intrastatColumns = ref([ }, { name: 'amount', - label: 'invoiceIn.summary.amount', + label: 'invoiceIn.list.amount', field: (row) => toCurrency(row.amount), sortable: true, align: 'left', @@ -210,7 +210,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; /> </QCardSection> <VnLv - :label="t('invoiceIn.summary.supplier')" + :label="t('invoiceIn.list.supplier')" :value="entity.supplier?.name" > <template #value> @@ -221,7 +221,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; </template> </VnLv> <VnLv - :label="t('invoiceIn.summary.supplierRef')" + :label="t('invoiceIn.list.supplierRef')" :value="entity.supplierRef" /> <VnLv @@ -271,7 +271,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; :value="entity.expenseDeductible?.name" /> <VnLv - :label="t('invoiceIn.summary.company')" + :label="t('invoiceIn.card.company')" :value="entity.company?.code" /> <VnLv :label="t('invoiceIn.isBooked')" :value="invoiceIn?.isBooked" /> diff --git a/src/pages/InvoiceIn/InvoiceInCreate.vue b/src/pages/InvoiceIn/InvoiceInCreate.vue index e6863beb1..c809e032b 100644 --- a/src/pages/InvoiceIn/InvoiceInCreate.vue +++ b/src/pages/InvoiceIn/InvoiceInCreate.vue @@ -83,7 +83,7 @@ const redirectToInvoiceInBasicData = (__, { id }) => { </template> </VnSelect> <VnInput - :label="t('invoiceIn.summary.supplierRef')" + :label="t('invoiceIn.list.supplierRef')" v-model="data.supplierRef" /> </VnRow> diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue index 265f95b0e..d64876858 100644 --- a/src/pages/InvoiceIn/InvoiceInList.vue +++ b/src/pages/InvoiceIn/InvoiceInList.vue @@ -50,7 +50,7 @@ const cols = computed(() => [ { align: 'left', name: 'serial', - label: t('invoiceIn.list.serial'), + label: t('invoiceIn.serial'), }, { align: 'left', @@ -151,7 +151,7 @@ const cols = computed(() => [ </template> </VnSelect> <VnInput - :label="t('invoiceIn.summary.supplierRef')" + :label="t('invoiceIn.list.supplierRef')" v-model="data.supplierRef" /> <VnSelect diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml index b09340c81..b39511f29 100644 --- a/src/pages/InvoiceIn/locale/en.yml +++ b/src/pages/InvoiceIn/locale/en.yml @@ -5,14 +5,11 @@ invoiceIn: ref: Reference supplier: Supplier supplierRef: Supplier ref. - serial: Serial file: File issued: Issued awb: AWB amount: Amount card: - issued: Issued - amount: Amount client: Client company: Company customerCard: Customer card @@ -21,8 +18,6 @@ invoiceIn: dueDay: Due day intrastat: Intrastat summary: - supplier: Supplier - supplierRef: Supplier ref. currency: Currency issued: Expedition date operated: Operation date @@ -30,7 +25,6 @@ invoiceIn: bookedDate: Booked date sage: Sage withholding vat: Undeductible VAT - company: Company expense: Expense taxableBase: Taxable base rate: Rate @@ -38,7 +32,6 @@ invoiceIn: sageTransaction: Sage transaction dueDay: Date bank: Bank - amount: Amount foreignValue: Foreign value dueTotal: Due day noMatch: Do not match diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml index 31d41fc97..5f483dd08 100644 --- a/src/pages/InvoiceIn/locale/es.yml +++ b/src/pages/InvoiceIn/locale/es.yml @@ -11,8 +11,6 @@ invoiceIn: awb: AWB amount: Importe card: - issued: Fecha emisión - amount: Importe client: Cliente company: Empresa customerCard: Ficha del cliente @@ -20,8 +18,6 @@ invoiceIn: vat: Iva dueDay: Fecha de vencimiento summary: - supplier: Proveedor - supplierRef: Ref. proveedor currency: Divisa docNumber: Número documento issued: Fecha de expedición @@ -30,14 +26,12 @@ invoiceIn: bookedDate: Fecha contable sage: Retención sage vat: Iva no deducible - company: Empresa expense: Gasto taxableBase: Base imp. rate: Tasa sageTransaction: Sage transación dueDay: Fecha bank: Caja - amount: Importe foreignValue: Divisa dueTotal: Vencimiento code: Código diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml index a05125630..192f5b26f 100644 --- a/src/pages/InvoiceOut/locale/es.yml +++ b/src/pages/InvoiceOut/locale/es.yml @@ -9,9 +9,6 @@ invoiceOutList: id: ID ref: Referencia issued: Fecha emisión - customer: Cliente - company: Empresa - amount: Importe created: F. creación dueDate: F. máxima invoiceOutSerial: Serial @@ -20,12 +17,12 @@ invoiceOutList: DownloadPdf: Descargar PDF InvoiceOutSummary: Resumen negativeBases: - country: País - clientId: ID del cliente - client: Cliente - base: Base - ticketId: Ticket - active: Activo - hasToInvoice: Debe facturar - verifiedData: Datos verificados - commercial: Comercial \ No newline at end of file + country: País + clientId: ID del cliente + client: Cliente + base: Base + ticketId: Ticket + active: Activo + hasToInvoice: Debe facturar + verifiedData: Datos verificados + commercial: Comercial diff --git a/src/pages/Item/Card/CreateIntrastatForm.vue b/src/pages/Item/Card/CreateIntrastatForm.vue index 5fe254759..443615d7e 100644 --- a/src/pages/Item/Card/CreateIntrastatForm.vue +++ b/src/pages/Item/Card/CreateIntrastatForm.vue @@ -42,7 +42,7 @@ onMounted(async () => { :required="true" /> <VnInput - :label="t('createIntrastatForm.description')" + :label="t('itemBasicData.description')" v-model="data.description" :required="true" /> diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue index 68633caa2..a59bfa367 100644 --- a/src/pages/Item/Card/ItemDiary.vue +++ b/src/pages/Item/Card/ItemDiary.vue @@ -62,7 +62,7 @@ const columns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('itemDiary.reference'), + label: t('itemBasicData.reference'), field: 'reference', name: 'reference', align: 'left', diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue index b211790ca..5c0251ea8 100644 --- a/src/pages/Item/Card/ItemLastEntries.vue +++ b/src/pages/Item/Card/ItemLastEntries.vue @@ -59,7 +59,7 @@ const columns = computed(() => [ align: 'center', }, { - label: t('lastEntries.warehouse'), + label: t('itemDiary.warehouse'), name: 'warehouse', field: 'warehouse', align: 'left', @@ -94,7 +94,7 @@ const columns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('lastEntries.packing'), + label: t('shelvings.packing'), name: 'packing', align: 'center', }, @@ -104,7 +104,7 @@ const columns = computed(() => [ align: 'center', }, { - label: t('lastEntries.stems'), + label: t('itemBasicData.stems'), name: 'stems', field: 'stems', align: 'center', @@ -188,7 +188,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); <VnSubToolbar> <template #st-data> <VnInputDate - :label="t('lastEntries.since')" + :label="t('itemDiary.since')" dense v-model="from" class="q-mr-lg" diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue index 6f31d0cf8..de34cb9fe 100644 --- a/src/pages/Item/Card/ItemTags.vue +++ b/src/pages/Item/Card/ItemTags.vue @@ -147,7 +147,7 @@ const insertTag = (rows) => { :is-clearable="false" /> <VnInput - :label="t('itemTags.relevancy')" + :label="t('itemBasicData.relevancy')" type="number" v-model="row.priority" :required="true" diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index c32ee493c..647a01810 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -16,7 +16,6 @@ itemDiary: date: Date origin: Origin state: State - reference: Reference entity: Entity in: In out: Out @@ -48,22 +47,17 @@ itemBasicData: createIntrastatForm: title: New intrastat identifier: Identifier - description: Description tax: country: Country class: Class lastEntries: - since: Since to: To ig: Ig - warehouse: Warehouse landed: Landed entry: Entry pvp: PVP label: Label - packing: Packing grouping: Grouping - stems: Stems quantity: Quantity cost: Cost kg: Kg. @@ -77,7 +71,6 @@ itemTags: addTag: Add tag tag: Tag value: Value - relevancy: Relevancy searchbar: label: Search item info: Search by item id diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index d32cb7885..80eab8f26 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -16,7 +16,6 @@ itemDiary: date: Fecha origin: Origen state: Estado - reference: Referencia entity: Entidad in: Entrada out: Salida @@ -48,22 +47,17 @@ itemBasicData: createIntrastatForm: title: Nuevo intrastat identifier: Identificador - description: Descripción tax: country: País class: Clase lastEntries: - since: Desde to: Hasta ig: Ig - warehouse: Almacén landed: F. Entrega entry: Entrada pvp: PVP label: Etiquetas - packing: Packing grouping: Grouping - stems: Tallos quantity: Cantidad cost: Coste kg: Kg. @@ -77,7 +71,6 @@ itemTags: addTag: Añadir etiqueta tag: Etiqueta value: Valor - relevancy: Relevancia searchbar: label: Buscar artículo info: Buscar por id de artículo diff --git a/src/pages/ItemType/locale/es.yml b/src/pages/ItemType/locale/es.yml index 9a94dceb6..5a32d09a5 100644 --- a/src/pages/ItemType/locale/es.yml +++ b/src/pages/ItemType/locale/es.yml @@ -6,11 +6,6 @@ shared: temperature: Temperatura summary: id: id - code: Código - name: Nombre - worker: Trabajador - category: Reino - temperature: Temperatura life: Vida promo: Promoción itemPackingType: Tipo de embalaje diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue index fac601735..326fae0ee 100644 --- a/src/pages/Monitor/MonitorOrders.vue +++ b/src/pages/Monitor/MonitorOrders.vue @@ -44,7 +44,7 @@ const columns = computed(() => [ format: (row) => toDateTimeFormat(row.date_make), }, { - label: t('salesOrdersTable.client'), + label: t('salesClientsTable.client'), name: 'clientFk', align: 'left', columnFilter: { @@ -63,7 +63,7 @@ const columns = computed(() => [ columnFilter: false, }, { - label: t('salesOrdersTable.salesPerson'), + label: t('salesClientsTable.salesPerson'), name: 'salesPersonFk', align: 'left', optionFilter: 'firstName', diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue index d24230c64..406bf5f29 100644 --- a/src/pages/Monitor/Ticket/MonitorTickets.vue +++ b/src/pages/Monitor/Ticket/MonitorTickets.vue @@ -77,7 +77,7 @@ const columns = computed(() => [ }, }, { - label: t('salesTicketsTable.client'), + label: t('salesClientsTable.client'), name: 'clientFk', align: 'left', field: 'nickname', @@ -91,7 +91,7 @@ const columns = computed(() => [ }, }, { - label: t('salesTicketsTable.salesPerson'), + label: t('salesClientsTable.salesPerson'), name: 'salesPersonFk', field: 'userName', align: 'left', @@ -108,7 +108,7 @@ const columns = computed(() => [ }, }, { - label: t('salesTicketsTable.date'), + label: t('salesClientsTable.date'), name: 'shippedDate', align: 'left', columnFilter: { diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml index b8082f02a..2f839e5f5 100644 --- a/src/pages/Monitor/locale/en.yml +++ b/src/pages/Monitor/locale/en.yml @@ -13,8 +13,6 @@ salesOrdersTable: delete: Delete dateSend: Send date dateMake: Make date - client: Client - salesPerson: Salesperson deleteConfirmMessage: All the selected elements will be deleted. Are you sure you want to continue? agency: Agency import: Import @@ -29,9 +27,6 @@ salesTicketsTable: componentLack: Component lack tooLittle: Ticket too little identifier: Identifier - client: Client - salesPerson: Salesperson - date: Date theoretical: Theoretical practical: Practical province: Province diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml index 4ee5b90a9..5b7f4f551 100644 --- a/src/pages/Monitor/locale/es.yml +++ b/src/pages/Monitor/locale/es.yml @@ -13,8 +13,6 @@ salesOrdersTable: delete: Eliminar dateSend: Fecha de envío dateMake: Fecha de realización - client: Cliente - salesPerson: Comercial deleteConfirmMessage: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar? agency: Agencia import: Importe @@ -29,9 +27,6 @@ salesTicketsTable: componentLack: Faltan componentes tooLittle: Ticket demasiado pequeño identifier: Identificador - client: Cliente - salesPerson: Comercial - date: Fecha theoretical: Teórica practical: Práctica province: Provincia diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue index fdc75abda..90c579c4c 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue @@ -297,7 +297,7 @@ onMounted(() => onFormModelInit()); <QForm> <VnRow> <VnSelect - :label="t('basicData.client')" + :label="t('ticketList.client')" v-model="clientId" option-value="id" option-label="name" @@ -320,7 +320,7 @@ onMounted(() => onFormModelInit()); </template> </VnSelect> <VnSelect - :label="t('basicData.warehouse')" + :label="t('ticketList.warehouse')" v-model="warehouseId" option-value="id" option-label="name" @@ -328,7 +328,7 @@ onMounted(() => onFormModelInit()); hide-selected map-options :required="true" - :rules="validate('basicData.warehouse')" + :rules="validate('ticketList.warehouse')" /> </VnRow> <VnRow> @@ -394,7 +394,7 @@ onMounted(() => onFormModelInit()); </VnRow> <VnRow class="row q-gutter-md q-mb-md no-wrap"> <VnSelect - :label="t('basicData.company')" + :label="t('ticketList.company')" v-model="formData.companyFk" option-value="id" option-label="code" @@ -402,7 +402,7 @@ onMounted(() => onFormModelInit()); hide-selected map-options :required="true" - :rules="validate('basicData.company')" + :rules="validate('ticketList.company')" /> <VnSelect :label="t('basicData.agency')" @@ -416,7 +416,7 @@ onMounted(() => onFormModelInit()); :rules="validate('basicData.agency')" /> <VnSelect - :label="t('basicData.zone')" + :label="t('ticketList.zone')" v-model="zoneId" option-value="id" option-label="name" @@ -428,7 +428,7 @@ onMounted(() => onFormModelInit()); map-options :required="true" @focus="zonesFetchRef.fetch()" - :rules="validate('basicData.zone')" + :rules="validate('ticketList.zone')" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -445,10 +445,10 @@ onMounted(() => onFormModelInit()); </VnRow> <VnRow> <VnInputDate - :label="t('basicData.shipped')" + :label="t('ticketList.shipped')" v-model="formData.shipped" :required="true" - :rules="validate('basicData.shipped')" + :rules="validate('ticketList.shipped')" /> <VnInputTime :label="t('basicData.shippedHour')" diff --git a/src/pages/Ticket/Card/ExpeditionNewTicket.vue b/src/pages/Ticket/Card/ExpeditionNewTicket.vue index 9183ae405..4a6ca966d 100644 --- a/src/pages/Ticket/Card/ExpeditionNewTicket.vue +++ b/src/pages/Ticket/Card/ExpeditionNewTicket.vue @@ -66,7 +66,7 @@ const createTicket = async () => { <template #form-inputs="{ data }"> <VnRow> <VnInputDate - :label="t('expedition.landed')" + :label="t('basicData.landed')" v-model="data.landed" :model-value="date" /> diff --git a/src/pages/Ticket/Card/TicketComponents.vue b/src/pages/Ticket/Card/TicketComponents.vue index 0bccdaacd..a9573443b 100644 --- a/src/pages/Ticket/Card/TicketComponents.vue +++ b/src/pages/Ticket/Card/TicketComponents.vue @@ -72,7 +72,7 @@ const salesFilter = computed(() => ({ const columns = computed(() => [ { - label: t('ticketComponents.item'), + label: t('basicData.item'), name: 'item', align: 'left', }, @@ -92,13 +92,13 @@ const columns = computed(() => [ columnFilter: false, }, { - label: t('ticketComponents.description'), + label: t('basicData.description'), name: 'description', align: 'left', columnClass: 'expand', }, { - label: t('ticketComponents.quantity'), + label: t('basicData.quantity'), name: 'quantity', field: 'quantity', align: 'left', @@ -116,12 +116,12 @@ const columns = computed(() => [ align: 'left', }, { - label: t('ticketComponents.import'), + label: t('advanceTickets.import'), name: 'import', align: 'left', }, { - label: t('ticketComponents.total'), + label: t('basicData.total'), name: 'total', align: 'left', }, @@ -196,7 +196,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); <QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black"> <QCardSection horizontal> <span class="text-weight-bold text-subtitle1 text-center full-width"> - {{ t('ticketComponents.total') }} + {{ t('basicData.total') }} </span> </QCardSection> <QCardSection horizontal> @@ -238,9 +238,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </span> </QCardSection> <QCardSection horizontal> - <span class="q-mr-xs color-vn-label"> - {{ t('ticketComponents.price') }}: - </span> + <span class="q-mr-xs color-vn-label"> {{ t('basicData.price') }}: </span> <span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span> </QCardSection> <QCardSection horizontal> @@ -250,18 +248,14 @@ onUnmounted(() => (stateStore.rightDrawer = false)); <span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span> </QCardSection> <QCardSection horizontal> - <span class="q-mr-xs color-vn-label"> - {{ t('ticketComponents.zone') }}: - </span> + <span class="q-mr-xs color-vn-label"> {{ t('ticketList.zone') }}: </span> <span class="link"> {{ dashIfEmpty(ticketData?.zone?.name) }} <ZoneDescriptorProxy :id="ticketData?.zone?.id" /> </span> </QCardSection> <QCardSection v-if="ticketData?.zone?.isVolumetric" horizontal> - <span class="q-mr-xs color-vn-label"> - {{ t('ticketComponents.volume') }}: - </span> + <span class="q-mr-xs color-vn-label"> {{ t('volume.volume') }}: </span> <span>{{ ticketVolume }}</span> </QCardSection> <QCardSection horizontal> diff --git a/src/pages/Ticket/Card/TicketCreateRequest.vue b/src/pages/Ticket/Card/TicketCreateRequest.vue index ffe009516..539780a6a 100644 --- a/src/pages/Ticket/Card/TicketCreateRequest.vue +++ b/src/pages/Ticket/Card/TicketCreateRequest.vue @@ -32,10 +32,7 @@ const attendersOptions = ref([]); > <template #form-inputs="{ data }"> <VnRow> - <VnInput - v-model="data.description" - :label="t('purchaseRequest.description')" - /> + <VnInput v-model="data.description" :label="t('basicData.description')" /> <VnSelect :label="t('purchaseRequest.atender')" v-model="data.attenderFk" @@ -48,13 +45,13 @@ const attendersOptions = ref([]); <VnRow> <VnInput v-model="data.quantity" - :label="t('purchaseRequest.quantity')" + :label="t('basicData.quantity')" type="number" min="1" /> <VnInput v-model="data.price" - :label="t('purchaseRequest.price')" + :label="t('basicData.price')" type="number" min="0" /> diff --git a/src/pages/Ticket/Card/TicketCreateServiceType.vue b/src/pages/Ticket/Card/TicketCreateServiceType.vue index 067d7dee8..2f5857e86 100644 --- a/src/pages/Ticket/Card/TicketCreateServiceType.vue +++ b/src/pages/Ticket/Card/TicketCreateServiceType.vue @@ -34,7 +34,7 @@ onMounted(async () => { <VnRow> <VnInput ref="nameInputRef" - :label="t('service.description')" + :label="t('basicData.description')" v-model="data.name" :required="true" /> diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue index d692f550d..3ea762c6c 100644 --- a/src/pages/Ticket/Card/TicketCreateTracking.vue +++ b/src/pages/Ticket/Card/TicketCreateTracking.vue @@ -39,7 +39,7 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id); <VnRow> <VnSelect v-model="data.stateFk" - :label="t('tracking.state')" + :label="t('ticketList.state')" :options="statesOptions" @update:model-value="onStateFkChange(data)" hide-selected @@ -47,7 +47,7 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id); option-value="id" /> <VnSelect - :label="t('tracking.worker')" + :label="t('expedition.worker')" v-model="data.userFk" url="Workers/search" fields=" ['id', 'name']" diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue index 4becb3db3..fc408272d 100644 --- a/src/pages/Ticket/Card/TicketExpedition.vue +++ b/src/pages/Ticket/Card/TicketExpedition.vue @@ -81,7 +81,7 @@ const columns = computed(() => [ }, }, { - label: t('expedition.item'), + label: t('basicData.item'), name: 'packagingItemFk', align: 'left', cardVisible: true, @@ -131,7 +131,7 @@ const columns = computed(() => [ format: (row) => toDateTimeFormat(row.created), }, { - label: t('expedition.state'), + label: t('ticketList.state'), name: 'state', align: 'left', cardVisible: true, @@ -153,7 +153,7 @@ const columns = computed(() => [ const logTableColumns = computed(() => [ { - label: t('expedition.state'), + label: t('ticketList.state'), name: 'state', field: 'state', align: 'center', diff --git a/src/pages/Ticket/Card/TicketNotes.vue b/src/pages/Ticket/Card/TicketNotes.vue index b5302d15f..12f7ba2c6 100644 --- a/src/pages/Ticket/Card/TicketNotes.vue +++ b/src/pages/Ticket/Card/TicketNotes.vue @@ -88,7 +88,7 @@ async function handleSave() { :disable="!!row.id" /> <VnInput - :label="t('ticketNotes.description')" + :label="t('basicData.description')" v-model="row.description" class="col" @keyup.enter="handleSave" diff --git a/src/pages/Ticket/Card/TicketPackage.vue b/src/pages/Ticket/Card/TicketPackage.vue index c0418bcf6..04d6020f3 100644 --- a/src/pages/Ticket/Card/TicketPackage.vue +++ b/src/pages/Ticket/Card/TicketPackage.vue @@ -93,7 +93,7 @@ watch( </template> </VnSelect> <VnInput - :label="t('package.quantity')" + :label="t('basicData.quantity')" v-model.number="row.quantity" class="col" type="number" diff --git a/src/pages/Ticket/Card/TicketPurchaseRequest.vue b/src/pages/Ticket/Card/TicketPurchaseRequest.vue index d0af9efd0..7715e9e21 100644 --- a/src/pages/Ticket/Card/TicketPurchaseRequest.vue +++ b/src/pages/Ticket/Card/TicketPurchaseRequest.vue @@ -81,7 +81,7 @@ const crudModelFilter = reactive({ const columns = computed(() => [ { align: 'left', - label: t('purchaseRequest.id'), + label: t('ticketList.id'), name: 'id', chip: { condition: () => true, @@ -90,13 +90,13 @@ const columns = computed(() => [ }, { align: 'left', - label: t('purchaseRequest.description'), + label: t('basicData.description'), name: 'description', columnClass: 'expand', }, { align: 'left', - label: t('purchaseRequest.created'), + label: t('expedition.created'), name: 'created', format: (row) => toDateFormat(row.created), cardVisible: true, @@ -117,12 +117,12 @@ const columns = computed(() => [ }, { align: 'left', - label: t('purchaseRequest.quantity'), + label: t('basicData.quantity'), name: 'quantity', }, { align: 'left', - label: t('purchaseRequest.price'), + label: t('basicData.price'), name: 'price', }, { @@ -133,7 +133,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('purchaseRequest.state'), + label: t('ticketList.state'), name: 'isOk', cardVisible: true, }, @@ -248,10 +248,7 @@ onMounted(() => (stateStore.rightDrawer = false)); </template> <template #more-create-dialog="{ data }"> - <VnInput - v-model="data.description" - :label="t('purchaseRequest.description')" - /> + <VnInput v-model="data.description" :label="t('basicData.description')" /> <VnSelect :label="t('purchaseRequest.atender')" v-model="data.attenderFk" @@ -262,13 +259,13 @@ onMounted(() => (stateStore.rightDrawer = false)); /> <VnInput v-model="data.quantity" - :label="t('purchaseRequest.quantity')" + :label="t('basicData.quantity')" type="number" min="1" /> <VnInput v-model="data.price" - :label="t('purchaseRequest.price')" + :label="t('basicData.price')" type="number" min="0" /> diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue index 43af8d528..d49007e9d 100644 --- a/src/pages/Ticket/Card/TicketSale.vue +++ b/src/pages/Ticket/Card/TicketSale.vue @@ -90,25 +90,25 @@ const columns = computed(() => [ }, { align: 'left', - label: t('ticketSale.id'), + label: t('ticketList.id'), name: 'itemFk', }, { align: 'left', - label: t('ticketSale.quantity'), + label: t('basicData.quantity'), name: 'quantity', format: (row) => toCurrency(row.quantity), }, { align: 'left', - label: t('ticketSale.item'), + label: t('basicData.item'), name: 'item', format: (row) => row?.item?.name, columnClass: 'expand', }, { align: 'left', - label: t('ticketSale.price'), + label: t('basicData.price'), name: 'price', format: (row) => toCurrency(row.price), }, @@ -120,7 +120,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('ticketSale.amount'), + label: t('ticketList.amount'), name: 'amount', format: (row) => parseInt(row.amount * row.quantity), }, @@ -516,7 +516,7 @@ watch( <QBtnDropdown ref="stateBtnDropdownRef" color="primary" - :label="t('ticketSale.state')" + :label="t('ticketList.state')" :disable="!isTicketEditable" > <VnSelect @@ -587,7 +587,7 @@ watch( }}</span> </QCardSection> <QCardSection class="justify-end text-weight-bold text-subtitle1" horizontal> - <span class="q-mr-xs color-vn-label"> {{ t('ticketSale.total') }}: </span> + <span class="q-mr-xs color-vn-label"> {{ t('basicData.total') }}: </span> <span>{{ toCurrency(store.data?.totalWithVat) }}</span> </QCardSection> </div></QDrawer @@ -753,7 +753,7 @@ watch( > <VnInput v-model.number="edit.price" - :label="t('ticketSale.price')" + :label="t('basicData.price')" type="number" /> </TicketEditManaProxy> diff --git a/src/pages/Ticket/Card/TicketSaleTracking.vue b/src/pages/Ticket/Card/TicketSaleTracking.vue index e7830bf37..4d1b82bec 100644 --- a/src/pages/Ticket/Card/TicketSaleTracking.vue +++ b/src/pages/Ticket/Card/TicketSaleTracking.vue @@ -42,19 +42,19 @@ const columns = computed(() => [ sortable: true, }, { - label: t('ticketSaleTracking.item'), + label: t('basicData.item'), name: 'item', align: 'left', sortable: true, }, { - label: t('ticketSaleTracking.description'), + label: t('basicData.description'), name: 'description', align: 'left', sortable: true, }, { - label: t('ticketSaleTracking.quantity'), + label: t('basicData.quantity'), name: 'quantity', field: 'quantity', align: 'left', @@ -78,7 +78,7 @@ const columns = computed(() => [ const logTableColumns = computed(() => [ { - label: t('ticketSaleTracking.quantity'), + label: t('basicData.quantity'), name: 'quantity', field: 'quantity', align: 'left', @@ -92,20 +92,20 @@ const logTableColumns = computed(() => [ sortable: true, }, { - label: t('ticketSaleTracking.worker'), + label: t('expedition.worker'), name: 'worker', align: 'left', sortable: true, }, { - label: t('ticketSaleTracking.state'), + label: t('ticketList.state'), name: 'state', field: 'state', align: 'left', sortable: true, }, { - label: t('ticketSaleTracking.created'), + label: t('expedition.created'), name: 'created', field: 'created', align: 'left', @@ -116,13 +116,13 @@ const logTableColumns = computed(() => [ const shelvingsTableColumns = computed(() => [ { - label: t('ticketSaleTracking.quantity'), + label: t('basicData.quantity'), name: 'quantity', align: 'left', sortable: true, }, { - label: t('ticketSaleTracking.worker'), + label: t('expedition.worker'), name: 'worker', align: 'left', sortable: true, @@ -140,7 +140,7 @@ const shelvingsTableColumns = computed(() => [ sortable: true, }, { - label: t('ticketSaleTracking.created'), + label: t('expedition.created'), name: 'created', field: 'created', align: 'left', diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue index 45a870f7f..285890e08 100644 --- a/src/pages/Ticket/Card/TicketService.vue +++ b/src/pages/Ticket/Card/TicketService.vue @@ -85,21 +85,21 @@ const getDefaultTaxClass = async () => { const columns = computed(() => [ { name: 'description', - label: t('service.description'), + label: t('basicData.description'), field: (row) => row.ticketServiceTypeFk, sortable: true, align: 'left', }, { name: 'quantity', - label: t('service.quantity'), + label: t('basicData.quantity'), field: (row) => row.quantity, sortable: true, align: 'left', }, { name: 'price', - label: t('service.price'), + label: t('basicData.price'), field: (row) => row.price, sortable: true, align: 'left', diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue index 00b517765..f5ed03b0d 100644 --- a/src/pages/Ticket/Card/TicketTracking.vue +++ b/src/pages/Ticket/Card/TicketTracking.vue @@ -52,19 +52,19 @@ const paginateFilter = reactive({ const columns = computed(() => [ { - label: t('tracking.state'), + label: t('ticketList.state'), name: 'state', field: 'state', align: 'left', format: (val) => val.name, }, { - label: t('tracking.worker'), + label: t('expedition.worker'), name: 'worker', align: 'left', }, { - label: t('tracking.created'), + label: t('expedition.created'), name: 'created', field: 'created', align: 'left', diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue index e1a011a84..d7aff3ef7 100644 --- a/src/pages/Ticket/Card/TicketTransfer.vue +++ b/src/pages/Ticket/Card/TicketTransfer.vue @@ -33,19 +33,19 @@ const _transfer = ref(); const transferLinesColumns = computed(() => [ { - label: t('ticketSale.id'), + label: t('ticketList.id'), name: 'itemFk', field: 'itemFk', align: 'left', }, { - label: t('ticketSale.item'), + label: t('basicData.item'), name: 'item', field: 'concept', align: 'left', }, { - label: t('ticketSale.quantity'), + label: t('basicData.quantity'), name: 'quantity', field: 'quantity', align: 'left', @@ -54,26 +54,26 @@ const transferLinesColumns = computed(() => [ const destinationTicketColumns = computed(() => [ { - label: t('ticketSale.id'), + label: t('ticketList.id'), name: 'id', field: 'id', align: 'left', }, { - label: t('ticketSale.shipped'), + label: t('ticketList.shipped'), name: 'item', field: 'shipped', align: 'left', format: (val) => toDateFormat(val), }, { - label: t('ticketSale.agency'), + label: t('basicData.agency'), name: 'agency', field: 'agencyName', align: 'left', }, { - label: t('ticketSale.address'), + label: t('basicData.address'), name: 'address', field: 'address', align: 'left', diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue index 2cf7ffc42..15b79dad7 100644 --- a/src/pages/Ticket/Card/TicketVolume.vue +++ b/src/pages/Ticket/Card/TicketVolume.vue @@ -39,7 +39,7 @@ const packingTypeVolume = ref([]); const columns = computed(() => [ { align: 'left', - label: t('volume.item'), + label: t('basicData.item'), name: 'itemFk', chip: { condition: () => true, @@ -48,7 +48,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('volume.description'), + label: t('basicData.description'), name: 'concept', columnClass: 'expand', cardVisible: true, @@ -62,7 +62,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('volume.quantity'), + label: t('basicData.quantity'), name: 'quantity', cardVisible: true, }, diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue index 43b500dc0..1fc45f713 100644 --- a/src/pages/Ticket/TicketAdvance.vue +++ b/src/pages/Ticket/TicketAdvance.vue @@ -127,7 +127,7 @@ const ticketColumns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('advanceTickets.state'), + label: t('ticketList.state'), name: 'state', align: 'left', sortable: true, diff --git a/src/pages/Ticket/TicketFuture.vue b/src/pages/Ticket/TicketFuture.vue index 2078d0595..35c0f6eb2 100644 --- a/src/pages/Ticket/TicketFuture.vue +++ b/src/pages/Ticket/TicketFuture.vue @@ -95,7 +95,7 @@ const ticketColumns = computed(() => [ columnFilter: null, }, { - label: t('futureTickets.ticketId'), + label: t('advanceTickets.ticketId'), name: 'ticketId', align: 'center', sortable: true, @@ -118,7 +118,7 @@ const ticketColumns = computed(() => [ columnFilter: null, }, { - label: t('futureTickets.ipt'), + label: t('advanceTickets.ipt'), name: 'ipt', field: 'ipt', align: 'left', @@ -139,14 +139,14 @@ const ticketColumns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('futureTickets.state'), + label: t('ticketList.state'), name: 'state', align: 'left', sortable: true, columnFilter: null, }, { - label: t('futureTickets.liters'), + label: t('advanceTickets.liters'), name: 'liters', field: 'liters', align: 'left', @@ -162,7 +162,7 @@ const ticketColumns = computed(() => [ }, }, { - label: t('futureTickets.import'), + label: t('advanceTickets.import'), field: 'import', name: 'import', align: 'left', @@ -186,7 +186,7 @@ const ticketColumns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('futureTickets.futureId'), + label: t('advanceTickets.futureId'), name: 'futureId', align: 'left', sortable: true, @@ -211,7 +211,7 @@ const ticketColumns = computed(() => [ }, { - label: t('futureTickets.futureIpt'), + label: t('advanceTickets.futureIpt'), name: 'futureIpt', field: 'futureIpt', align: 'left', @@ -232,7 +232,7 @@ const ticketColumns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('futureTickets.futureState'), + label: t('advanceTickets.futureState'), name: 'futureState', align: 'right', sortable: true, @@ -259,7 +259,7 @@ const moveTicketsFuture = async () => { let params = { tickets: ticketsToMove }; await axios.post('Tickets/merge', params); - notify(t('futureTickets.moveTicketSuccess'), 'positive'); + notify(t('advanceTickets.moveTicketSuccess'), 'positive'); selectedTickets.value = []; arrayData.fetch({ append: false }); } catch (error) { @@ -333,14 +333,14 @@ onMounted(async () => { colspan="8" translate > - {{ t('futureTickets.origin') }} + {{ t('advanceTickets.origin') }} </QTh> <QTh class="horizontal-separator text-uppercase color-vn-label" colspan="4" translate > - {{ t('futureTickets.destination') }} + {{ t('advanceTickets.destination') }} </QTh> </QTr> <QTr> @@ -409,7 +409,7 @@ onMounted(async () => { size="xs" > <QTooltip> - {{ t('futureTickets.noVisible') }} + {{ t('ticketSale.noVisible') }} </QTooltip> </QIcon> <QIcon diff --git a/src/pages/Ticket/TicketWeekly.vue b/src/pages/Ticket/TicketWeekly.vue index d68d18c24..05477d2fb 100644 --- a/src/pages/Ticket/TicketWeekly.vue +++ b/src/pages/Ticket/TicketWeekly.vue @@ -47,7 +47,7 @@ const columns = computed(() => [ { align: 'left', name: 'clientFk', - label: t('weeklyTickets.client'), + label: t('ticketList.client'), isTitle: true, cardVisible: true, component: 'select', @@ -79,7 +79,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('weeklyTickets.agency'), + label: t('basicData.agency'), name: 'agencyModeFk', cardVisible: true, columnFilter: { @@ -95,7 +95,7 @@ const columns = computed(() => [ { align: 'left', name: 'warehouseFk', - label: t('weeklyTickets.warehouse'), + label: t('ticketList.warehouse'), cardVisible: true, columnFilter: { component: 'select', diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml index 829ea7a91..41c393a42 100644 --- a/src/pages/Ticket/locale/en.yml +++ b/src/pages/Ticket/locale/en.yml @@ -2,16 +2,12 @@ card: search: Search tickets searchInfo: You can search by ticket id or alias volume: - item: Item - description: Description packingType: Packing Type - quantity: Quantity volumeQuantity: m³ per quantity type: Type volume: Volume ticketNotes: observationType: Observation type - description: Description removeNote: Remove note addNote: Add note observationTypes: @@ -25,29 +21,18 @@ ticketNotes: DropOff: Drop Off Sustitución: Sustitution ticketSale: - id: Id visible: Visible available: Available - quantity: Quantity - item: Item - price: Price discount: Disc - amount: Amount packaging: Packaging subtotal: Subtotal tax: VAT - total: Total history: History claim: Claim reserved: Reserved - noVisible: Not visible hasComponentLack: Component lack ok: Ok - state: State more: More - shipped: Shipped - agency: Agency - address: Address advanceTickets: preparation: Preparation origin: Origin @@ -56,7 +41,6 @@ advanceTickets: destinationAgency: 'Destination agency: {agency}' ticketId: ID ipt: IPT - state: State liters: Liters lines: Lines import: Import @@ -81,17 +65,9 @@ advanceTickets: searchInfo: Search advance tickets by ID or client ID futureTickets: problems: Problems - ticketId: ID shipped: Date - ipt: IPT - state: State - liters: Liters - import: Import availableLines: Available lines - futureId: ID futureShipped: Date - futureIpt: IPT - futureState: State noVerified: No verified data noVisible: Not visible purchaseRequest: Purchase request @@ -99,11 +75,8 @@ futureTickets: componentLack: Component lack rounding: Rounding risk: Risk - origin: Origin - destination: Destination moveTicketTitle: Move tickets moveTicketDialogSubtitle: 'Do you want to move {selectedTickets} tickets to the future?' - moveTicketSuccess: Tickets moved successfully! searchInfo: Search future tickets by date futureTicket: Future tickets FREE: Free @@ -113,17 +86,14 @@ futureTickets: DELIVERED: Delivered expedition: id: Expedition - item: Item name: Name packageType: Package type counter: Counter externalId: external Id 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 @@ -138,17 +108,12 @@ basicData: next: Next back: Back finalize: Finalize - client: Client - warehouse: Warehouse address: Address inactive: (Inactive) noDeliveryZoneAvailable: No delivery zone available for this landing date editAddress: Edit address alias: Alias - company: Company agency: Agency - zone: Zone - shipped: Shipped landed: Landed shippedHour: Shipped hour priceDifference: Price difference @@ -171,37 +136,22 @@ basicData: chooseAnOption: Choose an option unroutedTicket: The ticket has been unrouted purchaseRequest: - id: Id - description: Description - created: Created requester: Requester atender: Atender - quantity: Quantity - price: Price saleFk: Item id - state: State newRequest: New request weeklyTickets: id: Ticket ID - client: Client shipment: Shipment - agency: Agency - warehouse: Warehouse salesperson: Salesperson search: Search weekly tickets searchInfo: Search weekly tickets by id or client id ticketSaleTracking: isChecked: Is checked - item: Item - description: Description - quantity: Quantity parking: Parking historyAction: Log states shelvingAction: Shelvings sale original: Original - worker: Worker - state: State - created: Created shelving: Shelving saleGroupDetail: sale group detail previousSelected: previous selected @@ -210,40 +160,25 @@ ticketSaleTracking: checked: checked service: pay: Pay - description: Description - quantity: Quantity - price: Price removeService: Remove service newService: New service type addService: Add service quantityInfo: To create services with negative amounts mark the service on the source ticket and press the pay button. createRefundSuccess: 'The following refund ticket have been created: { ticketId }' ticketComponents: - item: Item - description: Description - quantity: Quantity serie: Serie components: Components - import: Import - total: Total baseToCommission: Base to commission totalWithoutVat: Total without VAT zoneBreakdown: Zone breakdown - price: Price bonus: Bonus - zone: Zone - volume: Volume theoricalCost: Theorical cost totalPrice: Total price packages: Packages tracking: - state: State - worker: Worker - created: Created addState: Add state package: package: Package - quantity: Quantity added: Added addPackage: Add package removePackage: Remove package diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml index b372e48ef..2f7e2add8 100644 --- a/src/pages/Ticket/locale/es.yml +++ b/src/pages/Ticket/locale/es.yml @@ -1,32 +1,22 @@ service: pay: Abonar - description: Descripción - quantity: Cantidad - price: Precio removeService: Quitar servicio newService: Nuevo tipo de servicio addService: Añadir servicio quantityInfo: Para crear sevicios con cantidades negativas marcar servicio en el ticket origen y apretar el boton abonar. createRefundSuccess: 'Se ha creado siguiente ticket de abono: { ticketId }' tracking: - state: Estado - worker: Trabajador - created: Fecha creación addState: Añadir estado card: search: Buscar tickets searchInfo: Buscar tickets por identificador o alias volume: - item: Artículo - description: Descripción packingType: Encajado - quantity: Cantidad volumeQuantity: m³ por cantidad type: Tipo volume: Volumen ticketNotes: observationType: Tipo de observación - description: Descripción removeNote: Quitar nota addNote: Añadir nota observationTypes: @@ -42,31 +32,20 @@ ticketNotes: Accepted: Aceptado Denied: Denegado purchaseRequest: - Id: Id - description: Descripción - created: Fecha creación requester: Solicitante atender: Comprador - quantity: Cantidad - price: Precio saleFk: Id artículo - state: Estado newRequest: Crear petición basicData: next: Siguiente back: Anterior finalize: Finalizar - client: Cliente - warehouse: Almacén address: Consignatario inactive: (Inactivo) noDeliveryZoneAvailable: No hay una zona de reparto disponible para la fecha de envío seleccionada editAddress: Editar dirección alias: Alias - company: Empresa agency: Agencia - zone: Zona - shipped: F. Envío landed: F. Entrega shippedHour: Hora de envío priceDifference: Diferencia de precio @@ -90,10 +69,7 @@ basicData: unroutedTicket: El ticket ha sido desenrutado weeklyTickets: id: ID Ticket - client: Cliente shipment: Salida - agency: Agencia - warehouse: Almacén salesperson: Comercial search: Buscar por tickets programados searchInfo: Buscar tickets programados por el identificador o el identificador del cliente @@ -105,7 +81,6 @@ advanceTickets: destinationAgency: 'Agencia destino: {agency}' ticketId: ID ipt: IPT - state: Estado liters: Litros lines: Líneas import: Importe @@ -130,29 +105,17 @@ advanceTickets: searchInfo: Buscar tickets adelantados por el identificador o el identificador del cliente futureTickets: problems: Problemas - ticketId: ID shipped: Fecha - ipt: IPT - state: Estado - liters: Litros - import: Importe availableLines: Líneas disponibles - futureId: ID futureShipped: Fecha - futureIpt: IPT - futureState: Estado noVerified: Sin datos comprobados - noVisible: No visible purchaseRequest: Petición de compra clientFrozen: Cliente congelado risk: Riesgo componentLack: Faltan componentes rounding: Redondeo - origin: Origen - destination: Destino moveTicketTitle: Mover tickets moveTicketDialogSubtitle: '¿Desea mover {selectedTickets} tickets hacia el futuro?' - moveTicketSuccess: Tickets movidos correctamente searchInfo: Buscar tickets por fecha futureTicket: Tickets a futuro FREE: Libre @@ -161,60 +124,40 @@ futureTickets: PACKED: Encajado DELIVERED: Servido ticketSale: - id: Id visible: Visible available: Disponible - quantity: Cantidad - item: Artículo - price: Precio discount: Dto - amount: Importe packaging: Encajado subtotal: Subtotal tax: IVA - total: Total history: Historial claim: Reclamación reserved: Reservado noVisible: No visible hasComponentLack: Faltan componentes ok: Ok - state: Estado more: Más - shipped: F. Envío - agency: Agencia address: Consignatario ticketComponents: - item: Artículo - description: Descripción - quantity: Cantidad serie: Serie components: Componentes - import: Importe - total: Total baseToCommission: Base comisionable totalWithoutVat: Total sin IVA zoneBreakdown: Desglose zona - price: Precio bonus: Bonificación - zone: Zona - volume: Volúmen theoricalCost: Porte teórico totalPrice: Precio total packages: Bultos expedition: id: Expedición - item: Artículo name: Nombre packageType: Embalaje counter: Contador externalId: ID externo 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 @@ -227,22 +170,15 @@ expedition: removeExpedition: Eliminar expedición package: package: Embalaje - quantity: Cantidad added: Añadido addPackage: Añadir embalaje removePackage: Quitar embalaje ticketSaleTracking: isChecked: Comprobado - item: Artículo - description: Descripción - quantity: Cantidad parking: Parking historyAction: Historial estados shelvingAction: Carros línea original: Original - worker: Trabajador - state: Estado - created: Fecha creación shelving: Matrícula saleGroupDetail: detalle grupo líneas previousSelected: previa seleccionado diff --git a/src/pages/Zone/Card/ZoneCreateWarehouse.vue b/src/pages/Zone/Card/ZoneCreateWarehouse.vue index 86c4dcc72..a46ec2e6c 100644 --- a/src/pages/Zone/Card/ZoneCreateWarehouse.vue +++ b/src/pages/Zone/Card/ZoneCreateWarehouse.vue @@ -32,7 +32,7 @@ const warehousesOptions = ref([]); <VnRow> <div class="col"> <VnSelect - :label="t('warehouses.warehouse')" + :label="t('list.warehouse')" v-model="ZoneWarehouseFormData.warehouseFk" :options="warehousesOptions" option-value="id" diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue index 04fb22ba5..f991818fb 100644 --- a/src/pages/Zone/Card/ZoneDescriptor.vue +++ b/src/pages/Zone/Card/ZoneDescriptor.vue @@ -57,11 +57,11 @@ const setData = (entity) => { <ZoneDescriptorMenuItems :zone="entity" /> </template> <template #body="{ entity }"> - <VnLv :label="t('summary.agency')" :value="entity.agencyMode.name" /> - <VnLv :label="t('summary.closeHour')" :value="toTimeFormat(entity.hour)" /> - <VnLv :label="t('summary.travelingDays')" :value="entity.travelingDays" /> - <VnLv :label="t('summary.price')" :value="toCurrency(entity.price)" /> - <VnLv :label="t('summary.bonus')" :value="toCurrency(entity.bonus)" /> + <VnLv :label="t('list.agency')" :value="entity.agencyMode.name" /> + <VnLv :label="t('zone.closing')" :value="toTimeFormat(entity.hour)" /> + <VnLv :label="t('zone.travelingDays')" :value="entity.travelingDays" /> + <VnLv :label="t('list.price')" :value="toCurrency(entity.price)" /> + <VnLv :label="t('zone.bonus')" :value="toCurrency(entity.bonus)" /> </template> </CardDescriptor> </template> diff --git a/src/pages/Zone/Card/ZoneEventExclusionForm.vue b/src/pages/Zone/Card/ZoneEventExclusionForm.vue index 215c12f46..72c02a5cd 100644 --- a/src/pages/Zone/Card/ZoneEventExclusionForm.vue +++ b/src/pages/Zone/Card/ZoneEventExclusionForm.vue @@ -186,8 +186,8 @@ onMounted(() => { class="q-mr-sm" @click=" openConfirmationModal( - t('eventsPanel.deleteTitle'), - t('eventsPanel.deleteSubtitle'), + t('zone.deleteTitle'), + t('zone.deleteSubtitle'), () => deleteEvent() ) " diff --git a/src/pages/Zone/Card/ZoneEventInclusionForm.vue b/src/pages/Zone/Card/ZoneEventInclusionForm.vue index 66e41607f..8b1645426 100644 --- a/src/pages/Zone/Card/ZoneEventInclusionForm.vue +++ b/src/pages/Zone/Card/ZoneEventInclusionForm.vue @@ -153,7 +153,7 @@ onMounted(() => { <div class="col flex justify-center"> <VnInputDate v-if="inclusionType === 'day'" - :label="t('eventsInclusionForm.day')" + :label="t('eventsExclusionForm.day')" v-model="eventInclusionFormData.dated" class="full-width" /> @@ -176,11 +176,11 @@ onMounted(() => { <VnRow> <VnInputTime v-model="eventInclusionFormData.hour" - :label="t('eventsInclusionForm.closing')" + :label="t('zone.closing')" /> <VnInput v-model="eventInclusionFormData.travelingDays" - :label="t('eventsInclusionForm.travelingDays')" + :label="t('zone.travelingDays')" type="number" min="0" /> @@ -188,13 +188,13 @@ onMounted(() => { <VnRow> <VnInput v-model="eventInclusionFormData.price" - :label="t('eventsInclusionForm.price')" + :label="t('list.price')" type="number" min="0" /> <VnInput v-model="eventInclusionFormData.bonus" - :label="t('eventsInclusionForm.bonus')" + :label="t('zone.bonus')" type="number" min="0" /> @@ -202,7 +202,7 @@ onMounted(() => { <VnRow> <VnInput v-model="eventInclusionFormData.m3Max" - :label="t('eventsInclusionForm.m3Max')" + :label="t('zone.m3Max')" type="number" min="0" /> @@ -224,8 +224,8 @@ onMounted(() => { class="q-mr-sm" @click=" openConfirmationModal( - t('eventsPanel.deleteTitle'), - t('eventsPanel.deleteSubtitle'), + t('zone.deleteTitle'), + t('zone.deleteSubtitle'), () => deleteEvent() ) " diff --git a/src/pages/Zone/Card/ZoneEventsPanel.vue b/src/pages/Zone/Card/ZoneEventsPanel.vue index 2cfa98246..55bc27ebe 100644 --- a/src/pages/Zone/Card/ZoneEventsPanel.vue +++ b/src/pages/Zone/Card/ZoneEventsPanel.vue @@ -150,31 +150,31 @@ onMounted(async () => { </span> </div> <span class="color-vn-label"> - {{ t('eventsPanel.closing') }}: + {{ t('zone.closing') }}: <span class="color-vn-text q-ml-xs"> {{ dashIfEmpty(toTimeFormat(event.hour)) }} </span> </span> <span class="color-vn-label"> - {{ t('eventsPanel.travelingDays') }}: + {{ t('zone.travelingDays') }}: <span class="color-vn-text"> {{ dashIfEmpty(event.travelingDays) }} </span> </span> <span class="color-vn-label"> - {{ t('eventsPanel.price') }}: + {{ t('list.price') }}: <span class="color-vn-text"> {{ dashOrCurrency(event.price)() }}</span > </span> <span class="color-vn-label"> - {{ t('eventsPanel.bonus') }}: + {{ t('zone.bonus') }}: <span class="color-vn-text"> {{ dashOrCurrency(event.bonus)() }}</span > </span> <span class="color-vn-label"> - {{ t('eventsPanel.m3Max') }}: + {{ t('zone.m3Max') }}: <span class="color-vn-text"> {{ dashIfEmpty(event.m3Max) }}</span> </span> </QItemSection> @@ -187,8 +187,8 @@ onMounted(async () => { color="primary" @click.stop=" openConfirmationModal( - t('eventsPanel.deleteTitle'), - t('eventsPanel.deleteSubtitle'), + t('zone.deleteTitle'), + t('zone.deleteSubtitle'), () => deleteEvent(event.id) ) " diff --git a/src/pages/Zone/Card/ZoneLocations.vue b/src/pages/Zone/Card/ZoneLocations.vue index f357e9e5b..321748f00 100644 --- a/src/pages/Zone/Card/ZoneLocations.vue +++ b/src/pages/Zone/Card/ZoneLocations.vue @@ -23,7 +23,7 @@ const onSelected = async (val, node) => { <template> <QPage class="column items-center q-pa-md"> <QCard class="full-width q-pa-md" style="max-width: 800px"> - <ZoneLocationsTree :root-label="t('zoneLocations.locations')"> + <ZoneLocationsTree :root-label="t('zone.pageTitles.locations')"> <template #content="{ node }"> <span v-if="!node.id">{{ node.name }}</span> <QCheckbox diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue index d46282c10..384ee1fe9 100644 --- a/src/pages/Zone/Card/ZoneSummary.vue +++ b/src/pages/Zone/Card/ZoneSummary.vue @@ -40,7 +40,7 @@ const filter = computed(() => { const columns = computed(() => [ { - label: t('summary.name'), + label: t('list.name'), name: 'name', field: 'warehouse', align: 'left', @@ -82,22 +82,22 @@ onMounted(async () => { <template #body="{ entity: zone }"> <QCard class="vn-one"> <VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" /> - <VnLv :label="t('summary.agency')" :value="zone.agencyMode?.name" /> - <VnLv :label="t('summary.price')" :value="toCurrency(zone.price)" /> - <VnLv :label="t('summary.bonus')" :value="toCurrency(zone.bonus)" /> + <VnLv :label="t('list.agency')" :value="zone.agencyMode?.name" /> + <VnLv :label="t('list.price')" :value="toCurrency(zone.price)" /> + <VnLv :label="t('zone.bonus')" :value="toCurrency(zone.bonus)" /> </QCard> <QCard class="vn-one"> <VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" /> <VnLv :label="t('summary.closeHour')" :value="toTimeFormat(zone.hour)" /> - <VnLv :label="t('summary.travelingDays')" :value="zone.travelingDays" /> + <VnLv :label="t('zone.travelingDays')" :value="zone.travelingDays" /> <QCheckbox - :label="t('summary.volumetric')" + :label="t('zone.volumetric')" v-model="zone.isVolumetric" :disable="true" /> </QCard> <QCard class="full-width"> - <VnTitle :url="zoneUrl + `warehouses`" :text="t('summary.warehouse')" /> + <VnTitle :url="zoneUrl + `warehouses`" :text="t('list.warehouse')" /> <QTable :columns="columns" :rows="warehouses" diff --git a/src/pages/Zone/Card/ZoneWarehouses.vue b/src/pages/Zone/Card/ZoneWarehouses.vue index 6b2933224..e61aae9ec 100644 --- a/src/pages/Zone/Card/ZoneWarehouses.vue +++ b/src/pages/Zone/Card/ZoneWarehouses.vue @@ -90,14 +90,14 @@ const openCreateWarehouseForm = () => createWarehouseDialogRef.value.show(); color="primary" @click=" openConfirmationModal( - t('warehouses.deleteTitle'), - t('warehouses.deleteSubtitle'), + t('zone.deleteTitle'), + t('zone.deleteSubtitle'), () => deleteWarehouse(row, rows, rowIndex) ) " > <QTooltip> - {{ t('warehouses.delete') }} + {{ t('eventsPanel.delete') }} </QTooltip> </QIcon> </QTd> diff --git a/src/pages/Zone/ZoneClosingTable.vue b/src/pages/Zone/ZoneClosingTable.vue index ce0c91af7..049f82271 100644 --- a/src/pages/Zone/ZoneClosingTable.vue +++ b/src/pages/Zone/ZoneClosingTable.vue @@ -23,28 +23,28 @@ defineProps({ const columns = computed(() => [ { - label: t('zoneClosingTable.id'), + label: t('list.id'), name: 'id', field: 'id', sortable: true, align: 'left', }, { - label: t('zoneClosingTable.name'), + label: t('list.name'), name: 'name', field: 'name', sortable: true, align: 'left', }, { - label: t('zoneClosingTable.agency'), + label: t('list.agency'), name: 'agency', field: 'agencyModeName', sortable: true, align: 'left', }, { - label: t('zoneClosingTable.closing'), + label: t('zone.closing'), name: 'close', field: 'hour', sortable: true, @@ -52,7 +52,7 @@ const columns = computed(() => [ format: (val) => toTimeFormat(val), }, { - label: t('zoneClosingTable.price'), + label: t('list.price'), name: 'price', field: 'price', sortable: true, @@ -73,7 +73,7 @@ const redirectToZoneSummary = (id) => { <template> <div> <div class="header"> - <span>{{ t('zoneClosingTable.zones') }}</span> + <span>{{ t('zone.pageTitles.zones') }}</span> </div> <QTable :rows="rows" diff --git a/src/pages/Zone/ZoneCreate.vue b/src/pages/Zone/ZoneCreate.vue index 7d7fa24a3..6db83c51d 100644 --- a/src/pages/Zone/ZoneCreate.vue +++ b/src/pages/Zone/ZoneCreate.vue @@ -54,13 +54,13 @@ const redirectToZoneLocations = (_, { id }) => { <VnRow> <VnInput v-model="data.name" - :label="t('create.name')" + :label="t('list.name')" :required="true" /> </VnRow> <VnRow> <VnSelect - :label="t('create.warehouse')" + :label="t('list.warehouse')" :options="warehousesOptions" hide-selected option-label="name" @@ -68,7 +68,7 @@ const redirectToZoneLocations = (_, { id }) => { v-model="data.warehouseFk" /> <VnSelect - :label="t('create.agency')" + :label="t('list.agency')" :options="agencyOptions" hide-selected option-label="name" @@ -80,7 +80,7 @@ const redirectToZoneLocations = (_, { id }) => { <VnRow> <VnInput v-model="data.travelingDays" - :label="t('create.travelingDays')" + :label="t('zone.travelingDays')" type="number" min="0" /> @@ -90,20 +90,20 @@ const redirectToZoneLocations = (_, { id }) => { <VnRow> <VnInput v-model="data.price" - :label="t('create.price')" + :label="t('list.price')" type="number" min="0" /> <VnInput v-model="data.bonus" - :label="t('create.bonus')" + :label="t('zone.bonus')" type="number" min="0" /> </VnRow> <VnRow> <QCheckbox - :label="t('create.volumetric')" + :label="t('zone.volumetric')" v-model="data.isVolumetric" :toggle-indeterminate="false" /> diff --git a/src/pages/Zone/ZoneDeliveryPanel.vue b/src/pages/Zone/ZoneDeliveryPanel.vue index 423095d6e..a2d215ed6 100644 --- a/src/pages/Zone/ZoneDeliveryPanel.vue +++ b/src/pages/Zone/ZoneDeliveryPanel.vue @@ -117,7 +117,7 @@ watch( <VnSelect data-key="delivery" v-if="deliveryMethodFk == 'delivery'" - :label="t('deliveryPanel.agency')" + :label="t('list.agency')" v-model="formData.agencyModeFk" url="AgencyModes/isActive" :fields="['id', 'name']" @@ -132,7 +132,7 @@ watch( /> <VnSelect v-else - :label="t('deliveryPanel.warehouse')" + :label="t('list.warehouse')" v-model="formData.agencyModeFk" url="AgencyModes/isActive" :fields="['id', 'name']" diff --git a/src/pages/Zone/ZoneFilterPanel.vue b/src/pages/Zone/ZoneFilterPanel.vue index 25c55d75c..efe710360 100644 --- a/src/pages/Zone/ZoneFilterPanel.vue +++ b/src/pages/Zone/ZoneFilterPanel.vue @@ -38,11 +38,7 @@ const agencies = ref([]); <template #body="{ params, searchFn }"> <QItem> <QItemSection> - <VnInput - :label="t('filterPanel.name')" - v-model="params.name" - is-outlined - /> + <VnInput :label="t('list.name')" v-model="params.name" is-outlined /> </QItemSection> </QItem> <QItem> diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue index d160ea6b5..060b266ab 100644 --- a/src/pages/Zone/ZoneList.vue +++ b/src/pages/Zone/ZoneList.vue @@ -174,13 +174,13 @@ onMounted(() => (stateStore.rightDrawer = true)); /> <VnInput v-model="data.bonus" - :label="t('list.bonus')" + :label="t('zone.bonus')" min="0" type="number" /> <VnInput v-model="data.travelingDays" - :label="t('list.travelingDays')" + :label="t('zone.travelingDays')" type="number" min="0" /> diff --git a/src/pages/Zone/ZoneUpcoming.vue b/src/pages/Zone/ZoneUpcoming.vue index ecf82bf4f..c74ae6078 100644 --- a/src/pages/Zone/ZoneUpcoming.vue +++ b/src/pages/Zone/ZoneUpcoming.vue @@ -22,13 +22,13 @@ const columns = computed(() => [ align: 'left', }, { - label: t('upcomingDeliveries.closing'), + label: t('zone.closing'), name: 'closing', field: 'hour', align: 'left', }, { - label: t('upcomingDeliveries.id'), + label: t('list.id'), name: 'id', field: 'zoneFk', align: 'left', diff --git a/src/pages/Zone/locale/en.yml b/src/pages/Zone/locale/en.yml index 2608c071c..bf7d8f0de 100644 --- a/src/pages/Zone/locale/en.yml +++ b/src/pages/Zone/locale/en.yml @@ -8,6 +8,13 @@ zone: upcomingDeliveries: Upcoming deliveries warehouses: Warehouses calendar: Calendar + m3Max: Max m³ + deleteTitle: This item will be deleted + deleteSubtitle: Are you sure you want to continue? + volumetric: Volumetric + bonus: Bonus + closing: Closing + travelingDays: Traveling days list: clone: Clone id: Id @@ -22,74 +29,38 @@ list: searchInfo: Search zone by id or name confirmCloneTitle: All it's properties will be copied confirmCloneSubtitle: Do you want to clone this zone? - travelingDays: Traveling days warehouse: Warehouse - bonus: Bonus - isVolumetric: Volumetric createZone: Create zone zoneSummary: Summary create: name: Name - warehouse: Warehouse - agency: Agency - travelingDays: Traveling days closingHour: Closing hour - price: Price - bonus: Bonus - volumetric: Volumetric itemMaxSize: Max m³ inflation: Inflation summary: - agency: Agency - price: Price basicData: Basic data - bonus: Bonus closeHour: Close hour - travelingDays: Traveling days - volumetric: Volumetric - warehouse: Warehouse - name: Name filterPanel: - name: Name agencyModeFk: Agency -zoneLocations: - locations: Locations deliveryPanel: pickup: Pick up delivery: Delivery postcode: Postcode - agency: Agency - warehouse: Warehouse query: Query noEventsWarning: No service for the specified zone zoneClosingTable: - id: Id - name: Name - agency: Agency - closing: Closing - price: Price preview: Preview - zones: Zones warehouses: - delete: Delete deleteTitle: This item will be deleted deleteSubtitle: Are you sure you want to continue? - warehouse: Warehouse add: Add eventsPanel: editMode: Edit mode include: Include exclude: Exclude events: Events - closing: Closing - travelingDays: Traveling days - price: Price - bonus: Bonus - m3Max: Max m³ everyday: Everyday delete: Delete - deleteTitle: This item will be deleted - deleteSubtitle: Are you sure you want to continue? eventsExclusionForm: addExclusion: Add exclusion editExclusion: Edit exclusion @@ -103,15 +74,8 @@ eventsInclusionForm: oneDay: One day indefinitely: Indefinitely rangeOfDates: Range of dates - day: Day - closing: Closing - travelingDays: Traveling days - price: Price - bonus: Bonus - m3Max: Max m³ from: From to: To upcomingDeliveries: province: Province closing: Closing - id: Id diff --git a/src/pages/Zone/locale/es.yml b/src/pages/Zone/locale/es.yml index 7ecfb580d..91541bea3 100644 --- a/src/pages/Zone/locale/es.yml +++ b/src/pages/Zone/locale/es.yml @@ -8,6 +8,13 @@ zone: upcomingDeliveries: Próximos repartos warehouses: Almacenes calendar: Calendario + m3Max: Medida máxima + deleteTitle: Este elemento será eliminado + deleteSubtitle: ¿Seguro que quieres continuar? + volumetric: Volumétrico + bonus: Bonificación + closing: Cierre + travelingDays: Días de viaje list: clone: Clonar id: Id @@ -22,76 +29,38 @@ list: searchInfo: Buscar zonas por identificador o nombre confirmCloneTitle: Todas sus propiedades serán copiadas confirmCloneSubtitle: ¿Seguro que quieres clonar esta zona? - travelingDays: Días de viaje warehouse: Almacén - bonus: Bonus isVolumetric: Volumétrico createZone: Crear zona zoneSummary: Resumen create: - name: Nombre - warehouse: Almacén - agency: Agencia - travelingDays: Días de viaje closingHour: Hora de cierre - price: Precio - bonus: Bonificación - volumetric: Volumétrico itemMaxSize: Medida máxima inflation: Inflación summary: - agency: Agencia - price: Precio basicData: Datos básicos - bonus: Bonificación closeHour: Hora de cierre - travelingDays: Días de viaje - volumetric: Volumétrico - warehouse: Almacén - name: Nombre filterPanel: - name: Nombre agencyModeFk: Agencia -zoneLocations: - locations: Localizaciones deliveryPanel: pickup: Recogida delivery: Entrega postcode: Código postal - agency: Agencia - warehouse: Almacén query: Consultar noEventsWarning: No hay servicio para la zona especificada zoneClosingTable: - id: Id - name: Nombre - agency: Agencia - closing: Cierre preview: Vista previa - price: Precio - zones: Zonas Search zones: Buscar zonas You can search by zone reference: Puedes buscar por referencia de la zona warehouses: - delete: Eliminar - deleteTitle: Este elemento será eliminado - deleteSubtitle: ¿Seguro que quieres continuar? - warehouse: Almacén add: Añadir eventsPanel: editMode: Modo edición include: Incluir exclude: Excluir events: Eventos - closing: Cierre - travelingDays: Días de viaje - price: Precio - bonus: Bonificación - m3Max: Medida máxima everyday: Todos los días delete: Eliminar - deleteTitle: Este elemento será eliminado - deleteSubtitle: ¿Seguro que quieres continuar? eventsExclusionForm: addExclusion: Añadir exclusión editExclusion: Editar exclusión @@ -105,15 +74,7 @@ eventsInclusionForm: oneDay: Un día indefinitely: Indefinido rangeOfDates: Rango de fechas - day: Día - closing: Cierre - travelingDays: Días de viaje - price: Precio - bonus: Bonificación - m3Max: Medida máxima from: Desde to: Hasta upcomingDeliveries: province: Provincia - closing: Cierre - id: Id From 8eef9c0009a47fcf9ac5d29b3c3299ce8725adfc Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Fri, 18 Oct 2024 09:21:18 +0200 Subject: [PATCH 045/207] refactor: refs #7132 customer's module translations --- src/pages/Customer/Card/CustomerBasicData.vue | 14 +++---- .../Customer/Card/CustomerDescriptor.vue | 18 ++++++--- src/pages/Customer/Card/CustomerSummary.vue | 6 +-- src/pages/Customer/CustomerFilter.vue | 4 +- src/pages/Customer/CustomerList.vue | 22 +++++------ src/pages/Customer/locale/en.yml | 39 ------------------- src/pages/Customer/locale/es.yml | 38 ------------------ 7 files changed, 35 insertions(+), 106 deletions(-) diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue index d31669b43..a77d2f865 100644 --- a/src/pages/Customer/Card/CustomerBasicData.vue +++ b/src/pages/Customer/Card/CustomerBasicData.vue @@ -55,7 +55,7 @@ const exprBuilder = (param, value) => { /> <VnSelect :input-debounce="0" - :label="t('customer.basicData.businessType')" + :label="t('customer.summary.businessType')" :options="businessTypes" :rules="validate('client.businessTypeFk')" emit-value @@ -67,13 +67,13 @@ const exprBuilder = (param, value) => { </VnRow> <VnRow> <VnInput - :label="t('customer.basicData.contact')" + :label="t('customer.summary.contact')" :rules="validate('client.contact')" clearable v-model="data.contact" /> <VnInput - :label="t('customer.basicData.email')" + :label="t('globals.params.email')" :rules="validate('client.email')" clearable type="email" @@ -90,13 +90,13 @@ const exprBuilder = (param, value) => { </VnRow> <VnRow> <VnInput - :label="t('customer.basicData.phone')" + :label="t('customer.extendedList.tableVisibleColumns.phone')" :rules="validate('client.phone')" clearable v-model="data.phone" /> <VnInput - :label="t('customer.basicData.mobile')" + :label="t('customer.summary.mobile')" :rules="validate('client.mobile')" clearable v-model="data.mobile" @@ -106,7 +106,7 @@ const exprBuilder = (param, value) => { <VnSelect url="Workers/search" v-model="data.salesPersonFk" - :label="t('customer.basicData.salesPerson')" + :label="t('customer.summary.salesPerson')" :params="{ departmentCodes: ['VT', 'shopping'], }" @@ -144,7 +144,7 @@ const exprBuilder = (param, value) => { option-value="id" option-label="name" emit-value - :label="t('customer.basicData.contactChannel')" + :label="t('customer.summary.contactChannel')" map-options :rules="validate('client.contactChannelFk')" :input-debounce="0" diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue index 43103bd68..b73354386 100644 --- a/src/pages/Customer/Card/CustomerDescriptor.vue +++ b/src/pages/Customer/Card/CustomerDescriptor.vue @@ -53,11 +53,17 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit <CustomerDescriptorMenu :customer="entity" /> </template> <template #body="{ entity }"> - <VnLv :label="t('customer.card.payMethod')" :value="entity.payMethod.name" /> - - <VnLv :label="t('customer.card.credit')" :value="toCurrency(entity.credit)" /> <VnLv - :label="t('customer.card.securedCredit')" + :label="t('customer.summary.payMethod')" + :value="entity.payMethod.name" + /> + + <VnLv + :label="t('customer.summary.credit')" + :value="toCurrency(entity.credit)" + /> + <VnLv + :label="t('customer.summary.securedCredit')" :value="toCurrency(entity.creditInsurance)" /> @@ -66,7 +72,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit :value="toCurrency(entity.debt)" :info="t('customer.summary.riskInfo')" /> - <VnLv :label="t('customer.card.salesPerson')"> + <VnLv :label="t('customer.summary.salesPerson')"> <template #value> <VnUserLink v-if="entity.salesPersonUser" @@ -77,7 +83,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit </template> </VnLv> <VnLv - :label="t('customer.card.businessTypeFk')" + :label="t('customer.extendedList.tableVisibleColumns.businessTypeFk')" :value="entity.businessType.description" /> </template> diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 8b5f0f2c2..047c46016 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -79,7 +79,7 @@ const sumRisk = ({ clientRisks }) => { <VnLv :label="t('customer.summary.contact')" :value="entity.contact" /> <VnLv :value="entity.phone"> <template #label> - {{ t('customer.summary.phone') }} + {{ t('customer.extendedList.tableVisibleColumns.phone') }} <VnLinkPhone :phone-number="entity.phone" /> </template> </VnLv> @@ -89,7 +89,7 @@ const sumRisk = ({ clientRisks }) => { <VnLinkPhone :phone-number="entity.mobile" /> </template> </VnLv> - <VnLv :label="t('customer.summary.email')" :value="entity.email" copy /> + <VnLv :label="t('globals.params.email')" :value="entity.email" copy /> <VnLv :label="t('customer.summary.salesPerson')" :value="entity?.salesPersonUser?.name" @@ -201,7 +201,7 @@ const sumRisk = ({ clientRisks }) => { :value="entity.defaultAddress.city" /> <VnLv - :label="t('customer.summary.addressStreet')" + :label="t('customer.summary.street')" :value="entity.defaultAddress.street" /> </QCard> diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue index 6c50cc9df..ae3a42514 100644 --- a/src/pages/Customer/CustomerFilter.vue +++ b/src/pages/Customer/CustomerFilter.vue @@ -34,7 +34,7 @@ defineProps({ <QItem class="q-mb-sm"> <QItemSection> <VnInput - :label="t('customerFilter.filter.name')" + :label="t('globals.name')" v-model="params.name" is-outlined /> @@ -43,7 +43,7 @@ defineProps({ <QItem class="q-mb-sm"> <QItemSection> <VnInput - :label="t('customerFilter.filter.socialName')" + :label="t('customer.summary.socialName')" v-model="params.socialName" is-outlined /> diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue index 63f5149e8..0cf984f20 100644 --- a/src/pages/Customer/CustomerList.vue +++ b/src/pages/Customer/CustomerList.vue @@ -78,7 +78,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.credit'), + label: t('customer.summary.credit'), name: 'credit', columnFilter: { component: 'number', @@ -116,7 +116,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.mobile'), + label: t('customer.summary.mobile'), name: 'mobile', cardVisible: true, columnFilter: { @@ -163,17 +163,17 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.city'), + label: t('customer.summary.city'), name: 'city', }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.postcode'), + label: t('customer.summary.postcode'), name: 'postcode', }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.email'), + label: t('globals.params.email'), name: 'email', cardVisible: true, }, @@ -208,7 +208,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.payMethodFk'), + label: t('customer.summary.payMethodFk'), name: 'payMethodFk', columnFilter: { component: 'select', @@ -251,7 +251,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.isActive'), + label: t('customer.summary.isActive'), name: 'isActive', chip: { color: null, @@ -280,7 +280,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.isEqualizated'), + label: t('customer.summary.isEqualizated'), name: 'isEqualizated', create: true, columnFilter: { @@ -326,7 +326,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.hasLcr'), + label: t('customer.summary.hasLcr'), name: 'hasLcr', columnFilter: { inWhere: true, @@ -334,7 +334,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('customer.extendedList.tableVisibleColumns.hasCoreVnl'), + label: t('customer.summary.hasCoreVnl'), name: 'hasCoreVnl', columnFilter: { inWhere: true, @@ -425,7 +425,7 @@ function handleLocation(data, location) { <VnSelect url="Workers/search" v-model="data.salesPersonFk" - :label="t('customer.basicData.salesPerson')" + :label="t('customer.summary.salesPerson')" :params="{ departmentCodes: ['VT', 'shopping'], }" diff --git a/src/pages/Customer/locale/en.yml b/src/pages/Customer/locale/en.yml index 545c3f274..07ec53964 100644 --- a/src/pages/Customer/locale/en.yml +++ b/src/pages/Customer/locale/en.yml @@ -1,21 +1,5 @@ -customerFilter: - filter: - name: Name - socialName: Social name customer: - list: - phone: Phone - email: Email - customerOrders: Display customer orders - moreOptions: More options card: - customerList: Customer list - customerId: Claim ID - salesPerson: Sales person - credit: Credit - risk: Risk - securedCredit: Secured credit - payMethod: Pay method debt: Debt isFrozen: Customer frozen hasDebt: Customer has debt @@ -23,9 +7,7 @@ customer: notChecked: Customer no checked webAccountInactive: Web account inactive noWebAccess: Web access is disabled - businessType: Business type passwordRequirements: 'The password must have at least { length } length characters, {nAlpha} alphabetic characters, {nUpper} capital letters, {nDigits} digits and {nPunct} symbols (Ex: $%&.)\n' - businessTypeFk: Business type summary: basicData: Basic data fiscalAddress: Fiscal address @@ -37,9 +19,7 @@ customer: customerId: Customer ID name: Name contact: Contact - phone: Phone mobile: Mobile - email: Email salesPerson: Sales person contactChannel: Contact channel socialName: Social name @@ -63,7 +43,6 @@ customer: hasB2BVnl: Has B2B VNL addressName: Address name addressCity: City - addressStreet: Street username: Username webAccess: Web access totalGreuge: Total greuge @@ -92,45 +71,27 @@ customer: goToLines: Go to lines basicData: socialName: Fiscal name - businessType: Business type - contact: Contact youCanSaveMultipleEmails: You can save multiple emails - email: Email - phone: Phone - mobile: Mobile - salesPerson: Sales person - contactChannel: Contact channel previousClient: Previous client extendedList: tableVisibleColumns: id: Identifier - name: Name socialName: Social name fi: Tax number salesPersonFk: Salesperson - credit: Credit creditInsurance: Credit insurance phone: Phone - mobile: Mobile street: Street countryFk: Country provinceFk: Province - city: City - postcode: Postcode - email: Email created: Created businessTypeFk: Business type - payMethodFk: Billing data sageTaxTypeFk: Sage tax type sageTransactionTypeFk: Sage tr. type - isActive: Active isVies: Vies isTaxDataChecked: Verified data - isEqualizated: Is equalizated isFreezed: Freezed hasToInvoice: Invoice hasToInvoiceByAddress: Invoice by address isToBeMailed: Mailing - hasLcr: Received LCR - hasCoreVnl: VNL core received hasSepaVnl: VNL B2B received diff --git a/src/pages/Customer/locale/es.yml b/src/pages/Customer/locale/es.yml index 451784425..36a266497 100644 --- a/src/pages/Customer/locale/es.yml +++ b/src/pages/Customer/locale/es.yml @@ -1,22 +1,7 @@ Search customer: Buscar cliente You can search by customer id or name: Puedes buscar por id o nombre del cliente -customerFilter: - filter: - name: Nombre - socialName: Razón Social customer: - list: - phone: Teléfono - email: Email - customerOrders: Mostrar órdenes del cliente - moreOptions: Más opciones card: - customerId: ID cliente - salesPerson: Comercial - credit: Crédito - risk: Riesgo - securedCredit: Crédito asegurado - payMethod: Método de pago debt: Riesgo isFrozen: Cliente congelado hasDebt: Cliente con riesgo @@ -24,9 +9,7 @@ customer: notChecked: Cliente no comprobado webAccountInactive: Sin acceso web noWebAccess: El acceso web está desactivado - businessType: Tipo de negocio passwordRequirements: 'La contraseña debe tener al menos { length } caracteres de longitud, {nAlpha} caracteres alfabéticos, {nUpper} letras mayúsculas, {nDigits} dígitos y {nPunct} símbolos (Ej: $%&.)' - businessTypeFk: Tipo de negocio summary: basicData: Datos básicos fiscalAddress: Dirección fiscal @@ -38,9 +21,7 @@ customer: customerId: ID cliente name: Nombre contact: Contacto - phone: Teléfono mobile: Móvil - email: Email salesPerson: Comercial contactChannel: Canal de contacto socialName: Razón social @@ -64,7 +45,6 @@ customer: hasB2BVnl: Recibido B2B VNL addressName: Nombre de la dirección addressCity: Ciudad - addressStreet: Calle username: Usuario webAccess: Acceso web totalGreuge: Greuge total @@ -93,45 +73,27 @@ customer: goToLines: Ir a líneas basicData: socialName: Nombre fiscal - businessType: Tipo de negocio - contact: Contacto youCanSaveMultipleEmails: Puede guardar varios correos electrónicos encadenándolos mediante comas sin espacios{','} ejemplo{':'} user{'@'}dominio{'.'}com, user2{'@'}dominio{'.'}com siendo el primer correo electrónico el principal - email: Email - phone: Teléfono - mobile: Móvil - salesPerson: Comercial - contactChannel: Canal de contacto previousClient: Cliente anterior extendedList: tableVisibleColumns: id: Identificador - name: Nombre socialName: Razón social fi: NIF / CIF salesPersonFk: Comercial - credit: Crédito creditInsurance: Crédito asegurado phone: Teléfono - mobile: Móvil street: Dirección fiscal countryFk: País provinceFk: Provincia - city: Población - postcode: Código postal - email: Email created: Fecha creación businessTypeFk: Tipo de negocio - payMethodFk: Forma de pago sageTaxTypeFk: Tipo de impuesto Sage sageTransactionTypeFk: Tipo tr. sage - isActive: Activo isVies: Vies isTaxDataChecked: Datos comprobados - isEqualizated: Recargo de equivalencias isFreezed: Congelado hasToInvoice: Factura hasToInvoiceByAddress: Factura por consigna isToBeMailed: Env. emails - hasLcr: Recibido LCR - hasCoreVnl: Recibido core VNL hasSepaVnl: Recibido B2B VNL From 0e77d4b68f9f62d2516337179bb6ab5e7d98d33e Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Fri, 18 Oct 2024 10:40:40 +0200 Subject: [PATCH 046/207] refactor: refs #7132 account's module translations --- src/pages/Account/AccountCreate.vue | 8 +-- src/pages/Account/AccountFilter.vue | 2 +- src/pages/Account/AccountLdap.vue | 8 +-- src/pages/Account/AccountSamba.vue | 6 +-- src/pages/Account/Alias/AliasCreateForm.vue | 7 +-- .../Account/Alias/Card/AliasBasicData.vue | 4 +- .../Account/Alias/Card/AliasDescriptor.vue | 2 +- src/pages/Account/Alias/Card/AliasSummary.vue | 4 +- src/pages/Account/Card/AccountBasicData.vue | 2 +- src/pages/Account/Role/AccountRolesFilter.vue | 2 +- src/pages/Account/Role/Card/RoleBasicData.vue | 7 +-- .../Account/Role/Card/RoleDescriptor.vue | 2 +- src/pages/Account/Role/Card/RoleForm.vue | 7 +-- src/pages/Account/Role/Card/RoleSummary.vue | 6 +-- src/pages/Account/locale/en.yml | 49 ++---------------- src/pages/Account/locale/es.yml | 50 ++----------------- 16 files changed, 35 insertions(+), 131 deletions(-) diff --git a/src/pages/Account/AccountCreate.vue b/src/pages/Account/AccountCreate.vue index e584a1acd..6b7c049c8 100644 --- a/src/pages/Account/AccountCreate.vue +++ b/src/pages/Account/AccountCreate.vue @@ -37,7 +37,7 @@ const redirectToAccountBasicData = (_, { id }) => { <div class="column q-gutter-sm"> <VnInput v-model="data.name" - :label="t('account.create.name')" + :label="t('globals.name')" :rules="validate('VnUser.name')" /> <VnInput @@ -47,12 +47,12 @@ const redirectToAccountBasicData = (_, { id }) => { /> <VnInput v-model="data.email" - :label="t('account.create.email')" + :label="t('globals.params.email')" type="email" :rules="validate('VnUser.email')" /> <VnSelect - :label="t('account.create.role')" + :label="t('account.card.role')" v-model="data.roleFk" :options="rolesOptions" option-value="id" @@ -63,7 +63,7 @@ const redirectToAccountBasicData = (_, { id }) => { /> <VnInput v-model="data.password" - :label="t('account.create.password')" + :label="t('ldap.password')" type="password" :rules="validate('VnUser.password')" /> diff --git a/src/pages/Account/AccountFilter.vue b/src/pages/Account/AccountFilter.vue index 1775aa06b..22c167d43 100644 --- a/src/pages/Account/AccountFilter.vue +++ b/src/pages/Account/AccountFilter.vue @@ -44,7 +44,7 @@ const rolesOptions = ref([]); <QItem class="q-my-sm"> <QItemSection> <VnInput - :label="t('account.card.name')" + :label="t('globals.name')" v-model="params.name" lazy-rules is-outlined diff --git a/src/pages/Account/AccountLdap.vue b/src/pages/Account/AccountLdap.vue index 7b8433e73..84d8f1cde 100644 --- a/src/pages/Account/AccountLdap.vue +++ b/src/pages/Account/AccountLdap.vue @@ -102,11 +102,11 @@ onMounted(async () => await getInitialLdapConfig()); <QBtn class="q-ml-none" color="primary" - :label="t('ldap.testConnection')" + :label="t('account.card.testConnection')" @click="onTestConection()" > <QTooltip> - {{ t('ldap.testConnection') }} + {{ t('account.card.testConnection') }} </QTooltip> </QBtn> </template> @@ -114,7 +114,7 @@ onMounted(async () => await getInitialLdapConfig()); <VnRow class="row q-gutter-md"> <div class="col"> <QCheckbox - :label="t('ldap.enableSync')" + :label="t('account.card.enableSync')" v-model="data.hasData" @update:model-value="($event) => (hasData = $event)" :toggle-indeterminate="false" @@ -146,7 +146,7 @@ onMounted(async () => await getInitialLdapConfig()); /> <VnInput :label="t('ldap.userDN')" clearable v-model="data.userDn" /> <VnInput - :label="t('ldap.groupDN')" + :label="t('account.card.groupDN')" clearable v-model="data.groupDn" /> diff --git a/src/pages/Account/AccountSamba.vue b/src/pages/Account/AccountSamba.vue index 7af9f4364..15b886f27 100644 --- a/src/pages/Account/AccountSamba.vue +++ b/src/pages/Account/AccountSamba.vue @@ -110,12 +110,12 @@ onMounted(async () => await getInitialSambaConfig()); <QBtn class="q-ml-none" color="primary" - :label="t('samba.testConnection')" + :label="t('account.card.testConnection')" :disable="formModel.hasChanges" @click="onTestConection()" > <QTooltip> - {{ t('samba.testConnection') }} + {{ t('account.card.testConnection') }} </QTooltip> </QBtn> </template> @@ -123,7 +123,7 @@ onMounted(async () => await getInitialSambaConfig()); <VnRow class="row q-gutter-md"> <div class="col"> <QCheckbox - :label="t('samba.enableSync')" + :label="t('account.card.enableSync')" v-model="data.hasData" @update:model-value="($event) => (hasData = $event)" :toggle-indeterminate="false" diff --git a/src/pages/Account/Alias/AliasCreateForm.vue b/src/pages/Account/Alias/AliasCreateForm.vue index b21099555..e401b6d54 100644 --- a/src/pages/Account/Alias/AliasCreateForm.vue +++ b/src/pages/Account/Alias/AliasCreateForm.vue @@ -36,15 +36,12 @@ const onDataSaved = ({ id }) => { <template #form-inputs="{ data }"> <VnRow> <div class="col"> - <VnInput v-model="data.alias" :label="t('mailAlias.name')" /> + <VnInput v-model="data.alias" :label="t('globals.name')" /> </div> </VnRow> <VnRow> <div class="col"> - <VnInput - v-model="data.description" - :label="t('mailAlias.description')" - /> + <VnInput v-model="data.description" :label="t('role.description')" /> </div> </VnRow> </template> diff --git a/src/pages/Account/Alias/Card/AliasBasicData.vue b/src/pages/Account/Alias/Card/AliasBasicData.vue index ba940cda5..c78dfb4df 100644 --- a/src/pages/Account/Alias/Card/AliasBasicData.vue +++ b/src/pages/Account/Alias/Card/AliasBasicData.vue @@ -11,8 +11,8 @@ const { t } = useI18n(); <FormModel model="Alias"> <template #form="{ data }"> <div class="column q-gutter-y-md"> - <VnInput v-model="data.alias" :label="t('mailAlias.name')" /> - <VnInput v-model="data.description" :label="t('mailAlias.description')" /> + <VnInput v-model="data.alias" :label="t('globals.name')" /> + <VnInput v-model="data.description" :label="t('role.description')" /> <QCheckbox :label="t('mailAlias.isPublic')" v-model="data.isPublic" /> </div> </template> diff --git a/src/pages/Account/Alias/Card/AliasDescriptor.vue b/src/pages/Account/Alias/Card/AliasDescriptor.vue index 963f84547..713cecf75 100644 --- a/src/pages/Account/Alias/Card/AliasDescriptor.vue +++ b/src/pages/Account/Alias/Card/AliasDescriptor.vue @@ -71,7 +71,7 @@ const removeAlias = () => { </QItem> </template> <template #body="{ entity }"> - <VnLv :label="t('mailAlias.description')" :value="entity.description" /> + <VnLv :label="t('role.description')" :value="entity.description" /> </template> </CardDescriptor> </template> diff --git a/src/pages/Account/Alias/Card/AliasSummary.vue b/src/pages/Account/Alias/Card/AliasSummary.vue index b2dc1f0fc..1f76fe7c2 100644 --- a/src/pages/Account/Alias/Card/AliasSummary.vue +++ b/src/pages/Account/Alias/Card/AliasSummary.vue @@ -42,8 +42,8 @@ const entityId = computed(() => $props.id || route.params.id); <QIcon name="open_in_new" /> </router-link> </QCardSection> - <VnLv :label="t('mailAlias.id')" :value="alias.id" /> - <VnLv :label="t('mailAlias.description')" :value="alias.description" /> + <VnLv :label="t('role.id')" :value="alias.id" /> + <VnLv :label="t('role.description')" :value="alias.description" /> </QCard> </template> </CardSummary> diff --git a/src/pages/Account/Card/AccountBasicData.vue b/src/pages/Account/Card/AccountBasicData.vue index f1cdaf9df..e6c9da6fe 100644 --- a/src/pages/Account/Card/AccountBasicData.vue +++ b/src/pages/Account/Card/AccountBasicData.vue @@ -36,7 +36,7 @@ watch( <div class="q-gutter-y-sm"> <VnInput v-model="data.name" :label="t('account.card.nickname')" /> <VnInput v-model="data.nickname" :label="t('account.card.alias')" /> - <VnInput v-model="data.email" :label="t('account.card.email')" /> + <VnInput v-model="data.email" :label="t('globals.params.email')" /> <VnSelect url="Languages" v-model="data.lang" diff --git a/src/pages/Account/Role/AccountRolesFilter.vue b/src/pages/Account/Role/AccountRolesFilter.vue index 8340b965d..ff4411897 100644 --- a/src/pages/Account/Role/AccountRolesFilter.vue +++ b/src/pages/Account/Role/AccountRolesFilter.vue @@ -29,7 +29,7 @@ const props = defineProps({ <QItem class="q-my-sm"> <QItemSection> <VnInput - :label="t('role.name')" + :label="t('globals.name')" v-model="params.name" lazy-rules is-outlined diff --git a/src/pages/Account/Role/Card/RoleBasicData.vue b/src/pages/Account/Role/Card/RoleBasicData.vue index 56f4f0c27..1de9ff387 100644 --- a/src/pages/Account/Role/Card/RoleBasicData.vue +++ b/src/pages/Account/Role/Card/RoleBasicData.vue @@ -12,15 +12,12 @@ const { t } = useI18n(); <template #form="{ data }"> <VnRow> <div class="col"> - <VnInput v-model="data.name" :label="t('role.card.name')" /> + <VnInput v-model="data.name" :label="t('globals.name')" /> </div> </VnRow> <VnRow> <div class="col"> - <VnInput - v-model="data.description" - :label="t('role.card.description')" - /> + <VnInput v-model="data.description" :label="t('role.description')" /> </div> </VnRow> </template> diff --git a/src/pages/Account/Role/Card/RoleDescriptor.vue b/src/pages/Account/Role/Card/RoleDescriptor.vue index e4af3ed13..af018565a 100644 --- a/src/pages/Account/Role/Card/RoleDescriptor.vue +++ b/src/pages/Account/Role/Card/RoleDescriptor.vue @@ -58,7 +58,7 @@ const removeRole = async () => { </QItem> </template> <template #body="{ entity }"> - <VnLv :label="t('role.card.description')" :value="entity.description" /> + <VnLv :label="t('role.description')" :value="entity.description" /> </template> </CardDescriptor> </template> diff --git a/src/pages/Account/Role/Card/RoleForm.vue b/src/pages/Account/Role/Card/RoleForm.vue index 382639beb..09a098085 100644 --- a/src/pages/Account/Role/Card/RoleForm.vue +++ b/src/pages/Account/Role/Card/RoleForm.vue @@ -22,15 +22,12 @@ const { t } = useI18n(); <template #form-inputs="{ data }"> <VnRow> <div class="col"> - <VnInput v-model="data.name" :label="t('role.card.name')" /> + <VnInput v-model="data.name" :label="t('globals.name')" /> </div> </VnRow> <VnRow> <div class="col"> - <VnInput - v-model="data.description" - :label="t('role.card.description')" - /> + <VnInput v-model="data.description" :label="t('role.description')" /> </div> </VnRow> </template> diff --git a/src/pages/Account/Role/Card/RoleSummary.vue b/src/pages/Account/Role/Card/RoleSummary.vue index 76c72e947..fef85f919 100644 --- a/src/pages/Account/Role/Card/RoleSummary.vue +++ b/src/pages/Account/Role/Card/RoleSummary.vue @@ -44,9 +44,9 @@ const filter = { <QIcon name="open_in_new" /> </a> </QCardSection> - <VnLv :label="t('role.card.id')" :value="role.id" /> - <VnLv :label="t('role.card.name')" :value="role.name" /> - <VnLv :label="t('role.card.description')" :value="role.description" /> + <VnLv :label="t('role.id')" :value="role.id" /> + <VnLv :label="t('globals.name')" :value="role.name" /> + <VnLv :label="t('role.description')" :value="role.description" /> </QCard> </template> </CardSummary> diff --git a/src/pages/Account/locale/en.yml b/src/pages/Account/locale/en.yml index fe8707eb8..f2f563923 100644 --- a/src/pages/Account/locale/en.yml +++ b/src/pages/Account/locale/en.yml @@ -1,32 +1,15 @@ account: - pageTitles: - users: Users - list: Users - roles: Roles - alias: Mail aliasses - accounts: Accounts - ldap: LDAP - samba: Samba - acls: ACLs - connections: Connections - inheritedRoles: Inherited Roles - subRoles: Sub Roles - newRole: New role - privileges: Privileges - mailAlias: Mail Alias - mailForwarding: Mail Forwarding - accountCreate: New user - aliasUsers: Users card: - name: Name nickname: User role: Role - email: Email alias: Alias lang: Language roleFk: Role newUser: New user ticketTracking: Ticket tracking + enableSync: Habilitar sincronización + groupDN: DN grupos + testConnection: Probar conexión privileges: delegate: Can delegate privileges enabled: Account enabled! @@ -74,11 +57,7 @@ account: search: Search user searchInfo: You can search by id, name or nickname create: - name: Name nickname: Nickname - email: Email - role: Role - password: Password active: Active mailForwarding: forwardingMail: Forward email @@ -86,50 +65,30 @@ account: enableMailForwarding: Enable mail forwarding mailInputInfo: All emails will be forwarded to the specified address. role: - pageTitles: - inheritedRoles: Inherited Roles - subRoles: Sub Roles - card: - description: Description - id: Id - name: Name newRole: New role searchRoles: Search role searchInfo: Search role by id or name - name: Name description: Description id: Id mailAlias: - pageTitles: - aliasUsers: Users search: Search mail alias searchInfo: Search alias by id or name - alias: Alias - description: Description - id: Id newAlias: New alias - name: Name isPublic: Public ldap: - enableSync: Enable synchronization server: Server rdn: RDN userDN: User DN filter: Filter - groupDN: Group DN - testConnection: Test connection success: LDAP connection established! password: Password samba: - enableSync: Enable synchronization domainController: Domain controller domainAD: AD domain userAD: AD user - groupDN: Group DN passwordAD: AD password domainPart: User DN (without domain part) verifyCertificate: Verify certificate - testConnection: Test connection success: Samba connection established! accounts: homedir: Homedir base @@ -147,8 +106,6 @@ connections: created: Created killSession: Kill session acls: - role: Role - accessType: Access type permissions: Permission search: Search acls searchInfo: Search acls by model name diff --git a/src/pages/Account/locale/es.yml b/src/pages/Account/locale/es.yml index 112ffe9cc..ba559f2c3 100644 --- a/src/pages/Account/locale/es.yml +++ b/src/pages/Account/locale/es.yml @@ -1,27 +1,7 @@ account: - pageTitles: - users: Usuarios - list: Usuarios - roles: Roles - alias: Alias de correo - accounts: Cuentas - ldap: LDAP - samba: Samba - acls: ACLs - connections: Conexiones - inheritedRoles: Roles heredados - newRole: Nuevo rol - subRoles: Subroles - privileges: Privilegios - mailAlias: Alias de correo - mailForwarding: Reenvío de correo - accountCreate: Nuevo usuario - aliasUsers: Usuarios card: nickname: Usuario - name: Nombre role: Rol - email: Mail alias: Alias lang: Idioma roleFk: Rol @@ -33,6 +13,9 @@ account: deactivated: ¡Usuario desactivado! newUser: Nuevo usuario twoFactor: Doble factor + enableSync: Habilitar sincronización + groupDN: DN grupos + testConnection: Probar conexión privileges: delegate: Puede delegar privilegios actions: @@ -73,11 +56,7 @@ account: search: Buscar usuario searchInfo: Puedes buscar por id, nombre o usuario create: - name: Nombre nickname: Nombre mostrado - email: Email - role: Rol - password: Contraseña active: Activo mailForwarding: forwardingMail: Dirección de reenvío @@ -85,51 +64,30 @@ account: enableMailForwarding: Habilitar redirección de correo mailInputInfo: Todos los correos serán reenviados a la dirección especificada, no se mantendrá copia de los mismos en el buzón del usuario. role: - pageTitles: - inheritedRoles: Roles heredados - subRoles: Subroles - newRole: Nuevo rol - card: - description: Descripción - id: Id - name: Nombre newRole: Nuevo rol searchRoles: Buscar roles searchInfo: Buscar rol por id o nombre - name: Nombre description: Descripción id: Id mailAlias: - pageTitles: - aliasUsers: Usuarios search: Buscar alias de correo searchInfo: Buscar alias por id o nombre - alias: Alias - description: Descripción - id: Id newAlias: Nuevo alias - name: Nombre isPublic: Público ldap: password: Contraseña - enableSync: Habilitar sincronización server: Servidor rdn: RDN userDN: DN usuarios filter: Filtro - groupDN: DN grupos - testConnection: Probar conexión success: ¡Conexión con LDAP establecida! samba: - enableSync: Habilitar sincronización domainController: Controlador de dominio domainAD: Dominio AD - groupDN: DN grupos userAD: Usuario AD passwordAD: Contraseña AD domainPart: DN usuarios (sin la parte del dominio) verifyCertificate: Verificar certificado - testConnection: Probar conexión success: ¡Conexión con Samba establecida! accounts: homedir: Directorio base para carpetas de usuario @@ -147,8 +105,6 @@ connections: created: Creado killSession: Matar sesión acls: - role: Rol - accessType: Tipo de acceso permissions: Permiso search: Buscar acls searchInfo: Buscar acls por nombre From 89cb9aacec0ebbca0b539fbfa69586e65ed45f15 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Fri, 18 Oct 2024 12:54:21 +0200 Subject: [PATCH 047/207] refactor: refs #7132 1st wave of changes in global translations files --- src/components/FilterTravelForm.vue | 4 +- src/components/common/VnDms.vue | 2 +- src/i18n/locale/en.yml | 71 +------------------ src/i18n/locale/es.yml | 68 ------------------ .../Department/Card/DepartmentBasicData.vue | 4 +- .../Department/Card/DepartmentSummary.vue | 6 +- src/pages/Entry/Card/EntryBasicData.vue | 5 +- src/pages/Entry/Card/EntryBuys.vue | 5 +- src/pages/Entry/Card/EntryBuysImport.vue | 7 +- src/pages/Entry/Card/EntrySummary.vue | 6 +- src/pages/Entry/EntryLatestBuys.vue | 8 +-- src/pages/Entry/EntryList.vue | 2 +- .../InvoiceOut/Card/InvoiceOutSummary.vue | 2 +- .../InvoiceOutNegativeBasesFilter.vue | 6 +- src/pages/Item/Card/ItemSummary.vue | 4 +- src/pages/Item/ItemRequest.vue | 2 +- src/pages/Order/Card/OrderSummary.vue | 6 +- .../Shelving/Card/ShelvingDescriptor.vue | 2 +- src/pages/Shelving/Card/ShelvingForm.vue | 2 +- src/pages/Shelving/Card/ShelvingSummary.vue | 2 +- .../Supplier/Card/SupplierConsumption.vue | 6 +- src/pages/Supplier/Card/SupplierSummary.vue | 2 +- src/pages/Ticket/Card/TicketDescriptor.vue | 4 +- src/pages/Ticket/Card/TicketSummary.vue | 17 ++--- src/pages/Travel/Card/TravelBasicData.vue | 7 +- src/pages/Travel/Card/TravelSummary.vue | 2 +- src/pages/Travel/Card/TravelThermographs.vue | 2 +- .../Travel/Card/TravelThermographsForm.vue | 4 +- src/pages/Travel/TravelList.vue | 2 +- src/pages/Wagon/WagonCreate.vue | 6 +- src/pages/Wagon/WagonList.vue | 2 +- src/pages/Worker/Card/WorkerDescriptor.vue | 2 +- src/pages/Worker/Card/WorkerFormation.vue | 2 +- src/pages/Worker/Card/WorkerMedical.vue | 4 +- src/pages/Worker/Card/WorkerSummary.vue | 4 +- 35 files changed, 61 insertions(+), 219 deletions(-) diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue index c84772d9b..841a55bba 100644 --- a/src/components/FilterTravelForm.vue +++ b/src/components/FilterTravelForm.vue @@ -70,7 +70,7 @@ const tableColumns = computed(() => [ warehousesOptions.value.find((warehouse) => warehouse.id === val).name, }, { - label: t('entry.basicData.shipped'), + label: t('globals.shipped'), name: 'shipped', field: 'shipped', align: 'left', @@ -170,7 +170,7 @@ const selectTravel = ({ id }) => { v-model="travelFilterParams.warehouseInFk" /> <VnInputDate - :label="t('entry.basicData.shipped')" + :label="t('globals.shipped')" v-model="travelFilterParams.shipped" /> <VnInputDate diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 920b7f137..d2b40d7d6 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -158,7 +158,7 @@ function addDefaultData(data) { /> <QFile ref="inputFileRef" - :label="t('entry.buys.file')" + :label="t('globals.file')" v-model="dms.files" :multiple="false" :accept="allowedContentTypes" diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index b73395df2..f4d258585 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -300,8 +300,6 @@ globals: salesPersonFk: Sales person warehouseFk: Warehouse provinceFk: Province - from: From - To: To stateFk: State departmentFk: Department email: Email @@ -328,8 +326,7 @@ login: loginError: Invalid username or password fieldRequired: This field is required twoFactorRequired: Two-factor verification required -twoFactor: - code: Code +twoFactorRequired: validate: Validate insert: Enter the verification code explanation: >- @@ -357,7 +354,6 @@ entry: ordered: Ordered tableVisibleColumns: id: Id - reference: Reference created: Creation supplierFk: Supplier isBooked: Booked @@ -372,7 +368,6 @@ entry: commission: Commission currency: Currency company: Company - reference: Reference invoiceNumber: Invoice number ordered: Ordered confirmed: Confirmed @@ -388,10 +383,8 @@ entry: travelWarehouseIn: Warehouse In travelReceived: Received buys: Buys - quantity: Quantity stickers: Stickers package: Package - weight: Weight packing: Packing grouping: Grouping buyingValue: Buying value @@ -401,7 +394,6 @@ entry: basicData: supplier: Supplier travel: Travel - reference: Reference invoiceNumber: Invoice number company: Company currency: Currency @@ -415,13 +407,11 @@ entry: agency: Agency warehouseOut: Warehouse Out warehouseIn: Warehouse In - shipped: Shipped landed: Landed id: ID buys: groupingPrice: Grouping price packingPrice: Packing price - reference: Reference observations: Observations item: Item size: Size @@ -429,7 +419,6 @@ entry: grouping: Grouping buyingValue: Buying value packagingFk: Box - file: File name: Name producer: Producer type: Type @@ -448,7 +437,6 @@ entry: itemFk: Item ID packing: Packing grouping: Grouping - quantity: Quantity size: Size tags: Tags type: Type @@ -461,14 +449,12 @@ entry: buyingValue: Buying value freightValue: Freight value comissionValue: Commission value - description: Description packageValue: Package value isIgnored: Is ignored price2: Grouping price3: Packing minPrice: Min ektFk: Ekt - weight: Weight packagingFk: Package packingOut: Package out landing: Landing @@ -476,17 +462,10 @@ entry: isRaid: Raid ticket: pageTitles: - tickets: Tickets list: List - ticketCreate: New ticket summary: Summary - basicData: Basic Data - boxing: Boxing - sms: Sms - notes: Notes sale: Sale dms: File management - volume: Volume observation: Notes ticketAdvance: Advance tickets futureTickets: Future tickets @@ -495,17 +474,13 @@ ticket: list: nickname: Nickname state: State - shipped: Shipped landed: Landed - salesPerson: Sales person total: Total card: ticketId: Ticket ID state: State customerId: Customer ID - salesPerson: Sales person agency: Agency - shipped: Shipped warehouse: Warehouse customerCard: Customer card alias: Alias @@ -521,7 +496,6 @@ ticket: notFound: No videos available summary: state: State - salesPerson: Sales person agency: Agency zone: Zone warehouse: Warehouse @@ -543,7 +517,6 @@ ticket: item: Item visible: Visible available: Available - quantity: Quantity price: Price discount: Discount packing: Packing @@ -559,12 +532,10 @@ ticket: requester: Requester atender: Atender request: Request - weight: Weight goTo: Go to summaryAmount: Summary purchaseRequest: Purchase request service: Service - description: Description attender: Attender ok: Ok create: @@ -584,7 +555,6 @@ invoiceOut: company: Company dued: Due date shortDued: Due date - amount: Amount card: issued: Issued client: Client @@ -604,7 +574,6 @@ invoiceOut: tickets: Tickets ticketId: Ticket id nickname: Alias - shipped: Shipped totalWithVat: Amount globalInvoices: errors: @@ -625,13 +594,10 @@ invoiceOut: percentageText: '{getPercentage}% {getAddressNumber} of {getNAddresses}' pdfsNumberText: '{nPdfs} of {totalPdfs} PDFs' negativeBases: - from: From - to: To company: Company country: Country clientId: Client Id client: Client - amount: Amount base: Base ticketId: Ticket Id active: Active @@ -646,13 +612,11 @@ shelving: priority: Priority newShelving: New Shelving summary: - code: Code parking: Parking priority: Priority worker: Worker recyclable: Recyclable basicData: - code: Code parking: Parking priority: Priority recyclable: Recyclable @@ -694,7 +658,6 @@ order: phone: Phone createdFrom: Created From address: Address - notes: Notes subtotal: Subtotal total: Total vat: VAT @@ -702,18 +665,14 @@ order: alias: Alias items: Items orderTicketList: Order Ticket List - details: Details item: Item - quantity: Quantity price: Price amount: Amount department: pageTitles: - basicData: Basic data department: Department summary: Summary name: Name - code: Code chat: Chat bossDepartment: Boss Department email: Email @@ -728,20 +687,16 @@ worker: pageTitles: workers: Workers list: List - basicData: Basic data summary: Summary - notifications: Notifications workerCreate: New worker department: Department pda: PDA - notes: Notas dms: My documentation pbx: Private Branch Exchange log: Log calendar: Calendar timeControl: Time control locker: Locker - balance: Balance medical: Medical list: name: Name @@ -754,7 +709,6 @@ worker: newWorker: New worker card: workerId: Worker ID - user: User name: Name email: Email phone: Phone @@ -762,9 +716,7 @@ worker: active: Active warehouse: Warehouse agency: Agency - salesPerson: Sales person summary: - basicData: Basic data boss: Boss phoneExtension: Phone extension entPhone: Enterprise phone @@ -820,16 +772,13 @@ worker: endDate: End date center: Training center invoice: Invoice - amount: Amount remark: Remark hasDiploma: Has diploma medical: tableVisibleColumns: - date: Date time: Hour center: Formation Center invoice: Invoice - amount: Amount isFit: Fit remark: Observations imageNotFound: Image not found @@ -865,7 +814,6 @@ wagon: removeItem: Wagon removed successfully create: plate: Plate - volume: Volume type: Type label: Label warnings: @@ -898,7 +846,6 @@ supplier: country: Country summary: responsible: Responsible - notes: Notes verified: Verified isActive: Is active billingData: Billing data @@ -978,15 +925,12 @@ supplier: addRow: Add row consumption: entry: Entry - date: Date - reference: Reference travel: travelList: tableVisibleColumns: id: Id ref: Reference agency: Agency - shipped: Shipped landed: Landed shipHour: Shipment Hour landHour: Landing Hour @@ -1017,29 +961,23 @@ travel: landedFrom: Landed from landedTo: Landed to continent: Continent out - totalEntries: Total entries basicData: - reference: Reference agency: Agency - shipped: Shipped landed: Landed warehouseOut: Warehouse Out warehouseIn: Warehouse In delivered: Delivered received: Received thermographs: - code: Code temperature: Temperature state: State destination: Destination created: Created thermograph: Thermograph - reference: Reference type: Type company: Company warehouse: Warehouse travelFileDescription: 'Travel id { travelId }' - file: File item: descriptor: item: Item @@ -1056,7 +994,6 @@ item: id: Identifier grouping: Grouping packing: Packing - description: Description stems: Stems category: Category typeName: Type @@ -1087,7 +1024,6 @@ item: origin: Origin buyRequest: ticketId: 'Ticket ID' - shipped: 'Shipped' requester: 'Requester' requested: 'Requested' price: 'Price' @@ -1097,9 +1033,7 @@ item: concept: 'Concept' state: 'State' summary: - basicData: 'Basic data' otherData: 'Other data' - description: 'Description' tax: 'Tax' tags: 'Tags' botanical: 'Botanical' @@ -1143,7 +1077,6 @@ components: salesPersonFk: Buyer supplierFk: Supplier from: From - to: To active: Is active visible: Is visible floramondo: Is floramondo @@ -1151,7 +1084,6 @@ components: userPanel: copyToken: Token copied to clipboard settings: Settings - logOut: Log Out localWarehouse: Local warehouse localBank: Local bank localCompany: Local company @@ -1159,7 +1091,6 @@ components: userCompany: User company smartCard: downloadFile: Download file - clone: Clone openCard: View openSummary: Summary cardDescriptor: diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 2552c9549..a8d582c30 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -304,8 +304,6 @@ globals: salesPersonFk: Comercial warehouseFk: Almacén provinceFk: Provincia - from: Desde - To: Hasta stateFk: Estado departmentFk: Departamento email: Correo @@ -333,7 +331,6 @@ login: fieldRequired: Este campo es obligatorio twoFactorRequired: Verificación de doble factor requerida twoFactor: - code: Código validate: Validar insert: Introduce el código de verificación explanation: Por favor introduce el código de verificación que te hemos enviado a tu email en los próximos 5 minutos @@ -359,7 +356,6 @@ entry: ordered: Pedida tableVisibleColumns: id: Id - reference: Referencia created: Creación supplierFk: Proveedor isBooked: Asentado @@ -374,7 +370,6 @@ entry: commission: Comisión currency: Moneda company: Empresa - reference: Referencia invoiceNumber: Núm. factura ordered: Pedida confirmed: Confirmada @@ -390,10 +385,8 @@ entry: travelWarehouseIn: Alm. entrada travelReceived: Recibida buys: Compras - quantity: Cantidad stickers: Etiquetas package: Embalaje - weight: Peso packing: Packing grouping: Grouping buyingValue: Coste @@ -403,7 +396,6 @@ entry: basicData: supplier: Proveedor travel: Envío - reference: Referencia invoiceNumber: Núm. factura company: Empresa currency: Moneda @@ -417,13 +409,11 @@ entry: agency: Agencia warehouseOut: Alm. salida warehouseIn: Alm. entrada - shipped: F. envío landed: F. entrega id: ID buys: groupingPrice: Precio grouping packingPrice: Precio packing - reference: Referencia observations: Observaciónes item: Artículo size: Medida @@ -431,7 +421,6 @@ entry: grouping: Grouping buyingValue: Coste packagingFk: Embalaje - file: Fichero name: Nombre producer: Productor type: Tipo @@ -450,7 +439,6 @@ entry: itemFk: Id Artículo packing: packing grouping: Grouping - quantity: Cantidad size: Medida tags: Etiquetas type: Tipo @@ -463,14 +451,12 @@ entry: buyingValue: Coste freightValue: Porte comissionValue: Comisión - description: Descripción packageValue: Embalaje isIgnored: Ignorado price2: Grouping price3: Packing minPrice: Min ektFk: Ekt - weight: Peso packagingFk: Embalaje packingOut: Embalaje envíos landing: Llegada @@ -478,17 +464,9 @@ entry: isRaid: Redada ticket: pageTitles: - tickets: Tickets list: Listado - ticketCreate: Nuevo ticket summary: Resumen - basicData: Datos básicos - boxing: Encajado - sms: Sms - notes: Notas - sale: Lineas del pedido dms: Gestión documental - volume: Volumen observation: Notas ticketAdvance: Adelantar tickets futureTickets: Tickets a futuro @@ -500,21 +478,16 @@ ticket: tracking: Estados components: Componentes pictures: Fotos - packages: Embalajes list: nickname: Alias state: Estado - shipped: Enviado landed: Entregado - salesPerson: Comercial total: Total card: ticketId: ID ticket state: Estado customerId: ID cliente - salesPerson: Comercial agency: Agencia - shipped: Enviado warehouse: Almacén customerCard: Ficha del cliente alias: Alias @@ -530,7 +503,6 @@ ticket: notFound: No hay vídeos disponibles summary: state: Estado - salesPerson: Comercial agency: Agencia zone: Zona warehouse: Almacén @@ -552,7 +524,6 @@ ticket: item: Artículo visible: Visible available: Disponible - quantity: Cantidad price: Precio discount: Descuento packing: Encajado @@ -568,12 +539,10 @@ ticket: requester: Solicitante atender: Comprador request: Petición de compra - weight: Peso goTo: Ir a summaryAmount: Resumen purchaseRequest: Petición de compra service: Servicio - description: Descripción attender: Consignatario create: client: Cliente @@ -592,7 +561,6 @@ invoiceOut: company: Empresa dued: Fecha vencimineto shortDued: F. vencimiento - amount: Importe card: issued: Fecha emisión client: Cliente @@ -613,7 +581,6 @@ invoiceOut: tickets: Tickets ticketId: Id ticket nickname: Alias - shipped: F. envío totalWithVat: Importe globalInvoices: errors: @@ -638,7 +605,6 @@ invoiceOut: country: País clientId: Id cliente client: Cliente - amount: Importe base: Base ticketId: Id ticket active: Activo @@ -675,7 +641,6 @@ order: phone: Teléfono createdFrom: Creado desde address: Dirección - notes: Notas subtotal: Subtotal total: Total vat: IVA @@ -683,9 +648,7 @@ order: alias: Alias items: Items orderTicketList: Tickets del pedido - details: Detalles item: Item - quantity: Cantidad price: Precio amount: Monto shelving: @@ -694,13 +657,11 @@ shelving: priority: Prioridad newShelving: Nuevo Carro summary: - code: Código parking: Parking priority: Prioridad worker: Trabajador recyclable: Reciclable basicData: - code: Código parking: Parking priority: Prioridad recyclable: Reciclable @@ -715,11 +676,9 @@ parking: label: Buscar parking... department: pageTitles: - basicData: Basic data department: Departamentos summary: Resumen name: Nombre - code: Código chat: Chat bossDepartment: Jefe de departamento email: Email @@ -734,20 +693,16 @@ worker: pageTitles: workers: Trabajadores list: Listado - basicData: Datos básicos summary: Resumen - notifications: Notificaciones workerCreate: Nuevo trabajador department: Departamentos pda: PDA - notes: Notas dms: Mi documentación pbx: Centralita log: Historial calendar: Calendario timeControl: Control de horario locker: Taquilla - balance: Balance formation: Formación medical: Mutua list: @@ -761,7 +716,6 @@ worker: newWorker: Nuevo trabajador card: workerId: ID Trabajador - user: Usuario name: Nombre email: Correo personal phone: Teléfono @@ -769,9 +723,7 @@ worker: active: Activo warehouse: Almacén agency: Empresa - salesPerson: Comercial summary: - basicData: Datos básicos boss: Jefe phoneExtension: Extensión de teléfono entPhone: Teléfono de empresa @@ -818,16 +770,13 @@ worker: endDate: Fecha Fin center: Centro Formación invoice: Factura - amount: Importe remark: Bonficado hasDiploma: Diploma medical: tableVisibleColumns: - date: Fecha time: Hora center: Centro de Formación invoice: Factura - amount: Importe isFit: Apto remark: Observaciones imageNotFound: No se ha encontrado la imagen @@ -863,7 +812,6 @@ wagon: removeItem: Vagón borrado correctamente create: plate: Matrícula - volume: Volumen type: Tipo label: Etiqueta warnings: @@ -895,7 +843,6 @@ supplier: country: País summary: responsible: Responsable - notes: Notas verified: Verificado isActive: Está activo billingData: Forma de pago @@ -975,15 +922,12 @@ supplier: addRow: Añadir fila consumption: entry: Entrada - date: Fecha - reference: Referencia travel: travelList: tableVisibleColumns: id: Id ref: Referencia agency: Agencia - shipped: F.envío shipHour: Hora de envío landHour: Hora de llegada landed: F.entrega @@ -1014,29 +958,23 @@ travel: landedFrom: Llegada desde landedTo: Llegada hasta continent: Cont. Salida - totalEntries: Ent. totales basicData: - reference: Referencia agency: Agencia - shipped: F. Envío landed: F. entrega warehouseOut: Alm. salida warehouseIn: Alm. entrada delivered: Enviada received: Recibida thermographs: - code: Código temperature: Temperatura state: Estado destination: Destino created: Fecha creación thermograph: Termógrafo - reference: Referencia type: Tipo company: Empresa warehouse: Almacén travelFileDescription: 'Id envío { travelId }' - file: Fichero item: descriptor: item: Artículo @@ -1053,7 +991,6 @@ item: id: Identificador grouping: Grouping packing: Packing - description: Descripción stems: Tallos category: Reino typeName: Tipo @@ -1083,9 +1020,7 @@ item: intrastat: Intrastat origin: Origen summary: - basicData: 'Datos básicos' otherData: 'Otros datos' - description: 'Descripción' tax: 'IVA' tags: 'Etiquetas' botanical: 'Botánico' @@ -1114,7 +1049,6 @@ item: specie: 'Specie' buyRequest: ticketId: 'ID Ticket' - shipped: 'F. envío' requester: 'Solicitante' requested: 'Solicitado' price: 'Precio' @@ -1146,7 +1080,6 @@ components: userPanel: copyToken: Token copiado al portapapeles settings: Configuración - logOut: Cerrar sesión localWarehouse: Almacén local localBank: Banco local localCompany: Empresa local @@ -1154,7 +1087,6 @@ components: userCompany: Empresa del usuario smartCard: downloadFile: Descargar archivo - clone: Clonar openCard: Ficha openSummary: Detalles viewSummary: Vista previa diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue index 141bb4159..384881792 100644 --- a/src/pages/Department/Card/DepartmentBasicData.vue +++ b/src/pages/Department/Card/DepartmentBasicData.vue @@ -28,8 +28,8 @@ const { t } = useI18n(); /> <VnInput v-model="data.code" - :label="t('department.code')" - :rules="validate('department.code')" + :label="t('globals.code')" + :rules="validate('globals.code')" clearable /> </VnRow> diff --git a/src/pages/Department/Card/DepartmentSummary.vue b/src/pages/Department/Card/DepartmentSummary.vue index ecbb39ed0..05a9e073e 100644 --- a/src/pages/Department/Card/DepartmentSummary.vue +++ b/src/pages/Department/Card/DepartmentSummary.vue @@ -50,11 +50,7 @@ onMounted(async () => { :value="department.name" dash /> - <VnLv - :label="t('department.code')" - :value="department.code" - dash - /> + <VnLv :label="t('globals.code')" :value="department.code" dash /> <VnLv :label="t('department.chat')" :value="department.chatName" diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index b81b1db22..2a00bfd74 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -108,10 +108,7 @@ const onFilterTravelSelected = (formData, id) => { </VnSelectDialog> </VnRow> <VnRow> - <VnInput - v-model="data.reference" - :label="t('entry.basicData.reference')" - /> + <VnInput v-model="data.reference" :label="t('globals.reference')" /> </VnRow> <VnRow> <VnInput diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue index ff89faada..35972b85a 100644 --- a/src/pages/Entry/Card/EntryBuys.vue +++ b/src/pages/Entry/Card/EntryBuys.vue @@ -5,7 +5,6 @@ import { useI18n } from 'vue-i18n'; import { QBtn } from 'quasar'; import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'components/common/VnSelect.vue'; import VnInput from 'src/components/common/VnInput.vue'; import FetchedTags from 'components/ui/FetchedTags.vue'; @@ -163,7 +162,7 @@ const entriesTableColumns = computed(() => { align: 'left', }, { - label: t('entry.summary.quantity'), + label: t('globals.quantity'), field: 'quantity', name: 'quantity', align: 'left', @@ -187,7 +186,7 @@ const entriesTableColumns = computed(() => { align: 'left', }, { - label: t('entry.summary.weight'), + label: t('globals.weight'), field: 'weight', name: 'weight', align: 'left', diff --git a/src/pages/Entry/Card/EntryBuysImport.vue b/src/pages/Entry/Card/EntryBuysImport.vue index 8431e1096..36ca3b797 100644 --- a/src/pages/Entry/Card/EntryBuysImport.vue +++ b/src/pages/Entry/Card/EntryBuysImport.vue @@ -200,7 +200,7 @@ const redirectToBuysView = () => { <VnRow> <QFile ref="inputFileRef" - :label="t('entry.buys.file')" + :label="t('globals.file')" v-model="importData.file" :multiple="false" accept=".json" @@ -220,10 +220,7 @@ const redirectToBuysView = () => { </VnRow> <div v-if="importData.file"> <VnRow> - <VnInput - :label="t('entry.buys.reference')" - v-model="importData.ref" - /> + <VnInput :label="t('globals.reference')" v-model="importData.ref" /> </VnRow> <VnRow> <VnInput diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue index 58a5c2e1b..0ed2e8a67 100644 --- a/src/pages/Entry/Card/EntrySummary.vue +++ b/src/pages/Entry/Card/EntrySummary.vue @@ -83,7 +83,7 @@ const tableColumnComponents = { const entriesTableColumns = computed(() => { return [ { - label: t('entry.summary.quantity'), + label: t('globals.quantity'), field: 'quantity', name: 'quantity', align: 'left', @@ -101,7 +101,7 @@ const entriesTableColumns = computed(() => { align: 'left', }, { - label: t('entry.summary.weight'), + label: t('globals.weight'), field: 'weight', name: 'weight', align: 'left', @@ -190,7 +190,7 @@ const fetchEntryBuys = async () => { :value="entry.currency?.name" /> <VnLv :label="t('entry.summary.company')" :value="entry.company.code" /> - <VnLv :label="t('entry.summary.reference')" :value="entry.reference" /> + <VnLv :label="t('globals.reference')" :value="entry.reference" /> <VnLv :label="t('entry.summary.invoiceNumber')" :value="entry.invoiceNumber" diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue index 61c430b23..756948182 100644 --- a/src/pages/Entry/EntryLatestBuys.vue +++ b/src/pages/Entry/EntryLatestBuys.vue @@ -47,12 +47,12 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.quantity'), + label: t('globals.quantity'), name: 'quantity', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.description'), + label: t('globals.description'), name: 'description', }, { @@ -82,7 +82,7 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.weightByPiece'), + label: t('globals.weightByPiece'), name: 'weightByPiece', }, { @@ -147,7 +147,7 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.weight'), + label: t('globals.weight'), name: 'weight', }, { diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 6f7ff1935..e44e3891e 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -50,7 +50,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('entry.list.tableVisibleColumns.reference'), + label: t('globals.reference'), name: 'reference', isTitle: true, component: 'input', diff --git a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue index e9d5a2f1f..83b1bf8a4 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue @@ -86,7 +86,7 @@ const ticketsColumns = ref([ }, { name: 'landed', - label: t('invoiceOut.summary.shipped'), + label: t('globals.shipped'), field: (row) => row.shipped, format: (value) => toDate(value), sortable: true, diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue index 94eab2aab..cf4c27e65 100644 --- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue +++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue @@ -33,7 +33,7 @@ const props = defineProps({ <QItemSection> <VnInputDate v-model="params.from" - :label="t('invoiceOut.negativeBases.from')" + :label="t('globals.from')" is-outlined /> </QItemSection> @@ -42,7 +42,7 @@ const props = defineProps({ <QItemSection> <VnInputDate v-model="params.to" - :label="t('invoiceOut.negativeBases.to')" + :label="t('globals.to')" is-outlined /> </QItemSection> @@ -88,7 +88,7 @@ const props = defineProps({ <QItemSection> <VnInputNumber v-model="params.amount" - :label="t('invoiceOut.negativeBases.amount')" + :label="t('globals.amount')" is-outlined /> </QItemSection> diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue index 7b6015c30..dd2c0649b 100644 --- a/src/pages/Item/Card/ItemSummary.vue +++ b/src/pages/Item/Card/ItemSummary.vue @@ -55,7 +55,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; <QCard class="vn-one"> <VnTitle :url="getUrl(entityId, 'basic-data')" - :text="t('item.summary.basicData')" + :text="t('globals.summary.basicData')" /> <VnLv :label="t('item.summary.name')" :value="item.name" /> <VnLv :label="t('item.summary.completeName')" :value="item.longName" /> @@ -126,7 +126,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; <QCard class="vn-one" v-if="item.description"> <VnTitle :url="getUrl(entityId, 'basic-data')" - :text="t('item.summary.description')" + :text="t('globals.description')" /> <p v-text="item.description" /> </QCard> diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 8a41bbe04..7dd961a35 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -47,7 +47,7 @@ const columns = computed(() => [ sortable: true, }, { - label: t('item.buyRequest.shipped'), + label: t('globals.shipped'), field: 'shipped', name: 'shipped', align: 'left', diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index 60358f744..ceacbc75b 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -35,7 +35,7 @@ const detailsColumns = ref([ }, { name: 'quantity', - label: t('order.summary.quantity'), + label: t('globals.quantity'), field: (row) => row?.quantity, }, { @@ -161,13 +161,13 @@ const detailsColumns = ref([ </VnLv> </QCard> <QCard> - <VnTitle :text="t('order.summary.details')" /> + <VnTitle :text="t('globals.details')" /> <QTable :columns="detailsColumns" :rows="entity?.rows" flat> <template #header="props"> <QTr :props="props"> <QTh auto-width>{{ t('order.summary.item') }}</QTh> <QTh>{{ t('globals.description') }}</QTh> - <QTh auto-width>{{ t('order.summary.quantity') }}</QTh> + <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('order.summary.price') }}</QTh> <QTh auto-width>{{ t('order.summary.amount') }}</QTh> </QTr> diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue index 6beca6d88..30e807d20 100644 --- a/src/pages/Shelving/Card/ShelvingDescriptor.vue +++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue @@ -53,7 +53,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity @on-fetch="setData" > <template #body="{ entity }"> - <VnLv :label="t('shelving.summary.code')" :value="entity.code" /> + <VnLv :label="t('globals.code')" :value="entity.code" /> <VnLv :label="t('shelving.summary.parking')" :value="entity.parking?.code" /> <VnLv v-if="entity.worker" :label="t('shelving.summary.worker')"> <template #value> diff --git a/src/pages/Shelving/Card/ShelvingForm.vue b/src/pages/Shelving/Card/ShelvingForm.vue index dc0234c22..f69d427b0 100644 --- a/src/pages/Shelving/Card/ShelvingForm.vue +++ b/src/pages/Shelving/Card/ShelvingForm.vue @@ -58,7 +58,7 @@ const onSave = (shelving, newShelving) => { <VnRow> <VnInput v-model="data.code" - :label="t('shelving.basicData.code')" + :label="t('globals.code')" :rules="validate('Shelving.code')" /> <VnSelect diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue index 94175b0c1..a196b1992 100644 --- a/src/pages/Shelving/Card/ShelvingSummary.vue +++ b/src/pages/Shelving/Card/ShelvingSummary.vue @@ -54,7 +54,7 @@ const filter = { {{ t('globals.pageTitles.basicData') }} <QIcon name="open_in_new" /> </RouterLink> - <VnLv :label="t('shelving.summary.code')" :value="entity.code" /> + <VnLv :label="t('globals.code')" :value="entity.code" /> <VnLv :label="t('shelving.summary.parking')" :value="entity.parking?.code" diff --git a/src/pages/Supplier/Card/SupplierConsumption.vue b/src/pages/Supplier/Card/SupplierConsumption.vue index 8fa6a1e5c..fe1cec260 100644 --- a/src/pages/Supplier/Card/SupplierConsumption.vue +++ b/src/pages/Supplier/Card/SupplierConsumption.vue @@ -190,13 +190,11 @@ onMounted(async () => { <span>{{ row.id }}</span> </QTd> <QTd no-hover> - <span class="label">{{ t('supplier.consumption.date') }}: </span> + <span class="label">{{ t('globals.date') }}: </span> <span>{{ toDate(row.shipped) }}</span></QTd > <QTd colspan="6" no-hover> - <span class="label" - >{{ t('supplier.consumption.reference') }}: - </span> + <span class="label">{{ t('globals.reference') }}: </span> <span>{{ row.invoiceNumber }}</span> </QTd> </QTr> diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue index 5791db1eb..6ffb95344 100644 --- a/src/pages/Supplier/Card/SupplierSummary.vue +++ b/src/pages/Supplier/Card/SupplierSummary.vue @@ -60,7 +60,7 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`; /> </template> </VnLv> - <VnLv :label="t('supplier.summary.notes')" class="q-mb-xs"> + <VnLv :label="t('globals.notes')" class="q-mb-xs"> <template #value> <span> {{ dashIfEmpty(supplier.note) }} </span> </template> diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue index 70fd9ab1e..af9021e36 100644 --- a/src/pages/Ticket/Card/TicketDescriptor.vue +++ b/src/pages/Ticket/Card/TicketDescriptor.vue @@ -135,7 +135,7 @@ function ticketFilter(ticket) { </QBadge> </template> </VnLv> - <VnLv :label="t('ticket.summary.salesPerson')"> + <VnLv :label="t('globals.salesPerson')"> <template #value> <VnUserLink :name="entity.client?.salesPersonUser?.name" @@ -144,7 +144,7 @@ function ticketFilter(ticket) { </template> </VnLv> <VnLv - :label="t('ticket.card.shipped')" + :label="t('globals.shipped')" :value="toDateTimeFormat(entity.shipped)" /> <VnLv diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index af96c2724..ac2ae0509 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -142,7 +142,7 @@ function toTicketUrl(section) { </QBadge> </template> </VnLv> - <VnLv :label="t('ticket.summary.salesPerson')"> + <VnLv :label="t('globals.salesPerson')"> <template #value> <VnUserLink :name="entity.client?.salesPersonUser?.name" @@ -200,10 +200,7 @@ function toTicketUrl(section) { </span> </template> </VnLv> - <VnLv - :label="t('ticket.summary.weight')" - :value="dashIfEmpty(entity.weight)" - /> + <VnLv :label="t('globals.weight')" :value="dashIfEmpty(entity.weight)" /> </QCard> <QCard class="vn-one" style="flex: 2 1"> <VnTitle @@ -313,7 +310,7 @@ function toTicketUrl(section) { <QTh auto-width>{{ t('ticket.summary.item') }}</QTh> <QTh auto-width>{{ t('ticket.summary.visible') }}</QTh> <QTh auto-width>{{ t('ticket.summary.available') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh> + <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('globals.description') }}</QTh> <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> <QTh auto-width>{{ t('ticket.summary.discount') }}</QTh> @@ -476,7 +473,7 @@ function toTicketUrl(section) { <QTr class="tr-header" :props="props"> <QTh auto-width>{{ t('ticket.summary.created') }}</QTh> <QTh auto-width>{{ t('ticket.summary.package') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh> + <QTh auto-width>{{ t('globals.quantity') }}</QTh> </QTr> </template> <template #body="props"> @@ -496,7 +493,7 @@ function toTicketUrl(section) { <QTable :rows="ticket.services" flat style="text-align: center"> <template #header="props"> <QTr class="tr-header" :props="props"> - <QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh> + <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('globals.description') }}</QTh> <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> <QTh auto-width>{{ t('ticket.summary.taxClass') }}</QTh> @@ -524,11 +521,11 @@ function toTicketUrl(section) { <QTable :rows="ticket.requests" flat style="text-align: center"> <template #header="props"> <QTr class="tr-header" :props="props"> - <QTh auto-width>{{ t('ticket.summary.description') }}</QTh> + <QTh auto-width>{{ t('globals.description') }}</QTh> <QTh auto-width>{{ t('ticket.summary.created') }}</QTh> <QTh auto-width>{{ t('ticket.summary.requester') }}</QTh> <QTh auto-width>{{ t('ticket.summary.attender') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh> + <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> <QTh auto-width>{{ t('ticket.summary.item') }}</QTh> <QTh auto-width>{{ t('ticket.summary.ok') }}</QTh> diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index a3620a6ba..ca9caf82d 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -29,7 +29,7 @@ const agenciesOptions = ref([]); > <template #form="{ data }"> <VnRow> - <VnInput v-model="data.ref" :label="t('travel.basicData.reference')" /> + <VnInput v-model="data.ref" :label="t('globals.reference')" /> <VnSelect :label="t('travel.basicData.agency')" v-model="data.agencyModeFk" @@ -41,10 +41,7 @@ const agenciesOptions = ref([]); /> </VnRow> <VnRow> - <VnInputDate - v-model="data.shipped" - :label="t('travel.basicData.shipped')" - /> + <VnInputDate v-model="data.shipped" :label="t('globals.shipped')" /> <VnInputDate v-model="data.landed" :label="t('travel.basicData.landed')" diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index 4be198493..d48ed2847 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -110,7 +110,7 @@ const entriesTableColumns = computed(() => { const thermographsTableColumns = computed(() => { return [ { - label: t('travel.thermographs.code'), + label: t('globals.code'), field: 'thermographFk', name: 'thermographFk', align: 'left', diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue index e308243e3..96544a8ca 100644 --- a/src/pages/Travel/Card/TravelThermographs.vue +++ b/src/pages/Travel/Card/TravelThermographs.vue @@ -36,7 +36,7 @@ const thermographFilter = { const TableColumns = computed(() => { return [ { - label: t('travel.thermographs.code'), + label: t('globals.code'), field: 'thermographFk', name: 'thermographFk', align: 'left', diff --git a/src/pages/Travel/Card/TravelThermographsForm.vue b/src/pages/Travel/Card/TravelThermographsForm.vue index 5e3ecdc3e..b70e93dfc 100644 --- a/src/pages/Travel/Card/TravelThermographsForm.vue +++ b/src/pages/Travel/Card/TravelThermographsForm.vue @@ -222,7 +222,7 @@ const onThermographCreated = async (data) => { <VnRow> <VnInput v-model="thermographForm.reference" - :label="t('travel.thermographs.reference')" + :label="t('globals.reference')" /> <VnSelect :label="t('travel.thermographs.type')" @@ -279,7 +279,7 @@ const onThermographCreated = async (data) => { <VnRow> <QFile ref="inputFileRef" - :label="t('travel.thermographs.file')" + :label="t('globals.file')" multiple :accept="allowedContentTypes" v-model="thermographForm.files" diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index a8c0e69cb..7ea2b3f7a 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -100,7 +100,7 @@ const columns = computed(() => [ { align: 'left', name: 'shipped', - label: t('travel.travelList.tableVisibleColumns.shipped'), + label: t('globals.shipped'), component: 'date', columnField: { component: null, diff --git a/src/pages/Wagon/WagonCreate.vue b/src/pages/Wagon/WagonCreate.vue index 411c36632..2ec0f4d55 100644 --- a/src/pages/Wagon/WagonCreate.vue +++ b/src/pages/Wagon/WagonCreate.vue @@ -111,12 +111,10 @@ function filterType(val, update) { <QInput filled v-model="wagon.volume" - :label="t('wagon.create.volume')" + :label="t('wagon.list.volume')" type="number" min="0" - :rules="[ - (val) => !!val || t('wagon.warnings.volumeNotEmpty'), - ]" + :rules="[(val) => !!val || t('wagon.warnings.volumeNotEmpty')]" /> <QSelect filled diff --git a/src/pages/Wagon/WagonList.vue b/src/pages/Wagon/WagonList.vue index 02e3b6d16..61679b933 100644 --- a/src/pages/Wagon/WagonList.vue +++ b/src/pages/Wagon/WagonList.vue @@ -129,7 +129,7 @@ async function remove(row) { <VnInput filled v-model="data.volume" - :label="t('wagon.create.volume')" + :label="t('wagon.list.volume')" type="number" min="0" :rules="[(val) => !!val || t('wagon.warnings.volumeNotEmpty')]" diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index 1cb42bbfb..491105e09 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -138,7 +138,7 @@ const handlePhotoUpdated = (evt = false) => { </div> </template> <template #body="{ entity }"> - <VnLv :label="t('worker.card.user')" :value="entity.user?.name" /> + <VnLv :label="t('globals.user')" :value="entity.user?.name" /> <VnLv :label="t('worker.card.email')" :value="entity.user?.emailUser?.email" diff --git a/src/pages/Worker/Card/WorkerFormation.vue b/src/pages/Worker/Card/WorkerFormation.vue index c11dd019e..1f5b54c4a 100644 --- a/src/pages/Worker/Card/WorkerFormation.vue +++ b/src/pages/Worker/Card/WorkerFormation.vue @@ -77,7 +77,7 @@ const columns = computed(() => [ { align: 'left', name: 'amount', - label: t('worker.formation.tableVisibleColumns.amount'), + label: t('globals.amount'), component: 'input', field: 'amount', create: true, diff --git a/src/pages/Worker/Card/WorkerMedical.vue b/src/pages/Worker/Card/WorkerMedical.vue index fab1416c9..bb8c8da58 100644 --- a/src/pages/Worker/Card/WorkerMedical.vue +++ b/src/pages/Worker/Card/WorkerMedical.vue @@ -12,7 +12,7 @@ const columns = [ { align: 'left', name: 'date', - label: t('worker.medical.tableVisibleColumns.date'), + label: t('globals.date'), create: true, component: 'date', }, @@ -47,7 +47,7 @@ const columns = [ { align: 'left', name: 'amount', - label: t('worker.medical.tableVisibleColumns.amount'), + label: t('globals.amount'), create: true, component: 'input', }, diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index ed34e771d..3f562a77b 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -52,7 +52,7 @@ onBeforeMount(async () => { </template> <template #body="{ entity: worker }"> <QCard class="vn-one"> - <VnTitle :url="basicDataUrl" :text="t('worker.summary.basicData')" /> + <VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" /> <VnLv :label="t('worker.card.name')" :value="worker.user?.nickname" /> <VnLv :label="t('worker.list.department')"> <template #value> @@ -91,7 +91,7 @@ onBeforeMount(async () => { </VnLv> </QCard> <QCard class="vn-one" v-if="advancedSummary"> - <VnTitle :url="basicDataUrl" :text="t('worker.summary.basicData')" /> + <VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" /> <VnLv :label="t('worker.summary.fiDueDate')" :value="toDate(worker.fiDueDate)" From 11bf70d76ce3aa42d7c5ae2d94e4ebeb0a281082 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Fri, 18 Oct 2024 14:12:23 +0200 Subject: [PATCH 048/207] fix: category and tags filters --- src/components/ui/VnSearchbar.vue | 4 +- src/pages/Order/Card/OrderCatalogFilter.vue | 111 +++++++++++++++----- 2 files changed, 88 insertions(+), 27 deletions(-) diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index fc292e980..569e0ed18 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -9,7 +9,7 @@ import { useStateStore } from 'src/stores/useStateStore'; const quasar = useQuasar(); const { t } = useI18n(); const state = useStateStore(); -const emit = defineEmits(['on-search']); +const emit = defineEmits(['onSearch']); const props = defineProps({ dataKey: { @@ -119,7 +119,7 @@ async function search() { delete filter.params.search; } await arrayData.applyFilter(filter); - emit('on-search', store.data); + emit('onSearch', store.data); } </script> <template> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 9c713e77e..850212a62 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -1,12 +1,12 @@ <script setup> -import { computed, ref, onMounted } from 'vue'; +import { computed, ref, onMounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; -import VnInput from 'src/components/common/VnInput.vue'; +// import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; const { t } = useI18n(); @@ -48,12 +48,15 @@ const orderBySelected = ref('relevancy DESC, name'); const orderWaySelected = ref('ASC'); const routeQuery = JSON.parse(route?.query.params ?? '{}'); -const params = ref({}); +const paramsSearch = ref({}); onMounted(() => { - const filter = routeQuery.filter; - params.value = JSON.parse(filter ?? '{}')?.where ?? {}; - if (Object.keys(params.value).length > 0) vnFilterPanelRef.value.search(); + paramsSearch.value = JSON.parse(routeQuery.filter ?? '{}')?.where ?? {}; + if (Object.keys(paramsSearch.value).length > 0) vnFilterPanelRef.value.search(); + if (routeQuery.categoryFk && routeQuery.typeFk) { + selectedCategoryFk.value = routeQuery.categoryFk; + selectedTypeFk.value = routeQuery.typeFk; + } }); const createValue = (val, done) => { @@ -70,12 +73,18 @@ const resetCategory = () => { }; const selectCategory = (category, search) => { - if (!params.value?.filter) params.value.filter = { where: {} }; - const where = params.value.filter.where; + if (!paramsSearch.value?.filter) paramsSearch.value.filter = { where: {} }; + const where = paramsSearch.value.filter.where; if (where.categoryFk === category?.id) { resetCategory(); where.categoryFk = null; } else { + if (where.categoryFk && where.categoryFk !== category?.id) { + paramsSearch.value.typeFk = null; + selectedTypeFk.value = null; + typeList.value = []; + } + selectedCategoryFk.value = category?.id; where.categoryFk = category?.id; loadTypes(category?.id); @@ -90,6 +99,10 @@ const loadTypes = async (categoryFk = selectedCategoryFk.value) => { typeList.value = data; }; +watch(selectedTypeFk, (newValue) => { + paramsSearch.value.typeFk = newValue; +}); + const selectedCategory = computed(() => (categoryList.value || []).find( (category) => category?.id === selectedCategoryFk.value @@ -107,25 +120,55 @@ const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); +// const applyTagFilter = (params, search) => { + +// if (params.tagGroups) params.tagGroups = null; +// if (!tagValues.value?.length) { +// params.tagGroups = null; +// search(); +// return; +// } +// if (!params.tagGroups) { +// params.tagGroups = []; +// } +// params.tagGroups.push( +// JSON.stringify({ +// values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), +// tagSelection: { +// ...selectedTag.value, +// orgShowField: selectedTag?.value?.name, +// }, +// tagFk: selectedTag?.value?.tagFk, +// }) +// ); +// search(); +// selectedTag.value = null; +// tagValues.value = [{}]; +// }; + const applyTagFilter = (params, search) => { if (!tagValues.value?.length) { params.tagGroups = null; search(); return; } + if (!params.tagGroups) { params.tagGroups = []; + } else if (typeof params.tagGroups === 'string') { + params.tagGroups = [params.tagGroups]; } - params.tagGroups.push( - JSON.stringify({ - values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), - tagSelection: { - ...selectedTag.value, - orgShowField: selectedTag?.value?.name, - }, - tagFk: selectedTag?.value?.tagFk, - }) - ); + + const newTagGroup = JSON.stringify({ + values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), + tagSelection: { + ...selectedTag.value, + orgShowField: selectedTag?.value?.name, + }, + tagFk: selectedTag?.value?.tagFk, + }); + params.tagGroups.push(newTagGroup); + search(); selectedTag.value = null; tagValues.value = [{}]; @@ -155,6 +198,22 @@ function addOrder(value, field, params) { params.orderBy = JSON.stringify(orderBy); vnFilterPanelRef.value.search(); } + +const data = ref([]); + +function getTagData(value) { + if (Array.isArray(value) && value.length >= 1) { + const parsedTags = value.map((obj) => JSON.parse(obj)); + + if (parsedTags.length === 1) { + data.value = parsedTags[0]; + } else { + data.value = parsedTags; + } + } else { + data.value = JSON.parse(value); + } +} </script> <template> @@ -162,13 +221,14 @@ function addOrder(value, field, params) { <VnFilterPanel ref="vnFilterPanelRef" :data-key="props.dataKey" - v-model="params" + v-model="paramsSearch" :redirect="false" :hidden-tags="['orderFk', 'orderBy', 'filter', 'search', 'or', 'and']" - :un-removable-params="['orderFk', 'orderBy']" + :unremovable-params="['orderFk', 'orderBy']" :disable-submit-event="true" > <template #tags="{ tag, formatFn }"> + {{ console.log('tag.label: ', tag.label) }} <strong v-if="tag.label === 'categoryFk'"> {{ t(selectedCategory?.name || '') }} </strong> @@ -176,10 +236,11 @@ function addOrder(value, field, params) { {{ t(selectedType?.name || '') }} </strong> <div v-else-if="tag.label === 'tagGroups'" class="q-gutter-x-xs"> - <strong v-if="JSON.parse(tag.value).tagSelection.name" - >{{ JSON.parse(tag.value).tagSelection?.name }}: - </strong> - <span>{{ JSON.parse(tag.value).values[0].value }}</span> + {{ getTagData(tag.value) }} + <strong> {{ data.tagSelection?.name }}: </strong> + <span> + {{ console.log('data', data.values) }} + </span> </div> <div v-else class="q-gutter-x-xs"> <strong>{{ t(`params.${tag.label}`) }}: </strong> @@ -328,7 +389,7 @@ function addOrder(value, field, params) { @new-value="createValue" @update:model-value="applyTagFilter(params, searchFn)" /> - <VnInput + <QInput v-else :label="t('params.value')" v-model="value.value" From e5cd9d4b8f40dae59f976dd8afe0da24b6690ea3 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 21 Oct 2024 12:56:09 +0200 Subject: [PATCH 049/207] refactor: refs #7132 global translations files changed --- src/components/FilterItemForm.vue | 14 +- src/components/FilterTravelForm.vue | 16 +- src/components/ItemsFilterPanel.vue | 2 +- src/i18n/locale/en.yml | 311 +++-------------- src/i18n/locale/es.yml | 314 +++--------------- .../Department/Card/DepartmentBasicData.vue | 8 +- .../Department/Card/DepartmentSummary.vue | 6 +- src/pages/Entry/Card/EntryBasicData.vue | 22 +- src/pages/Entry/Card/EntryBuys.vue | 6 +- src/pages/Entry/Card/EntryBuysImport.vue | 8 +- src/pages/Entry/Card/EntryDescriptor.vue | 7 +- src/pages/Entry/Card/EntrySummary.vue | 8 +- src/pages/Entry/EntryBuysTableDialog.vue | 2 +- src/pages/Entry/EntryLatestBuys.vue | 20 +- src/pages/Entry/EntryList.vue | 2 +- .../InvoiceOut/Card/InvoiceOutDescriptor.vue | 4 +- .../InvoiceOut/Card/InvoiceOutSummary.vue | 16 +- src/pages/InvoiceOut/InvoiceOutGlobal.vue | 2 +- .../InvoiceOutNegativeBasesFilter.vue | 6 +- src/pages/Item/Card/ItemDescriptor.vue | 7 +- src/pages/Item/Card/ItemDescriptorImage.vue | 4 +- src/pages/Item/Card/ItemSummary.vue | 10 +- src/pages/Item/ItemCreate.vue | 13 +- src/pages/Item/ItemFixedPrice.vue | 4 +- src/pages/Item/ItemList.vue | 14 +- src/pages/Item/ItemRequest.vue | 8 +- src/pages/Order/Card/OrderBasicData.vue | 2 +- src/pages/Order/Card/OrderCreateDialog.vue | 3 +- src/pages/Order/Card/OrderDescriptor.vue | 10 +- src/pages/Order/Card/OrderSummary.vue | 24 +- .../Shelving/Card/ShelvingDescriptor.vue | 4 +- src/pages/Shelving/Card/ShelvingForm.vue | 6 +- src/pages/Shelving/Card/ShelvingSummary.vue | 9 +- src/pages/Supplier/Card/SupplierAddresses.vue | 9 +- .../Supplier/Card/SupplierAddressesCreate.vue | 20 +- src/pages/Supplier/Card/SupplierBasicData.vue | 2 +- .../Supplier/Card/SupplierBillingData.vue | 2 +- src/pages/Supplier/Card/SupplierContacts.vue | 17 +- .../Supplier/Card/SupplierDescriptor.vue | 2 +- .../Supplier/Card/SupplierFiscalData.vue | 8 +- src/pages/Supplier/Card/SupplierSummary.vue | 11 +- src/pages/Supplier/SupplierList.vue | 12 +- src/pages/Ticket/Card/TicketBoxing.vue | 4 +- src/pages/Ticket/Card/TicketDescriptor.vue | 8 +- src/pages/Ticket/Card/TicketSummary.vue | 39 +-- src/pages/Ticket/TicketCreate.vue | 8 +- src/pages/Ticket/TicketCreateDialog.vue | 8 +- src/pages/Ticket/TicketList.vue | 6 +- src/pages/Travel/Card/TravelBasicData.vue | 15 +- src/pages/Travel/Card/TravelDescriptor.vue | 4 +- src/pages/Travel/Card/TravelSummary.vue | 10 +- src/pages/Travel/Card/TravelThermographs.vue | 4 +- .../Travel/Card/TravelThermographsForm.vue | 8 +- src/pages/Travel/ExtraCommunity.vue | 4 +- src/pages/Travel/TravelCreate.vue | 4 +- src/pages/Travel/TravelList.vue | 10 +- src/pages/Wagon/Type/WagonTypeEdit.vue | 2 +- src/pages/Wagon/WagonCreate.vue | 4 +- src/pages/Wagon/WagonList.vue | 6 +- src/pages/Worker/Card/WorkerDescriptor.vue | 4 +- src/pages/Worker/Card/WorkerSummary.vue | 6 +- src/pages/Worker/WorkerCreate.vue | 10 +- src/pages/Worker/WorkerList.vue | 8 +- 63 files changed, 322 insertions(+), 825 deletions(-) diff --git a/src/components/FilterItemForm.vue b/src/components/FilterItemForm.vue index 1cf36deeb..d1ceff4ce 100644 --- a/src/components/FilterItemForm.vue +++ b/src/components/FilterItemForm.vue @@ -50,25 +50,25 @@ const loading = ref(false); const tableColumns = computed(() => [ { - label: t('entry.buys.id'), + label: t('globals.id'), name: 'id', field: 'id', align: 'left', }, { - label: t('entry.buys.name'), + label: t('globals.name'), name: 'name', field: 'name', align: 'left', }, { - label: t('entry.buys.size'), + label: t('globals.size'), name: 'size', field: 'size', align: 'left', }, { - label: t('entry.buys.producer'), + label: t('globals.producer'), name: 'producerName', field: 'producer', align: 'left', @@ -152,10 +152,10 @@ const selectItem = ({ id }) => { </span> <h1 class="title">{{ t('Filter item') }}</h1> <VnRow> - <VnInput :label="t('entry.buys.name')" v-model="itemFilterParams.name" /> + <VnInput :label="t('globals.name')" v-model="itemFilterParams.name" /> <VnInput :label="t('entry.buys.size')" v-model="itemFilterParams.size" /> <VnSelect - :label="t('entry.buys.producer')" + :label="t('globals.producer')" :options="producersOptions" hide-selected option-label="name" @@ -163,7 +163,7 @@ const selectItem = ({ id }) => { v-model="itemFilterParams.producerFk" /> <VnSelect - :label="t('entry.buys.type')" + :label="t('globals.type')" :options="ItemTypesOptions" hide-selected option-label="name" diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue index 841a55bba..a471552f2 100644 --- a/src/components/FilterTravelForm.vue +++ b/src/components/FilterTravelForm.vue @@ -48,13 +48,13 @@ const loading = ref(false); const tableColumns = computed(() => [ { - label: t('entry.basicData.id'), + label: t('globals.id'), name: 'id', field: 'id', align: 'left', }, { - label: t('entry.basicData.warehouseOut'), + label: t('globals.warehouseOut'), name: 'warehouseOutFk', field: 'warehouseOutFk', align: 'left', @@ -62,7 +62,7 @@ const tableColumns = computed(() => [ warehousesOptions.value.find((warehouse) => warehouse.id === val).name, }, { - label: t('entry.basicData.warehouseIn'), + label: t('globals.warehouseIn'), name: 'warehouseInFk', field: 'warehouseInFk', align: 'left', @@ -77,7 +77,7 @@ const tableColumns = computed(() => [ format: (val) => toDate(val), }, { - label: t('entry.basicData.landed'), + label: t('globals.landed'), name: 'landed', field: 'landed', align: 'left', @@ -146,7 +146,7 @@ const selectTravel = ({ id }) => { <h1 class="title">{{ t('Filter travels') }}</h1> <VnRow> <VnSelect - :label="t('entry.basicData.agency')" + :label="t('globals.agency')" :options="agenciesOptions" hide-selected option-label="name" @@ -154,7 +154,7 @@ const selectTravel = ({ id }) => { v-model="travelFilterParams.agencyModeFk" /> <VnSelect - :label="t('entry.basicData.warehouseOut')" + :label="t('globals.warehouseOut')" :options="warehousesOptions" hide-selected option-label="name" @@ -162,7 +162,7 @@ const selectTravel = ({ id }) => { v-model="travelFilterParams.warehouseOutFk" /> <VnSelect - :label="t('entry.basicData.warehouseIn')" + :label="t('globals.warehouseIn')" :options="warehousesOptions" hide-selected option-label="name" @@ -174,7 +174,7 @@ const selectTravel = ({ id }) => { v-model="travelFilterParams.shipped" /> <VnInputDate - :label="t('entry.basicData.landed')" + :label="t('globals.landed')" v-model="travelFilterParams.landed" /> </VnRow> diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue index e89d32da4..938dceb4d 100644 --- a/src/components/ItemsFilterPanel.vue +++ b/src/components/ItemsFilterPanel.vue @@ -248,7 +248,7 @@ const removeTag = (index, params, search) => { > <QItemSection class="col"> <VnSelect - :label="t('components.itemsFilterPanel.tag')" + :label="t('globals.tag')" v-model="value.selectedTag" :options="tagOptions" option-label="name" diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index f4d258585..aa6e3ba2c 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -59,7 +59,7 @@ globals: downloadCSVSuccess: CSV downloaded successfully reference: Reference agency: Agency - wareHouseOut: Warehouse Out + warehouseOut: Warehouse Out wareHouseIn: Warehouse In landed: Landed shipped: Shipped @@ -106,6 +106,26 @@ globals: weight: Weight error: Ups! Something went wrong recalc: Recalculate + alias: Alias + vat: VAT + intrastat: Intrastat + tags: Tags + size: Size + producer: Producer + origin: Origin + state: State + subtotal: Subtotal + visible: Visible + price: Price + client: Client + country: Country + phone: Phone + mobile: Mobile + postcode: Postcode + street: Street + tag: Tag + ticketId: Ticket ID + confirmed: Confirmed pageTitles: logIn: Login addressEdit: Update address @@ -295,7 +315,6 @@ globals: maxTemperature: Max minTemperature: Min params: - id: ID clientFk: Client id salesPersonFk: Sales person warehouseFk: Warehouse @@ -346,14 +365,7 @@ resetPassword: entry: list: newEntry: New entry - landed: Landed - invoiceNumber: Invoice number - supplier: Supplier - booked: Booked - confirmed: Confirmed - ordered: Ordered tableVisibleColumns: - id: Id created: Creation supplierFk: Supplier isBooked: Booked @@ -362,25 +374,20 @@ entry: companyFk: Company travelFk: Travel isExcludedFromAvailable: Inventory - isRaid: Raid invoiceAmount: Import summary: commission: Commission currency: Currency - company: Company invoiceNumber: Invoice number ordered: Ordered - confirmed: Confirmed booked: Booked raid: Raid excludedFromAvailable: Inventory travelReference: Reference travelAgency: Agency travelShipped: Shipped - travelWarehouseOut: Warehouse Out travelDelivered: Delivered travelLanded: Landed - travelWarehouseIn: Warehouse In travelReceived: Received buys: Buys stickers: Stickers @@ -390,63 +397,29 @@ entry: buyingValue: Buying value import: Import pvp: PVP - item: Item basicData: - supplier: Supplier travel: Travel - invoiceNumber: Invoice number - company: Company currency: Currency commission: Commission observation: Observation - ordered: Ordered - confirmed: Confirmed booked: Booked raid: Raid excludedFromAvailable: Inventory - agency: Agency - warehouseOut: Warehouse Out - warehouseIn: Warehouse In - landed: Landed - id: ID buys: - groupingPrice: Grouping price - packingPrice: Packing price observations: Observations - item: Item - size: Size - packing: Packing - grouping: Grouping - buyingValue: Buying value packagingFk: Box - name: Name - producer: Producer - type: Type color: Color - id: ID printedStickers: Printed stickers notes: observationType: Observation type - descriptor: - agency: Agency - landed: Landed - warehouseOut: Warehouse Out latestBuys: tableVisibleColumns: image: Picture itemFk: Item ID - packing: Packing - grouping: Grouping - size: Size - tags: Tags - type: Type - intrastat: Intrastat - origin: Origin weightByPiece: Weight/Piece isActive: Active family: Family entryFk: Entry - buyingValue: Buying value freightValue: Freight value comissionValue: Commission value packageValue: Package value @@ -455,7 +428,6 @@ entry: price3: Packing minPrice: Min ektFk: Ekt - packagingFk: Package packingOut: Package out landing: Landing isExcludedFromAvailable: Es inventory @@ -471,60 +443,38 @@ ticket: futureTickets: Future tickets purchaseRequest: Purchase request weeklyTickets: Weekly tickets - list: - nickname: Nickname - state: State - landed: Landed - total: Total card: - ticketId: Ticket ID - state: State customerId: Customer ID - agency: Agency - warehouse: Warehouse customerCard: Customer card - alias: Alias ticketList: Ticket List newOrder: New Order boxing: expedition: Expedition - item: Item created: Created - worker: Worker selectTime: 'Select time:' selectVideo: 'Select video:' notFound: No videos available summary: - state: State - agency: Agency zone: Zone - warehouse: Warehouse collection: Collection route: Route invoice: Invoice shipped: Shipped - landed: Landed consigneePhone: Consignee phone consigneeMobile: Consignee mobile consigneeAddress: Consignee address clientPhone: Client phone clientMobile: Client mobile consignee: Consignee - subtotal: Subtotal - vat: VAT total: Total saleLines: Line items - item: Item - visible: Visible available: Available - price: Price discount: Discount packing: Packing hasComponentLack: Component lack itemShortage: Not visible claim: Claim reserved: Reserved - created: Created package: Package taxClass: Tax class services: Services @@ -539,41 +489,20 @@ ticket: attender: Attender ok: Ok create: - client: Client address: Address - landed: Landed - warehouse: Warehouse - agency: Agency invoiceOut: - list: - ref: Reference - issued: Issued - shortIssued: Issued - client: Client - created: Created - shortCreated: Created - company: Company - dued: Due date - shortDued: Due date card: issued: Issued - client: Client - company: Company customerCard: Customer card summary: issued: Issued - created: Created dued: Due booked: Booked - company: Company taxBreakdown: Tax breakdown - type: Type taxableBase: Taxable base rate: Rate fee: Fee tickets: Tickets - ticketId: Ticket id - nickname: Alias totalWithVat: Amount globalInvoices: errors: @@ -587,19 +516,14 @@ invoiceOut: noTicketsToInvoice: There are not tickets to invoice criticalInvoiceError: 'Critical invoicing error, process stopped' table: - client: Client addressId: Address id streetAddress: Street statusCard: percentageText: '{getPercentage}% {getAddressNumber} of {getNAddresses}' pdfsNumberText: '{nPdfs} of {totalPdfs} PDFs' negativeBases: - company: Company - country: Country clientId: Client Id - client: Client base: Base - ticketId: Ticket Id active: Active hasToInvoice: Has to Invoice verifiedData: Verified Data @@ -612,13 +536,6 @@ shelving: priority: Priority newShelving: New Shelving summary: - parking: Parking - priority: Priority - worker: Worker - recyclable: Recyclable - basicData: - parking: Parking - priority: Priority recyclable: Recyclable parking: pickingOrder: Picking order @@ -633,49 +550,28 @@ parking: order: field: salesPersonFk: Sales Person - clientFk: Client - isConfirmed: Confirmed - created: Created - landed: Landed - hour: Hour - agency: Agency - total: Total form: clientFk: Client addressFk: Address - landed: Landed agencyModeFk: Agency list: newOrder: New Order summary: basket: Basket - nickname: Nickname - company: Company - confirmed: Confirmed notConfirmed: Not confirmed created: Created - landed: Landed - phone: Phone createdFrom: Created From address: Address - subtotal: Subtotal total: Total - vat: VAT - state: State - alias: Alias items: Items orderTicketList: Order Ticket List - item: Item - price: Price amount: Amount department: pageTitles: department: Department summary: Summary - name: Name chat: Chat bossDepartment: Boss Department - email: Email selfConsumptionCustomer: Self-consumption customer telework: Telework notifyOnErrors: Notify on errors @@ -699,23 +595,9 @@ worker: locker: Locker medical: Medical list: - name: Name - email: Email - phone: Phone - mobile: Mobile - active: Active department: Department schedule: Schedule newWorker: New worker - card: - workerId: Worker ID - name: Name - email: Email - phone: Phone - mobile: Mobile - active: Active - warehouse: Warehouse - agency: Agency summary: boss: Boss phoneExtension: Phone extension @@ -748,19 +630,12 @@ worker: serialNumber: Serial number removePDA: Deallocate PDA create: - name: Name lastName: Last name birth: Birth fi: Fi code: Worker code - phone: Phone - postcode: Postcode - province: Province - city: City - street: Street webUser: Web user personalEmail: Personal email - company: Company boss: Boss payMethods: Pay method iban: IBAN @@ -801,7 +676,6 @@ wagon: wagonCounter: Trolley counter wagonTray: Tray List type: - name: Name submit: Submit reset: Reset trayColor: Tray color @@ -809,12 +683,10 @@ wagon: list: plate: Plate volume: Volume - type: Type remove: Remove removeItem: Wagon removed successfully create: plate: Plate - type: Type label: Label warnings: noData: No data available @@ -831,25 +703,17 @@ wagon: supplier: list: payMethod: Pay method - payDeadline: Pay deadline - payDay: Pay day account: Account newSupplier: New supplier tableVisibleColumns: - id: Id - name: Name nif: NIF/CIF - nickname: Alias account: Account - payMethod: Pay Method payDay: Pay Day - country: Country summary: responsible: Responsible verified: Verified isActive: Is active billingData: Billing data - payMethod: Pay method payDeadline: Pay deadline payDay: Pay day account: Account @@ -862,15 +726,10 @@ supplier: fiscalAddress: Fiscal address socialName: Social name taxNumber: Tax number - street: Street city: City - postCode: Postcode - province: Province - country: Country create: supplierName: Supplier name basicData: - alias: Alias workerFk: Responsible isSerious: Verified isActive: Active @@ -884,36 +743,18 @@ supplier: sageWithholdingFk: Sage withholding sageTransactionTypeFk: Sage transaction type supplierActivityFk: Supplier activity - healthRegister: Health register - street: Street - postcode: Postcode - city: City * - provinceFk: Province - country: Country isTrucker: Trucker isVies: Vies billingData: payMethodFk: Billing data payDemFk: Payment deadline - payDay: Pay day accounts: iban: Iban bankEntity: Bank entity beneficiary: Beneficiary contacts: - name: Name - phone: Phone - mobile: Mobile email: Email observation: Notes - addresses: - street: Street - postcode: Postcode - phone: Phone - name: Name - city: City - province: Province - mobile: Mobile agencyTerms: agencyFk: Agency minimumM3: Minimum M3 @@ -928,19 +769,13 @@ supplier: travel: travelList: tableVisibleColumns: - id: Id ref: Reference - agency: Agency - landed: Landed shipHour: Shipment Hour landHour: Landing Hour - warehouseIn: Warehouse in - warehouseOut: Warehouse out totalEntries: Total entries totalEntriesTooltip: Total entries daysOnward: Landed days onwards summary: - confirmed: Confirmed entryId: Entry Id freight: Freight package: Package @@ -953,59 +788,28 @@ travel: AddEntry: Add entry thermographs: Thermographs hb: HB - variables: - search: Id/Reference - agencyModeFk: Agency - warehouseInFk: ' Warehouse In' - warehouseOutFk: Warehouse Out - landedFrom: Landed from - landedTo: Landed to - continent: Continent out - basicData: - agency: Agency - landed: Landed - warehouseOut: Warehouse Out - warehouseIn: Warehouse In - delivered: Delivered - received: Received thermographs: temperature: Temperature - state: State destination: Destination - created: Created thermograph: Thermograph - type: Type - company: Company - warehouse: Warehouse travelFileDescription: 'Travel id { travelId }' item: descriptor: - item: Item buyer: Buyer color: Color category: Category - stems: Stems - visible: Visible available: Available warehouseText: 'Calculated on the warehouse of { warehouseName }' itemDiary: Item diary - producer: Producer list: id: Identifier - grouping: Grouping - packing: Packing stems: Stems category: Category typeName: Type - intrastat: Intrastat isActive: Active - size: Size - origin: Origin userName: Buyer weightByPiece: Weight/Piece stemMultiplier: Multiplier - producer: Producer - landed: Landed fixedPrice: itemFk: Item ID groupingPrice: Grouping price @@ -1014,71 +818,52 @@ item: minPrice: Min price started: Started ended: Ended - warehouse: Warehouse create: - name: Name - tag: Tag priority: Priority - type: Type - intrastat: Intrastat - origin: Origin buyRequest: - ticketId: 'Ticket ID' - requester: 'Requester' - requested: 'Requested' - price: 'Price' - attender: 'Atender' - item: 'Item' - achieved: 'Achieved' - concept: 'Concept' - state: 'State' + requester: Requester + requested: Requested + attender: Atender + achieved: Achieved + concept: Concept summary: - otherData: 'Other data' - tax: 'Tax' - tags: 'Tags' - botanical: 'Botanical' - barcode: 'Barcode' - name: 'Nombre' - completeName: 'Nombre completo' - family: 'Familia' - size: 'Medida' - origin: 'Origen' - stems: 'Tallos' - multiplier: 'Multiplicador' - buyer: 'Comprador' - doPhoto: 'Do photo' - intrastatCode: 'Código intrastat' - intrastat: 'Intrastat' - ref: 'Referencia' - relevance: 'Relevancia' - weight: 'Peso (gramos)/tallo' - units: 'Unidades/caja' - expense: 'Gasto' - generic: 'Genérico' - recycledPlastic: 'Plástico reciclado' - nonRecycledPlastic: 'Plástico no reciclado' - minSalesQuantity: 'Cantidad mínima de venta' - genus: 'Genus' - specie: 'Specie' + otherData: Other data + tax: Tax + botanical: Botanical + barcode: Barcode + completeName: Complete name + family: Familiy + stems: Stems + multiplier: Multiplier + buyer: Buyer + doPhoto: Do photo + intrastatCode: Intrastat code + ref: Reference + relevance: Relevance + weight: Weight (gram)/stem + units: Units/box + expense: Expense + generic: Generic + recycledPlastic: Recycled plastic + nonRecycledPlastic: Non recycled plastic + minSalesQuantity: Min sales quantity + genus: Genus + specie: Specie components: topbar: {} itemsFilterPanel: typeFk: Type - tag: Tag value: Value # ItemFixedPriceFilter buyerFk: Buyer - warehouseFk: Warehouse started: From ended: To mine: For me hasMinPrice: Minimum price # LatestBuysFilter salesPersonFk: Buyer - supplierFk: Supplier from: From active: Is active - visible: Is visible floramondo: Is floramondo showBadDates: Show future items userPanel: diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index a8d582c30..92507db40 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -58,8 +58,8 @@ globals: downloadCSVSuccess: Descarga de CSV exitosa reference: Referencia agency: Agencia - wareHouseOut: Alm. salida - wareHouseIn: Alm. entrada + warehouseOut: Alm. salida + warehouseIn: Alm. entrada landed: F. entrega shipped: F. envío totalEntries: Ent. totales @@ -108,6 +108,26 @@ globals: weight: Peso error: ¡Ups! Algo salió mal recalc: Recalcular + alias: Alias + vat: IVA + intrastat: Intrastat + tags: Etiquetas + size: Medida + producer: Productor + origin: Origen + state: Estado + subtotal: Subtotal + visible: Visible + price: Precio + client: Cliente + country: País + phone: Teléfono + mobile: Móvil + postcode: Código postal + street: Dirección + tag: Etiqueta + ticketId: ID ticket + confirmed: Confirmado pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario @@ -299,7 +319,6 @@ globals: maxTemperature: Máx minTemperature: Mín params: - id: Id clientFk: Id cliente salesPersonFk: Comercial warehouseFk: Almacén @@ -348,14 +367,7 @@ resetPassword: entry: list: newEntry: Nueva entrada - landed: F. entrega - invoiceNumber: Núm. factura - supplier: Proveedor - booked: Asentado - confirmed: Confirmado - ordered: Pedida tableVisibleColumns: - id: Id created: Creación supplierFk: Proveedor isBooked: Asentado @@ -364,15 +376,12 @@ entry: companyFk: Empresa travelFk: Envio isExcludedFromAvailable: Inventario - isRaid: Redada invoiceAmount: Importe summary: commission: Comisión currency: Moneda - company: Empresa invoiceNumber: Núm. factura ordered: Pedida - confirmed: Confirmada booked: Contabilizada raid: Redada excludedFromAvailable: Inventario @@ -382,7 +391,6 @@ entry: travelWarehouseOut: Alm. salida travelDelivered: Enviada travelLanded: F. entrega - travelWarehouseIn: Alm. entrada travelReceived: Recibida buys: Compras stickers: Etiquetas @@ -392,63 +400,29 @@ entry: buyingValue: Coste import: Importe pvp: PVP - item: Artículo basicData: - supplier: Proveedor travel: Envío - invoiceNumber: Núm. factura - company: Empresa currency: Moneda observation: Observación commission: Comisión - ordered: Pedida - confirmed: Confirmado booked: Asentado raid: Redada excludedFromAvailable: Inventario - agency: Agencia - warehouseOut: Alm. salida - warehouseIn: Alm. entrada - landed: F. entrega - id: ID buys: - groupingPrice: Precio grouping - packingPrice: Precio packing observations: Observaciónes - item: Artículo - size: Medida - packing: Packing - grouping: Grouping - buyingValue: Coste packagingFk: Embalaje - name: Nombre - producer: Productor - type: Tipo color: Color - id: ID printedStickers: Etiquetas impresas notes: observationType: Tipo de observación - descriptor: - agency: Agencia - landed: F. entrega - warehouseOut: Alm. salida latestBuys: tableVisibleColumns: image: Foto itemFk: Id Artículo - packing: packing - grouping: Grouping - size: Medida - tags: Etiquetas - type: Tipo - intrastat: Intrastat - origin: Origen weightByPiece: Peso (gramos)/tallo isActive: Activo family: Familia entryFk: Entrada - buyingValue: Coste freightValue: Porte comissionValue: Comisión packageValue: Embalaje @@ -457,7 +431,6 @@ entry: price3: Packing minPrice: Min ektFk: Ekt - packagingFk: Embalaje packingOut: Embalaje envíos landing: Llegada isExcludedFromAvailable: Es inventario @@ -478,60 +451,38 @@ ticket: tracking: Estados components: Componentes pictures: Fotos - list: - nickname: Alias - state: Estado - landed: Entregado - total: Total card: - ticketId: ID ticket - state: Estado customerId: ID cliente - agency: Agencia - warehouse: Almacén customerCard: Ficha del cliente - alias: Alias ticketList: Listado de tickets newOrder: Nuevo pedido boxing: expedition: Expedición - item: Artículo created: Creado - worker: Trabajador selectTime: 'Seleccionar hora:' selectVideo: 'Seleccionar vídeo:' notFound: No hay vídeos disponibles summary: - state: Estado - agency: Agencia zone: Zona - warehouse: Almacén collection: Colección route: Ruta invoice: Factura shipped: Enviado - landed: Entregado consigneePhone: Tel. consignatario consigneeMobile: Móv. consignatario consigneeAddress: Dir. consignatario clientPhone: Tel. cliente clientMobile: Móv. cliente consignee: Consignatario - subtotal: Subtotal - vat: IVA total: Total saleLines: Líneas del pedido - item: Artículo - visible: Visible available: Disponible - price: Precio discount: Descuento packing: Encajado hasComponentLack: Faltan componentes itemShortage: No visible claim: Reclamación reserved: Reservado - created: Fecha creación package: Embalaje taxClass: Tipo IVA services: Servicios @@ -545,42 +496,21 @@ ticket: service: Servicio attender: Consignatario create: - client: Cliente address: Dirección - landed: F. entrega - warehouse: Almacén - agency: Agencia invoiceOut: - list: - ref: Referencia - issued: Fecha emisión - shortIssued: F. emisión - client: Cliente - created: Fecha creación - shortCreated: F. creación - company: Empresa - dued: Fecha vencimineto - shortDued: F. vencimiento card: issued: Fecha emisión - client: Cliente - company: Empresa customerCard: Ficha del cliente ticketList: Listado de tickets summary: issued: Fecha - created: Fecha creación dued: Vencimiento booked: Contabilizada - company: Empresa taxBreakdown: Desglose impositivo - type: Tipo taxableBase: Base imp. rate: Tarifa fee: Cuota tickets: Tickets - ticketId: Id ticket - nickname: Alias totalWithVat: Importe globalInvoices: errors: @@ -594,19 +524,14 @@ invoiceOut: noTicketsToInvoice: No existen tickets para facturar criticalInvoiceError: Error crítico en la facturación proceso detenido table: - client: Cliente addressId: Id dirección streetAddress: Dirección fiscal statusCard: percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}' pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs' negativeBases: - company: Empresa - country: País clientId: Id cliente - client: Cliente base: Base - ticketId: Id ticket active: Activo hasToInvoice: Facturar verifiedData: Datos comprobados @@ -616,40 +541,21 @@ invoiceOut: order: field: salesPersonFk: Comercial - clientFk: Cliente - isConfirmed: Confirmada - created: Creado - landed: F. entrega - hour: Hora - agency: Agencia - total: Total form: clientFk: Cliente addressFk: Dirección - landed: F. entrega agencyModeFk: Agencia list: newOrder: Nuevo Pedido summary: basket: Cesta - nickname: Alias - company: Empresa - confirmed: Confirmada notConfirmed: No confirmada created: Creado - landed: F. entrega - phone: Teléfono createdFrom: Creado desde address: Dirección - subtotal: Subtotal total: Total - vat: IVA - state: Estado - alias: Alias items: Items orderTicketList: Tickets del pedido - item: Item - price: Precio amount: Monto shelving: list: @@ -657,13 +563,6 @@ shelving: priority: Prioridad newShelving: Nuevo Carro summary: - parking: Parking - priority: Prioridad - worker: Trabajador - recyclable: Reciclable - basicData: - parking: Parking - priority: Prioridad recyclable: Reciclable parking: pickingOrder: Orden de recogida @@ -678,10 +577,8 @@ department: pageTitles: department: Departamentos summary: Resumen - name: Nombre chat: Chat bossDepartment: Jefe de departamento - email: Email selfConsumptionCustomer: Cliente autoconsumo telework: Teletrabaja notifyOnErrors: Notificar errores @@ -706,23 +603,9 @@ worker: formation: Formación medical: Mutua list: - name: Nombre - email: Email - phone: Teléfono - mobile: Móvil - active: Activo department: Departamento schedule: Horario newWorker: Nuevo trabajador - card: - workerId: ID Trabajador - name: Nombre - email: Correo personal - phone: Teléfono - mobile: Móvil - active: Activo - warehouse: Almacén - agency: Empresa summary: boss: Jefe phoneExtension: Extensión de teléfono @@ -746,19 +629,12 @@ worker: serialNumber: Número de serie removePDA: Desasignar PDA create: - name: Nombre lastName: Apellido birth: Fecha de nacimiento fi: DNI/NIF/NIE code: Código de trabajador - phone: Teléfono - postcode: Código postal - province: Provincia - city: Población - street: Dirección webUser: Usuario Web personalEmail: Correo personal - company: Empresa boss: Jefe payMethods: Método de pago iban: IBAN @@ -799,7 +675,6 @@ wagon: wagonCounter: Contador de carros wagonTray: Listado bandejas type: - name: Nombre submit: Guardar reset: Deshacer cambios trayColor: Color de la bandeja @@ -807,12 +682,9 @@ wagon: list: plate: Matrícula volume: Volumen - type: Tipo remove: Borrar removeItem: Vagón borrado correctamente create: - plate: Matrícula - type: Tipo label: Etiqueta warnings: noData: Sin datos disponibles @@ -828,25 +700,16 @@ wagon: supplier: list: payMethod: Método de pago - payDeadline: Plazo de pago - payDay: Día de pago account: Cuenta newSupplier: Nuevo proveedor tableVisibleColumns: - id: Id - name: Nombre nif: NIF/CIF - nickname: Alias account: Cuenta - payMethod: Método de pago - payDay: Dia de pago - country: País summary: responsible: Responsable verified: Verificado isActive: Está activo billingData: Forma de pago - payMethod: Método de pago payDeadline: Plazo de pago payDay: Día de pago account: Cuenta @@ -859,15 +722,11 @@ supplier: fiscalAddress: Dirección fiscal socialName: Razón social taxNumber: NIF/CIF - street: Dirección city: Población - postCode: Código postal province: Provincia - country: País create: supplierName: Nombre del proveedor basicData: - alias: Alias workerFk: Responsable isSerious: Verificado isActive: Activo @@ -881,36 +740,17 @@ supplier: sageWithholdingFk: Retención sage sageTransactionTypeFk: Tipo de transacción sage supplierActivityFk: Actividad proveedor - healthRegister: Pasaporte sanitario - street: Calle - postcode: Código postal - city: Población * - provinceFk: Provincia - country: País isTrucker: Transportista isVies: Vies billingData: payMethodFk: Forma de pago payDemFk: Plazo de pago - payDay: Día de pago accounts: iban: Iban bankEntity: Entidad bancaria beneficiary: Beneficiario contacts: - name: Nombre - phone: Teléfono - mobile: Móvil - email: Email observation: Notas - addresses: - street: Dirección - postcode: Código postal - phone: Teléfono - name: Nombre - city: Población - province: Provincia - mobile: Móvil agencyTerms: agencyFk: Agencia minimumM3: M3 mínimos @@ -925,19 +765,13 @@ supplier: travel: travelList: tableVisibleColumns: - id: Id ref: Referencia - agency: Agencia shipHour: Hora de envío landHour: Hora de llegada - landed: F.entrega - warehouseIn: Alm.salida - warehouseOut: Alm.entrada totalEntries: ∑ totalEntriesTooltip: Entradas totales daysOnward: Días de llegada en adelante summary: - confirmed: Confirmado entryId: Id entrada freight: Porte package: Embalaje @@ -950,59 +784,28 @@ travel: AddEntry: Añadir entrada thermographs: Termógrafos hb: HB - variables: - search: Id/Referencia - agencyModeFk: Agencia - warehouseInFk: Alm. entrada - warehouseOutFk: ' Alm. salida' - landedFrom: Llegada desde - landedTo: Llegada hasta - continent: Cont. Salida - basicData: - agency: Agencia - landed: F. entrega - warehouseOut: Alm. salida - warehouseIn: Alm. entrada - delivered: Enviada - received: Recibida thermographs: temperature: Temperatura - state: Estado destination: Destino - created: Fecha creación thermograph: Termógrafo - type: Tipo - company: Empresa - warehouse: Almacén travelFileDescription: 'Id envío { travelId }' item: descriptor: - item: Artículo buyer: Comprador color: Color category: Categoría - stems: Tallos - visible: Visible available: Disponible warehouseText: 'Calculado sobre el almacén de { warehouseName }' itemDiary: Registro de compra-venta - producer: Productor list: id: Identificador - grouping: Grouping - packing: Packing stems: Tallos category: Reino typeName: Tipo - intrastat: Intrastat isActive: Activo - size: Medida - origin: Origen weightByPiece: Peso (gramos)/tallo userName: Comprador stemMultiplier: Multiplicador - producer: Productor - landed: F. entrega fixedPrice: itemFk: ID Artículo groupingPrice: Precio grouping @@ -1011,70 +814,51 @@ item: minPrice: Precio min started: Inicio ended: Fin - warehouse: Almacén create: - name: Nombre - tag: Etiqueta priority: Prioridad - type: Tipo - intrastat: Intrastat - origin: Origen summary: - otherData: 'Otros datos' - tax: 'IVA' - tags: 'Etiquetas' - botanical: 'Botánico' - barcode: 'Código de barras' - name: 'Nombre' - completeName: 'Nombre completo' - family: 'Familia' - size: 'Medida' - origin: 'Origen' - stems: 'Tallos' - multiplier: 'Multiplicador' - buyer: 'Comprador' - doPhoto: 'Hacer foto' - intrastatCode: 'Código intrastat' - intrastat: 'Intrastat' - ref: 'Referencia' - relevance: 'Relevancia' - weight: 'Peso (gramos)/tallo' - units: 'Unidades/caja' - expense: 'Gasto' - generic: 'Genérico' - recycledPlastic: 'Plástico reciclado' - nonRecycledPlastic: 'Plástico no reciclado' - minSalesQuantity: 'Cantidad mínima de venta' - genus: 'Genus' - specie: 'Specie' + otherData: Otros datos + tax: IVA + botanical: Botánico + barcode: Código de barras + completeName: Nombre completo + family: Familia + stems: Tallos + multiplier: Multiplicador + buyer: Comprador + doPhoto: Hacer foto + intrastatCode: Código intrastat + ref: Referencia + relevance: Relevancia + weight: Peso (gramos)/tallo + units: Unidades/caja + expense: Gasto + generic: Genérico + recycledPlastic: Plástico reciclado + nonRecycledPlastic: Plástico no reciclado + minSalesQuantity: Cantidad mínima de venta + genus: Genus + specie: Specie buyRequest: - ticketId: 'ID Ticket' - requester: 'Solicitante' - requested: 'Solicitado' - price: 'Precio' - attender: 'Comprador' - item: 'Artículo' - achieved: 'Conseguido' - concept: 'Concepto' - state: 'Estado' + requester: Solicitante + requested: Solicitado + attender: Comprador + achieved: Conseguido + concept: Concepto components: topbar: {} itemsFilterPanel: typeFk: Tipo - tag: Etiqueta value: Valor # ItemFixedPriceFilter buyerFk: Comprador - warehouseFk: Almacén started: Desde ended: Hasta mine: Para mi hasMinPrice: Precio mínimo # LatestBuysFilter salesPersonFk: Comprador - supplierFk: Proveedor active: Activo - visible: Visible floramondo: Floramondo showBadDates: Ver items a futuro userPanel: diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue index 384881792..07bccd971 100644 --- a/src/pages/Department/Card/DepartmentBasicData.vue +++ b/src/pages/Department/Card/DepartmentBasicData.vue @@ -20,9 +20,9 @@ const { t } = useI18n(); <template #form="{ data, validate }"> <VnRow> <VnInput - :label="t('department.name')" + :label="t('globals.name')" v-model="data.name" - :rules="validate('department.name')" + :rules="validate('globals.name')" clearable autofocus /> @@ -42,8 +42,8 @@ const { t } = useI18n(); /> <VnInput v-model="data.notificationEmail" - :label="t('department.email')" - :rules="validate('department.email')" + :label="t('globals.params.email')" + :rules="validate('globals.params.email')" clearable /> </VnRow> diff --git a/src/pages/Department/Card/DepartmentSummary.vue b/src/pages/Department/Card/DepartmentSummary.vue index 05a9e073e..623eab94a 100644 --- a/src/pages/Department/Card/DepartmentSummary.vue +++ b/src/pages/Department/Card/DepartmentSummary.vue @@ -45,11 +45,7 @@ onMounted(async () => { /> <div class="full-width row wrap justify-between content-between"> <div class="column" style="min-width: 50%"> - <VnLv - :label="t('department.name')" - :value="department.name" - dash - /> + <VnLv :label="t('globals.name')" :value="department.name" dash /> <VnLv :label="t('globals.code')" :value="department.code" dash /> <VnLv :label="t('department.chat')" diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index 2a00bfd74..64ef60956 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -53,7 +53,7 @@ const onFilterTravelSelected = (formData, id) => { <template #form="{ data }"> <VnRow> <VnSelect - :label="t('entry.basicData.supplier')" + :label="t('globals.supplier')" v-model="data.supplierFk" url="Suppliers" option-value="id" @@ -113,10 +113,10 @@ const onFilterTravelSelected = (formData, id) => { <VnRow> <VnInput v-model="data.invoiceNumber" - :label="t('entry.basicData.invoiceNumber')" + :label="t('entry.summary.invoiceNumber')" /> <VnSelect - :label="t('entry.basicData.company')" + :label="t('globals.company')" v-model="data.companyFk" :options="companiesOptions" option-value="id" @@ -128,14 +128,14 @@ const onFilterTravelSelected = (formData, id) => { </VnRow> <VnRow> <VnSelect - :label="t('entry.basicData.currency')" + :label="t('entry.summary.currency')" v-model="data.currencyFk" :options="currenciesOptions" option-value="id" option-label="code" /> <QInput - :label="t('entry.basicData.commission')" + :label="t('entry.summary.commission')" v-model="data.commission" type="number" autofocus @@ -153,17 +153,11 @@ const onFilterTravelSelected = (formData, id) => { /> </VnRow> <VnRow> - <QCheckbox - v-model="data.isOrdered" - :label="t('entry.basicData.ordered')" - /> - <QCheckbox - v-model="data.isConfirmed" - :label="t('entry.basicData.confirmed')" - /> + <QCheckbox v-model="data.isOrdered" :label="t('entry.summary.ordered')" /> + <QCheckbox v-model="data.isConfirmed" :label="t('globals.confirmed')" /> <QCheckbox v-model="data.isExcludedFromAvailable" - :label="t('entry.basicData.excludedFromAvailable')" + :label="t('entry.summary.excludedFromAvailable')" /> <QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" /> <QCheckbox diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue index 35972b85a..98ce884cf 100644 --- a/src/pages/Entry/Card/EntryBuys.vue +++ b/src/pages/Entry/Card/EntryBuys.vue @@ -156,7 +156,7 @@ const tableColumnComponents = computed(() => ({ const entriesTableColumns = computed(() => { return [ { - label: t('entry.summary.item'), + label: t('globals.item'), field: 'itemFk', name: 'item', align: 'left', @@ -211,13 +211,13 @@ const entriesTableColumns = computed(() => { format: (value) => toCurrency(value), }, { - label: t('entry.buys.groupingPrice'), + label: t('item.fixedPrice.groupingPrice'), field: 'price2', name: 'price2', align: 'left', }, { - label: t('entry.buys.packingPrice'), + label: t('item.fixedPrice.packingPrice'), field: 'price3', name: 'price3', align: 'left', diff --git a/src/pages/Entry/Card/EntryBuysImport.vue b/src/pages/Entry/Card/EntryBuysImport.vue index 36ca3b797..c03b7756f 100644 --- a/src/pages/Entry/Card/EntryBuysImport.vue +++ b/src/pages/Entry/Card/EntryBuysImport.vue @@ -35,7 +35,7 @@ const packagingsOptions = ref([]); const columns = computed(() => [ { - label: t('entry.buys.item'), + label: t('globals.item'), name: 'item', field: 'itemFk', options: lastItemBuysOptions.value, @@ -56,19 +56,19 @@ const columns = computed(() => [ align: 'left', }, { - label: t('entry.buys.packing'), + label: t('entry.summary.packing'), name: 'packing', field: 'packing', align: 'left', }, { - label: t('entry.buys.grouping'), + label: t('entry.summary.grouping'), name: 'grouping', field: 'grouping', align: 'left', }, { - label: t('entry.buys.buyingValue'), + label: t('entry.summary.buyingValue'), name: 'buyingValue', field: 'buyingValue', align: 'left', diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index b22d6ba53..fa75e820d 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -122,14 +122,11 @@ watch; </QItem> </template> <template #body="{ entity }"> - <VnLv - :label="t('entry.descriptor.agency')" - :value="entity.travel?.agency?.name" - /> + <VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" /> <VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" /> <VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" /> <VnLv - :label="t('entry.descriptor.warehouseOut')" + :label="t('globals.warehouseOut')" :value="entity.travel?.warehouseOut?.name" /> </template> diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue index 0ed2e8a67..9fe9ae265 100644 --- a/src/pages/Entry/Card/EntrySummary.vue +++ b/src/pages/Entry/Card/EntrySummary.vue @@ -189,7 +189,7 @@ const fetchEntryBuys = async () => { :label="t('entry.summary.currency')" :value="entry.currency?.name" /> - <VnLv :label="t('entry.summary.company')" :value="entry.company.code" /> + <VnLv :label="t('globals.company')" :value="entry.company.code" /> <VnLv :label="t('globals.reference')" :value="entry.reference" /> <VnLv :label="t('entry.summary.invoiceNumber')" @@ -218,7 +218,7 @@ const fetchEntryBuys = async () => { /> <VnLv :label="t('shipped')" :value="toDate(entry.travel.shipped)" /> <VnLv - :label="t('entry.summary.travelWarehouseOut')" + :label="t('globals.warehouseOut')" :value="entry.travel.warehouseOut?.name" /> <QCheckbox @@ -228,7 +228,7 @@ const fetchEntryBuys = async () => { /> <VnLv :label="t('landed')" :value="toDate(entry.travel.landed)" /> <VnLv - :label="t('entry.summary.travelWarehouseIn')" + :label="t('globals.warehouseIn')" :value="entry.travel.warehouseIn?.name" /> <QCheckbox @@ -251,7 +251,7 @@ const fetchEntryBuys = async () => { :disable="true" /> <QCheckbox - :label="t('entry.summary.confirmed')" + :label="t('globals.confirmed')" v-model="entry.isConfirmed" :disable="true" /> diff --git a/src/pages/Entry/EntryBuysTableDialog.vue b/src/pages/Entry/EntryBuysTableDialog.vue index 0f9be6298..960c936ee 100644 --- a/src/pages/Entry/EntryBuysTableDialog.vue +++ b/src/pages/Entry/EntryBuysTableDialog.vue @@ -35,7 +35,7 @@ const entriesTableColumns = computed(() => [ { align: 'left', name: 'item', - label: t('entry.summary.item'), + label: t('globals.item'), field: (row) => row.item.name, }, { diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue index 756948182..9e1492bb6 100644 --- a/src/pages/Entry/EntryLatestBuys.vue +++ b/src/pages/Entry/EntryLatestBuys.vue @@ -37,12 +37,12 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.packing'), + label: t('entry.summary.packing'), name: 'packing', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.grouping'), + label: t('entry.summary.grouping'), name: 'grouping', }, { @@ -57,27 +57,27 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.size'), + label: t('globals.size'), name: 'size', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.tags'), + label: t('globals.tags'), name: 'tags', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.type'), + label: t('globals.type'), name: 'type', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.intrastat'), + label: t('globals.intrastat'), name: 'intrastat', }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.origin'), + label: t('globals.origin'), name: 'origin', }, { @@ -102,7 +102,7 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.buyingValue'), + label: t('entry.summary.buyingValue'), name: 'buyingValue', }, { @@ -117,7 +117,7 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.packageValue'), + label: t('entry.buys.packageValue'), name: 'packageValue', }, { @@ -152,7 +152,7 @@ const columns = [ }, { align: 'left', - label: t('entry.latestBuys.tableVisibleColumns.packagingFk'), + label: t('entry.buys.packagingFk'), name: 'packagingFk', }, { diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index e44e3891e..2bfea2a4d 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -43,7 +43,7 @@ const entryFilter = { const columns = computed(() => [ { align: 'left', - label: t('entry.list.tableVisibleColumns.id'), + label: t('globals.id'), name: 'id', isTitle: true, cardVisible: true, diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue index 5e4be407e..2b60948dd 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue @@ -69,7 +69,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. <template #body="{ entity }"> <VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" /> <VnLv :label="t('globals.amount')" :value="toCurrency(entity.amount)" /> - <VnLv v-if="entity.client" :label="t('invoiceOut.card.client')"> + <VnLv v-if="entity.client" :label="t('globals.client')"> <template #value> <span class="link"> {{ entity.client.name }} @@ -79,7 +79,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. </VnLv> <VnLv v-if="entity.company" - :label="t('invoiceOut.card.company')" + :label="t('globals.company')" :value="entity.company.code" /> </template> diff --git a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue index 83b1bf8a4..027f08109 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue @@ -42,7 +42,7 @@ function fetch() { const taxColumns = ref([ { name: 'item', - label: 'invoiceOut.summary.type', + label: 'globals.type', field: (row) => row.name, sortable: true, }, @@ -72,14 +72,14 @@ const taxColumns = ref([ const ticketsColumns = ref([ { name: 'item', - label: t('invoiceOut.summary.ticketId'), + label: t('globals.ticketId'), field: (row) => row.id, sortable: true, align: 'left', }, { name: 'quantity', - label: t('invoiceOut.summary.nickname'), + label: t('globals.alias'), field: (row) => row.nickname, sortable: true, align: 'left', @@ -124,18 +124,12 @@ const ticketsColumns = ref([ :label="t('invoiceOut.summary.dued')" :value="toDate(invoiceOut.dued)" /> - <VnLv - :label="t('invoiceOut.summary.created')" - :value="toDate(invoiceOut.created)" - /> + <VnLv :label="t('globals.created')" :value="toDate(invoiceOut.created)" /> <VnLv :label="t('invoiceOut.summary.booked')" :value="toDate(invoiceOut.booked)" /> - <VnLv - :label="t('invoiceOut.summary.company')" - :value="invoiceOut.company.code" - /> + <VnLv :label="t('globals.company')" :value="invoiceOut.company.code" /> </QCard> <QCard class="vn-three"> <VnTitle :text="t('invoiceOut.summary.taxBreakdown')" /> diff --git a/src/pages/InvoiceOut/InvoiceOutGlobal.vue b/src/pages/InvoiceOut/InvoiceOutGlobal.vue index 5f2eb3c02..7f6bf41d3 100644 --- a/src/pages/InvoiceOut/InvoiceOutGlobal.vue +++ b/src/pages/InvoiceOut/InvoiceOutGlobal.vue @@ -59,7 +59,7 @@ const columns = computed(() => [ field: 'clientId', }, { - label: t('invoiceOut.globalInvoices.table.client'), + label: t('globals.client'), field: 'clientName', name: 'clientName', align: 'left', diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue index cf4c27e65..8c8c01e9c 100644 --- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue +++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue @@ -51,7 +51,7 @@ const props = defineProps({ <QItemSection> <VnInput v-model="params.company" - :label="t('invoiceOut.negativeBases.company')" + :label="t('globals.company')" is-outlined /> </QItemSection> @@ -60,7 +60,7 @@ const props = defineProps({ <QItemSection> <VnInput v-model="params.country" - :label="t('invoiceOut.negativeBases.country')" + :label="t('globals.country')" is-outlined /> </QItemSection> @@ -79,7 +79,7 @@ const props = defineProps({ <QItemSection> <VnInput v-model="params.clientSocialName" - :label="t('invoiceOut.negativeBases.client')" + :label="t('globals.client')" is-outlined /> </QItemSection> diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index ef844824f..805ba6e11 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -173,10 +173,7 @@ const openCloneDialog = async () => { </span> </template> </VnLv> - <VnLv - :label="t('item.descriptor.producer')" - :value="dashIfEmpty(entity.subName)" - /> + <VnLv :label="t('globals.producer')" :value="dashIfEmpty(entity.subName)" /> <VnLv v-if="entity.value5" :label="t('item.descriptor.color')" @@ -190,7 +187,7 @@ const openCloneDialog = async () => { /> <VnLv v-if="entity.value7" - :label="t('item.descriptor.stems')" + :label="t('item.list.stems')" :value="entity.value7" /> </template> diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue index a4ef22ce3..063c77c65 100644 --- a/src/pages/Item/Card/ItemDescriptorImage.vue +++ b/src/pages/Item/Card/ItemDescriptorImage.vue @@ -75,7 +75,7 @@ const handlePhotoUpdated = (evt = false) => { <QIcon name="vn:item" /> </div> <div class="text-grey-5" style="opacity: 0.4"> - {{ t('item.descriptor.item') }} + {{ t('globals.item') }} </div> </div> </div> @@ -107,7 +107,7 @@ const handlePhotoUpdated = (evt = false) => { > <div class="col column items-center"> <span class="text-uppercase color-vn-white" style="font-size: 11px"> - {{ t('item.descriptor.visible') }} + {{ t('globals.visible') }} </span> <span class="text-weight-bold text-h5 color-vn-white">{{ visible }}</span> </div> diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue index dd2c0649b..4570b2319 100644 --- a/src/pages/Item/Card/ItemSummary.vue +++ b/src/pages/Item/Card/ItemSummary.vue @@ -57,11 +57,11 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; :url="getUrl(entityId, 'basic-data')" :text="t('globals.summary.basicData')" /> - <VnLv :label="t('item.summary.name')" :value="item.name" /> + <VnLv :label="t('globals.name')" :value="item.name" /> <VnLv :label="t('item.summary.completeName')" :value="item.longName" /> <VnLv :label="t('item.summary.family')" :value="item.itemType.name" /> - <VnLv :label="t('item.summary.size')" :value="item.size" /> - <VnLv :label="t('item.summary.origin')" :value="item.origin.name" /> + <VnLv :label="t('globals.size')" :value="item.size" /> + <VnLv :label="t('globals.origin')" :value="item.origin.name" /> <VnLv :label="t('item.summary.stems')" :value="item.stems" /> <VnLv :label="t('item.summary.multiplier')" @@ -96,7 +96,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; :value="item.intrastat.id" /> <VnLv - :label="t('item.summary.intrastat')" + :label="t('globals.intrastat')" :value="item.intrastat.description" /> <VnLv :label="t('item.summary.ref')" :value="item.comment" /> @@ -115,7 +115,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; /> </QCard> <QCard class="vn-one"> - <VnTitle :url="getUrl(entityId, 'tags')" :text="t('item.summary.tags')" /> + <VnTitle :url="getUrl(entityId, 'tags')" :text="t('globals.tags')" /> <VnLv v-for="(tag, index) in tags" :key="index" diff --git a/src/pages/Item/ItemCreate.vue b/src/pages/Item/ItemCreate.vue index 6b6234b70..d69153820 100644 --- a/src/pages/Item/ItemCreate.vue +++ b/src/pages/Item/ItemCreate.vue @@ -86,12 +86,9 @@ onBeforeMount(async () => { > <template #form="{ data }"> <VnRow> - <VnInput - v-model="data.provisionalName" - :label="t('item.create.name')" - /> + <VnInput v-model="data.provisionalName" :label="t('globals.name')" /> <VnSelect - :label="t('item.create.tag')" + :label="t('globals.tag')" v-model="data.tag" :options="tagsOptions" option-value="id" @@ -109,7 +106,7 @@ onBeforeMount(async () => { </VnRow> <VnRow> <VnSelect - :label="t('item.create.type')" + :label="t('globals.type')" v-model="data.typeFk" :options="itemTypesOptions" option-label="name" @@ -133,7 +130,7 @@ onBeforeMount(async () => { </template> </VnSelect> <VnSelect - :label="t('item.create.intrastat')" + :label="t('globals.intrastat')" v-model="data.intrastatFk" :options="intrastatsOptions" option-label="description" @@ -156,7 +153,7 @@ onBeforeMount(async () => { </VnRow> <VnRow> <VnSelect - :label="t('item.create.origin')" + :label="t('globals.origin')" v-model="data.originFk" :options="originsOptions" option-value="id" diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index 7d4d6b896..4205d8344 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -132,7 +132,7 @@ const columns = computed(() => [ }, { - label: t('item.fixedPrice.warehouse'), + label: t('globals.warehouse'), field: 'warehouseFk', name: 'warehouseFk', ...defaultColumnAttrs, @@ -192,7 +192,7 @@ const editTableFieldsOptions = [ }, { field: 'warehouseFk', - label: t('item.fixedPrice.warehouse'), + label: t('globals.warehouse'), component: 'select', attrs: { options: [], diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index ae4c9531c..2ad9c92d0 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -114,7 +114,7 @@ const columns = computed(() => [ }, }, { - label: t('item.list.grouping'), + label: t('entry.summary.grouping'), field: 'grouping', name: 'grouping', align: 'left', @@ -131,7 +131,7 @@ const columns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('item.list.packing'), + label: t('entry.summary.packing'), field: 'packing', name: 'packing', align: 'left', @@ -180,7 +180,7 @@ const columns = computed(() => [ }, }, { - label: t('item.list.size'), + label: t('globals.size'), field: 'size', name: 'size', align: 'left', @@ -237,7 +237,7 @@ const columns = computed(() => [ }, { - label: t('item.list.intrastat'), + label: t('globals.intrastat'), field: 'intrastat', name: 'intrastat', align: 'left', @@ -256,7 +256,7 @@ const columns = computed(() => [ }, }, { - label: t('item.list.origin'), + label: t('globals.origin'), field: 'origin', name: 'origin', align: 'left', @@ -337,7 +337,7 @@ const columns = computed(() => [ columnFilter: null, }, { - label: t('item.list.producer'), + label: t('globals.producer'), field: 'producer', name: 'producer', align: 'left', @@ -354,7 +354,7 @@ const columns = computed(() => [ format: (val) => dashIfEmpty(val), }, { - label: t('item.list.landed'), + label: t('globals.landed'), field: 'landed', name: 'landed', align: 'left', diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 7dd961a35..be378893e 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -40,7 +40,7 @@ watch( const columns = computed(() => [ { - label: t('item.buyRequest.ticketId'), + label: t('globals.ticketId'), name: 'id', field: 'id', align: 'left', @@ -74,7 +74,7 @@ const columns = computed(() => [ sortable: true, }, { - label: t('item.buyRequest.price'), + label: t('globals.price'), field: 'price', name: 'price', align: 'left', @@ -89,7 +89,7 @@ const columns = computed(() => [ sortable: true, }, { - label: t('item.buyRequest.item'), + label: t('globals.item'), field: 'item', name: 'item', align: 'left', @@ -110,7 +110,7 @@ const columns = computed(() => [ sortable: true, }, { - label: t('item.buyRequest.state'), + label: t('globals.state'), field: 'state', name: 'state', align: 'left', diff --git a/src/pages/Order/Card/OrderBasicData.vue b/src/pages/Order/Card/OrderBasicData.vue index 4bc9e2e43..dc8d1a429 100644 --- a/src/pages/Order/Card/OrderBasicData.vue +++ b/src/pages/Order/Card/OrderBasicData.vue @@ -162,7 +162,7 @@ const onClientChange = async (clientId) => { <VnRow> <VnInputDate placeholder="dd-mm-aaa" - :label="t('order.form.landed')" + :label="t('globals.landed')" v-model="data.landed" @update:model-value=" () => fetchAgencyList(data.landed, data.addressFk) diff --git a/src/pages/Order/Card/OrderCreateDialog.vue b/src/pages/Order/Card/OrderCreateDialog.vue index bcc62aa43..b9b232115 100644 --- a/src/pages/Order/Card/OrderCreateDialog.vue +++ b/src/pages/Order/Card/OrderCreateDialog.vue @@ -10,7 +10,6 @@ import VnSelect from 'components/common/VnSelect.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import { useDialogPluginComponent } from 'quasar'; import { reactive } from 'vue'; -import FetchData from 'components/FetchData.vue'; const { t } = useI18n(); const state = useState(); @@ -186,7 +185,7 @@ onMounted(async () => { <VnRow class="row q-gutter-md q-mb-md"> <VnInputDate placeholder="dd-mm-aaa" - :label="t('order.form.landed')" + :label="t('globals.landed')" v-model="data.landed" @update:model-value=" () => fetchAgencyList(data.landed, data.addressId) diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue index a035971b0..0bd645e42 100644 --- a/src/pages/Order/Card/OrderDescriptor.vue +++ b/src/pages/Order/Card/OrderDescriptor.vue @@ -67,7 +67,7 @@ const setData = (entity) => { }; const getConfirmationValue = (isConfirmed) => { - return t(isConfirmed ? 'order.summary.confirmed' : 'order.summary.notConfirmed'); + return t(isConfirmed ? 'globals.confirmed' : 'order.summary.notConfirmed'); }; const total = ref(null); @@ -98,7 +98,7 @@ function ticketFilter(order) { </template> <template #body="{ entity }"> <VnLv - :label="t('order.summary.state')" + :label="t('globals.state')" :value="getConfirmationValue(entity.isConfirmed)" /> <VnLv :label="t('order.field.salesPersonFk')"> @@ -109,9 +109,9 @@ function ticketFilter(order) { </span> </template> </VnLv> - <VnLv :label="t('order.summary.landed')" :value="toDate(entity?.landed)" /> - <VnLv :label="t('order.field.agency')" :value="entity?.agencyMode?.name" /> - <VnLv :label="t('order.summary.alias')" :value="entity?.address?.nickname" /> + <VnLv :label="t('globals.landed')" :value="toDate(entity?.landed)" /> + <VnLv :label="t('globals.agency')" :value="entity?.agencyMode?.name" /> + <VnLv :label="t('globals.alias')" :value="entity?.address?.nickname" /> <VnLv :label="t('order.summary.items')" :value="(entity?.rows?.length || DEFAULT_ITEMS).toString()" diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index ceacbc75b..9e9c371bf 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -24,7 +24,7 @@ const entityId = computed(() => $props.id || route.params.id); const detailsColumns = ref([ { name: 'item', - label: t('order.summary.item'), + label: t('globals.item'), field: (row) => row?.item?.id, sortable: true, }, @@ -40,7 +40,7 @@ const detailsColumns = ref([ }, { name: 'price', - label: t('order.summary.price'), + label: t('globals.price'), field: (row) => toCurrency(row?.price), }, { @@ -69,7 +69,7 @@ const detailsColumns = ref([ :text="t('globals.pageTitles.basicData')" /> <VnLv label="ID" :value="entity.id" /> - <VnLv :label="t('order.summary.nickname')" dash> + <VnLv :label="t('globals.alias')" dash> <template #value> <span class="link"> {{ dashIfEmpty(entity?.address?.nickname) }} @@ -78,11 +78,11 @@ const detailsColumns = ref([ </template> </VnLv> <VnLv - :label="t('order.summary.company')" + :label="t('globals.company')" :value="entity?.address?.companyFk" /> <VnLv - :label="t('order.summary.confirmed')" + :label="t('globals.confirmed')" :value="Boolean(entity?.isConfirmed)" /> </QCard> @@ -96,14 +96,14 @@ const detailsColumns = ref([ :value="toDateHourMinSec(entity?.created)" /> <VnLv - :label="t('order.summary.confirmed')" + :label="t('globals.confirmed')" :value="toDateHourMinSec(entity?.confirmed)" /> <VnLv - :label="t('order.summary.landed')" + :label="t('globals.landed')" :value="toDateHourMinSec(entity?.landed)" /> - <VnLv :label="t('order.summary.phone')"> + <VnLv :label="t('globals.phone')"> <template #value> {{ dashIfEmpty(entity?.address?.phone) }} <a @@ -135,7 +135,7 @@ const detailsColumns = ref([ <VnTitle :text="t('order.summary.total')" /> <VnLv> <template #label> - <span class="text-h6">{{ t('order.summary.subtotal') }}</span> + <span class="text-h6">{{ t('globals.subtotal') }}</span> </template> <template #value> <span class="text-h6">{{ @@ -145,7 +145,7 @@ const detailsColumns = ref([ </VnLv> <VnLv> <template #label> - <span class="text-h6">{{ t('order.summary.vat') }}</span> + <span class="text-h6">{{ t('globals.vat') }}</span> </template> <template #value> <span class="text-h6">{{ toCurrency(entity?.VAT) }}</span> @@ -165,10 +165,10 @@ const detailsColumns = ref([ <QTable :columns="detailsColumns" :rows="entity?.rows" flat> <template #header="props"> <QTr :props="props"> - <QTh auto-width>{{ t('order.summary.item') }}</QTh> + <QTh auto-width>{{ t('globals.item') }}</QTh> <QTh>{{ t('globals.description') }}</QTh> <QTh auto-width>{{ t('globals.quantity') }}</QTh> - <QTh auto-width>{{ t('order.summary.price') }}</QTh> + <QTh auto-width>{{ t('globals.price') }}</QTh> <QTh auto-width>{{ t('order.summary.amount') }}</QTh> </QTr> </template> diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue index 30e807d20..b1ff4a8ae 100644 --- a/src/pages/Shelving/Card/ShelvingDescriptor.vue +++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue @@ -54,8 +54,8 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity > <template #body="{ entity }"> <VnLv :label="t('globals.code')" :value="entity.code" /> - <VnLv :label="t('shelving.summary.parking')" :value="entity.parking?.code" /> - <VnLv v-if="entity.worker" :label="t('shelving.summary.worker')"> + <VnLv :label="t('shelving.list.parking')" :value="entity.parking?.code" /> + <VnLv v-if="entity.worker" :label="t('globals.worker')"> <template #value> <VnUserLink :name="entity.worker?.user?.nickname" diff --git a/src/pages/Shelving/Card/ShelvingForm.vue b/src/pages/Shelving/Card/ShelvingForm.vue index f69d427b0..3bbd94a0a 100644 --- a/src/pages/Shelving/Card/ShelvingForm.vue +++ b/src/pages/Shelving/Card/ShelvingForm.vue @@ -68,7 +68,7 @@ const onSave = (shelving, newShelving) => { option-label="code" :filter-options="['id', 'code']" :fields="['id', 'code']" - :label="t('shelving.basicData.parking')" + :label="t('shelving.list.parking')" :rules="validate('Shelving.parkingFk')" /> </VnRow> @@ -76,12 +76,12 @@ const onSave = (shelving, newShelving) => { <VnInput v-model="data.priority" type="number" - :label="t('shelving.basicData.priority')" + :label="t('shelving.list.priority')" :rules="validate('Shelving.priority')" /> <QCheckbox v-model="data.isRecyclable" - :label="t('shelving.basicData.recyclable')" + :label="t('shelving.summary.recyclable')" :rules="validate('Shelving.isRecyclable')" /> </VnRow> diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue index a196b1992..db7ac34f5 100644 --- a/src/pages/Shelving/Card/ShelvingSummary.vue +++ b/src/pages/Shelving/Card/ShelvingSummary.vue @@ -56,14 +56,11 @@ const filter = { </RouterLink> <VnLv :label="t('globals.code')" :value="entity.code" /> <VnLv - :label="t('shelving.summary.parking')" + :label="t('shelving.list.parking')" :value="entity.parking?.code" /> - <VnLv - :label="t('shelving.summary.priority')" - :value="entity.priority" - /> - <VnLv v-if="entity.worker" :label="t('shelving.summary.worker')"> + <VnLv :label="t('shelving.list.priority')" :value="entity.priority" /> + <VnLv v-if="entity.worker" :label="t('globals.worker')"> <template #value> <VnUserLink :name="entity.worker?.user?.nickname" diff --git a/src/pages/Supplier/Card/SupplierAddresses.vue b/src/pages/Supplier/Card/SupplierAddresses.vue index f46a3be19..f1e95b8de 100644 --- a/src/pages/Supplier/Card/SupplierAddresses.vue +++ b/src/pages/Supplier/Card/SupplierAddresses.vue @@ -69,16 +69,13 @@ const redirectToUpdateView = (addressData) => { @click="redirectToUpdateView(row)" > <template #list-items> + <VnLv :label="t('globals.street')" :value="row.street" /> <VnLv - :label="t('supplier.addresses.street')" - :value="row.street" - /> - <VnLv - :label="t('supplier.addresses.postcode')" + :label="t('globals.postcode')" :value="`${row.postalCode} - ${row.city}, ${row.province.name}`" /> <VnLv - :label="t('supplier.addresses.phone')" + :label="t('globals.phone')" :value="`${row.phone}, ${row.mobile}`" /> </template> diff --git a/src/pages/Supplier/Card/SupplierAddressesCreate.vue b/src/pages/Supplier/Card/SupplierAddressesCreate.vue index 0feceb74a..7a078f03b 100644 --- a/src/pages/Supplier/Card/SupplierAddressesCreate.vue +++ b/src/pages/Supplier/Card/SupplierAddressesCreate.vue @@ -72,14 +72,8 @@ function handleLocation(data, location) { > <template #form="{ data, validate }"> <VnRow> - <VnInput - v-model="data.nickname" - :label="t('supplier.addresses.name')" - /> - <VnInput - v-model="data.street" - :label="t('supplier.addresses.street')" - /> + <VnInput v-model="data.nickname" :label="t('globals.name')" /> + <VnInput v-model="data.street" :label="t('globals.street')" /> </VnRow> <VnRow> <VnLocation @@ -101,14 +95,8 @@ function handleLocation(data, location) { </VnLocation> </VnRow> <VnRow> - <VnInput - v-model="data.phone" - :label="t('supplier.addresses.phone')" - /> - <VnInput - v-model="data.mobile" - :label="t('supplier.addresses.mobile')" - /> + <VnInput v-model="data.phone" :label="t('globals.phone')" /> + <VnInput v-model="data.mobile" :label="t('globals.mobile')" /> </VnRow> </template> </FormModel> diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue index 52964557d..101007756 100644 --- a/src/pages/Supplier/Card/SupplierBasicData.vue +++ b/src/pages/Supplier/Card/SupplierBasicData.vue @@ -24,7 +24,7 @@ const workersOptions = ref([]); <VnRow> <VnInput v-model="data.nickname" - :label="t('supplier.basicData.alias')" + :label="t('globals.alias')" :rules="validate('supplier.nickname')" clearable /> diff --git a/src/pages/Supplier/Card/SupplierBillingData.vue b/src/pages/Supplier/Card/SupplierBillingData.vue index 7200bbba6..05c9858d9 100644 --- a/src/pages/Supplier/Card/SupplierBillingData.vue +++ b/src/pages/Supplier/Card/SupplierBillingData.vue @@ -58,7 +58,7 @@ const formatPayDems = (data) => { </VnRow> <VnRow> <QInput - :label="t('supplier.billingData.payDay')" + :label="t('supplier.summary.payDay')" type="number" v-model="data.payDay" /> diff --git a/src/pages/Supplier/Card/SupplierContacts.vue b/src/pages/Supplier/Card/SupplierContacts.vue index 3f2063784..6781c8d34 100644 --- a/src/pages/Supplier/Card/SupplierContacts.vue +++ b/src/pages/Supplier/Card/SupplierContacts.vue @@ -44,21 +44,12 @@ const insertRow = () => { <VnRow class="row q-gutter-md"> <VnInput input-name-focusable - :label="t('supplier.contacts.name')" + :label="t('globals.name')" v-model="row.name" /> - <VnInput - :label="t('supplier.contacts.phone')" - v-model="row.phone" - /> - <VnInput - :label="t('supplier.contacts.mobile')" - v-model="row.mobile" - /> - <VnInput - :label="t('supplier.contacts.email')" - v-model="row.email" - /> + <VnInput :label="t('globals.phone')" v-model="row.phone" /> + <VnInput :label="t('globals.mobile')" v-model="row.mobile" /> + <VnInput :label="t('globals.params.email')" v-model="row.email" /> </VnRow> <VnRow class="row q-gutter-md"> <QInput diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue index 5754031b3..0fbe03c99 100644 --- a/src/pages/Supplier/Card/SupplierDescriptor.vue +++ b/src/pages/Supplier/Card/SupplierDescriptor.vue @@ -116,7 +116,7 @@ const getEntryQueryParams = (supplier) => { <VnLv :label="t('supplier.summary.taxNumber')" :value="entity.nif" /> <VnLv label="Alias" :value="entity.nickname" /> <VnLv - :label="t('supplier.summary.payMethod')" + :label="t('supplier.list.payMethod')" :value="entity?.payMethod?.name" /> <VnLv diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue index 169c4d796..547842960 100644 --- a/src/pages/Supplier/Card/SupplierFiscalData.vue +++ b/src/pages/Supplier/Card/SupplierFiscalData.vue @@ -147,16 +147,12 @@ function handleLocation(data, location) { /> <VnInput v-model="data.healthRegister" - :label="t('supplier.fiscalData.healthRegister')" + :label="t('supplier.summary.healthRegister')" clearable /> </VnRow> <VnRow> - <VnInput - v-model="data.street" - :label="t('supplier.fiscalData.street')" - clearable - /> + <VnInput v-model="data.street" :label="t('globals.street')" clearable /> </VnRow> <VnRow> <VnLocation diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue index 6ffb95344..dbb4c47e1 100644 --- a/src/pages/Supplier/Card/SupplierSummary.vue +++ b/src/pages/Supplier/Card/SupplierSummary.vue @@ -82,7 +82,7 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`; :text="t('supplier.summary.billingData')" /> <VnLv - :label="t('supplier.summary.payMethod')" + :label="t('supplier.list.payMethod')" :value="supplier.payMethod?.name" dash /> @@ -131,19 +131,16 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`; /> <VnLv :label="t('supplier.summary.socialName')" :value="supplier.name" /> <VnLv :label="t('supplier.summary.taxNumber')" :value="supplier.nif" /> - <VnLv :label="t('supplier.summary.street')" :value="supplier.street" /> + <VnLv :label="t('globals.street')" :value="supplier.street" /> <VnLv :label="t('supplier.summary.city')" :value="supplier.city" /> - <VnLv - :label="t('supplier.summary.postCode')" - :value="supplier.postCode" - /> + <VnLv :label="t('globals.postCode')" :value="supplier.postCode" /> <VnLv :label="t('supplier.summary.province')" :value="supplier.province?.name" dash /> <VnLv - :label="t('supplier.summary.country')" + :label="t('globals.country')" :value="supplier.country?.name" dash /> diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue index ea79947a4..69f826201 100644 --- a/src/pages/Supplier/SupplierList.vue +++ b/src/pages/Supplier/SupplierList.vue @@ -12,13 +12,13 @@ const tableRef = ref(); const columns = computed(() => [ { align: 'left', - label: t('supplier.list.tableVisibleColumns.id'), + label: t('globals.id'), name: 'id', isTitle: true, }, { align: 'left', - label: t('supplier.list.tableVisibleColumns.name'), + label: t('globals.name'), name: 'socialName', create: true, columnFilter: { @@ -35,7 +35,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('supplier.list.tableVisibleColumns.nickname'), + label: t('globals.alias'), name: 'alias', columnFilter: { name: 'search', @@ -51,7 +51,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('supplier.list.tableVisibleColumns.payMethod'), + label: t('supplier.list.payMethod'), name: 'payMethod', columnFilter: { inWhere: true, @@ -70,7 +70,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('supplier.list.tableVisibleColumns.payDay'), + label: t('supplier.summary.payDay'), name: 'payDay', columnFilter: { inWhere: true, @@ -79,7 +79,7 @@ const columns = computed(() => [ }, { align: 'left', - label: t('supplier.list.tableVisibleColumns.country'), + label: t('globals.country'), name: 'country', columnFilter: { component: 'select', diff --git a/src/pages/Ticket/Card/TicketBoxing.vue b/src/pages/Ticket/Card/TicketBoxing.vue index bff95c0e2..1a7287396 100644 --- a/src/pages/Ticket/Card/TicketBoxing.vue +++ b/src/pages/Ticket/Card/TicketBoxing.vue @@ -136,13 +136,13 @@ async function getVideoList(expeditionId, timed) { <QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel> </QItemSection> <QItemSection> - <QItemLabel caption>{{ t('ticket.boxing.created') }}</QItemLabel> + <QItemLabel caption>{{ t('globals.created') }}</QItemLabel> <QItemLabel> {{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }} </QItemLabel> - <QItemLabel caption>{{ t('ticket.boxing.item') }}</QItemLabel> + <QItemLabel caption>{{ t('globals.item') }}</QItemLabel> <QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel> <QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel> <QItemLabel>{{ expedition.userName }}</QItemLabel> diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue index af9021e36..f8ffb43ed 100644 --- a/src/pages/Ticket/Card/TicketDescriptor.vue +++ b/src/pages/Ticket/Card/TicketDescriptor.vue @@ -125,7 +125,7 @@ function ticketFilter(ticket) { </span> </template> </VnLv> - <VnLv v-if="entity.ticketState" :label="t('ticket.card.state')"> + <VnLv v-if="entity.ticketState" :label="t('globals.state')"> <template #value> <QBadge text-color="black" @@ -149,11 +149,11 @@ function ticketFilter(ticket) { /> <VnLv v-if="entity.agencyMode" - :label="t('ticket.card.agency')" + :label="t('globals.agency')" :value="entity.agencyMode.name" /> - <VnLv :label="t('ticket.card.warehouse')" :value="entity.warehouse?.name" /> - <VnLv :label="t('ticket.card.alias')" :value="entity.nickname" /> + <VnLv :label="t('globals.warehouse')" :value="entity.warehouse?.name" /> + <VnLv :label="t('globals.alias')" :value="entity.nickname" /> </template> <template #icons="{ entity }"> <QCardActions class="q-gutter-x-xs"> diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index ac2ae0509..45769daa5 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -132,7 +132,7 @@ function toTicketUrl(section) { :url="toTicketUrl('basic-data')" :text="t('globals.summary.basicData')" /> - <VnLv v-if="entity.ticketState" :label="t('ticket.summary.state')"> + <VnLv v-if="entity.ticketState" :label="t('globals.state')"> <template #value> <QBadge text-color="black" @@ -150,10 +150,7 @@ function toTicketUrl(section) { /> </template> </VnLv> - <VnLv - :label="t('ticket.summary.agency')" - :value="entity.agencyMode?.name" - /> + <VnLv :label="t('globals.agency')" :value="entity.agencyMode?.name" /> <VnLv :label="t('ticket.summary.zone')"> <template #value> <span class="link" @click.stop> @@ -162,10 +159,7 @@ function toTicketUrl(section) { </span> </template> </VnLv> - <VnLv - :label="t('ticket.summary.warehouse')" - :value="entity.warehouse?.name" - /> + <VnLv :label="t('globals.warehouse')" :value="entity.warehouse?.name" /> <VnLv v-if="ticket?.ticketCollections?.length > 0" :label="t('ticket.summary.collection')" @@ -211,10 +205,7 @@ function toTicketUrl(section) { :label="t('ticket.summary.shipped')" :value="toDate(entity.shipped)" /> - <VnLv - :label="t('ticket.summary.landed')" - :value="toDate(entity.landed)" - /> + <VnLv :label="t('globals.landed')" :value="toDate(entity.landed)" /> <VnLv :label="t('globals.packages')" :value="entity.packages" /> <VnLv :value="entity.address.phone"> <template #label> @@ -281,11 +272,11 @@ function toTicketUrl(section) { <VnTitle :text="t('ticket.summary.summaryAmount')" /> <div class="bodyCard"> <VnLv - :label="t('ticket.summary.subtotal')" + :label="t('globals.subtotal')" :value="toCurrency(entity.totalWithoutVat)" /> <VnLv - :label="t('ticket.summary.vat')" + :label="t('globals.vat')" :value="toCurrency(entity.totalWithVat - entity.totalWithoutVat)" /> <VnLv @@ -307,12 +298,12 @@ function toTicketUrl(section) { <template #header="props"> <QTr class="tr-header" :props="props"> <QTh auto-width></QTh> - <QTh auto-width>{{ t('ticket.summary.item') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.visible') }}</QTh> + <QTh auto-width>{{ t('globals.item') }}</QTh> + <QTh auto-width>{{ t('globals.visible') }}</QTh> <QTh auto-width>{{ t('ticket.summary.available') }}</QTh> <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('globals.description') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> + <QTh auto-width>{{ t('globals.price') }}</QTh> <QTh auto-width>{{ t('ticket.summary.discount') }}</QTh> <QTh auto-width>{{ t('globals.amount') }}</QTh> <QTh auto-width>{{ t('ticket.summary.packing') }}</QTh> @@ -364,7 +355,7 @@ function toTicketUrl(section) { size="xs" > <QTooltip> - {{ t('ticket.summary.visible') }}: + {{ t('globals.visible') }}: {{ props.row.visible }} </QTooltip> </QIcon> @@ -471,7 +462,7 @@ function toTicketUrl(section) { <QTable :rows="ticket.packagings" flat style="text-align: center"> <template #header="props"> <QTr class="tr-header" :props="props"> - <QTh auto-width>{{ t('ticket.summary.created') }}</QTh> + <QTh auto-width>{{ t('globals.created') }}</QTh> <QTh auto-width>{{ t('ticket.summary.package') }}</QTh> <QTh auto-width>{{ t('globals.quantity') }}</QTh> </QTr> @@ -495,7 +486,7 @@ function toTicketUrl(section) { <QTr class="tr-header" :props="props"> <QTh auto-width>{{ t('globals.quantity') }}</QTh> <QTh auto-width>{{ t('globals.description') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> + <QTh auto-width>{{ t('globals.price') }}</QTh> <QTh auto-width>{{ t('ticket.summary.taxClass') }}</QTh> <QTh auto-width>{{ t('globals.amount') }}</QTh> </QTr> @@ -522,12 +513,12 @@ function toTicketUrl(section) { <template #header="props"> <QTr class="tr-header" :props="props"> <QTh auto-width>{{ t('globals.description') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.created') }}</QTh> + <QTh auto-width>{{ t('globals.created') }}</QTh> <QTh auto-width>{{ t('ticket.summary.requester') }}</QTh> <QTh auto-width>{{ t('ticket.summary.attender') }}</QTh> <QTh auto-width>{{ t('globals.quantity') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.price') }}</QTh> - <QTh auto-width>{{ t('ticket.summary.item') }}</QTh> + <QTh auto-width>{{ t('globals.price') }}</QTh> + <QTh auto-width>{{ t('globals.item') }}</QTh> <QTh auto-width>{{ t('ticket.summary.ok') }}</QTh> </QTr> </template> diff --git a/src/pages/Ticket/TicketCreate.vue b/src/pages/Ticket/TicketCreate.vue index 3cc486122..1c6a76e6e 100644 --- a/src/pages/Ticket/TicketCreate.vue +++ b/src/pages/Ticket/TicketCreate.vue @@ -134,7 +134,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.client')" + :label="t('globals.client')" v-model="data.clientId" :options="clientOptions" option-value="id" @@ -188,7 +188,7 @@ const redirectToTicketList = (_, { id }) => { <div class="col"> <VnInputDate placeholder="dd-mm-aaa" - :label="t('ticket.create.landed')" + :label="t('globals.landed')" v-model="data.landed" @update:model-value="() => fetchAvailableAgencies(data)" /> @@ -197,7 +197,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.warehouse')" + :label="t('globals.warehouse')" v-model="data.warehouseId" :options="warehousesOptions" option-value="id" @@ -210,7 +210,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.agency')" + :label="t('globals.agency')" v-model="data.agencyModeId" :options="agenciesOptions" option-value="agencyModeFk" diff --git a/src/pages/Ticket/TicketCreateDialog.vue b/src/pages/Ticket/TicketCreateDialog.vue index 4138884bf..ba25a5744 100644 --- a/src/pages/Ticket/TicketCreateDialog.vue +++ b/src/pages/Ticket/TicketCreateDialog.vue @@ -128,7 +128,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.client')" + :label="t('globals.client')" v-model="data.clientId" url="Clients" :fields="['id', 'name', 'defaultAddressFk']" @@ -184,7 +184,7 @@ const redirectToTicketList = (_, { id }) => { <div class="col"> <VnInputDate placeholder="dd-mm-aaa" - :label="t('ticket.create.landed')" + :label="t('globals.landed')" v-model="data.landed" @update:model-value="() => fetchAvailableAgencies(data)" /> @@ -193,7 +193,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.warehouse')" + :label="t('globals.warehouse')" v-model="data.warehouseId" :options="warehousesOptions" option-value="id" @@ -206,7 +206,7 @@ const redirectToTicketList = (_, { id }) => { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.agency')" + :label="t('globals.agency')" v-model="data.agencyModeId" :options="agenciesOptions" option-value="agencyModeFk" diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index ad97e75c1..d50dc5a1b 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -661,7 +661,7 @@ function setReference(data) { <div class="col"> <VnInputDate placeholder="dd-mm-aaa" - :label="t('ticket.create.landed')" + :label="t('globals.landed')" v-model="data.landed" @update:model-value="() => fetchAvailableAgencies(data)" /> @@ -672,7 +672,7 @@ function setReference(data) { <VnSelect url="Warehouses" :sort-by="['name']" - :label="t('ticket.create.warehouse')" + :label="t('globals.warehouse')" v-model="data.warehouseId" :options="warehousesOptions" option-value="id" @@ -685,7 +685,7 @@ function setReference(data) { <VnRow> <div class="col"> <VnSelect - :label="t('ticket.create.agency')" + :label="t('globals.agency')" v-model="data.agencyModeId" :options="agenciesOptions" option-value="agencyModeFk" diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index ca9caf82d..a3d776795 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -31,7 +31,7 @@ const agenciesOptions = ref([]); <VnRow> <VnInput v-model="data.ref" :label="t('globals.reference')" /> <VnSelect - :label="t('travel.basicData.agency')" + :label="t('globals.agency')" v-model="data.agencyModeFk" :options="agenciesOptions" option-value="id" @@ -42,14 +42,11 @@ const agenciesOptions = ref([]); </VnRow> <VnRow> <VnInputDate v-model="data.shipped" :label="t('globals.shipped')" /> - <VnInputDate - v-model="data.landed" - :label="t('travel.basicData.landed')" - /> + <VnInputDate v-model="data.landed" :label="t('globals.landed')" /> </VnRow> <VnRow> <VnSelect - :label="t('travel.basicData.warehouseOut')" + :label="t('globals.warehouseOut')" v-model="data.warehouseOutFk" :options="agenciesOptions" option-value="id" @@ -58,7 +55,7 @@ const agenciesOptions = ref([]); hide-selected /> <VnSelect - :label="t('travel.basicData.warehouseIn')" + :label="t('globals.warehouseIn')" v-model="data.warehouseInFk" :options="agenciesOptions" option-value="id" @@ -72,11 +69,11 @@ const agenciesOptions = ref([]); </VnRow> <VnRow> <QCheckbox - :label="t('travel.basicData.delivered')" + :label="t('travel.summary.delivered')" v-model="data.isDelivered" /> <QCheckbox - :label="t('travel.basicData.received')" + :label="t('travel.summary.received')" v-model="data.isReceived" /> </VnRow> diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue index bda29903b..ba8d7f947 100644 --- a/src/pages/Travel/Card/TravelDescriptor.vue +++ b/src/pages/Travel/Card/TravelDescriptor.vue @@ -71,8 +71,8 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. <TravelDescriptorMenuItems :travel="entity" /> </template> <template #body="{ entity }"> - <VnLv :label="t('globals.wareHouseIn')" :value="entity.warehouseIn.name" /> - <VnLv :label="t('globals.wareHouseOut')" :value="entity.warehouseOut.name" /> + <VnLv :label="t('globals.warehouseIn')" :value="entity.warehouseIn.name" /> + <VnLv :label="t('globals.warehouseOut')" :value="entity.warehouseOut.name" /> <VnLv :label="t('globals.shipped')" :value="toDate(entity.shipped)" /> <VnLv :label="t('globals.landed')" :value="toDate(entity.landed)" /> <VnLv :label="t('globals.totalEntries')" :value="entity.totalEntries" /> diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index d48ed2847..b8e3c3407 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -33,7 +33,7 @@ const warehouses = ref([]); const entriesTableColumns = computed(() => { return [ { - label: t('travel.summary.confirmed'), + label: t('globals.confirmed'), field: 'isConfirmed', name: 'isConfirmed', align: 'left', @@ -136,7 +136,7 @@ const thermographsTableColumns = computed(() => { format: (val) => (val ? `${val}°` : ''), }, { - label: t('travel.thermographs.state'), + label: t('globals.state'), field: 'result', name: 'result', align: 'left', @@ -150,7 +150,7 @@ const thermographsTableColumns = computed(() => { warehouses.value.find((warehouse) => warehouse.id === val)?.name, }, { - label: t('travel.thermographs.created'), + label: t('globals.created'), field: 'created', name: 'created', align: 'left', @@ -265,7 +265,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; </QCardSection> <VnLv :label="t('globals.shipped')" :value="toDate(travel.shipped)" /> <VnLv - :label="t('globals.wareHouseOut')" + :label="t('globals.warehouseOut')" :value="travel.warehouseOut?.name" /> <QCheckbox @@ -283,7 +283,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; </QCardSection> <VnLv :label="t('globals.landed')" :value="toDate(travel.landed)" /> <VnLv - :label="t('globals.wareHouseIn')" + :label="t('globals.warehouseIn')" :value="travel.warehouseIn?.name" /> <QCheckbox diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue index 96544a8ca..0ac8ab5a7 100644 --- a/src/pages/Travel/Card/TravelThermographs.vue +++ b/src/pages/Travel/Card/TravelThermographs.vue @@ -62,7 +62,7 @@ const TableColumns = computed(() => { format: (val) => (val ? `${val}°` : ''), }, { - label: t('travel.thermographs.state'), + label: t('globals.state'), field: 'result', name: 'result', align: 'left', @@ -76,7 +76,7 @@ const TableColumns = computed(() => { warehouses.value.find((warehouse) => warehouse.id === val)?.name, }, { - label: t('travel.thermographs.created'), + label: t('globals.created'), field: 'created', name: 'created', align: 'left', diff --git a/src/pages/Travel/Card/TravelThermographsForm.vue b/src/pages/Travel/Card/TravelThermographsForm.vue index b70e93dfc..4d7b77edf 100644 --- a/src/pages/Travel/Card/TravelThermographsForm.vue +++ b/src/pages/Travel/Card/TravelThermographsForm.vue @@ -216,7 +216,7 @@ const onThermographCreated = async (data) => { </VnSelectDialog> <VnInput v-model="thermographForm.state" - :label="t('travel.thermographs.state')" + :label="t('globals.state')" /> </VnRow> <VnRow> @@ -225,7 +225,7 @@ const onThermographCreated = async (data) => { :label="t('globals.reference')" /> <VnSelect - :label="t('travel.thermographs.type')" + :label="t('globals.type')" v-model="thermographForm.dmsTypeId" :options="dmsTypesOptions" option-value="id" @@ -234,14 +234,14 @@ const onThermographCreated = async (data) => { </VnRow> <VnRow> <VnSelect - :label="t('travel.thermographs.company')" + :label="t('globals.company')" v-model="thermographForm.companyId" :options="companiesOptions" option-value="id" option-label="code" /> <VnSelect - :label="t('travel.thermographs.warehouse')" + :label="t('globals.warehouse')" v-model="thermographForm.warehouseId" :options="warehousesOptions" option-value="id" diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue index 4dc7eb052..d45fae5a6 100644 --- a/src/pages/Travel/ExtraCommunity.vue +++ b/src/pages/Travel/ExtraCommunity.vue @@ -220,7 +220,7 @@ const columns = computed(() => [ sortable: true, }, { - label: t('globals.wareHouseOut'), + label: t('globals.warehouseOut'), field: 'warehouseOutName', name: 'warehouseOutName', align: 'left', @@ -237,7 +237,7 @@ const columns = computed(() => [ format: (value) => toDate(value), }, { - label: t('globals.wareHouseIn'), + label: t('globals.wareHhuseIn'), field: 'warehouseInName', name: 'warehouseInName', align: 'left', diff --git a/src/pages/Travel/TravelCreate.vue b/src/pages/Travel/TravelCreate.vue index 6fb3274e4..72c34aad8 100644 --- a/src/pages/Travel/TravelCreate.vue +++ b/src/pages/Travel/TravelCreate.vue @@ -74,7 +74,7 @@ const redirectToTravelBasicData = (_, { id }) => { </VnRow> <VnRow> <VnSelect - :label="t('globals.wareHouseOut')" + :label="t('globals.warehouseOut')" v-model="data.warehouseOutFk" :options="warehousesOptions" option-value="id" @@ -82,7 +82,7 @@ const redirectToTravelBasicData = (_, { id }) => { hide-selected /> <VnSelect - :label="t('globals.wareHouseIn')" + :label="t('globals.warehouseIn')" v-model="data.warehouseInFk" :options="warehousesOptions" option-value="id" diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index 7ea2b3f7a..63d3bf956 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -48,7 +48,7 @@ const columns = computed(() => [ { align: 'left', name: 'id', - label: t('travel.travelList.tableVisibleColumns.id'), + label: t('globals.id'), isId: true, cardVisible: true, }, @@ -66,7 +66,7 @@ const columns = computed(() => [ { align: 'left', name: 'agencyModeFk', - label: t('travel.travelList.tableVisibleColumns.agency'), + label: t('globals.agency'), component: 'select', attrs: { url: 'agencyModes', @@ -82,7 +82,7 @@ const columns = computed(() => [ { align: 'left', name: 'warehouseInFk', - label: t('travel.travelList.tableVisibleColumns.warehouseIn'), + label: t('globals.warehouseIn'), component: 'select', attrs: { url: 'warehouses', @@ -118,7 +118,7 @@ const columns = computed(() => [ { align: 'left', name: 'warehouseOutFk', - label: t('travel.travelList.tableVisibleColumns.warehouseOut'), + label: t('globals.warehouseOut'), component: 'select', attrs: { url: 'warehouses', @@ -134,7 +134,7 @@ const columns = computed(() => [ { align: 'left', name: 'landed', - label: t('travel.travelList.tableVisibleColumns.landed'), + label: t('globals.landed'), component: 'date', columnField: { component: null, diff --git a/src/pages/Wagon/Type/WagonTypeEdit.vue b/src/pages/Wagon/Type/WagonTypeEdit.vue index eb8205d72..3de115fc0 100644 --- a/src/pages/Wagon/Type/WagonTypeEdit.vue +++ b/src/pages/Wagon/Type/WagonTypeEdit.vue @@ -95,7 +95,7 @@ watch( <VnInput filled v-model="data.name" - :label="t('wagon.type.name')" + :label="t('globals.name')" :rules="[(val) => !!val || t('wagon.warnings.nameNotEmpty')]" /> <QCheckbox diff --git a/src/pages/Wagon/WagonCreate.vue b/src/pages/Wagon/WagonCreate.vue index 2ec0f4d55..ac2aab6ce 100644 --- a/src/pages/Wagon/WagonCreate.vue +++ b/src/pages/Wagon/WagonCreate.vue @@ -103,7 +103,7 @@ function filterType(val, update) { <VnInput filled v-model="wagon.plate" - :label="t('wagon.create.plate')" + :label="t('wagon.list.plate')" :rules="[(val) => !!val || t('wagon.warnings.plateNotEmpty')]" /> </div> @@ -127,7 +127,7 @@ function filterType(val, update) { option-value="id" emit-value map-options - :label="t('wagon.create.type')" + :label="t('globals.type')" :options="filteredWagonTypes" :rules="[(val) => !!val || t('wagon.warnings.typeNotEmpty')]" @filter="filterType" diff --git a/src/pages/Wagon/WagonList.vue b/src/pages/Wagon/WagonList.vue index 61679b933..893b058ea 100644 --- a/src/pages/Wagon/WagonList.vue +++ b/src/pages/Wagon/WagonList.vue @@ -46,7 +46,7 @@ const columns = computed(() => [ { align: 'left', name: 'name', - label: t('wagon.list.type'), + label: t('globals.type'), cardVisible: true, format: (row) => row?.type?.name, }, @@ -123,7 +123,7 @@ async function remove(row) { <VnInput filled v-model="data.plate" - :label="t('wagon.create.plate')" + :label="t('wagon.list.plate')" :rules="[(val) => !!val || t('wagon.warnings.plateNotEmpty')]" /> <VnInput @@ -146,7 +146,7 @@ async function remove(row) { option-value="id" emit-value map-options - :label="t('wagon.create.type')" + :label="t('globals.type')" :options="filteredWagonTypes" :rules="[(val) => !!val || t('wagon.warnings.typeNotEmpty')]" @filter="filterType" diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index 491105e09..8cb688ec8 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -140,7 +140,7 @@ const handlePhotoUpdated = (evt = false) => { <template #body="{ entity }"> <VnLv :label="t('globals.user')" :value="entity.user?.name" /> <VnLv - :label="t('worker.card.email')" + :label="t('globals.params.email')" :value="entity.user?.emailUser?.email" copy /> @@ -150,7 +150,7 @@ const handlePhotoUpdated = (evt = false) => { /> <VnLv :value="entity.phone"> <template #label> - {{ t('worker.card.phone') }} + {{ t('globals.phone') }} <VnLinkPhone :phone-number="entity.phone" /> </template> </VnLv> diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index 3f562a77b..dcb9aa6d5 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -53,7 +53,7 @@ onBeforeMount(async () => { <template #body="{ entity: worker }"> <QCard class="vn-one"> <VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" /> - <VnLv :label="t('worker.card.name')" :value="worker.user?.nickname" /> + <VnLv :label="t('globals.name')" :value="worker.user?.nickname" /> <VnLv :label="t('worker.list.department')"> <template #value> <span class="link" v-text="worker.department?.department?.name" /> @@ -119,9 +119,9 @@ onBeforeMount(async () => { </QCard> <QCard class="vn-one"> <VnTitle :text="t('worker.summary.userData')" /> - <VnLv :label="t('worker.card.name')" :value="worker?.user?.nickname" /> + <VnLv :label="t('globals.name')" :value="worker?.user?.nickname" /> <VnLv - :label="t('worker.list.email')" + :label="t('globals.params.email')" :value="worker.user?.emailUser?.email" copy /> diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue index b51209879..5676837dd 100644 --- a/src/pages/Worker/WorkerCreate.vue +++ b/src/pages/Worker/WorkerCreate.vue @@ -111,7 +111,7 @@ async function autofillBic(worker) { <VnRow> <VnInput v-model="data.firstName" - :label="t('worker.create.name')" + :label="t('globals.name')" :rules="validate('Worker.firstName')" @update:model-value="generateCodeUser(data)" /> @@ -141,7 +141,7 @@ async function autofillBic(worker) { </VnRow> <VnRow> <VnSelect - :label="t('worker.create.company')" + :label="t('globals.company')" v-model="data.companyFk" :options="companiesOptions" option-value="id" @@ -150,7 +150,7 @@ async function autofillBic(worker) { :rules="validate('Worker.company')" /> <VnSelect - :label="t('worker.create.boss')" + :label="t('worker.summary.boss')" v-model="data.bossFk" url="Workers/search" option-value="id" @@ -185,7 +185,7 @@ async function autofillBic(worker) { /> <VnInput v-model="data.phone" - :label="t('worker.create.phone')" + :label="t('globals.phone')" :rules="validate('Worker.phone')" :disable="formData.isFreelance" /> @@ -201,7 +201,7 @@ async function autofillBic(worker) { </VnRow> <VnRow> <VnInput - :label="t('worker.create.street')" + :label="t('globals.street')" v-model="data.street" :rules="validate('Worker.street')" :disable="formData.isFreelance" diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 7a3f760bc..a2ce43b77 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -233,7 +233,7 @@ async function autofillBic(worker) { <VnInput next v-model="data.firstName" - :label="t('worker.create.name')" + :label="t('globals.name')" @update:model-value="generateCodeUser(data)" /> <VnInput @@ -253,7 +253,7 @@ async function autofillBic(worker) { </VnRow> <VnRow> <VnSelect - :label="t('worker.create.company')" + :label="t('globals.company')" v-model="data.companyFk" :options="companiesOptions" option-value="id" @@ -261,7 +261,7 @@ async function autofillBic(worker) { hide-selected /> <VnSelect - :label="t('worker.create.boss')" + :label="t('worker.summary.boss')" v-model="data.bossFk" url="Workers/search" option-value="id" @@ -290,7 +290,7 @@ async function autofillBic(worker) { /> <VnInput v-model="data.phone" - :label="t('worker.create.phone')" + :label="t('globals.phone')" :disable="data.isFreelance" /> </VnRow> From df3b4e7a186afeaa329055e94be04fb7ef76944d Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 21 Oct 2024 13:07:07 +0200 Subject: [PATCH 050/207] refactor: refs #7132 deleted useless code --- src/pages/Ticket/TicketAdvance.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue index 1fc45f713..98792760b 100644 --- a/src/pages/Ticket/TicketAdvance.vue +++ b/src/pages/Ticket/TicketAdvance.vue @@ -551,7 +551,6 @@ onMounted(async () => { style="max-width: 99%" > <template #header="props"> - {{ userParams.scopeDays }} <QTr :props="props"> <QTh class="horizontal-separator text-uppercase color-vn-label" From 52981953f7e9efbc1a8875c321376e02a50c3b33 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 21 Oct 2024 13:23:45 +0200 Subject: [PATCH 051/207] feat(): refs #8039 canceledError not notify --- src/boot/axios.js | 5 +++-- src/boot/quasar.js | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/boot/axios.js b/src/boot/axios.js index 3bd80f487..d3e981adb 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -3,6 +3,7 @@ import { useSession } from 'src/composables/useSession'; import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; import { useStateQueryStore } from 'src/stores/useStateQueryStore'; +import { CanceledError } from 'axios'; const session = useSession(); const { notify } = useNotify(); @@ -42,7 +43,7 @@ const onResponseError = (error) => { let message = ''; const response = error.response; - const responseData = response && response.data; + const responseData = response?.data; const responseError = responseData && response.data.error; if (responseError) { message = responseError.message; @@ -78,7 +79,7 @@ const onResponseError = (error) => { return Promise.reject(error); } - notify(message, 'negative'); + if (!(error instanceof CanceledError)) notify(message, 'negative'); return Promise.reject(error); }; diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 5db6edd24..41a7990c7 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -3,6 +3,7 @@ import qFormMixin from './qformMixin'; import mainShortcutMixin from './mainShortcutMixin'; import keyShortcut from './keyShortcut'; import useNotify from 'src/composables/useNotify.js'; +import { CanceledError } from 'axios'; const { notify } = useNotify(); export default boot(({ app }) => { @@ -11,6 +12,6 @@ export default boot(({ app }) => { app.directive('shortcut', keyShortcut); app.config.errorHandler = function (err) { console.error(err); - notify('globals.error', 'negative', 'error'); + if (!(err instanceof CanceledError)) notify('globals.error', 'negative', 'error'); }; }); From 9780fe596fa0af4212f308a3150d1066a3275517 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 21 Oct 2024 13:33:12 +0200 Subject: [PATCH 052/207] feat: refs #8039 notify error unify --- src/boot/axios.js | 34 +--------------------------------- src/boot/quasar.js | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/boot/axios.js b/src/boot/axios.js index d3e981adb..b084b835d 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -40,37 +40,7 @@ const onResponse = (response) => { const onResponseError = (error) => { stateQuery.remove(error.config); - let message = ''; - - const response = error.response; - const responseData = response?.data; - const responseError = responseData && response.data.error; - if (responseError) { - message = responseError.message; - } - - switch (response?.status) { - case 422: - if (error.name == 'ValidationError') - message += - ' "' + - responseError.details.context + - '.' + - Object.keys(responseError.details.codes).join(',') + - '"'; - break; - case 500: - message = 'errors.statusInternalServerError'; - break; - case 502: - message = 'errors.statusBadGateway'; - break; - case 504: - message = 'errors.statusGatewayTimeout'; - break; - } - - if (session.isLoggedIn() && response?.status === 401) { + if (session.isLoggedIn() && error.response?.status === 401) { session.destroy(false); const hash = window.location.hash; const url = hash.slice(1); @@ -79,8 +49,6 @@ const onResponseError = (error) => { return Promise.reject(error); } - if (!(error instanceof CanceledError)) notify(message, 'negative'); - return Promise.reject(error); }; diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 41a7990c7..bf5175ee6 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -10,8 +10,39 @@ export default boot(({ app }) => { app.mixin(qFormMixin); app.mixin(mainShortcutMixin); app.directive('shortcut', keyShortcut); - app.config.errorHandler = function (err) { - console.error(err); - if (!(err instanceof CanceledError)) notify('globals.error', 'negative', 'error'); + app.config.errorHandler = (error) => { + let message; + const response = error.response; + const responseData = response?.data; + const responseError = responseData && response.data.error; + if (responseError) { + message = responseError.message; + } + + switch (response?.status) { + case 422: + if (error.name == 'ValidationError') + message += + ' "' + + responseError.details.context + + '.' + + Object.keys(responseError.details.codes).join(',') + + '"'; + break; + case 500: + message = 'errors.statusInternalServerError'; + break; + case 502: + message = 'errors.statusBadGateway'; + break; + case 504: + message = 'errors.statusGatewayTimeout'; + break; + } + + console.error(error); + if (error instanceof CanceledError) return; + + notify(message ?? 'globals.error', 'negative', 'error'); }; }); From c69f7af3906e5d88f321350813ec42cc692bd6f4 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 21 Oct 2024 13:38:35 +0200 Subject: [PATCH 053/207] test: refs #8039 axios not notify --- test/vitest/__tests__/boot/axios.spec.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js index 7a802b4d2..19d396ec5 100644 --- a/test/vitest/__tests__/boot/axios.spec.js +++ b/test/vitest/__tests__/boot/axios.spec.js @@ -36,8 +36,6 @@ describe('Axios boot', () => { describe('onResponseError()', async () => { it('should call to the Notify plugin with a message error for an status code "500"', async () => { - Notify.create = vi.fn(); - const error = { response: { status: 500, @@ -45,19 +43,10 @@ describe('Axios boot', () => { }; const result = onResponseError(error); - expect(result).rejects.toEqual(expect.objectContaining(error)); - expect(Notify.create).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'An internal server error has ocurred', - type: 'negative', - }) - ); }); it('should call to the Notify plugin with a message from the response property', async () => { - Notify.create = vi.fn(); - const error = { response: { status: 401, @@ -70,14 +59,7 @@ describe('Axios boot', () => { }; const result = onResponseError(error); - expect(result).rejects.toEqual(expect.objectContaining(error)); - expect(Notify.create).toHaveBeenCalledWith( - expect.objectContaining({ - message: 'Invalid user or password', - type: 'negative', - }) - ); }); }); }); From 29a7f3b2fed499111e620941fd17baa55611a388 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Mon, 21 Oct 2024 13:48:43 +0200 Subject: [PATCH 054/207] fix: refs #7283 #7283 ItemDiary subToolbar --- src/pages/Item/Card/ItemDiary.vue | 67 ++++++++++++++++--------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue index a36b6a246..23dc6214e 100644 --- a/src/pages/Item/Card/ItemDiary.vue +++ b/src/pages/Item/Card/ItemDiary.vue @@ -188,7 +188,7 @@ async function updateWarehouse(warehouseFk) { }, }); await stock.fetch({}); - stock.store.data.itemFk = route.params.id + stock.store.data.itemFk = route.params.id; } </script> @@ -205,38 +205,39 @@ async function updateWarehouse(warehouseFk) { auto-load @on-fetch="(data) => (warehousesOptions = data)" /> - <QToolbar class="justify-end"> - <div id="st-data" class="row"> - <VnSelect - :label="t('itemDiary.warehouse')" - :options="warehousesOptions" - hide-selected - option-label="name" - option-value="id" - dense - v-model="itemsBalanceFilter.where.warehouseFk" - @update:model-value=" - (value) => fetchItemBalances() && updateWarehouse(value) - " - class="q-mr-lg" - /> - <QCheckbox - :label="t('itemDiary.showBefore')" - v-model="showWhatsBeforeInventory" - @update:model-value="fetchItemBalances" - class="q-mr-lg" - /> - <VnInputDate - v-if="showWhatsBeforeInventory" - :label="t('itemDiary.since')" - dense - v-model="itemsBalanceFilter.where.date" - @update:model-value="fetchItemBalances" - /> - </div> - <QSpace /> - <div id="st-actions"></div> - </QToolbar> + <template v-if="stateStore.isHeaderMounted()"> + <Teleport to="#st-data"> + <div class="row"> + <VnSelect + :label="t('itemDiary.warehouse')" + :options="warehousesOptions" + hide-selected + option-label="name" + option-value="id" + dense + v-model="itemsBalanceFilter.where.warehouseFk" + @update:model-value=" + (value) => fetchItemBalances() && updateWarehouse(value) + " + class="q-mr-lg" + /> + <QCheckbox + :label="t('itemDiary.showBefore')" + v-model="showWhatsBeforeInventory" + @update:model-value="fetchItemBalances" + class="q-mr-lg" + /> + <VnInputDate + v-if="showWhatsBeforeInventory" + :label="t('itemDiary.since')" + dense + v-model="itemsBalanceFilter.where.date" + @update:model-value="fetchItemBalances" + /> + </div> + </Teleport> + <Teleport to="#st-actions"> </Teleport> + </template> <QPage class="column items-center q-pa-md"> <QTable :rows="itemBalances" From f4a7e20c574ab8603d6f4b2dabd222556a9a31ea Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Mon, 21 Oct 2024 14:31:31 +0200 Subject: [PATCH 055/207] test: refs #6943 #6943 add comands to solve tests --- .../integration/client/clientBalance.spec.js | 2 +- .../integration/client/clientCredits.spec.js | 2 +- .../integration/client/clientList.spec.js | 6 +-- .../client/clientRecoveries.spec.js | 2 +- .../clientCreditOpinion.spec.js | 2 +- .../client/others/clientConsumption.spec.js | 2 +- .../client/others/clientMandates.spec.js | 2 +- .../client/others/clientSamples.spec.js | 2 +- .../client/others/clientWebPayments.spec.js | 4 +- test/cypress/support/commands.js | 42 +++++++++++++++++++ 10 files changed, 54 insertions(+), 12 deletions(-) diff --git a/test/cypress/integration/client/clientBalance.spec.js b/test/cypress/integration/client/clientBalance.spec.js index 4a666bdb1..dfba56b16 100644 --- a/test/cypress/integration/client/clientBalance.spec.js +++ b/test/cypress/integration/client/clientBalance.spec.js @@ -8,6 +8,6 @@ describe('Client balance', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/clientCredits.spec.js b/test/cypress/integration/client/clientCredits.spec.js index f81bf987d..5f303b40d 100644 --- a/test/cypress/integration/client/clientCredits.spec.js +++ b/test/cypress/integration/client/clientCredits.spec.js @@ -8,6 +8,6 @@ describe('Client credits', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 93e53b9f6..909bd3933 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -44,7 +44,7 @@ describe('Client list', () => { }); }); - it('Client founded create ticket', () => { + it.skip('Client founded create ticket', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); cy.clickButtonsDescriptor(2); @@ -52,10 +52,10 @@ describe('Client list', () => { cy.waitForElement('.q-form'); cy.checkValueForm(1, search); }); - it('Client founded create order', () => { + it.skip('Client founded create order', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); - cy.clickButtonsDescriptor(4); + cy.clickButtonsDescriptor(3); cy.waitForElement('#formModel'); cy.waitForElement('.q-form'); cy.checkValueForm(2, search); diff --git a/test/cypress/integration/client/clientRecoveries.spec.js b/test/cypress/integration/client/clientRecoveries.spec.js index a4e220008..ea6f14407 100644 --- a/test/cypress/integration/client/clientRecoveries.spec.js +++ b/test/cypress/integration/client/clientRecoveries.spec.js @@ -8,6 +8,6 @@ describe('Client recoveries', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js b/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js index 7d9c0fa77..c32215f01 100644 --- a/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js +++ b/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js @@ -8,6 +8,6 @@ describe('Client credit opinion', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/others/clientConsumption.spec.js b/test/cypress/integration/client/others/clientConsumption.spec.js index 179a37707..bbc11998e 100644 --- a/test/cypress/integration/client/others/clientConsumption.spec.js +++ b/test/cypress/integration/client/others/clientConsumption.spec.js @@ -8,6 +8,6 @@ describe('Client consumption', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/others/clientMandates.spec.js b/test/cypress/integration/client/others/clientMandates.spec.js index aaeb7f930..055eda2d0 100644 --- a/test/cypress/integration/client/others/clientMandates.spec.js +++ b/test/cypress/integration/client/others/clientMandates.spec.js @@ -8,6 +8,6 @@ describe('Client mandates', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/others/clientSamples.spec.js b/test/cypress/integration/client/others/clientSamples.spec.js index 03b7238f4..a50120402 100644 --- a/test/cypress/integration/client/others/clientSamples.spec.js +++ b/test/cypress/integration/client/others/clientSamples.spec.js @@ -8,6 +8,6 @@ describe('Client samples', () => { }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/integration/client/others/clientWebPayments.spec.js b/test/cypress/integration/client/others/clientWebPayments.spec.js index 5f7087d21..f35b12612 100644 --- a/test/cypress/integration/client/others/clientWebPayments.spec.js +++ b/test/cypress/integration/client/others/clientWebPayments.spec.js @@ -3,11 +3,11 @@ describe('Client web payments', () => { beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); - cy.visit('#/customer/1101/others/web-payments', { + cy.visit('#/customer/1101/others/web-payment', { timeout: 5000, }); }); it('Should load layout', () => { - cy.get('.q-card').should('be.visible'); + cy.get('.q-page').should('be.visible'); }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 83f45b721..9106a64cd 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -245,6 +245,13 @@ Cypress.Commands.add('validateContent', (selector, expectedValue) => { cy.get(selector).should('have.text', expectedValue); }); +Cypress.Commands.add('openActionDescriptor', (opt) => { + cy.openActionsDescriptor(); + const listItem = '[role="menu"] .q-list .q-item'; + cy.contains(listItem, opt).click(); + 1; +}); + Cypress.Commands.add('openActionsDescriptor', () => { cy.get('.header > :nth-child(3) > .q-btn__content > .q-icon').click(); }); @@ -254,3 +261,38 @@ Cypress.Commands.add('openUserPanel', () => { '.column > .q-avatar > .q-avatar__content > .q-img > .q-img__container > .q-img__image' ).click(); }); + +Cypress.Commands.add('clickButtonsDescriptor', (id) => { + cy.get(`.actions > .q-card__actions> .q-btn:nth-child(${id})`) + .invoke('removeAttr', 'target') + .click(); +}); + +Cypress.Commands.add('openActions', (row) => { + cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); +}); + +Cypress.Commands.add('checkNotification', (type) => { + const values = { + created: 'Data created', + updated: 'Data saved', + deleted: 'Data deleted', + }; + cy.get('.q-notification__message').should('have.text', values[type]); +}); + +Cypress.Commands.add('checkValueForm', (id, search) => { + cy.get( + `.grid-create > :nth-child(${id}) > .q-field__inner>.q-field__control> .q-field__control-container>.q-field__native >.q-field__input` + ).should('have.value', search); +}); + +Cypress.Commands.add('checkValueSelectForm', (id, search) => { + cy.get( + `.grid-create > :nth-child(${id}) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container>.q-field__native>.q-field__input` + ).should('have.value', search); +}); + +Cypress.Commands.add('searchByLabel', (label, value) => { + cy.get(`[label="${label}"] > .q-field > .q-field__inner`).type(`${value}{enter}`); +}); From f3a62091893009b75b4ef3a701f7db1b43f151e1 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 22 Oct 2024 12:00:11 +0200 Subject: [PATCH 056/207] fix: refs #7283 #7283 bugs --- src/pages/Item/Card/ItemDescriptorImage.vue | 4 +- src/pages/Item/ItemList.vue | 55 ++++++++++++++++----- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue index b035a630a..3cd51758b 100644 --- a/src/pages/Item/Card/ItemDescriptorImage.vue +++ b/src/pages/Item/Card/ItemDescriptorImage.vue @@ -134,10 +134,10 @@ es: Regularize stock: Regularizar stock All it's properties will be copied: Todas sus propiedades serán copiadas Do you want to clone this item?: ¿Desea clonar este artículo? - warehouseText: Calculated on the warehouse of { warehouseName } + warehouseText: Calculado sobre el almacén de { warehouseName } en: - warehouseText: Calculado sobre el almacén de { warehouseName } + warehouseText: Calculated on the warehouse of { warehouseName } </i18n> <style lang="scss" scoped> diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 6c7b7eaed..92c9d188b 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -11,6 +11,9 @@ import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import ItemSummary from '../Item/Card/ItemSummary.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; +import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; +import VnConfirm from 'src/components/ui/VnConfirm.vue'; +import { useQuasar } from 'quasar'; const entityId = computed(() => route.params.id); const { viewSummary } = useSummaryDialog(); @@ -18,6 +21,7 @@ const router = useRouter(); const { t } = useI18n(); const tableRef = ref(); const route = useRoute(); +const quasar = useQuasar(); const itemFilter = { include: [ @@ -53,10 +57,12 @@ const columns = computed(() => [ id: row?.id, zoomResolution: '1600x900', zoom: true, + class: 'rounded', }; }, }, columnFilter: false, + cardVisible: true, }, { label: t('item.list.id'), @@ -66,6 +72,7 @@ const columns = computed(() => [ chip: { condition: () => true, }, + cardVisible: true, }, { label: t('item.list.grouping'), @@ -93,6 +100,7 @@ const columns = computed(() => [ columnFilter: { name: 'search', }, + cardVisible: true, }, { label: t('item.list.stems'), @@ -102,6 +110,7 @@ const columns = computed(() => [ component: 'number', inWhere: true, }, + cardVisible: true, }, { label: t('item.list.size'), @@ -111,6 +120,7 @@ const columns = computed(() => [ component: 'number', inWhere: true, }, + cardVisible: true, }, { label: t('item.list.typeName'), @@ -172,6 +182,7 @@ const columns = computed(() => [ component: null, }, create: true, + cardVisible: true, }, { label: t('item.list.origin'), @@ -197,6 +208,7 @@ const columns = computed(() => [ component: null, }, create: true, + cardVisible: true, }, { label: t('item.list.userName'), @@ -270,13 +282,14 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('Clone item'), + title: t('globals.clone'), + icon: 'vn:clone', - action: cloneItem, + action: openCloneDialog, isPrimary: true, }, { - title: t('view Summary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', action: (row) => viewSummary(row.id, ItemSummary), isPrimary: true, @@ -285,21 +298,34 @@ const columns = computed(() => [ }, ]); -const cloneItem = async (itemFk) => { +const cloneItem = async () => { try { - const { data } = await axios.post(`Items/${itemFk.id}/clone`); - if (!data) return; + const { data } = await axios.post(`Items/${entityId.value}/clone`); router.push({ name: 'ItemTags', params: { id: data.id } }); } catch (err) { - console.error('Error cloning item', err); + console.error('Error cloning item'); } }; + +const openCloneDialog = async () => { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: t('All its properties will be copied'), + message: t('Do you want to clone this item?'), + }, + }) + .onOk(async () => { + await cloneItem(); + }); +}; </script> <template> <VnSearchbar data-key="ItemList" - :label="t('Search Item')" + :label="t('item.searchbar.label')" :info="t('You can search by id')" /> <VnTable @@ -309,19 +335,25 @@ const cloneItem = async (itemFk) => { url-create="Items" :create="{ urlCreate: 'Items', - title: 'Create Item', + title: t('Create Item'), onDataSaved: () => tableRef.redirect(), formInitialData: { editorFk: entityId, }, }" - order="id ASC" + :order="['isActive DESC', 'name', 'id']" :columns="columns" auto-load redirect="Item" :is-editable="false" :filer="itemFilter" > + <template #column-id="{ row }"> + <span class="link" @click.stop> + {{ row.id }} + <ItemDescriptorProxy :id="row.id" /> + </span> + </template> <template #column-userName="{ row }"> <span class="link" @click.stop> {{ row.userName }} @@ -349,7 +381,8 @@ const cloneItem = async (itemFk) => { <i18n> es: New item: Nuevo artículo - All it's properties will be copied: Todas sus propiedades serán copiadas + All its properties will be copied: Todas sus propiedades serán copiadas Do you want to clone this item?: ¿Desea clonar este artículo? Preview: Vista previa + Regularize stock: Regularizar stock </i18n> From 1346a2e7fd52f8811ac0b2efbd0c03676becca1f Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Tue, 22 Oct 2024 12:05:44 +0200 Subject: [PATCH 057/207] fix: tag chips --- src/pages/Order/Card/OrderCatalogFilter.vue | 113 +++++++++----------- 1 file changed, 50 insertions(+), 63 deletions(-) diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 850212a62..0fe8c4d64 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -6,8 +6,8 @@ import axios from 'axios'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; -// import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; +import VnFilterPanelChip from 'src/components/ui/VnFilterPanelChip.vue'; const { t } = useI18n(); @@ -49,6 +49,7 @@ const orderWaySelected = ref('ASC'); const routeQuery = JSON.parse(route?.query.params ?? '{}'); const paramsSearch = ref({}); +const tagData = ref([]); onMounted(() => { paramsSearch.value = JSON.parse(routeQuery.filter ?? '{}')?.where ?? {}; @@ -120,32 +121,6 @@ const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); -// const applyTagFilter = (params, search) => { - -// if (params.tagGroups) params.tagGroups = null; -// if (!tagValues.value?.length) { -// params.tagGroups = null; -// search(); -// return; -// } -// if (!params.tagGroups) { -// params.tagGroups = []; -// } -// params.tagGroups.push( -// JSON.stringify({ -// values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), -// tagSelection: { -// ...selectedTag.value, -// orgShowField: selectedTag?.value?.name, -// }, -// tagFk: selectedTag?.value?.tagFk, -// }) -// ); -// search(); -// selectedTag.value = null; -// tagValues.value = [{}]; -// }; - const applyTagFilter = (params, search) => { if (!tagValues.value?.length) { params.tagGroups = null; @@ -153,27 +128,46 @@ const applyTagFilter = (params, search) => { return; } - if (!params.tagGroups) { + if (!params.tagGroups || typeof params.tagGroups === 'string') { params.tagGroups = []; - } else if (typeof params.tagGroups === 'string') { - params.tagGroups = [params.tagGroups]; } - const newTagGroup = JSON.stringify({ - values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), - tagSelection: { - ...selectedTag.value, - orgShowField: selectedTag?.value?.name, - }, - tagFk: selectedTag?.value?.tagFk, - }); - params.tagGroups.push(newTagGroup); + params.tagGroups.push( + JSON.stringify({ + values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), + tagSelection: { + ...selectedTag.value, + orgShowField: selectedTag?.value?.name, + }, + tagFk: selectedTag?.value?.tagFk, + }) + ); + tagData.value.push(JSON.parse(params.tagGroups[params.tagGroups.length - 1])); search(); selectedTag.value = null; tagValues.value = [{}]; }; +const removeTagChip = (selection, params, search) => { + if (typeof params.tagGroups === 'string') { + try { + params.tagGroups = JSON.parse(params.tagGroups); + } catch (error) { + console.error('Error parsing tagGroups:', error); + params.tagGroups = []; + } + } + console.log('params.tagGroups: ', params.tagGroups); + console.log('selection: ', selection); + + if (Array.isArray(params.tagGroups)) { + params.tagGroups = params.tagGroups.filter((value) => value !== selection); + } + + search(); +}; + const setCategoryList = (data) => { categoryList.value = (data || []) .filter((category) => category.display) @@ -198,22 +192,6 @@ function addOrder(value, field, params) { params.orderBy = JSON.stringify(orderBy); vnFilterPanelRef.value.search(); } - -const data = ref([]); - -function getTagData(value) { - if (Array.isArray(value) && value.length >= 1) { - const parsedTags = value.map((obj) => JSON.parse(obj)); - - if (parsedTags.length === 1) { - data.value = parsedTags[0]; - } else { - data.value = parsedTags; - } - } else { - data.value = JSON.parse(value); - } -} </script> <template> @@ -224,29 +202,37 @@ function getTagData(value) { v-model="paramsSearch" :redirect="false" :hidden-tags="['orderFk', 'orderBy', 'filter', 'search', 'or', 'and']" + :custom-tags="['tagGroups']" :unremovable-params="['orderFk', 'orderBy']" :disable-submit-event="true" > <template #tags="{ tag, formatFn }"> - {{ console.log('tag.label: ', tag.label) }} <strong v-if="tag.label === 'categoryFk'"> {{ t(selectedCategory?.name || '') }} </strong> <strong v-else-if="tag.label === 'typeFk'"> {{ t(selectedType?.name || '') }} </strong> - <div v-else-if="tag.label === 'tagGroups'" class="q-gutter-x-xs"> - {{ getTagData(tag.value) }} - <strong> {{ data.tagSelection?.name }}: </strong> - <span> - {{ console.log('data', data.values) }} - </span> - </div> <div v-else class="q-gutter-x-xs"> <strong>{{ t(`params.${tag.label}`) }}: </strong> <span>{{ formatFn(tag.value) }}</span> </div> </template> + <template #customTags="{ tags: customTags, params, searchFn }"> + <template v-for="tag in customTags" :key="tag.label"> + <template v-if="tag.label === 'tagGroups'"> + <VnFilterPanelChip + v-for="chip in tagData" + :key="chip" + removable + @remove="removeTagChip(chip, params, searchFn)" + > + <strong>{{ chip.tagSelection?.name }}: </strong> + <span>{{ chip.values[0].value }}</span> + </VnFilterPanelChip> + </template> + </template> + </template> <template #body="{ params, searchFn }"> <QItem class="category-filter q-mt-md"> <div @@ -410,6 +396,7 @@ function getTagData(value) { icon="add_circle" shortcut="+" flat + size="md" class="filter-icon" @click="tagValues.push({})" /> From d6b8d41b6c4cf5144018754d8bc7cdee1e73f5ba Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 22 Oct 2024 12:09:19 +0200 Subject: [PATCH 058/207] fix: refs #7283 #7283 ItemSummary bugs --- src/pages/Item/Card/ItemSummary.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue index 7b6015c30..071203038 100644 --- a/src/pages/Item/Card/ItemSummary.vue +++ b/src/pages/Item/Card/ItemSummary.vue @@ -135,7 +135,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; <VnLv v-for="(tax, index) in item.taxes" :key="index" - :label="tax.country.country" + :label="tax.country.name" :value="tax.taxClass.description" /> </QCard> @@ -155,7 +155,8 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; :url="getUrl(entityId, 'barcode')" :text="t('item.summary.barcode')" /> - <p + <div + class="text-bold" v-for="(barcode, index) in item.itemBarcode" :key="index" v-text="barcode.code" From fff3310658db3eb3a80d8a259e94ac57a02a3d48 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 22 Oct 2024 12:09:32 +0200 Subject: [PATCH 059/207] fix: refs #7283 tooltips !Item --- src/pages/Account/AccountList.vue | 2 +- src/pages/Account/Role/AccountRoles.vue | 2 +- src/pages/Route/RouteAutonomous.vue | 2 +- src/pages/Route/RouteExtendedList.vue | 2 +- src/pages/Ticket/TicketList.vue | 2 +- src/pages/Zone/ZoneList.vue | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/Account/AccountList.vue b/src/pages/Account/AccountList.vue index 72c445fa9..9e7f1b10a 100644 --- a/src/pages/Account/AccountList.vue +++ b/src/pages/Account/AccountList.vue @@ -74,7 +74,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('View Summary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', action: (row) => viewSummary(row.id, AccountSummary), isPrimary: true, diff --git a/src/pages/Account/Role/AccountRoles.vue b/src/pages/Account/Role/AccountRoles.vue index ea175d913..5398485e3 100644 --- a/src/pages/Account/Role/AccountRoles.vue +++ b/src/pages/Account/Role/AccountRoles.vue @@ -54,7 +54,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('View Summary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', action: (row) => viewSummary(row.id, RoleSummary), isPrimary: true, diff --git a/src/pages/Route/RouteAutonomous.vue b/src/pages/Route/RouteAutonomous.vue index 5ad349942..4a691dbef 100644 --- a/src/pages/Route/RouteAutonomous.vue +++ b/src/pages/Route/RouteAutonomous.vue @@ -126,7 +126,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('Preview'), + title: t('components.smartCard.viewSummary'), icon: 'preview', isPrimary: true, action: (row) => viewSummary(row?.routeFk, RouteSummary), diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue index 51da4ec12..dbf646935 100644 --- a/src/pages/Route/RouteExtendedList.vue +++ b/src/pages/Route/RouteExtendedList.vue @@ -204,7 +204,7 @@ const columns = computed(() => [ isPrimary: true, }, { - title: t('route.components.smartCard.viewSummary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', action: (row) => viewSummary(row?.id, RouteSummary), isPrimary: true, diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index ad97e75c1..272d3a666 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -202,7 +202,7 @@ const columns = computed(() => [ action: (row) => redirectToLines(row.id), }, { - title: t('ticketList.summary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', isPrimary: true, action: (row) => viewSummary(row.id, TicketSummary), diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue index d160ea6b5..89f2dd42c 100644 --- a/src/pages/Zone/ZoneList.vue +++ b/src/pages/Zone/ZoneList.vue @@ -103,7 +103,7 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('list.zoneSummary'), + title: t('components.smartCard.viewSummary'), icon: 'preview', action: (row) => viewSummary(row.id, ZoneSummary), isPrimary: true, From 49c0d64c07e27e2c469499d85dacba8a611184e3 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 22 Oct 2024 12:13:43 +0200 Subject: [PATCH 060/207] fix: refs #7283 #7283 ItemSummary bugs --- src/pages/Item/Card/ItemSummary.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue index 071203038..6ad09ac64 100644 --- a/src/pages/Item/Card/ItemSummary.vue +++ b/src/pages/Item/Card/ItemSummary.vue @@ -119,7 +119,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; <VnLv v-for="(tag, index) in tags" :key="index" - :label="`${tag.priority} ${tag.tag.name}`" + :label="`${tag.priority} ${tag.tag.name}:`" :value="tag.value" /> </QCard> From 9db1c4f721a3a0d5f3f3a103060a65b78bca4fa4 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 12:29:33 +0200 Subject: [PATCH 061/207] fix: refs #8039 bad tests --- src/components/FormModel.vue | 3 --- test/cypress/integration/outLogin/logout.spec.js | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index 05f947cf3..9ac2d38a5 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -217,9 +217,6 @@ async function save() { updateAndEmit('onDataSaved', formData.value, response?.data); if ($props.reload) await arrayData.fetch({}); hasChanges.value = false; - } catch (err) { - console.error(err); - notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; } diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/outLogin/logout.spec.js index 423189908..8d4e90aac 100644 --- a/test/cypress/integration/outLogin/logout.spec.js +++ b/test/cypress/integration/outLogin/logout.spec.js @@ -13,7 +13,7 @@ describe('Logout', () => { }); describe('not user', () => { beforeEach(() => { - cy.intercept('GET', '**/VnUsers/acl', { + cy.intercept('GET', '**DefaultViewConfigs**', { statusCode: 401, body: { error: { @@ -24,10 +24,11 @@ describe('Logout', () => { }, }, statusMessage: 'AUTHORIZATION_REQUIRED', - }).as('someRoute'); + }); }); + it('when token not exists', () => { - cy.reload(); + cy.get('.q-list > [href="#/item"]').click(); cy.get('.q-notification__message').should( 'have.text', 'Authorization Required' From d25cdbf34e808838eec6cddbc0f3347af84c60f0 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 22 Oct 2024 12:43:58 +0200 Subject: [PATCH 062/207] test: refs #6943 #6943 use command correctly --- test/cypress/integration/client/clientList.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 909bd3933..1b41e55cd 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -50,7 +50,7 @@ describe('Client list', () => { cy.clickButtonsDescriptor(2); cy.waitForElement('#formModel'); cy.waitForElement('.q-form'); - cy.checkValueForm(1, search); + cy.checkValueSelectForm(1, search); }); it.skip('Client founded create order', () => { const search = 'Jessica Jones'; From a732ec05fbe6ba834d46c8eaf3d348c9dbcc0b01 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 13:21:16 +0200 Subject: [PATCH 063/207] test: refs #8039 add hasNotify and, refactor: agencyWorkCenter test --- src/components/FormModelPopup.vue | 2 ++ .../route/agency/agencyWorkCenter.spec.js | 33 +++++++------------ test/cypress/support/commands.js | 11 +++++++ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue index 118c8f5f4..d91f07535 100644 --- a/src/components/FormModelPopup.vue +++ b/src/components/FormModelPopup.vue @@ -61,6 +61,7 @@ defineExpose({ :loading="isLoading" @click="emit('onDataCanceled')" v-close-popup + data-cy="FormModelPopup_cancel" /> <QBtn :label="t('globals.save')" @@ -70,6 +71,7 @@ defineExpose({ class="q-ml-sm" :disabled="isLoading" :loading="isLoading" + data-cy="FormModelPopup_save" /> </div> </template> diff --git a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js index 353c5805b..6a3cab664 100644 --- a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js +++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js @@ -7,31 +7,20 @@ describe('AgencyWorkCenter', () => { const createButton = '.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon'; const workCenterCombobox = 'input[role="combobox"]'; - it('assign workCenter', () => { + it('check workCenter crud', () => { + // create cy.get(createButton).click(); cy.get(workCenterCombobox).type('workCenterOne{enter}'); - cy.get('.q-notification__message').should('have.text', 'Data created'); - }); + cy.hasNotify('Data created'); - it('delete workCenter', () => { + // expect error when duplicate + cy.get(createButton).click(); + cy.get('[data-cy="FormModelPopup_save"]').click(); + cy.hasNotify('This workCenter is already assigned to this agency'); + cy.get('[data-cy="FormModelPopup_cancel"]').click(); + + // delete cy.get('.q-item__section--side > .q-btn > .q-btn__content > .q-icon').click(); - cy.get('.q-notification__message').should( - 'have.text', - 'WorkCenter removed successfully' - ); - }); - - it('error on duplicate workCenter', () => { - cy.get(createButton).click(); - cy.get(workCenterCombobox).type('workCenterOne{enter}'); - cy.get('.q-notification__message').should('have.text', 'Data created'); - cy.get(createButton).click(); - cy.get( - '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container' - ).type('workCenterOne{enter}'); - - cy.get( - ':nth-child(2) > .q-notification__wrapper > .q-notification__content > .q-notification__message' - ).should('have.text', 'This workCenter is already assigned to this agency'); + cy.hasNotify('WorkCenter removed successfully'); }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 83f45b721..c7b36cd3a 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -254,3 +254,14 @@ Cypress.Commands.add('openUserPanel', () => { '.column > .q-avatar > .q-avatar__content > .q-img > .q-img__container > .q-img__image' ).click(); }); + +Cypress.Commands.add('hasNotify', (text) => { + //last + cy.get('.q-notification') + .should('be.visible') + .last() + .then(($lastNotification) => { + if (!Cypress.$($lastNotification).text().includes(text)) + throw new Error(`Notification not found: "${text}"`); + }); +}); From 2d81cffb3329bb874f32e41b3fe38c2eef6eb55e Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 13:34:20 +0200 Subject: [PATCH 064/207] feat: refs #8039 show duplicate request in local --- src/boot/quasar.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index bf5175ee6..7845719fe 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -4,6 +4,7 @@ import mainShortcutMixin from './mainShortcutMixin'; import keyShortcut from './keyShortcut'; import useNotify from 'src/composables/useNotify.js'; import { CanceledError } from 'axios'; + const { notify } = useNotify(); export default boot(({ app }) => { @@ -41,7 +42,11 @@ export default boot(({ app }) => { } console.error(error); - if (error instanceof CanceledError) return; + if (error instanceof CanceledError) { + const env = process.env.NODE_ENV; + if (env && env !== 'development') return; + message = 'Duplicate request'; + } notify(message ?? 'globals.error', 'negative', 'error'); }; From 0c9c01b6e9f2ea6fa3674301039eed2f6501e65d Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 13:53:01 +0200 Subject: [PATCH 065/207] test: refs #8039 fix ZoneWarehouse e2e --- src/pages/Zone/Card/ZoneWarehouses.vue | 16 ++++------------ .../worker/workerNotificationsManager.spec.js | 5 +---- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/pages/Zone/Card/ZoneWarehouses.vue b/src/pages/Zone/Card/ZoneWarehouses.vue index 6b2933224..98e446797 100644 --- a/src/pages/Zone/Card/ZoneWarehouses.vue +++ b/src/pages/Zone/Card/ZoneWarehouses.vue @@ -34,21 +34,13 @@ const columns = computed(() => [ ]); const deleteWarehouse = async (row) => { - try { - await axios.delete(`${urlPath.value}/${row.id}`); - fetchWarehouses(); - } catch (error) { - console.error(error); - } + await axios.delete(`${urlPath.value}/${row.id}`); + fetchWarehouses(); }; const createZoneWarehouse = async (ZoneWarehouseFormData) => { - try { - await axios.post(urlPath.value, ZoneWarehouseFormData); - fetchWarehouses(); - } catch (error) { - console.error(error); - } + await axios.post(urlPath.value, ZoneWarehouseFormData); + fetchWarehouses(); }; watch( diff --git a/test/cypress/integration/worker/workerNotificationsManager.spec.js b/test/cypress/integration/worker/workerNotificationsManager.spec.js index ac452c4ff..367287a5a 100644 --- a/test/cypress/integration/worker/workerNotificationsManager.spec.js +++ b/test/cypress/integration/worker/workerNotificationsManager.spec.js @@ -17,10 +17,7 @@ describe('WorkerNotificationsManager', () => { cy.login('developer'); cy.visit(`/#/worker/${salesPersonId}/notifications`); cy.get(firstAvailableNotification).click(); - cy.notificationHas( - '.q-notification__message', - 'The notification subscription of this worker cant be modified' - ); + cy.hasNotify('The notification subscription of this worker cant be modified'); }); it('should active a notification that is yours', () => { From cd00a3c67f0fe72a4437f3a2eae3e7eae5266ebf Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 13:55:35 +0200 Subject: [PATCH 066/207] test: refs #8039 fix WorkerNotification e2e --- src/pages/Worker/Card/WorkerNotificationsManager.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/Worker/Card/WorkerNotificationsManager.vue b/src/pages/Worker/Card/WorkerNotificationsManager.vue index 731e073cd..53571fb93 100644 --- a/src/pages/Worker/Card/WorkerNotificationsManager.vue +++ b/src/pages/Worker/Card/WorkerNotificationsManager.vue @@ -44,8 +44,9 @@ async function toggleNotification(notification) { `worker.notificationsManager.${notification.active ? '' : 'un'}subscribed` ), }); - } catch { + } catch (e) { notification.active = !notification.active; + throw e; } } From dd2dc86eea3d035aa6ee6845a1dd0047fb653db0 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 14:05:15 +0200 Subject: [PATCH 067/207] fix: refs #8039 o not handle unnecessary errors --- src/pages/Account/Alias/Card/AliasUsers.vue | 10 +- src/pages/Account/Card/AccountMailAlias.vue | 20 +-- src/pages/Account/Role/Card/SubRoles.vue | 26 +-- .../Card/BasicData/TicketBasicDataForm.vue | 28 +-- .../Card/BasicData/TicketBasicDataView.vue | 85 ++++----- src/pages/Ticket/Card/ExpeditionNewTicket.vue | 32 ++-- src/pages/Ticket/Card/TicketComponents.vue | 26 +-- src/pages/Ticket/Card/TicketExpedition.vue | 58 +++---- .../Ticket/Card/TicketSaleMoreActions.vue | 12 +- src/pages/Ticket/Card/TicketSaleTracking.vue | 164 +++++++----------- src/pages/Ticket/Card/TicketService.vue | 52 +++--- src/pages/Ticket/Card/TicketVolume.vue | 22 +-- src/pages/Ticket/TicketAdvanceFilter.vue | 24 ++- src/pages/Ticket/TicketFutureFilter.vue | 40 ++--- 14 files changed, 228 insertions(+), 371 deletions(-) diff --git a/src/pages/Account/Alias/Card/AliasUsers.vue b/src/pages/Account/Alias/Card/AliasUsers.vue index 4a9c449e4..4aad68f1a 100644 --- a/src/pages/Account/Alias/Card/AliasUsers.vue +++ b/src/pages/Account/Alias/Card/AliasUsers.vue @@ -46,13 +46,9 @@ const columns = computed(() => [ ]); const deleteAlias = async (row) => { - try { - await axios.delete(`${urlPath.value}/${row.id}`); - notify(t('User removed'), 'positive'); - fetchAliases(); - } catch (error) { - console.error(error); - } + await axios.delete(`${urlPath.value}/${row.id}`); + notify(t('User removed'), 'positive'); + fetchAliases(); }; watch( diff --git a/src/pages/Account/Card/AccountMailAlias.vue b/src/pages/Account/Card/AccountMailAlias.vue index 15d03c665..8d3bd3b67 100644 --- a/src/pages/Account/Card/AccountMailAlias.vue +++ b/src/pages/Account/Card/AccountMailAlias.vue @@ -61,23 +61,15 @@ const fetchAccountExistence = async () => { }; const deleteMailAlias = async (row) => { - try { - await axios.delete(`${urlPath}/${row.id}`); - fetchMailAliases(); - notify(t('Unsubscribed from alias!'), 'positive'); - } catch (error) { - console.error(error); - } + await axios.delete(`${urlPath}/${row.id}`); + fetchMailAliases(); + notify(t('Unsubscribed from alias!'), 'positive'); }; const createMailAlias = async (mailAliasFormData) => { - try { - await axios.post(urlPath, mailAliasFormData); - notify(t('Subscribed to alias!'), 'positive'); - fetchMailAliases(); - } catch (error) { - console.error(error); - } + await axios.post(urlPath, mailAliasFormData); + notify(t('Subscribed to alias!'), 'positive'); + fetchMailAliases(); }; const fetchMailAliases = async () => { diff --git a/src/pages/Account/Role/Card/SubRoles.vue b/src/pages/Account/Role/Card/SubRoles.vue index d17f96dd8..6cac94667 100644 --- a/src/pages/Account/Role/Card/SubRoles.vue +++ b/src/pages/Account/Role/Card/SubRoles.vue @@ -46,29 +46,15 @@ const columns = computed(() => [ ]); const deleteSubRole = async (row) => { - try { - await axios.delete(`${urlPath.value}/${row.id}`); - fetchSubRoles(); - notify( - t('Role removed. Changes will take a while to fully propagate.'), - 'positive' - ); - } catch (error) { - console.error(error); - } + await axios.delete(`${urlPath.value}/${row.id}`); + fetchSubRoles(); + notify(t('Role removed. Changes will take a while to fully propagate.'), 'positive'); }; const createSubRole = async (subRoleFormData) => { - try { - await axios.post(urlPath.value, subRoleFormData); - notify( - t('Role added! Changes will take a while to fully propagate.'), - 'positive' - ); - fetchSubRoles(); - } catch (error) { - console.error(error); - } + await axios.post(urlPath.value, subRoleFormData); + notify(t('Role added! Changes will take a while to fully propagate.'), 'positive'); + fetchSubRoles(); }; watch( diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue index f5ce8a0f3..f6c20c514 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue @@ -112,32 +112,20 @@ const getShipped = async (params) => { }; const onChangeZone = async (zoneId) => { - try { - formData.value.agencyModeFk = null; - const { data } = await axios.get(`Zones/${zoneId}`); - formData.value.agencyModeFk = data.agencyModeFk; - } catch (error) { - console.error(error); - } + formData.value.agencyModeFk = null; + const { data } = await axios.get(`Zones/${zoneId}`); + formData.value.agencyModeFk = data.agencyModeFk; }; const onChangeAddress = async (addressId) => { - try { - formData.value.nickname = null; - const { data } = await axios.get(`Addresses/${addressId}`); - formData.value.nickname = data.nickname; - } catch (error) { - console.error(error); - } + formData.value.nickname = null; + const { data } = await axios.get(`Addresses/${addressId}`); + formData.value.nickname = data.nickname; }; const getClientDefaultAddress = async (clientId) => { - try { - const { data } = await axios.get(`Clients/${clientId}`); - if (data) addressId.value = data.defaultAddressFk; - } catch (error) { - console.error(error); - } + const { data } = await axios.get(`Clients/${clientId}`); + if (data) addressId.value = data.defaultAddressFk; }; const clientAddressesList = async (value) => { diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue index 92640f898..fb7881403 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue @@ -70,60 +70,51 @@ const isFormInvalid = () => { }; const getPriceDifference = async () => { - try { - const params = { - landed: formData.value.landed, - addressId: formData.value.addressFk, - agencyModeId: formData.value.agencyModeFk, - zoneId: formData.value.zoneFk, - warehouseId: formData.value.warehouseFk, - shipped: formData.value.shipped, - }; - const { data } = await axios.post( - `tickets/${formData.value.id}/priceDifference`, - params - ); - formData.value.sale = data; - } catch (error) { - console.error(error); - } + const params = { + landed: formData.value.landed, + addressId: formData.value.addressFk, + agencyModeId: formData.value.agencyModeFk, + zoneId: formData.value.zoneFk, + warehouseId: formData.value.warehouseFk, + shipped: formData.value.shipped, + }; + const { data } = await axios.post( + `tickets/${formData.value.id}/priceDifference`, + params + ); + formData.value.sale = data; }; const submit = async () => { - try { - if (!formData.value.option) - return notify(t('basicData.chooseAnOption'), 'negative'); + if (!formData.value.option) return notify(t('basicData.chooseAnOption'), 'negative'); - const params = { - clientFk: formData.value.clientFk, - nickname: formData.value.nickname, - agencyModeFk: formData.value.agencyModeFk, - addressFk: formData.value.addressFk, - zoneFk: formData.value.zoneFk, - warehouseFk: formData.value.warehouseFk, - companyFk: formData.value.companyFk, - shipped: formData.value.shipped, - landed: formData.value.landed, - isDeleted: formData.value.isDeleted, - option: formData.value.option, - isWithoutNegatives: formData.value.withoutNegatives, - withWarningAccept: formData.value.withWarningAccept, - keepPrice: false, - }; + const params = { + clientFk: formData.value.clientFk, + nickname: formData.value.nickname, + agencyModeFk: formData.value.agencyModeFk, + addressFk: formData.value.addressFk, + zoneFk: formData.value.zoneFk, + warehouseFk: formData.value.warehouseFk, + companyFk: formData.value.companyFk, + shipped: formData.value.shipped, + landed: formData.value.landed, + isDeleted: formData.value.isDeleted, + option: formData.value.option, + isWithoutNegatives: formData.value.withoutNegatives, + withWarningAccept: formData.value.withWarningAccept, + keepPrice: false, + }; - const { data } = await axios.post( - `tickets/${formData.value.id}/componentUpdate`, - params - ); + const { data } = await axios.post( + `tickets/${formData.value.id}/componentUpdate`, + params + ); - if (!data) return; + if (!data) return; - const ticketToMove = data.id; - notify(t('basicData.unroutedTicket'), 'positive'); - router.push({ name: 'TicketSummary', params: { id: ticketToMove } }); - } catch (error) { - console.error(error); - } + const ticketToMove = data.id; + notify(t('basicData.unroutedTicket'), 'positive'); + router.push({ name: 'TicketSummary', params: { id: ticketToMove } }); }; const submitWithNegatives = async () => { diff --git a/src/pages/Ticket/Card/ExpeditionNewTicket.vue b/src/pages/Ticket/Card/ExpeditionNewTicket.vue index 9183ae405..c288f6cc2 100644 --- a/src/pages/Ticket/Card/ExpeditionNewTicket.vue +++ b/src/pages/Ticket/Card/ExpeditionNewTicket.vue @@ -34,26 +34,20 @@ const newTicketFormData = reactive({}); const date = new Date(); 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 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); - } + const { data } = await axios.post('Expeditions/moveExpeditions', params); + notify(t('globals.dataSaved'), 'positive'); + router.push({ name: 'TicketSummary', params: { id: data.id } }); }; </script> diff --git a/src/pages/Ticket/Card/TicketComponents.vue b/src/pages/Ticket/Card/TicketComponents.vue index 0bccdaacd..b5b3c430c 100644 --- a/src/pages/Ticket/Card/TicketComponents.vue +++ b/src/pages/Ticket/Card/TicketComponents.vue @@ -150,31 +150,19 @@ const getTotal = computed(() => { }); const getComponentsSum = async () => { - try { - const { data } = await axios.get(`Tickets/${route.params.id}/getComponentsSum`); - componentsList.value = data; - } catch (error) { - console.error(error); - } + const { data } = await axios.get(`Tickets/${route.params.id}/getComponentsSum`); + componentsList.value = data; }; const getTheoricalCost = async () => { - try { - const { data } = await axios.get(`Tickets/${route.params.id}/freightCost`); - theoricalCost.value = data; - } catch (error) { - console.error(error); - } + const { data } = await axios.get(`Tickets/${route.params.id}/freightCost`); + theoricalCost.value = data; }; const getTicketVolume = async () => { - try { - if (!ticketData.value) return; - const { data } = await axios.get(`Tickets/${ticketData.value.id}/getVolume`); - ticketVolume.value = data[0].volume; - } catch (error) { - console.error(error); - } + if (!ticketData.value) return; + const { data } = await axios.get(`Tickets/${ticketData.value.id}/getVolume`); + ticketVolume.value = data[0].volume; }; onMounted(() => { diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue index 4becb3db3..b4a2ca732 100644 --- a/src/pages/Ticket/Card/TicketExpedition.vue +++ b/src/pages/Ticket/Card/TicketExpedition.vue @@ -187,18 +187,12 @@ const showNewTicketDialog = (withRoute = false) => { }; 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 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'); }; const showLog = async (expedition) => { @@ -207,29 +201,25 @@ const showLog = async (expedition) => { }; const getExpeditionState = async (expedition) => { - try { - const filter = { - where: { expeditionFk: expedition.id }, - order: ['created DESC'], + const filter = { + where: { expeditionFk: expedition.id }, + order: ['created DESC'], + }; + + const { data: expeditionStates } = await axios.get(`ExpeditionStates/filter`, { + params: { filter: JSON.stringify(filter) }, + }); + const { data: scannedStates } = await axios.get(`ExpeditionStates`, { + params: { filter: JSON.stringify(filter), fields: ['id', 'isScanned'] }, + }); + + expeditionsLogsData.value = expeditionStates.map((state) => { + const scannedState = scannedStates.find((s) => s.id === state.id); + return { + ...state, + isScanned: scannedState ? scannedState.isScanned : false, }; - - const { data: expeditionStates } = await axios.get(`ExpeditionStates/filter`, { - params: { filter: JSON.stringify(filter) }, - }); - const { data: scannedStates } = await axios.get(`ExpeditionStates`, { - params: { filter: JSON.stringify(filter), fields: ['id', 'isScanned'] }, - }); - - expeditionsLogsData.value = expeditionStates.map((state) => { - const scannedState = scannedStates.find((s) => s.id === state.id); - return { - ...state, - isScanned: scannedState ? scannedState.isScanned : false, - }; - }); - } catch (error) { - console.error(error); - } + }); }; onMounted(async () => { diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue index 2ec519d2d..588f78a7b 100644 --- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue +++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue @@ -165,14 +165,10 @@ const createRefund = async (withWarehouse) => { negative: true, }; - try { - const { data } = await axios.post('Tickets/cloneAll', params); - const [refundTicket] = data; - notify(t('refundTicketCreated', { ticketId: refundTicket.id }), 'positive'); - push({ name: 'TicketSale', params: { id: refundTicket.id } }); - } catch (error) { - console.error(error); - } + const { data } = await axios.post('Tickets/cloneAll', params); + const [refundTicket] = data; + notify(t('refundTicketCreated', { ticketId: refundTicket.id }), 'positive'); + push({ name: 'TicketSale', params: { id: refundTicket.id } }); }; </script> diff --git a/src/pages/Ticket/Card/TicketSaleTracking.vue b/src/pages/Ticket/Card/TicketSaleTracking.vue index e7830bf37..1083393c4 100644 --- a/src/pages/Ticket/Card/TicketSaleTracking.vue +++ b/src/pages/Ticket/Card/TicketSaleTracking.vue @@ -150,18 +150,14 @@ const shelvingsTableColumns = computed(() => [ ]); const getSaleTrackings = async (sale) => { - try { - const filter = { - where: { saleFk: sale.saleFk }, - order: ['itemFk DESC'], - }; - const { data } = await axios.get(`SaleTrackings/listSaleTracking`, { - params: { filter: JSON.stringify(filter) }, - }); - saleTrackings.value = data; - } catch (error) { - console.error(error); - } + const filter = { + where: { saleFk: sale.saleFk }, + order: ['itemFk DESC'], + }; + const { data } = await axios.get(`SaleTrackings/listSaleTracking`, { + params: { filter: JSON.stringify(filter) }, + }); + saleTrackings.value = data; }; const showLog = async (sale) => { @@ -170,17 +166,13 @@ const showLog = async (sale) => { }; const getItemShelvingSales = async (sale) => { - try { - const filter = { - where: { saleFk: sale.saleFk }, - }; - const { data } = await axios.get(`ItemShelvingSales/filter`, { - params: { filter: JSON.stringify(filter) }, - }); - itemShelvingsSales.value = data; - } catch (error) { - console.error(error); - } + const filter = { + where: { saleFk: sale.saleFk }, + }; + const { data } = await axios.get(`ItemShelvingSales/filter`, { + params: { filter: JSON.stringify(filter) }, + }); + itemShelvingsSales.value = data; }; const showShelving = async (sale) => { @@ -189,36 +181,28 @@ const showShelving = async (sale) => { }; const updateQuantity = async (sale) => { - try { - if (oldQuantity.value === sale.quantity) return; - const params = { - quantity: sale.quantity, - }; - await axios.patch(`ItemShelvingSales/${sale.id}`, params); - oldQuantity.value = null; - } catch (error) { - console.error(error); - } + if (oldQuantity.value === sale.quantity) return; + const params = { + quantity: sale.quantity, + }; + await axios.patch(`ItemShelvingSales/${sale.id}`, params); + oldQuantity.value = null; }; const updateParking = async (sale) => { - try { - const filter = { - fields: ['id'], - where: { - code: sale.shelvingFk, - }, - }; - const { data } = await axios.get(`Shelvings/findOne`, { - params: { filter: JSON.stringify(filter) }, - }); - const params = { - parkingFk: sale.parkingFk, - }; - await axios.patch(`Shelvings/${data.id}`, params); - } catch (error) { - console.error(error); - } + const filter = { + fields: ['id'], + where: { + code: sale.shelvingFk, + }, + }; + const { data } = await axios.get(`Shelvings/findOne`, { + params: { filter: JSON.stringify(filter) }, + }); + const params = { + parkingFk: sale.parkingFk, + }; + await axios.patch(`Shelvings/${data.id}`, params); }; const updateShelving = async (sale) => { @@ -241,61 +225,41 @@ const updateShelving = async (sale) => { }; const saleTrackingNew = async (sale, stateCode, isChecked) => { - try { - const params = { - saleFk: sale.saleFk, - isChecked, - quantity: sale.quantity, - stateCode, - }; - await axios.post(`SaleTrackings/new`, params); - notify(t('globals.dataSaved'), 'positive'); - } catch (error) { - console.error(error); - } + const params = { + saleFk: sale.saleFk, + isChecked, + quantity: sale.quantity, + stateCode, + }; + await axios.post(`SaleTrackings/new`, params); + notify(t('globals.dataSaved'), 'positive'); }; const saleTrackingDel = async ({ saleFk }, stateCode) => { - try { - const params = { - saleFk, - stateCodes: [stateCode], - }; - await axios.post(`SaleTrackings/delete`, params); - notify(t('globals.dataSaved'), 'positive'); - } catch (error) { - console.error(error); - } + const params = { + saleFk, + stateCodes: [stateCode], + }; + await axios.post(`SaleTrackings/delete`, params); + notify(t('globals.dataSaved'), 'positive'); }; const clickSaleGroupDetail = async (sale) => { - try { - if (!sale.saleGroupDetailFk) return; + if (!sale.saleGroupDetailFk) return; - await axios.delete(`SaleGroupDetails/${sale.saleGroupDetailFk}`); - sale.hasSaleGroupDetail = false; - notify(t('globals.dataSaved'), 'positive'); - } catch (error) { - console.error(error); - } + await axios.delete(`SaleGroupDetails/${sale.saleGroupDetailFk}`); + sale.hasSaleGroupDetail = false; + notify(t('globals.dataSaved'), 'positive'); }; const clickPreviousSelected = (sale) => { - try { - qCheckBoxController(sale, 'isPreviousSelected'); - if (!sale.isPreviousSelected) sale.isPrevious = false; - } catch (error) { - console.error(error); - } + qCheckBoxController(sale, 'isPreviousSelected'); + if (!sale.isPreviousSelected) sale.isPrevious = false; }; const clickPrevious = (sale) => { - try { - qCheckBoxController(sale, 'isPrevious'); - if (sale.isPrevious) sale.isPreviousSelected = true; - } catch (error) { - console.error(error); - } + qCheckBoxController(sale, 'isPrevious'); + if (sale.isPrevious) sale.isPreviousSelected = true; }; const qCheckBoxController = (sale, action) => { @@ -306,16 +270,12 @@ const qCheckBoxController = (sale, action) => { isPreviousSelected: 'PREVIOUS_PREPARATION', }; const stateCode = STATE_CODES[action]; - try { - if (!sale[action]) { - saleTrackingNew(sale, stateCode, true); - sale[action] = true; - } else { - saleTrackingDel(sale, stateCode); - sale[action] = false; - } - } catch (error) { - console.error(error); + if (!sale[action]) { + saleTrackingNew(sale, stateCode, true); + sale[action] = true; + } else { + saleTrackingDel(sale, stateCode); + sale[action] = false; } }; </script> diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue index 45a870f7f..47c28a422 100644 --- a/src/pages/Ticket/Card/TicketService.vue +++ b/src/pages/Ticket/Card/TicketService.vue @@ -46,40 +46,32 @@ watch( onMounted(async () => await getDefaultTaxClass()); const createRefund = async () => { - try { - if (!selected.value.length) return; + if (!selected.value.length) return; - const params = { - servicesIds: selected.value.map((s) => +s.id), - withWarehouse: false, - negative: true, - }; - const { data } = await axios.post('Sales/clone', params); - const [refundTicket] = data; - notify( - t('service.createRefundSuccess', { - ticketId: refundTicket.id, - }), - 'positive' - ); - router.push({ name: 'TicketSale', params: { id: refundTicket.id } }); - } catch (error) { - console.error(error); - } + const params = { + servicesIds: selected.value.map((s) => +s.id), + withWarehouse: false, + negative: true, + }; + const { data } = await axios.post('Sales/clone', params); + const [refundTicket] = data; + notify( + t('service.createRefundSuccess', { + ticketId: refundTicket.id, + }), + 'positive' + ); + router.push({ name: 'TicketSale', params: { id: refundTicket.id } }); }; const getDefaultTaxClass = async () => { - try { - let filter = { - where: { code: 'G' }, - }; - const { data } = await axios.get('TaxClasses/findOne', { - params: { filter: JSON.stringify(filter) }, - }); - defaultTaxClass.value = data; - } catch (error) { - console.error(error); - } + let filter = { + where: { code: 'G' }, + }; + const { data } = await axios.get('TaxClasses/findOne', { + params: { filter: JSON.stringify(filter) }, + }); + defaultTaxClass.value = data; }; const columns = computed(() => [ diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue index 2cf7ffc42..edfe489d9 100644 --- a/src/pages/Ticket/Card/TicketVolume.vue +++ b/src/pages/Ticket/Card/TicketVolume.vue @@ -75,22 +75,18 @@ const columns = computed(() => [ ]); const applyVolumes = async (salesData) => { - try { - if (!salesData.length) return; + if (!salesData.length) return; - sales.value = salesData; - const ticket = sales.value[0].ticketFk; - const { data } = await axios.get(`Tickets/${ticket}/getVolume`); - const volumes = new Map(data.saleVolume.map((volume) => [volume.saleFk, volume])); + sales.value = salesData; + const ticket = sales.value[0].ticketFk; + const { data } = await axios.get(`Tickets/${ticket}/getVolume`); + const volumes = new Map(data.saleVolume.map((volume) => [volume.saleFk, volume])); - sales.value.forEach((sale) => { - sale.saleVolume = volumes.get(sale.id); - }); + sales.value.forEach((sale) => { + sale.saleVolume = volumes.get(sale.id); + }); - packingTypeVolume.value = data.packingTypeVolume; - } catch (error) { - console.error(error); - } + packingTypeVolume.value = data.packingTypeVolume; }; onMounted(() => (stateStore.rightDrawer = true)); diff --git a/src/pages/Ticket/TicketAdvanceFilter.vue b/src/pages/Ticket/TicketAdvanceFilter.vue index b25ebdea6..27cacd80a 100644 --- a/src/pages/Ticket/TicketAdvanceFilter.vue +++ b/src/pages/Ticket/TicketAdvanceFilter.vue @@ -27,20 +27,16 @@ const warehousesOptions = ref([]); const itemPackingTypes = ref([]); const getItemPackingTypes = async () => { - try { - const filter = { - where: { isActive: true }, - }; - const { data } = await axios.get('ItemPackingTypes', { - params: { filter: JSON.stringify(filter) }, - }); - itemPackingTypes.value = data.map((ipt) => ({ - description: t(ipt.description), - code: ipt.code, - })); - } catch (error) { - console.error(error); - } + const filter = { + where: { isActive: true }, + }; + const { data } = await axios.get('ItemPackingTypes', { + params: { filter: JSON.stringify(filter) }, + }); + itemPackingTypes.value = data.map((ipt) => ({ + description: t(ipt.description), + code: ipt.code, + })); }; onMounted(async () => await getItemPackingTypes()); diff --git a/src/pages/Ticket/TicketFutureFilter.vue b/src/pages/Ticket/TicketFutureFilter.vue index 6345f62b3..ffe967272 100644 --- a/src/pages/Ticket/TicketFutureFilter.vue +++ b/src/pages/Ticket/TicketFutureFilter.vue @@ -24,33 +24,25 @@ const itemPackingTypes = ref([]); const stateOptions = ref([]); const getItemPackingTypes = async () => { - try { - const filter = { - where: { isActive: true }, - }; - const { data } = await axios.get('ItemPackingTypes', { - params: { filter: JSON.stringify(filter) }, - }); - itemPackingTypes.value = data.map((ipt) => ({ - description: t(ipt.description), - code: ipt.code, - })); - } catch (error) { - console.error(error); - } + const filter = { + where: { isActive: true }, + }; + const { data } = await axios.get('ItemPackingTypes', { + params: { filter: JSON.stringify(filter) }, + }); + itemPackingTypes.value = data.map((ipt) => ({ + description: t(ipt.description), + code: ipt.code, + })); }; const getGroupedStates = async () => { - try { - const { data } = await axios.get('AlertLevels'); - stateOptions.value = data.map((state) => ({ - id: state.id, - name: t(`futureTickets.${state.code}`), - code: state.code, - })); - } catch (error) { - console.error(error); - } + const { data } = await axios.get('AlertLevels'); + stateOptions.value = data.map((state) => ({ + id: state.id, + name: t(`futureTickets.${state.code}`), + code: state.code, + })); }; onMounted(async () => { From ee31bc8262d511bc659316d7046b5f9d0228034d Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 22 Oct 2024 14:07:27 +0200 Subject: [PATCH 068/207] chore: refs #8039 not required --- src/boot/axios.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/boot/axios.js b/src/boot/axios.js index b084b835d..aee38e887 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -3,7 +3,6 @@ import { useSession } from 'src/composables/useSession'; import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; import { useStateQueryStore } from 'src/stores/useStateQueryStore'; -import { CanceledError } from 'axios'; const session = useSession(); const { notify } = useNotify(); From ae56c06628010c4197c0b5fa9f858df99711800f Mon Sep 17 00:00:00 2001 From: jgallego <jgallego@verdnatura.es> Date: Wed, 23 Oct 2024 07:45:00 +0200 Subject: [PATCH 069/207] feat: refs #7349 usa back con permisos --- src/pages/Item/ItemRequest.vue | 23 ++++++++++++++---- src/pages/Item/ItemTypeCreate.vue | 24 ++++++++++++++----- src/pages/ItemType/Card/ItemTypeBasicData.vue | 22 +++++++++++++---- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 82c3b48e0..25082697d 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -258,15 +258,28 @@ onBeforeMount(() => { <template #body-cell-attender="{ row }"> <QTd> <VnSelect + url="Workers/search" v-model="row.attenderFk" - :where="{ role: 'buyer' }" - sort-by="id" - url="Workers" + :params="{ departmentCodes: ['shopping'] }" + :fields="['id', 'nickname']" + sort-by="nickname ASC" hide-selected - option-label="firstName" + option-label="nickname" option-value="id" dense - /> + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt?.name }}</QItemLabel> + <QItemLabel caption + >{{ scope.opt?.nickname }}, + {{ scope.opt?.code }}</QItemLabel + > + </QItemSection> + </QItem> + </template> + </VnSelect> </QTd> </template> <template #body-cell-item="{ row }"> diff --git a/src/pages/Item/ItemTypeCreate.vue b/src/pages/Item/ItemTypeCreate.vue index 290a40389..60c037510 100644 --- a/src/pages/Item/ItemTypeCreate.vue +++ b/src/pages/Item/ItemTypeCreate.vue @@ -52,15 +52,27 @@ const redirectToItemTypeBasicData = (_, { id }) => { </VnRow> <VnRow> <VnSelect + url="Workers/search" v-model="data.workerFk" - :label="t('itemType.shared.worker')" - url="Workers" - sort-by="firstName ASC" - :fields="['id', 'firstName']" + :label="t('shared.worker')" + sort-by="nickname ASC" + :fields="['id', 'nickname']" + :params="{ departmentCodes: ['shopping'] }" + option-label="nickname" option-value="id" - option-label="firstName" hide-selected - /> + ><template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt?.name }}</QItemLabel> + <QItemLabel caption + >{{ scope.opt?.nickname }}, + {{ scope.opt?.code }}</QItemLabel + > + </QItemSection> + </QItem> + </template> + </VnSelect> <VnSelect v-model="data.categoryFk" :label="t('itemType.shared.category')" diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/ItemType/Card/ItemTypeBasicData.vue index d35fbb17d..1d4a5cf94 100644 --- a/src/pages/ItemType/Card/ItemTypeBasicData.vue +++ b/src/pages/ItemType/Card/ItemTypeBasicData.vue @@ -41,15 +41,27 @@ const temperaturesOptions = ref([]); </VnRow> <VnRow> <VnSelect + url="Workers/search" v-model="data.workerFk" :label="t('shared.worker')" - url="Workers" - sort-by="firstName ASC" - :fields="['id', 'firstName']" + sort-by="nickname ASC" + :fields="['id', 'nickname']" + :params="{ departmentCodes: ['shopping'] }" + option-label="nickname" option-value="id" - option-label="firstName" hide-selected - /> + ><template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt?.name }}</QItemLabel> + <QItemLabel caption + >{{ scope.opt?.nickname }}, + {{ scope.opt?.code }}</QItemLabel + > + </QItemSection> + </QItem> + </template></VnSelect + > <VnSelect v-model="data.categoryFk" :label="t('shared.category')" From 1bf1844c8f9edf13b8c0a6f414510a184e70edf0 Mon Sep 17 00:00:00 2001 From: jgallego <jgallego@verdnatura.es> Date: Wed, 23 Oct 2024 07:46:52 +0200 Subject: [PATCH 070/207] fix: refs #7349 dependencia no usada --- src/components/VnSelectProvince.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue index 606799e50..9fcbef11e 100644 --- a/src/components/VnSelectProvince.vue +++ b/src/components/VnSelectProvince.vue @@ -1,5 +1,5 @@ <script setup> -import { ref, watch } from 'vue'; +import { ref } from 'vue'; import { useValidator } from 'src/composables/useValidator'; import { useI18n } from 'vue-i18n'; From b40af0ce7bb73660464db2b2b945261920528ece Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 23 Oct 2024 09:49:48 +0200 Subject: [PATCH 071/207] fix: refs #7283 fix pr --- src/pages/Item/Card/ItemBasicData.vue | 8 ++- src/pages/Item/Card/ItemBotanical.vue | 7 --- src/pages/Item/Card/ItemDescriptor.vue | 13 ++++ src/pages/Item/Card/ItemTax.vue | 4 +- src/pages/Item/ItemRequest.vue | 34 ++++++++++- src/pages/Item/ItemTypeList.vue | 85 +++++++++----------------- 6 files changed, 84 insertions(+), 67 deletions(-) diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue index 6b6d89c6d..1b0342668 100644 --- a/src/pages/Item/Card/ItemBasicData.vue +++ b/src/pages/Item/Card/ItemBasicData.vue @@ -85,13 +85,19 @@ const onIntrastatCreated = (response, formData) => { <VnInput :label="t('item.basicData.reference')" v-model="data.comment" /> <VnInput :label="t('item.basicData.relevancy')" + type="number" v-model="data.relevancy" /> </VnRow> <VnRow class="row q-gutter-md q-mb-md"> - <VnInput :label="t('item.basicData.stems')" v-model="data.stems" /> + <VnInput + :label="t('item.basicData.stems')" + type="number" + v-model="data.stems" + /> <VnInput :label="t('item.basicData.multiplier')" + type="number" v-model="data.stemMultiplier" /> <VnSelectDialog diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue index 5f7f3a5e4..1aa6faed1 100644 --- a/src/pages/Item/Card/ItemBotanical.vue +++ b/src/pages/Item/Card/ItemBotanical.vue @@ -20,15 +20,8 @@ let itemBotanicalsForm = reactive({ itemFk: null }); const entityId = computed(() => { return route.params.id; }); -// onMounted(async () => { -// itemBotanicalsForm.itemFk = entityId.value; -// // itemBotanicals.value = await itemBotanicalsRef.value.fetch(); -// if (itemBotanicals.value.length > 0) -// Object.assign(itemBotanicalsForm, itemBotanicals.value[0]); -// }); async function handleItemBotanical(data) { itemBotanicalsForm = data; - // if (data.length > 0) Object.assign(itemBotanicalsForm, itemBotanicals.value[0]); } </script> <template> diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index 09d6a8a4f..aa9795a74 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -189,6 +189,18 @@ const openCloneDialog = async () => { :value="entity.value7" /> </template> + <template #icons="{ entity }"> + <QCardActions v-if="entity" class="q-gutter-x-md"> + <QIcon + v-if="!entity.isActive" + name="vn:unavailable" + color="primary" + size="xs" + > + <QTooltip>{{ t('Inactive article') }}</QTooltip> + </QIcon> + </QCardActions> + </template> <template #actions="{}"> <QCardActions class="row justify-center"> <QBtn @@ -213,6 +225,7 @@ es: Regularize stock: Regularizar stock All its properties will be copied: Todas sus propiedades serán copiadas Do you want to clone this item?: ¿Desea clonar este artículo? + Inactive article: Artículo inactivo </i18n> <style lang="scss" scoped> diff --git a/src/pages/Item/Card/ItemTax.vue b/src/pages/Item/Card/ItemTax.vue index 489a2c7b2..9050db42e 100644 --- a/src/pages/Item/Card/ItemTax.vue +++ b/src/pages/Item/Card/ItemTax.vue @@ -22,7 +22,7 @@ const taxesFilter = { { relation: 'country', scope: { - fields: ['country'], + fields: ['name'], }, }, ], @@ -73,7 +73,7 @@ const submitTaxes = async (data) => { > <VnInput :label="t('tax.country')" - v-model="row.country.country" + v-model="row.country.name" disable /> <VnSelect diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 0eba6f9a4..ea265e706 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -5,7 +5,7 @@ import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.v import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import { useStateStore } from 'stores/useStateStore'; import { useArrayData } from 'composables/useArrayData'; -import { toCurrency } from 'filters/index'; +import { dashIfEmpty, toCurrency } from 'filters/index'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import ItemRequestDenyForm from './ItemRequestDenyForm.vue'; @@ -134,6 +134,20 @@ const columns = computed(() => [ }, ]); +const getBadgeColor = (date) => { + const today = Date.vnNew(); + today.setHours(0, 0, 0, 0); + + const orderLanded = new Date(date); + orderLanded.setHours(0, 0, 0, 0); + + const difference = today - orderLanded; + + if (difference == 0) return 'warning'; + if (difference < 0) return 'success'; + if (difference > 0) return 'alert'; +}; + const changeQuantity = async (request) => { try { if (request.saleFk) { @@ -212,6 +226,24 @@ onMounted(async () => { auto-load :disable-option="{ card: true }" > + <template #column-ticketFk="{ row }"> + <span class="link"> + {{ row.ticketFk }} + <TicketDescriptorProxy :id="row.ticketFk" /> + </span> + </template> + <template #column-shipped="{ row }"> + <QTd> + <QBadge + :color="getBadgeColor(row.shipped)" + text-color="black" + class="q-pa-sm" + style="font-size: 14px" + > + {{ toDate(row.shipped) }} + </QBadge> + </QTd> + </template> <template #column-attenderName="{ row }"> <span class="link" @click.stop> {{ row.attenderName }} diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 5ebbec62b..9981a0d68 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -1,54 +1,14 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; +import { useRoute } from 'vue-router'; import { ref, computed } from 'vue'; import ItemTypeSearchbar from '../ItemType/ItemTypeSearchbar.vue'; import VnTable from 'components/VnTable/VnTable.vue'; -const router = useRouter(); +const route = useRoute(); const { t } = useI18n(); const tableRef = ref(); -const redirectToItemTypeSummary = (id) => { - router.push({ name: 'ItemTypeSummary', params: { id } }); -}; - -const redirectToCreateView = () => { - router.push({ name: 'ItemTypeCreate' }); -}; - -const exprBuilder = (param, value) => { - switch (param) { - case 'name': - return { - name: { like: `%${value}%` }, - }; - case 'code': - return { - code: { like: `%${value}%` }, - }; - case 'search': - if (value) { - if (!isNaN(value)) { - return { id: value }; - } else { - return { - or: [ - { - name: { - like: `%${value}%`, - }, - }, - { - code: { - like: `%${value}%`, - }, - }, - ], - }; - } - } - } -}; +const entityId = computed(() => route.params.id); const columns = computed(() => [ { @@ -75,20 +35,21 @@ const columns = computed(() => [ }, { align: 'left', - name: 'worker', + name: 'workerFk', label: t('worker'), create: true, component: 'select', attrs: { url: 'Workers', - fields: ['id', 'firstName'], + optionLabel: 'firstName', + optionValue: 'id', }, - cardVisible: true, + cardVisible: false, visible: false, }, { align: 'left', - name: 'ItemCategory', + name: 'categoryFk', label: t('ItemCategory'), create: true, component: 'select', @@ -96,7 +57,7 @@ const columns = computed(() => [ url: 'ItemCategories', fields: ['id', 'name'], }, - cardVisible: true, + cardVisible: false, visible: false, }, { @@ -109,7 +70,7 @@ const columns = computed(() => [ url: 'Temperatures', fields: ['id', 'name'], }, - cardVisible: true, + cardVisible: false, visible: false, }, ]); @@ -121,18 +82,13 @@ const columns = computed(() => [ ref="tableRef" data-key="ItemTypeList" :url="`ItemTypes`" - :url-create="`ItemTypes`" - save-url="ItemTypes/crud" - :filter="courseFilter" :create="{ urlCreate: 'ItemTypes', title: 'Create ItemTypes', onDataSaved: () => tableRef.reload(), - formInitialData: { - workerFk: entityId, - }, + formInitialData: {}, }" - order="id DESC" + order="code ASC" :columns="columns" auto-load :right-search="false" @@ -140,3 +96,20 @@ const columns = computed(() => [ :use-model="true" /> </template> + +<i18n> + es: + id: Id + code: Código + name: Nombre + worker: Encargado + ItemCategory: Categoría + Temperature: Temperatura + Create ItemTypes: Crear familia + en: + code: Code + name: Name + worker: Worker + ItemCategory: ItemCategory + Temperature: Temperature +</i18n> From b69ef48a44ba04dfc7c5012a59c3cf97dcfd2baf Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Wed, 23 Oct 2024 12:21:34 +0200 Subject: [PATCH 072/207] refactor: refs #7132 deleted pageTitles repeated --- src/i18n/locale/en.yml | 43 ------------------------------------ src/i18n/locale/es.yml | 49 ------------------------------------------ 2 files changed, 92 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 9049a44a9..d7456ce8f 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -354,9 +354,6 @@ twoFactorRequired: explanation: >- Please, enter the verification code that we have sent to your email in the next 5 minutes -verifyEmail: - pageTitles: - verifyEmail: Email verification recoverPassword: userOrEmail: User or recovery email explanation: >- @@ -436,16 +433,6 @@ entry: isExcludedFromAvailable: Es inventory isRaid: Raid ticket: - pageTitles: - list: List - summary: Summary - sale: Sale - dms: File management - observation: Notes - ticketAdvance: Advance tickets - futureTickets: Future tickets - purchaseRequest: Purchase request - weeklyTickets: Weekly tickets card: customerId: Customer ID customerCard: Customer card @@ -544,8 +531,6 @@ parking: sector: Sector row: Row column: Column - pageTitles: - parking: Parking searchBar: info: You can search by parking code label: Search parking... @@ -569,9 +554,6 @@ order: orderTicketList: Order Ticket List amount: Amount department: - pageTitles: - department: Department - summary: Summary chat: Chat bossDepartment: Boss Department selfConsumptionCustomer: Self-consumption customer @@ -582,21 +564,6 @@ department: hasToSendMail: Send check-ins by email departmentRemoved: Department removed worker: - pageTitles: - workers: Workers - list: List - summary: Summary - workerCreate: New worker - department: Department - pda: PDA - dms: My documentation - pbx: Private Branch Exchange - log: Log - calendar: Calendar - timeControl: Time control - locker: Locker - medical: Medical - operator: Operator list: department: Department schedule: Schedule @@ -680,16 +647,6 @@ worker: isOnReservationMode: Reservation mode machine: Machine wagon: - pageTitles: - wagons: Wagons - wagonsList: Wagons List - wagonCreate: Create wagon - wagonEdit: Edit wagon - typesList: Types List - typeCreate: Create type - typeEdit: Edit type - wagonCounter: Trolley counter - wagonTray: Tray List type: submit: Submit reset: Reset diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 69f4f6b0c..71f820d8f 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -356,9 +356,6 @@ twoFactor: validate: Validar insert: Introduce el código de verificación explanation: Por favor introduce el código de verificación que te hemos enviado a tu email en los próximos 5 minutos -verifyEmail: - pageTitles: - verifyEmail: Verificación de correo recoverPassword: userOrEmail: Usuario o correo de recuperación explanation: >- @@ -439,21 +436,6 @@ entry: isExcludedFromAvailable: Es inventario isRaid: Redada ticket: - pageTitles: - list: Listado - summary: Resumen - dms: Gestión documental - observation: Notas - ticketAdvance: Adelantar tickets - futureTickets: Tickets a futuro - expedition: Expedición - purchaseRequest: Petición de compra - weeklyTickets: Tickets programados - saleTracking: Líneas preparadas - services: Servicios - tracking: Estados - components: Componentes - pictures: Fotos card: customerId: ID cliente customerCard: Ficha del cliente @@ -570,15 +552,10 @@ parking: pickingOrder: Orden de recogida row: Fila column: Columna - pageTitles: - parking: Parking searchBar: info: Puedes buscar por código de parking label: Buscar parking... department: - pageTitles: - department: Departamentos - summary: Resumen chat: Chat bossDepartment: Jefe de departamento selfConsumptionCustomer: Cliente autoconsumo @@ -589,22 +566,6 @@ department: hasToSendMail: Enviar fichadas por mail departmentRemoved: Departamento eliminado worker: - pageTitles: - workers: Trabajadores - list: Listado - summary: Resumen - workerCreate: Nuevo trabajador - department: Departamentos - pda: PDA - dms: Mi documentación - pbx: Centralita - log: Historial - calendar: Calendario - timeControl: Control de horario - locker: Taquilla - formation: Formación - medical: Mutua - operator: Operario list: department: Departamento schedule: Horario @@ -680,16 +641,6 @@ worker: machine: Máquina wagon: - pageTitles: - wagons: Vagones - wagonsList: Listado vagones - wagonCreate: Crear tipo - wagonEdit: Editar tipo - typesList: Listado tipos - typeCreate: Crear tipo - typeEdit: Editar tipo - wagonCounter: Contador de carros - wagonTray: Listado bandejas type: submit: Guardar reset: Deshacer cambios From d8b80cfa6d31087bee361d9b48a999b3f199e59a Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Wed, 23 Oct 2024 12:30:04 +0200 Subject: [PATCH 073/207] fix: refs #7283 fix pr --- src/pages/Item/Card/ItemBotanical.vue | 5 +---- src/pages/Item/Card/ItemDescriptor.vue | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue index 1aa6faed1..c4b561772 100644 --- a/src/pages/Item/Card/ItemBotanical.vue +++ b/src/pages/Item/Card/ItemBotanical.vue @@ -20,9 +20,6 @@ let itemBotanicalsForm = reactive({ itemFk: null }); const entityId = computed(() => { return route.params.id; }); -async function handleItemBotanical(data) { - itemBotanicalsForm = data; -} </script> <template> <FetchData @@ -41,7 +38,7 @@ async function handleItemBotanical(data) { :filter="{ where: { itemFk: entityId }, }" - @on-fetch="handleItemBotanical" + @on-fetch="(data) => (itemBotanicalsForm = data)" > <template #form="{ data }"> <VnRow> diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index aa9795a74..635dd17c8 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -50,7 +50,6 @@ const entityId = computed(() => { }); const regularizeStockFormDialog = ref(null); -const salixUrl = ref(); const mounted = ref(); const arrayDataStock = useArrayData('descriptorStock', { @@ -58,7 +57,6 @@ const arrayDataStock = useArrayData('descriptorStock', { }); onMounted(async () => { - salixUrl.value = await getUrl('getVisibleAvailable'); await getItemConfigs(); mounted.value = true; }); From 37b3affdbfc2c406b72116ac89657218e38f7adc Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Wed, 23 Oct 2024 13:02:28 +0200 Subject: [PATCH 074/207] refactor: revert catalog changes --- src/components/ui/VnFilterPanel.vue | 12 +-- src/components/ui/VnSearchbar.vue | 2 - src/pages/Order/Card/OrderCatalog.vue | 5 +- src/pages/Order/Card/OrderCatalogFilter.vue | 108 ++++++++------------ 4 files changed, 50 insertions(+), 77 deletions(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 66e9df5f5..43d634ad9 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -185,9 +185,6 @@ async function remove(key) { } function formatValue(value) { - if (typeof value === 'object') { - return value; - } if (typeof value === 'boolean') return value ? t('Yes') : t('No'); if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value); @@ -196,13 +193,6 @@ function formatValue(value) { function sanitizer(params) { for (const [key, value] of Object.entries(params)) { - if (key == 'and') { - value.forEach((andValue) => { - params = { ...params, ...andValue }; - }); - delete params[key]; - } - if (value && typeof value === 'object') { const param = Object.values(value)[0]; if (typeof param == 'string') params[key] = param.replaceAll('%', ''); @@ -221,7 +211,7 @@ function sanitizer(params) { icon="search" @click="search()" ></QBtn> - <QForm @submit="search" id="filterPanelForm" @keyup.enter.prevent="search(true)"> + <QForm @submit="search" id="filterPanelForm" @keyup.enter="search()"> <QList dense> <QItem class="q-mt-xs"> <QItemSection top> diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index 569e0ed18..dc6d4751c 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -9,7 +9,6 @@ import { useStateStore } from 'src/stores/useStateStore'; const quasar = useQuasar(); const { t } = useI18n(); const state = useStateStore(); -const emit = defineEmits(['onSearch']); const props = defineProps({ dataKey: { @@ -119,7 +118,6 @@ async function search() { delete filter.params.search; } await arrayData.applyFilter(filter); - emit('onSearch', store.data); } </script> <template> diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue index 110ea48af..f9bcca94c 100644 --- a/src/pages/Order/Card/OrderCatalog.vue +++ b/src/pages/Order/Card/OrderCatalog.vue @@ -86,8 +86,11 @@ function extractValueTags(items) { <div class="full-width"> <VnPaginate data-key="OrderCatalogList" + url="Orders/CatalogFilter" + :limit="50" + :user-params="catalogParams" + @on-fetch="extractTags" :update-router="false" - @on-change="extractTags" > <template #body="{ rows }"> <div class="catalog-list"> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 0fe8c4d64..6de43e86a 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -1,13 +1,14 @@ <script setup> -import { computed, ref, onMounted, watch } from 'vue'; +import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; +import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; +import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; -import VnFilterPanelChip from 'src/components/ui/VnFilterPanelChip.vue'; const { t } = useI18n(); @@ -47,19 +48,6 @@ const orderWayList = ref([ const orderBySelected = ref('relevancy DESC, name'); const orderWaySelected = ref('ASC'); -const routeQuery = JSON.parse(route?.query.params ?? '{}'); -const paramsSearch = ref({}); -const tagData = ref([]); - -onMounted(() => { - paramsSearch.value = JSON.parse(routeQuery.filter ?? '{}')?.where ?? {}; - if (Object.keys(paramsSearch.value).length > 0) vnFilterPanelRef.value.search(); - if (routeQuery.categoryFk && routeQuery.typeFk) { - selectedCategoryFk.value = routeQuery.categoryFk; - selectedTypeFk.value = routeQuery.typeFk; - } -}); - const createValue = (val, done) => { if (val.length > 2) { if (!tagOptions.value.includes(val)) { @@ -73,21 +61,19 @@ const resetCategory = () => { typeList.value = null; }; -const selectCategory = (category, search) => { - if (!paramsSearch.value?.filter) paramsSearch.value.filter = { where: {} }; - const where = paramsSearch.value.filter.where; - if (where.categoryFk === category?.id) { +const clearFilter = (key) => { + if (key === 'categoryFk') { resetCategory(); - where.categoryFk = null; - } else { - if (where.categoryFk && where.categoryFk !== category?.id) { - paramsSearch.value.typeFk = null; - selectedTypeFk.value = null; - typeList.value = []; - } + } +}; +const selectCategory = (params, category, search) => { + if (params.categoryFk === category?.id) { + resetCategory(); + params.categoryFk = null; + } else { selectedCategoryFk.value = category?.id; - where.categoryFk = category?.id; + params.categoryFk = category?.id; loadTypes(category?.id); } search(); @@ -100,10 +86,6 @@ const loadTypes = async (categoryFk = selectedCategoryFk.value) => { typeList.value = data; }; -watch(selectedTypeFk, (newValue) => { - paramsSearch.value.typeFk = newValue; -}); - const selectedCategory = computed(() => (categoryList.value || []).find( (category) => category?.id === selectedCategoryFk.value @@ -121,17 +103,26 @@ const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); +function exprBuilder(param, value) { + switch (param) { + case 'categoryFk': + case 'typeFk': + return { [param]: value }; + case 'search': + if (/^\d+$/.test(value)) return { 'i.id': value }; + else return { 'i.name': { like: `%${value}%` } }; + } +} + const applyTagFilter = (params, search) => { if (!tagValues.value?.length) { params.tagGroups = null; search(); return; } - - if (!params.tagGroups || typeof params.tagGroups === 'string') { + if (!params.tagGroups) { params.tagGroups = []; } - params.tagGroups.push( JSON.stringify({ values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), @@ -142,29 +133,17 @@ const applyTagFilter = (params, search) => { tagFk: selectedTag?.value?.tagFk, }) ); - - tagData.value.push(JSON.parse(params.tagGroups[params.tagGroups.length - 1])); search(); selectedTag.value = null; tagValues.value = [{}]; }; const removeTagChip = (selection, params, search) => { - if (typeof params.tagGroups === 'string') { - try { - params.tagGroups = JSON.parse(params.tagGroups); - } catch (error) { - console.error('Error parsing tagGroups:', error); - params.tagGroups = []; - } + if (params.tagGroups) { + params.tagGroups = (params.tagGroups || []).filter( + (value) => value !== selection + ); } - console.log('params.tagGroups: ', params.tagGroups); - console.log('selection: ', selection); - - if (Array.isArray(params.tagGroups)) { - params.tagGroups = params.tagGroups.filter((value) => value !== selection); - } - search(); }; @@ -199,12 +178,12 @@ function addOrder(value, field, params) { <VnFilterPanel ref="vnFilterPanelRef" :data-key="props.dataKey" - v-model="paramsSearch" - :redirect="false" - :hidden-tags="['orderFk', 'orderBy', 'filter', 'search', 'or', 'and']" + :hidden-tags="['orderFk', 'orderBy']" + :un-removable-params="['orderFk', 'orderBy']" + :expr-builder="exprBuilder" :custom-tags="['tagGroups']" - :unremovable-params="['orderFk', 'orderBy']" - :disable-submit-event="true" + @remove="clearFilter" + :redirect="false" > <template #tags="{ tag, formatFn }"> <strong v-if="tag.label === 'categoryFk'"> @@ -222,13 +201,17 @@ function addOrder(value, field, params) { <template v-for="tag in customTags" :key="tag.label"> <template v-if="tag.label === 'tagGroups'"> <VnFilterPanelChip - v-for="chip in tagData" + v-for="chip in tag.value" :key="chip" removable @remove="removeTagChip(chip, params, searchFn)" > - <strong>{{ chip.tagSelection?.name }}: </strong> - <span>{{ chip.values[0].value }}</span> + <strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong> + <span>{{ + (JSON.parse(chip).values || []) + .map((item) => item.value) + .join(' | ') + }}</span> </VnFilterPanelChip> </template> </template> @@ -243,7 +226,7 @@ function addOrder(value, field, params) { <QIcon :name="category.icon" class="category-icon" - @click="selectCategory(category, searchFn)" + @click="selectCategory(params, category, searchFn)" > <QTooltip> {{ t(category.name) }} @@ -337,7 +320,7 @@ function addOrder(value, field, params) { > <FetchData v-if="selectedTag" - :url="`Tags/${selectedTag.id}/filterValue`" + :url="`Tags/${selectedTag}/filterValue`" limit="30" auto-load @on-fetch="(data) => (tagOptions = data)" @@ -360,7 +343,7 @@ function addOrder(value, field, params) { @update:model-value="applyTagFilter(params, searchFn)" /> <VnSelect - v-else-if="selectedTag.id === 1" + v-else-if="selectedTag === 1" :label="t('params.value')" v-model="value.value" :options="tagOptions || []" @@ -375,7 +358,7 @@ function addOrder(value, field, params) { @new-value="createValue" @update:model-value="applyTagFilter(params, searchFn)" /> - <QInput + <VnInput v-else :label="t('params.value')" v-model="value.value" @@ -396,7 +379,6 @@ function addOrder(value, field, params) { icon="add_circle" shortcut="+" flat - size="md" class="filter-icon" @click="tagValues.push({})" /> From 1c8eabe2936e8a109a3580d3b3552b51d5f1712e Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 24 Oct 2024 00:39:35 +0200 Subject: [PATCH 075/207] perf: refs #7283 #7283 declare composable inst4ead code duplicated --- src/pages/Item/Card/ItemDescriptor.vue | 34 +++------------------- src/pages/Item/ItemList.vue | 34 +++------------------- src/pages/Item/composables/cloneItem.js | 38 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 60 deletions(-) create mode 100644 src/pages/Item/composables/cloneItem.js diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index 635dd17c8..6fbc5a4bd 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -1,20 +1,18 @@ <script setup> import { computed, ref, onMounted } from 'vue'; -import { useRoute, useRouter } from 'vue-router'; +import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import { useQuasar } from 'quasar'; import CardDescriptor from 'src/components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; -import VnConfirm from 'components/ui/VnConfirm.vue'; import RegularizeStockForm from 'components/RegularizeStockForm.vue'; import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue'; import useCardDescription from 'src/composables/useCardDescription'; import axios from 'axios'; -import { getUrl } from 'src/composables/getUrl'; import { dashIfEmpty } from 'src/filters'; import { useArrayData } from 'src/composables/useArrayData'; +import { cloneItem } from 'src/pages/Item/composables/cloneItem'; const $props = defineProps({ id: { @@ -40,9 +38,8 @@ const $props = defineProps({ }, }); -const quasar = useQuasar(); +const { openCloneDialog } = cloneItem(); const route = useRoute(); -const router = useRouter(); const { t } = useI18n(); const warehouseConfig = ref(null); const entityId = computed(() => { @@ -96,29 +93,6 @@ const updateStock = async () => { const openRegularizeStockForm = () => { regularizeStockFormDialog.value.show(); }; - -const cloneItem = async () => { - try { - const { data } = await axios.post(`Items/${entityId.value}/clone`); - router.push({ name: 'ItemTags', params: { id: data.id } }); - } catch (err) { - console.error('Error cloning item'); - } -}; - -const openCloneDialog = async () => { - quasar - .dialog({ - component: VnConfirm, - componentProps: { - title: t('All its properties will be copied'), - message: t('Do you want to clone this item?'), - }, - }) - .onOk(async () => { - await cloneItem(); - }); -}; </script> <template> @@ -144,7 +118,7 @@ const openCloneDialog = async () => { </QDialog> </QItemSection> </QItem> - <QItem v-ripple clickable @click="openCloneDialog()"> + <QItem v-ripple clickable @click="openCloneDialog(entityId)"> <QItemSection> {{ t('globals.clone') }} </QItemSection> diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 92c9d188b..30b86bc11 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -1,27 +1,24 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter, useRoute } from 'vue-router'; +import { useRoute } from 'vue-router'; import VnImg from 'src/components/ui/VnImg.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { toDate } from 'src/filters'; -import axios from 'axios'; import FetchedTags from 'src/components/ui/FetchedTags.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import ItemSummary from '../Item/Card/ItemSummary.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; -import VnConfirm from 'src/components/ui/VnConfirm.vue'; -import { useQuasar } from 'quasar'; -const entityId = computed(() => route.params.id); +import { cloneItem } from 'src/pages/Item/composables/cloneItem'; +const entityId = computed(() => route.params.id); +const { openCloneDialog } = cloneItem(); const { viewSummary } = useSummaryDialog(); -const router = useRouter(); const { t } = useI18n(); const tableRef = ref(); const route = useRoute(); -const quasar = useQuasar(); const itemFilter = { include: [ @@ -297,29 +294,6 @@ const columns = computed(() => [ ], }, ]); - -const cloneItem = async () => { - try { - const { data } = await axios.post(`Items/${entityId.value}/clone`); - router.push({ name: 'ItemTags', params: { id: data.id } }); - } catch (err) { - console.error('Error cloning item'); - } -}; - -const openCloneDialog = async () => { - quasar - .dialog({ - component: VnConfirm, - componentProps: { - title: t('All its properties will be copied'), - message: t('Do you want to clone this item?'), - }, - }) - .onOk(async () => { - await cloneItem(); - }); -}; </script> <template> diff --git a/src/pages/Item/composables/cloneItem.js b/src/pages/Item/composables/cloneItem.js new file mode 100644 index 000000000..f1114c779 --- /dev/null +++ b/src/pages/Item/composables/cloneItem.js @@ -0,0 +1,38 @@ +import axios from 'axios'; +import { computed, ref, onMounted } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; +import { useI18n } from 'vue-i18n'; +import { useQuasar } from 'quasar'; +import VnConfirm from 'components/ui/VnConfirm.vue'; + +export function cloneItem() { + const { t } = useI18n(); + + const quasar = useQuasar(); + const route = useRoute(); + const router = useRouter(); + const cloneItem = async (entityId) => { + const { id } = entityId; + try { + const { data } = await axios.post(`Items/${id ?? entityId}/clone`); + router.push({ name: 'ItemTags', params: { id: data.id } }); + } catch (err) { + console.error('Error cloning item'); + } + }; + + const openCloneDialog = async (entityId) => { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: t('All its properties will be copied'), + message: t('Do you want to clone this item?'), + }, + }) + .onOk(async () => { + await cloneItem(entityId); + }); + }; + return { openCloneDialog }; +} From 56ef811584970ae0c53f04f35604be941cd5a3ef Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 24 Oct 2024 07:47:26 +0200 Subject: [PATCH 076/207] fix: refs #7283 order translation --- src/pages/Item/ItemTypeList.vue | 4 +-- src/router/modules/item.js | 45 +++++++++++++++++---------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 9981a0d68..d9f7bba85 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -84,11 +84,11 @@ const columns = computed(() => [ :url="`ItemTypes`" :create="{ urlCreate: 'ItemTypes', - title: 'Create ItemTypes', + title: t('Create ItemTypes'), onDataSaved: () => tableRef.reload(), formInitialData: {}, }" - order="code ASC" + order="name ASC" :columns="columns" auto-load :right-search="false" diff --git a/src/router/modules/item.js b/src/router/modules/item.js index 48e19dd54..2838c3be7 100644 --- a/src/router/modules/item.js +++ b/src/router/modules/item.js @@ -48,6 +48,28 @@ export default { }, component: () => import('src/pages/Item/ItemList.vue'), }, + { + path: 'request', + name: 'ItemRequest', + meta: { + title: 'buyRequest', + icon: 'vn:buyrequest', + }, + component: () => import('src/pages/Item/ItemRequest.vue'), + }, + { + path: 'waste-breakdown', + name: 'WasteBreakdown', + meta: { + title: 'wasteBreakdown', + icon: 'vn:claims', + }, + beforeEnter: (to, from, next) => { + next({ name: 'ItemList' }); + window.location.href = + 'https://grafana.verdnatura.es/d/TTNXQAxVk'; + }, + }, { path: 'fixed-price', name: 'ItemFixedPrice', @@ -65,19 +87,7 @@ export default { }, component: () => import('src/pages/Item/ItemCreate.vue'), }, - { - path: 'waste-breakdown', - name: 'WasteBreakdown', - meta: { - title: 'wasteBreakdown', - icon: 'vn:claims', - }, - beforeEnter: (to, from, next) => { - next({ name: 'ItemList' }); - window.location.href = - 'https://grafana.verdnatura.es/d/TTNXQAxVk'; - }, - }, + { path: 'item-type-list', name: 'ItemTypeList', @@ -95,15 +105,6 @@ export default { }, component: () => import('src/pages/Item/ItemTypeCreate.vue'), }, - { - path: 'request', - name: 'ItemRequest', - meta: { - title: 'buyRequest', - icon: 'vn:buyrequest', - }, - component: () => import('src/pages/Item/ItemRequest.vue'), - }, ], }, { From 87d2e0a39b1ee2d12e8468a0ca802168d32273f8 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 24 Oct 2024 10:36:48 +0200 Subject: [PATCH 077/207] perf: refs #7283 #7283 handle composable i18n --- src/i18n/locale/es.yml | 108 ----------------------- src/pages/Item/Card/ItemDescriptor.vue | 2 - src/pages/Item/ItemList.vue | 2 - src/pages/Item/composables/cloneItem.js | 8 +- src/pages/Item/locale/en.yml | 112 ++++++++++++++++++++++++ src/pages/Item/locale/es.yml | 112 ++++++++++++++++++++++++ 6 files changed, 227 insertions(+), 117 deletions(-) diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 7c368b7b7..bd414a793 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -1053,114 +1053,6 @@ travel: warehouse: Almacén travelFileDescription: 'Id envío { travelId }' file: Fichero -item: - searchbar: - label: Buscar artículo - descriptor: - item: Artículo - buyer: Comprador - color: Color - category: Categoría - stems: Tallos - visible: Visible - available: Disponible - warehouseText: 'Calculado sobre el almacén de { warehouseName }' - itemDiary: Registro de compra-venta - producer: Productor - list: - id: Identificador - grouping: Grouping - packing: Packing - description: Descripción - stems: Tallos - category: Reino - typeName: Tipo - intrastat: Intrastat - isActive: Activo - size: Medida - origin: Origen - weightByPiece: Peso (gramos)/tallo - userName: Comprador - stemMultiplier: Multiplicador - producer: Productor - landed: F. entrega - basicData: - type: Tipo - reference: Referencia - relevancy: Relevancia - stems: Tallos - multiplier: Multiplicador - generic: Genérico - intrastat: Intrastat - expense: Gasto - weightByPiece: Peso (gramos)/tallo - boxUnits: Unidades/caja - recycledPlastic: Plastico reciclado - nonRecycledPlastic: Plático no reciclado - isActive: Activo - hasKgPrice: Precio en kg - isFragile: Frágil - isFragileTooltip: Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...) - isPhotoRequested: Hacer foto - isPhotoRequestedTooltip: Este artículo necesita una foto - description: Descripción - fixedPrice: - itemFk: ID Artículo - groupingPrice: Precio grouping - packingPrice: Precio packing - hasMinPrice: Tiene precio mínimo - minPrice: Precio min - started: Inicio - ended: Fin - warehouse: Almacén - create: - name: Nombre - tag: Etiqueta - priority: Prioridad - type: Tipo - intrastat: Intrastat - origin: Origen - summary: - basicData: 'Datos básicos' - otherData: 'Otros datos' - description: 'Descripción' - tax: 'IVA' - tags: 'Etiquetas' - botanical: 'Botánico' - barcode: 'Código de barras' - name: 'Nombre' - completeName: 'Nombre completo' - family: 'Familia' - size: 'Medida' - origin: 'Origen' - stems: 'Tallos' - multiplier: 'Multiplicador' - buyer: 'Comprador' - doPhoto: 'Hacer foto' - intrastatCode: 'Código intrastat' - intrastat: 'Intrastat' - ref: 'Referencia' - relevance: 'Relevancia' - weight: 'Peso (gramos)/tallo' - units: 'Unidades/caja' - expense: 'Gasto' - generic: 'Genérico' - recycledPlastic: 'Plástico reciclado' - nonRecycledPlastic: 'Plástico no reciclado' - minSalesQuantity: 'Cantidad mínima de venta' - genus: 'Genus' - specie: 'Specie' - buyRequest: - ticketId: 'ID Ticket' - shipped: 'F. envío' - requester: 'Solicitante' - requested: 'Solicitado' - price: 'Precio' - attender: 'Comprador' - item: 'Artículo' - achieved: 'Conseguido' - concept: 'Concepto' - state: 'Estado' components: topbar: {} itemsFilterPanel: diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index 6fbc5a4bd..243d4c7cb 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -195,8 +195,6 @@ const openRegularizeStockForm = () => { <i18n> es: Regularize stock: Regularizar stock - All its properties will be copied: Todas sus propiedades serán copiadas - Do you want to clone this item?: ¿Desea clonar este artículo? Inactive article: Artículo inactivo </i18n> diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index 30b86bc11..cca5560fe 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -355,8 +355,6 @@ const columns = computed(() => [ <i18n> es: New item: Nuevo artículo - All its properties will be copied: Todas sus propiedades serán copiadas - Do you want to clone this item?: ¿Desea clonar este artículo? Preview: Vista previa Regularize stock: Regularizar stock </i18n> diff --git a/src/pages/Item/composables/cloneItem.js b/src/pages/Item/composables/cloneItem.js index f1114c779..2421c0808 100644 --- a/src/pages/Item/composables/cloneItem.js +++ b/src/pages/Item/composables/cloneItem.js @@ -1,6 +1,5 @@ import axios from 'axios'; -import { computed, ref, onMounted } from 'vue'; -import { useRoute, useRouter } from 'vue-router'; +import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; import VnConfirm from 'components/ui/VnConfirm.vue'; @@ -9,7 +8,6 @@ export function cloneItem() { const { t } = useI18n(); const quasar = useQuasar(); - const route = useRoute(); const router = useRouter(); const cloneItem = async (entityId) => { const { id } = entityId; @@ -26,8 +24,8 @@ export function cloneItem() { .dialog({ component: VnConfirm, componentProps: { - title: t('All its properties will be copied'), - message: t('Do you want to clone this item?'), + title: t('item.descriptor.clone.title'), + message: t('item.descriptor.clone.subTitle'), }, }) .onOk(async () => { diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index c32ee493c..034e39a17 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -88,3 +88,115 @@ itemType: worker: Worker category: Category temperature: Temperature +item: + searchbar: + label: Search item + descriptor: + item: Item + buyer: Buyer + color: Color + category: Category + stems: Stems + visible: Visible + available: Available + warehouseText: 'Calculated on the warehouse of { warehouseName }' + itemDiary: Item diary + producer: Producer + clone: + title: All its properties will be copied + subTitle: Do you want to clone this item? + + list: + id: Identifier + grouping: Grouping + packing: Packing + description: Description + stems: Stems + category: Category + typeName: Type + intrastat: Intrastat + isActive: Active + size: Size + origin: Origin + userName: Buyer + weightByPiece: Weight/Piece + stemMultiplier: Multiplier + producer: Producer + landed: Landed + basicData: + type: Type + reference: Reference + relevancy: Relevancy + stems: Stems + multiplier: Multiplier + generic: Generic + intrastat: Intrastat + expense: Expense + weightByPiece: Weight/Piece + boxUnits: Units/Box + recycledPlastic: Recycled Plastic + nonRecycledPlastic: Non recycled plastic + isActive: Active + hasKgPrice: Price in kg + isFragile: Fragile + isFragileTooltip: Is shown at website, app that this item cannot travel (wreath, palms, ...) + isPhotoRequested: Do photo + isPhotoRequestedTooltip: This item does need a photo + description: Description + fixedPrice: + itemFk: Item ID + groupingPrice: Grouping price + packingPrice: Packing price + hasMinPrice: Has min price + minPrice: Min price + started: Started + ended: Ended + warehouse: Warehouse + create: + name: Name + tag: Tag + priority: Priority + type: Type + intrastat: Intrastat + origin: Origin + buyRequest: + ticketId: 'Ticket ID' + shipped: 'Shipped' + requester: 'Requester' + requested: 'Requested' + price: 'Price' + attender: 'Attender' + item: 'Item' + achieved: 'Achieved' + concept: 'Concept' + state: 'State' + summary: + basicData: 'Basic data' + otherData: 'Other data' + description: 'Description' + tax: 'Tax' + tags: 'Tags' + botanical: 'Botanical' + barcode: 'Barcode' + name: 'Nombre' + completeName: 'Nombre completo' + family: 'Familia' + size: 'Medida' + origin: 'Origen' + stems: 'Tallos' + multiplier: 'Multiplicador' + buyer: 'Comprador' + doPhoto: 'Do photo' + intrastatCode: 'Código intrastat' + intrastat: 'Intrastat' + ref: 'Referencia' + relevance: 'Relevancia' + weight: 'Peso (gramos)/tallo' + units: 'Unidades/caja' + expense: 'Gasto' + generic: 'Genérico' + recycledPlastic: 'Plástico reciclado' + nonRecycledPlastic: 'Plástico no reciclado' + minSalesQuantity: 'Cantidad mínima de venta' + genus: 'Genus' + specie: 'Specie' diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index d32cb7885..917bd7e5f 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -88,3 +88,115 @@ itemType: worker: Trabajador category: Reino temperature: Temperatura +item: + searchbar: + label: Buscar artículo + descriptor: + item: Artículo + buyer: Comprador + color: Color + category: Categoría + stems: Tallos + visible: Visible + available: Disponible + warehouseText: 'Calculado sobre el almacén de { warehouseName }' + itemDiary: Registro de compra-venta + producer: Productor + clone: + title: Todas sus propiedades serán copiadas + subTitle: ¿Desea clonar este artículo? + + list: + id: Identificador + grouping: Grouping + packing: Packing + description: Descripción + stems: Tallos + category: Reino + typeName: Tipo + intrastat: Intrastat + isActive: Activo + size: Medida + origin: Origen + weightByPiece: Peso (gramos)/tallo + userName: Comprador + stemMultiplier: Multiplicador + producer: Productor + landed: F. entrega + basicData: + type: Tipo + reference: Referencia + relevancy: Relevancia + stems: Tallos + multiplier: Multiplicador + generic: Genérico + intrastat: Intrastat + expense: Gasto + weightByPiece: Peso (gramos)/tallo + boxUnits: Unidades/caja + recycledPlastic: Plastico reciclado + nonRecycledPlastic: Plático no reciclado + isActive: Activo + hasKgPrice: Precio en kg + isFragile: Frágil + isFragileTooltip: Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...) + isPhotoRequested: Hacer foto + isPhotoRequestedTooltip: Este artículo necesita una foto + description: Descripción + fixedPrice: + itemFk: ID Artículo + groupingPrice: Precio grouping + packingPrice: Precio packing + hasMinPrice: Tiene precio mínimo + minPrice: Precio min + started: Inicio + ended: Fin + warehouse: Almacén + create: + name: Nombre + tag: Etiqueta + priority: Prioridad + type: Tipo + intrastat: Intrastat + origin: Origen + summary: + basicData: 'Datos básicos' + otherData: 'Otros datos' + description: 'Descripción' + tax: 'IVA' + tags: 'Etiquetas' + botanical: 'Botánico' + barcode: 'Código de barras' + name: 'Nombre' + completeName: 'Nombre completo' + family: 'Familia' + size: 'Medida' + origin: 'Origen' + stems: 'Tallos' + multiplier: 'Multiplicador' + buyer: 'Comprador' + doPhoto: 'Hacer foto' + intrastatCode: 'Código intrastat' + intrastat: 'Intrastat' + ref: 'Referencia' + relevance: 'Relevancia' + weight: 'Peso (gramos)/tallo' + units: 'Unidades/caja' + expense: 'Gasto' + generic: 'Genérico' + recycledPlastic: 'Plástico reciclado' + nonRecycledPlastic: 'Plástico no reciclado' + minSalesQuantity: 'Cantidad mínima de venta' + genus: 'Genus' + specie: 'Specie' + buyRequest: + ticketId: 'ID Ticket' + shipped: 'F. envío' + requester: 'Solicitante' + requested: 'Solicitado' + price: 'Precio' + attender: 'Comprador' + item: 'Artículo' + achieved: 'Conseguido' + concept: 'Concepto' + state: 'Estado' From 2d8789312b41049ae833bc9f05320af1256e3af8 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 24 Oct 2024 11:34:55 +0200 Subject: [PATCH 078/207] test: refs #6943 #6943 remove skip tests --- .../integration/client/clientList.spec.js | 17 ----------------- test/cypress/support/commands.js | 18 ------------------ 2 files changed, 35 deletions(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 1b41e55cd..f150fc190 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -43,21 +43,4 @@ describe('Client list', () => { cy.url().should('include', `/customer/${id}/summary`); }); }); - - it.skip('Client founded create ticket', () => { - const search = 'Jessica Jones'; - cy.searchByLabel('Name', search); - cy.clickButtonsDescriptor(2); - cy.waitForElement('#formModel'); - cy.waitForElement('.q-form'); - cy.checkValueSelectForm(1, search); - }); - it.skip('Client founded create order', () => { - const search = 'Jessica Jones'; - cy.searchByLabel('Name', search); - cy.clickButtonsDescriptor(3); - cy.waitForElement('#formModel'); - cy.waitForElement('.q-form'); - cy.checkValueForm(2, search); - }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 9106a64cd..33dfa85df 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -262,12 +262,6 @@ Cypress.Commands.add('openUserPanel', () => { ).click(); }); -Cypress.Commands.add('clickButtonsDescriptor', (id) => { - cy.get(`.actions > .q-card__actions> .q-btn:nth-child(${id})`) - .invoke('removeAttr', 'target') - .click(); -}); - Cypress.Commands.add('openActions', (row) => { cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); }); @@ -281,18 +275,6 @@ Cypress.Commands.add('checkNotification', (type) => { cy.get('.q-notification__message').should('have.text', values[type]); }); -Cypress.Commands.add('checkValueForm', (id, search) => { - cy.get( - `.grid-create > :nth-child(${id}) > .q-field__inner>.q-field__control> .q-field__control-container>.q-field__native >.q-field__input` - ).should('have.value', search); -}); - -Cypress.Commands.add('checkValueSelectForm', (id, search) => { - cy.get( - `.grid-create > :nth-child(${id}) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container>.q-field__native>.q-field__input` - ).should('have.value', search); -}); - Cypress.Commands.add('searchByLabel', (label, value) => { cy.get(`[label="${label}"] > .q-field > .q-field__inner`).type(`${value}{enter}`); }); From 3f640c650b12152f3a086464d3b0140a5bc6198d Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 24 Oct 2024 12:32:15 +0200 Subject: [PATCH 079/207] perf: refs #7283 #7283 handle i18n --- src/i18n/locale/en.yml | 108 ----------------------------------- src/pages/Item/locale/en.yml | 1 - src/pages/Item/locale/es.yml | 1 - 3 files changed, 110 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index b19363c12..c1748c8ff 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -1055,114 +1055,6 @@ travel: warehouse: Warehouse travelFileDescription: 'Travel id { travelId }' file: File -item: - searchbar: - label: Search item - descriptor: - item: Item - buyer: Buyer - color: Color - category: Category - stems: Stems - visible: Visible - available: Available - warehouseText: 'Calculated on the warehouse of { warehouseName }' - itemDiary: Item diary - producer: Producer - list: - id: Identifier - grouping: Grouping - packing: Packing - description: Description - stems: Stems - category: Category - typeName: Type - intrastat: Intrastat - isActive: Active - size: Size - origin: Origin - userName: Buyer - weightByPiece: Weight/Piece - stemMultiplier: Multiplier - producer: Producer - landed: Landed - basicData: - type: Type - reference: Reference - relevancy: Relevancy - stems: Stems - multiplier: Multiplier - generic: Generic - intrastat: Intrastat - expense: Expense - weightByPiece: Weight/Piece - boxUnits: Units/Box - recycledPlastic: Recycled Plastic - nonRecycledPlastic: Non recycled plastic - isActive: Active - hasKgPrice: Price in kg - isFragile: Fragile - isFragileTooltip: Is shown at website, app that this item cannot travel (wreath, palms, ...) - isPhotoRequested: Do photo - isPhotoRequestedTooltip: This item does need a photo - description: Description - fixedPrice: - itemFk: Item ID - groupingPrice: Grouping price - packingPrice: Packing price - hasMinPrice: Has min price - minPrice: Min price - started: Started - ended: Ended - warehouse: Warehouse - create: - name: Name - tag: Tag - priority: Priority - type: Type - intrastat: Intrastat - origin: Origin - buyRequest: - ticketId: 'Ticket ID' - shipped: 'Shipped' - requester: 'Requester' - requested: 'Requested' - price: 'Price' - attender: 'Attender' - item: 'Item' - achieved: 'Achieved' - concept: 'Concept' - state: 'State' - summary: - basicData: 'Basic data' - otherData: 'Other data' - description: 'Description' - tax: 'Tax' - tags: 'Tags' - botanical: 'Botanical' - barcode: 'Barcode' - name: 'Nombre' - completeName: 'Nombre completo' - family: 'Familia' - size: 'Medida' - origin: 'Origen' - stems: 'Tallos' - multiplier: 'Multiplicador' - buyer: 'Comprador' - doPhoto: 'Do photo' - intrastatCode: 'Código intrastat' - intrastat: 'Intrastat' - ref: 'Referencia' - relevance: 'Relevancia' - weight: 'Peso (gramos)/tallo' - units: 'Unidades/caja' - expense: 'Gasto' - generic: 'Genérico' - recycledPlastic: 'Plástico reciclado' - nonRecycledPlastic: 'Plástico no reciclado' - minSalesQuantity: 'Cantidad mínima de venta' - genus: 'Genus' - specie: 'Specie' components: topbar: {} itemsFilterPanel: diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index 034e39a17..53310cbd0 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -105,7 +105,6 @@ item: clone: title: All its properties will be copied subTitle: Do you want to clone this item? - list: id: Identifier grouping: Grouping diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index 917bd7e5f..1ade9b955 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -105,7 +105,6 @@ item: clone: title: Todas sus propiedades serán copiadas subTitle: ¿Desea clonar este artículo? - list: id: Identificador grouping: Grouping From 64f36c7d4b7a8210df9af7e087660094c0a28c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= <carlosap@verdnatura.es> Date: Thu, 24 Oct 2024 12:35:11 +0200 Subject: [PATCH 080/207] feat: refs #8087 Traspasar redadas a travels --- src/i18n/locale/en.yml | 5 +---- src/i18n/locale/es.yml | 5 +---- src/pages/Entry/Card/EntryBasicData.vue | 6 ------ src/pages/Entry/Card/EntryDescriptor.vue | 4 ++-- src/pages/Entry/Card/EntrySummary.vue | 5 ----- src/pages/Entry/EntryList.vue | 4 ++-- src/pages/Travel/Card/TravelBasicData.vue | 4 ++++ src/pages/Travel/Card/TravelSummary.vue | 4 ++++ 8 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index aa8df17e2..d1ea5ceb9 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -106,6 +106,7 @@ globals: weight: Weight error: Ups! Something went wrong recalc: Recalculate + daysInForward: Forward days pageTitles: logIn: Login addressEdit: Update address @@ -369,7 +370,6 @@ entry: companyFk: Company travelFk: Travel isExcludedFromAvailable: Inventory - isRaid: Raid invoiceAmount: Import summary: commission: Commission @@ -380,7 +380,6 @@ entry: ordered: Ordered confirmed: Confirmed booked: Booked - raid: Raid excludedFromAvailable: Inventory travelReference: Reference travelAgency: Agency @@ -413,7 +412,6 @@ entry: ordered: Ordered confirmed: Confirmed booked: Booked - raid: Raid excludedFromAvailable: Inventory agency: Agency warehouseOut: Warehouse Out @@ -476,7 +474,6 @@ entry: packingOut: Package out landing: Landing isExcludedFromAvailable: Es inventory - isRaid: Raid ticket: pageTitles: tickets: Tickets diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 575e2c6c7..18e580893 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -108,6 +108,7 @@ globals: weight: Peso error: ¡Ups! Algo salió mal recalc: Recalcular + daysInForward: Días en el futuro pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario @@ -371,7 +372,6 @@ entry: companyFk: Empresa travelFk: Envio isExcludedFromAvailable: Inventario - isRaid: Redada invoiceAmount: Importe summary: commission: Comisión @@ -382,7 +382,6 @@ entry: ordered: Pedida confirmed: Confirmada booked: Contabilizada - raid: Redada excludedFromAvailable: Inventario travelReference: Referencia travelAgency: Agencia @@ -415,7 +414,6 @@ entry: ordered: Pedida confirmed: Confirmado booked: Asentado - raid: Redada excludedFromAvailable: Inventario agency: Agencia warehouseOut: Alm. salida @@ -478,7 +476,6 @@ entry: packingOut: Embalaje envíos landing: Llegada isExcludedFromAvailable: Es inventario - isRaid: Redada ticket: pageTitles: tickets: Tickets diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index b81b1db22..d60ed8645 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -168,12 +168,6 @@ const onFilterTravelSelected = (formData, id) => { v-model="data.isExcludedFromAvailable" :label="t('entry.basicData.excludedFromAvailable')" /> - <QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" /> - <QCheckbox - v-if="isAdministrative()" - v-model="data.isBooked" - :label="t('entry.basicData.booked')" - /> </VnRow> </template> </FormModel> diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index b22d6ba53..d85e5e1a0 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -32,7 +32,6 @@ const entryFilter = { { relation: 'travel', scope: { - fields: ['id', 'landed', 'shipped', 'agencyModeFk', 'warehouseOutFk'], include: [ { relation: 'agency', @@ -143,8 +142,9 @@ watch; > <QTooltip>{{ t('Inventory entry') }}</QTooltip> </QIcon> + {{ console.log('currentEntry', currentEntry) }} <QIcon - v-if="currentEntry?.isRaid" + v-if="currentEntry?.travel?.daysInForward" name="vn:net" color="primary" size="xs" diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue index c2f1e6b57..62e13551a 100644 --- a/src/pages/Entry/Card/EntrySummary.vue +++ b/src/pages/Entry/Card/EntrySummary.vue @@ -259,11 +259,6 @@ const fetchEntryBuys = async () => { v-model="entry.isBooked" :disable="true" /> - <QCheckbox - :label="t('entry.summary.raid')" - v-model="entry.isRaid" - :disable="true" - /> <QCheckbox :label="t('entry.summary.excludedFromAvailable')" v-model="entry.isExcludedFromAvailable" diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 6f7ff1935..00b6c8626 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -168,8 +168,8 @@ const columns = computed(() => [ }, { align: 'left', - label: t('entry.list.tableVisibleColumns.isRaid'), - name: 'isRaid', + label: t('entry.list.tableVisibleColumns.daysInForward'), + name: 'daysInForward', chip: { color: null, condition: (value) => value, diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index a3620a6ba..aaf8abb91 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -72,6 +72,10 @@ const agenciesOptions = ref([]); </VnRow> <VnRow> <VnInput v-model="data.m3" label="m3" /> + <VnInput + :label="t('globals.daysInForward')" + v-model="data.daysInForward" + /> </VnRow> <VnRow> <QCheckbox diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index 4be198493..59059b0db 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -303,6 +303,10 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; <VnLv :label="t('globals.reference')" :value="travel.ref" /> <VnLv label="m³" :value="travel.m3" /> <VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" /> + <VnLv + :label="t('globals.daysInForward')" + :value="travel?.daysInForward" + /> </QCard> <QCard class="full-width"> <VnTitle :text="t('travel.summary.entries')" /> From 671d9fd6fb0f6686ade7b54bfe9e36b6d8a11a8c Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 24 Oct 2024 13:38:13 +0200 Subject: [PATCH 081/207] fix: refs #7283 itemtype fix --- src/pages/Item/ItemTypeList.vue | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index d9f7bba85..2c1153016 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -1,14 +1,14 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; import { ref, computed } from 'vue'; import ItemTypeSearchbar from '../ItemType/ItemTypeSearchbar.vue'; import VnTable from 'components/VnTable/VnTable.vue'; +import FetchData from 'components/FetchData.vue'; -const route = useRoute(); const { t } = useI18n(); const tableRef = ref(); -const entityId = computed(() => route.params.id); +const workerOptions = ref([]); +const ItemCategoriesOptions = ref([]); const columns = computed(() => [ { @@ -40,7 +40,7 @@ const columns = computed(() => [ create: true, component: 'select', attrs: { - url: 'Workers', + options: workerOptions.value, optionLabel: 'firstName', optionValue: 'id', }, @@ -54,8 +54,9 @@ const columns = computed(() => [ create: true, component: 'select', attrs: { - url: 'ItemCategories', + options: ItemCategoriesOptions.value, fields: ['id', 'name'], + order: 'name ASC', }, cardVisible: false, visible: false, @@ -77,6 +78,18 @@ const columns = computed(() => [ </script> <template> + <FetchData + url="Workers" + :filter="{ fields: ['id', 'firstName'], order: ['firstName ASC'] }" + @on-fetch="(data) => (workerOptions = data)" + auto-load + /> + <FetchData + url="ItemCategories" + :filter="{ fields: ['id', 'name'], order: ['name ASC'] }" + @on-fetch="(data) => (ItemCategoriesOptions = data)" + auto-load + /> <ItemTypeSearchbar /> <VnTable ref="tableRef" @@ -102,8 +115,8 @@ const columns = computed(() => [ id: Id code: Código name: Nombre - worker: Encargado - ItemCategory: Categoría + worker: Trabajador + ItemCategory: Reino Temperature: Temperatura Create ItemTypes: Crear familia en: From c2043902f8f77a6f4957b82d7f7576f540bf8f1e Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Thu, 24 Oct 2024 14:08:11 +0200 Subject: [PATCH 082/207] fix: refs #7283 fix required --- src/pages/Item/ItemRequestDenyForm.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/Item/ItemRequestDenyForm.vue b/src/pages/Item/ItemRequestDenyForm.vue index be70fb799..c9a4cbe9c 100644 --- a/src/pages/Item/ItemRequestDenyForm.vue +++ b/src/pages/Item/ItemRequestDenyForm.vue @@ -10,6 +10,7 @@ defineProps({ requestId: { type: Number, default: null, + required: true, }, }); @@ -43,6 +44,7 @@ onMounted(async () => { type="textarea" v-model="data.observation" fill-input + :required="true" autogrow /> </div> From 855979d22d3397182210a661717880e7bb04ab2d Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 24 Oct 2024 14:59:14 +0200 Subject: [PATCH 083/207] perf: refs #7283 #7283 i18n params --- src/pages/Item/ItemRequest.vue | 1 + src/pages/Item/locale/en.yml | 13 +++++++++++++ src/pages/Item/locale/es.yml | 15 +++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index ea265e706..450031a0e 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -225,6 +225,7 @@ onMounted(async () => { :is-editable="true" auto-load :disable-option="{ card: true }" + chip-locale="item.params" > <template #column-ticketFk="{ row }"> <span class="link"> diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index 53310cbd0..e99853760 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -89,6 +89,19 @@ itemType: category: Category temperature: Temperature item: + params: + daysOnward: Days onward + search: General search + ticketFk: Ticket id + attenderFk: Atender + clientFk: Client id + warehouseFk: Warehouse + requesterFk: Salesperson + from: From + to: To + mine: For me + state: State + myTeam: My team searchbar: label: Search item descriptor: diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index 1ade9b955..56c6ec317 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -88,7 +88,22 @@ itemType: worker: Trabajador category: Reino temperature: Temperatura +params: + state: asfsdf item: + params: + daysOnward: Días adelante + search: Búsqueda general + ticketFk: Id ticket + attenderFk: Comprador + clientFk: Id cliente + warehouseFk: Almacén + requesterFk: Comercial + from: Desde + to: Hasta + mine: Para mi + state: Estado + myTeam: Mi equipo searchbar: label: Buscar artículo descriptor: From 92e147355fea8b083948f544daf608fc8db8734c Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Thu, 24 Oct 2024 15:13:05 +0200 Subject: [PATCH 084/207] fix: better performance --- src/components/VnTable/VnTable.vue | 7 ++++--- src/pages/Account/AccountAcls.vue | 28 +++++++++++++++++++++++++--- src/pages/Account/AccountFilter.vue | 1 + 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 908157610..c1680bf13 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -151,8 +151,8 @@ const tableModes = [ }, ]; onBeforeMount(() => { - setUserParams(route.query[$props.searchUrl]); - hasParams.value = params.value && Object.keys(params.value).length !== 0; + const urlParams = route.query[$props.searchUrl]; + hasParams.value = urlParams && Object.keys(urlParams).length !== 0; }); onMounted(() => { @@ -185,7 +185,8 @@ watch( watch( () => route.query[$props.searchUrl], - (val) => setUserParams(val) + (val) => setUserParams(val), + { immediate: true, deep: true } ); const isTableMode = computed(() => mode.value == TABLE_MODE); diff --git a/src/pages/Account/AccountAcls.vue b/src/pages/Account/AccountAcls.vue index dd93a0cb5..63cdac9c7 100644 --- a/src/pages/Account/AccountAcls.vue +++ b/src/pages/Account/AccountAcls.vue @@ -9,6 +9,8 @@ import { useQuasar } from 'quasar'; import VnTable from 'components/VnTable/VnTable.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; +import FetchData from 'src/components/FetchData.vue'; +import { useValidator } from 'src/composables/useValidator'; defineProps({ id: { @@ -23,11 +25,18 @@ const stateStore = useStateStore(); const quasar = useQuasar(); const tableRef = ref(); - +const roles = ref(); +const validationsStore = useValidator(); +const { models } = validationsStore; const exprBuilder = (param, value) => { switch (param) { case 'search': - return { model: { like: `%${value}%` } }; + return { + or: [ + { model: { like: `%${value}%` } }, + { property: { like: `%${value}%` } }, + ], + }; default: return { [param]: value }; } @@ -47,6 +56,13 @@ const columns = computed(() => [ label: t('model'), cardVisible: true, create: true, + columnCreate: { + label: t('model'), + component: 'select', + attrs: { + options: Object.keys(models), + }, + }, }, { align: 'left', @@ -55,9 +71,10 @@ const columns = computed(() => [ cardVisible: true, component: 'select', attrs: { - url: 'VnRoles', + options: roles, optionLabel: 'name', optionValue: 'name', + inputDebounce: 0, }, create: true, }, @@ -130,6 +147,11 @@ const deleteAcl = async ({ id }) => { /> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> </QDrawer> + <FetchData + url="VnRoles?fields=['name']" + auto-load + @on-fetch="(data) => (roles = data)" + /> <VnTable ref="tableRef" data-key="AccountAcls" diff --git a/src/pages/Account/AccountFilter.vue b/src/pages/Account/AccountFilter.vue index 1775aa06b..3c8378d93 100644 --- a/src/pages/Account/AccountFilter.vue +++ b/src/pages/Account/AccountFilter.vue @@ -33,6 +33,7 @@ const rolesOptions = ref([]); :search-button="true" :hidden-tags="['search']" :redirect="false" + search-url="table" > <template #tags="{ tag, formatFn }"> <div class="q-gutter-x-xs"> From 12c236276d1d321ae657a2a005630df210917af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= <carlosap@verdnatura.es> Date: Thu, 24 Oct 2024 19:32:20 +0200 Subject: [PATCH 085/207] feat: refs #8087 Traspasar redadas a travels --- src/i18n/locale/en.yml | 3 +- src/i18n/locale/es.yml | 3 +- src/pages/Entry/Card/EntryDescriptor.vue | 19 +++++----- src/pages/Entry/EntryList.vue | 43 ++++++++++++---------- src/pages/Entry/locale/en.yml | 1 - src/pages/Entry/locale/es.yml | 1 - src/pages/Travel/Card/TravelBasicData.vue | 17 ++++++++- src/pages/Travel/Card/TravelDescriptor.vue | 17 +++++++++ src/pages/Travel/Card/TravelSummary.vue | 2 +- src/pages/Travel/TravelList.vue | 15 ++++++++ 10 files changed, 86 insertions(+), 35 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index d1ea5ceb9..928553293 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -106,7 +106,6 @@ globals: weight: Weight error: Ups! Something went wrong recalc: Recalculate - daysInForward: Forward days pageTitles: logIn: Login addressEdit: Update address @@ -313,6 +312,7 @@ globals: changePass: Change password deleteConfirmTitle: Delete selected elements changeState: Change state + raid: 'Raid {daysInForward} days' errors: statusUnauthorized: Access denied statusInternalServerError: An internal server error has ocurred @@ -1039,6 +1039,7 @@ travel: warehouseIn: Warehouse In delivered: Delivered received: Received + daysInForward: Days in forward thermographs: code: Code temperature: Temperature diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 18e580893..52bc821d1 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -108,7 +108,6 @@ globals: weight: Peso error: ¡Ups! Algo salió mal recalc: Recalcular - daysInForward: Días en el futuro pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario @@ -317,6 +316,7 @@ globals: changePass: Cambiar contraseña deleteConfirmTitle: Eliminar los elementos seleccionados changeState: Cambiar estado + raid: 'Redada {daysInForward} días' errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor @@ -1037,6 +1037,7 @@ travel: warehouseIn: Alm. entrada delivered: Enviada received: Recibida + daysInForward: Días redada thermographs: code: Código temperature: Temperatura diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index d85e5e1a0..bbfc73138 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -7,7 +7,6 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import useCardDescription from 'src/composables/useCardDescription'; -import { useState } from 'src/composables/useState'; import { toDate } from 'src/filters'; import { usePrintService } from 'composables/usePrintService'; import { getUrl } from 'src/composables/getUrl'; @@ -23,7 +22,6 @@ const $props = defineProps({ const route = useRoute(); const { t } = useI18n(); const { openReport } = usePrintService(); -const state = useState(); const entryDescriptorRef = ref(null); const url = ref(); @@ -74,8 +72,6 @@ const data = ref(useCardDescription()); const setData = (entity) => (data.value = useCardDescription(entity.supplier?.nickname, entity.id)); -const currentEntry = computed(() => state.get('entry')); - const getEntryRedirectionFilter = (entry) => { let entryTravel = entry && entry.travel; @@ -132,24 +128,29 @@ watch; :value="entity.travel?.warehouseOut?.name" /> </template> - <template #icons> + <template #icons="{ entity }"> <QCardActions class="q-gutter-x-md"> <QIcon - v-if="currentEntry?.isExcludedFromAvailable" + v-if="entity?.isExcludedFromAvailable" name="vn:inventory" color="primary" size="xs" > <QTooltip>{{ t('Inventory entry') }}</QTooltip> </QIcon> - {{ console.log('currentEntry', currentEntry) }} <QIcon - v-if="currentEntry?.travel?.daysInForward" + v-if="entity?.travel?.daysInForward" name="vn:net" color="primary" size="xs" > - <QTooltip>{{ t('Virtual entry') }}</QTooltip> + <QTooltip> + {{ + t('globals.raid', { + daysInForward: entity?.travel?.daysInForward, + }) + }}</QTooltip + > </QIcon> </QCardActions> </template> diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 00b6c8626..518d72d82 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -41,6 +41,10 @@ const entryFilter = { }; const columns = computed(() => [ + { + name: 'status', + hidden: true, + }, { align: 'left', label: t('entry.list.tableVisibleColumns.id'), @@ -154,27 +158,8 @@ const columns = computed(() => [ cardVisible: true, }, { - align: 'left', label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'), name: 'isExcludedFromAvailable', - chip: { - color: null, - condition: (value) => value, - icon: 'vn:inventory', - }, - columnFilter: { - inWhere: true, - }, - }, - { - align: 'left', - label: t('entry.list.tableVisibleColumns.daysInForward'), - name: 'daysInForward', - chip: { - color: null, - condition: (value) => value, - icon: 'vn:net', - }, columnFilter: { inWhere: true, }, @@ -225,6 +210,26 @@ onMounted(async () => { auto-load :right-search="false" > + <template #column-status="{ row }"> + <div class="row q-gutter-xs"> + <QIcon + v-if="!!row.isExcludedFromAvailable" + name="vn:inventory" + color="primary" + > + <QTooltip>{{ + t('entry.list.tableVisibleColumns.isExcludedFromAvailable') + }}</QTooltip> + </QIcon> + <QIcon v-if="!!row.daysInForward" name="vn:net" color="primary"> + <QTooltip> + {{ + t('globals.raid', { daysInForward: row.daysInForward }) + }}</QTooltip + > + </QIcon> + </div> + </template> <template #column-supplierFk="{ row }"> <span class="link" @click.stop> {{ row.supplierName }} diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml index f9dbd0589..cd5113d84 100644 --- a/src/pages/Entry/locale/en.yml +++ b/src/pages/Entry/locale/en.yml @@ -1,7 +1,6 @@ entryList: list: inventoryEntry: Inventory entry - virtualEntry: Virtual entry entryFilter: filter: search: General search diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml index feeea1fc9..3007c5d44 100644 --- a/src/pages/Entry/locale/es.yml +++ b/src/pages/Entry/locale/es.yml @@ -4,7 +4,6 @@ You can search by entry reference: Puedes buscar por referencia de la entrada entryList: list: inventoryEntry: Es inventario - virtualEntry: Es una redada entryFilter: filter: search: Búsqueda general diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index aaf8abb91..d6245e655 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -73,9 +73,15 @@ const agenciesOptions = ref([]); <VnRow> <VnInput v-model="data.m3" label="m3" /> <VnInput - :label="t('globals.daysInForward')" + :label="t('travel.basicData.daysInForward')" v-model="data.daysInForward" - /> + > + <template #append> + <QIcon name="info" class="cursor-info"> + <QTooltip>{{ t('raidDays') }}</QTooltip> + </QIcon> + </template> + </VnInput> </VnRow> <VnRow> <QCheckbox @@ -90,3 +96,10 @@ const agenciesOptions = ref([]); </template> </FormModel> </template> + +<i18n> +es: + raidDays: Al rellenarlo, generamos una redada. Indica los días que un travel se moverá automáticamente en el tiempo +en: + raidDays: When filling, a raid is generated. Enter the number of days the travel will automatically forward in time +</i18n> diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue index bda29903b..6025ad045 100644 --- a/src/pages/Travel/Card/TravelDescriptor.vue +++ b/src/pages/Travel/Card/TravelDescriptor.vue @@ -32,6 +32,7 @@ const filter = { 'warehouseOutFk', 'cargoSupplierFk', 'agencyModeFk', + 'daysInForward', ], include: [ { @@ -77,6 +78,22 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. <VnLv :label="t('globals.landed')" :value="toDate(entity.landed)" /> <VnLv :label="t('globals.totalEntries')" :value="entity.totalEntries" /> </template> + <template #icons="{ entity }"> + <QCardActions class="q-gutter-x-md"> + <QIcon + v-if="entity.daysInForward" + name="vn:net" + color="primary" + size="xs" + > + <QTooltip> + {{ + t('globals.raid', { daysInForward: entity.daysInForward }) + }}</QTooltip + > + </QIcon> + </QCardActions> + </template> <template #actions="{ entity }"> <QCardActions> <QBtn diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index 59059b0db..7dc267671 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -304,7 +304,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; <VnLv label="m³" :value="travel.m3" /> <VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" /> <VnLv - :label="t('globals.daysInForward')" + :label="t('travel.basicData.daysInForward')" :value="travel?.daysInForward" /> </QCard> diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index a8c0e69cb..199746bb7 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -45,6 +45,10 @@ const redirectCreateEntryView = (travelData) => { }; const columns = computed(() => [ + { + name: 'status', + hidden: true, + }, { align: 'left', name: 'id', @@ -221,6 +225,17 @@ const columns = computed(() => [ :is-editable="false" :use-model="true" > + <template #column-status="{ row }"> + <div class="row"> + <QIcon v-if="!!row.daysInForward" name="vn:net" color="primary"> + <QTooltip> + {{ + t('globals.raid', { daysInForward: row.daysInForward }) + }}</QTooltip + > + </QIcon> + </div> + </template> <template #column-shipped="{ row }"> <QBadge text-color="black" From e8d2a40dafbc8ccec24957715bf6cfea82e4bc25 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Fri, 25 Oct 2024 08:11:31 +0200 Subject: [PATCH 086/207] fix: entryFilters --- src/pages/Entry/EntryLatestBuys.vue | 65 ++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue index 61c430b23..119808176 100644 --- a/src/pages/Entry/EntryLatestBuys.vue +++ b/src/pages/Entry/EntryLatestBuys.vue @@ -23,7 +23,6 @@ const columns = [ return { id: row.id, size: '50x50', - width: '50px', }; }, }, @@ -34,21 +33,37 @@ const columns = [ label: t('entry.latestBuys.tableVisibleColumns.itemFk'), name: 'itemFk', isTitle: true, + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.packing'), name: 'packing', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.grouping'), name: 'grouping', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.quantity'), name: 'quantity', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', @@ -59,6 +74,10 @@ const columns = [ align: 'left', label: t('entry.latestBuys.tableVisibleColumns.size'), name: 'size', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', @@ -84,6 +103,10 @@ const columns = [ align: 'left', label: t('entry.latestBuys.tableVisibleColumns.weightByPiece'), name: 'weightByPiece', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', @@ -99,26 +122,46 @@ const columns = [ align: 'left', label: t('entry.latestBuys.tableVisibleColumns.entryFk'), name: 'entryFk', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.buyingValue'), name: 'buyingValue', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.freightValue'), name: 'freightValue', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.comissionValue'), name: 'comissionValue', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.packageValue'), name: 'packageValue', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', @@ -129,16 +172,28 @@ const columns = [ align: 'left', label: t('entry.latestBuys.tableVisibleColumns.price2'), name: 'price2', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.price3'), name: 'price3', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.minPrice'), name: 'minPrice', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', @@ -149,11 +204,19 @@ const columns = [ align: 'left', label: t('entry.latestBuys.tableVisibleColumns.weight'), name: 'weight', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', label: t('entry.latestBuys.tableVisibleColumns.packagingFk'), name: 'packagingFk', + columnFilter: { + component: 'number', + inWhere: true, + }, }, { align: 'left', From 4c1e4aedd2099bd08526c2a51d7d9308627a01dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= <carlosap@verdnatura.es> Date: Fri, 25 Oct 2024 10:03:09 +0200 Subject: [PATCH 087/207] feat: refs #8087 Traspasar redadas a travels --- src/pages/Entry/Card/EntryBasicData.vue | 6 ++++++ src/pages/Entry/Card/EntryDescriptor.vue | 8 ++++++++ src/pages/Entry/EntryList.vue | 2 +- src/pages/Travel/TravelList.vue | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index d60ed8645..b81b1db22 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -168,6 +168,12 @@ const onFilterTravelSelected = (formData, id) => { v-model="data.isExcludedFromAvailable" :label="t('entry.basicData.excludedFromAvailable')" /> + <QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" /> + <QCheckbox + v-if="isAdministrative()" + v-model="data.isBooked" + :label="t('entry.basicData.booked')" + /> </VnRow> </template> </FormModel> diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index bbfc73138..d66185aa9 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -30,6 +30,14 @@ const entryFilter = { { relation: 'travel', scope: { + fields: [ + 'id', + 'landed', + 'shipped', + 'agencyModeFk', + 'warehouseOutFk', + 'daysInForward', + ], include: [ { relation: 'agency', diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 518d72d82..e9179c239 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -43,7 +43,7 @@ const entryFilter = { const columns = computed(() => [ { name: 'status', - hidden: true, + columnFilter: false, }, { align: 'left', diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index 199746bb7..334640bff 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -47,7 +47,7 @@ const redirectCreateEntryView = (travelData) => { const columns = computed(() => [ { name: 'status', - hidden: true, + columnFilter: false, }, { align: 'left', From 9e57c5e4527b8ffade7be3d0a02889d0c2550346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= <carlosap@verdnatura.es> Date: Fri, 25 Oct 2024 10:13:09 +0200 Subject: [PATCH 088/207] feat: refs #8087 Traspasar redadas a travels --- src/pages/Entry/Card/EntryBasicData.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index b81b1db22..3288616fb 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -168,7 +168,6 @@ const onFilterTravelSelected = (formData, id) => { v-model="data.isExcludedFromAvailable" :label="t('entry.basicData.excludedFromAvailable')" /> - <QCheckbox v-model="data.isRaid" :label="t('entry.basicData.raid')" /> <QCheckbox v-if="isAdministrative()" v-model="data.isBooked" From ff559384aad8a7d59a9ebfcb7263ffd93cc40c60 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Fri, 25 Oct 2024 10:33:59 +0200 Subject: [PATCH 089/207] perf: refs #6943 #6943 merge command --- .../route/agency/agencyWorkCenter.spec.js | 6 +++--- .../worker/workerNotificationsManager.spec.js | 4 +++- test/cypress/support/commands.js | 20 ++++++++----------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js index 6a3cab664..311c0130c 100644 --- a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js +++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js @@ -11,16 +11,16 @@ describe('AgencyWorkCenter', () => { // create cy.get(createButton).click(); cy.get(workCenterCombobox).type('workCenterOne{enter}'); - cy.hasNotify('Data created'); + cy.checkNotification('created'); // expect error when duplicate cy.get(createButton).click(); cy.get('[data-cy="FormModelPopup_save"]').click(); - cy.hasNotify('This workCenter is already assigned to this agency'); + cy.checkNotification('This workCenter is already assigned to this agency'); cy.get('[data-cy="FormModelPopup_cancel"]').click(); // delete cy.get('.q-item__section--side > .q-btn > .q-btn__content > .q-icon').click(); - cy.hasNotify('WorkCenter removed successfully'); + cy.checkNotification('WorkCenter removed successfully'); }); }); diff --git a/test/cypress/integration/worker/workerNotificationsManager.spec.js b/test/cypress/integration/worker/workerNotificationsManager.spec.js index 367287a5a..f121b3894 100644 --- a/test/cypress/integration/worker/workerNotificationsManager.spec.js +++ b/test/cypress/integration/worker/workerNotificationsManager.spec.js @@ -17,7 +17,9 @@ describe('WorkerNotificationsManager', () => { cy.login('developer'); cy.visit(`/#/worker/${salesPersonId}/notifications`); cy.get(firstAvailableNotification).click(); - cy.hasNotify('The notification subscription of this worker cant be modified'); + cy.checkNotification( + 'The notification subscription of this worker cant be modified' + ); }); it('should active a notification that is yours', () => { diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index dcfb54a3e..7d5a44f78 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -274,21 +274,13 @@ Cypress.Commands.add('openActions', (row) => { cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); }); -Cypress.Commands.add('checkNotification', (type) => { - const values = { +Cypress.Commands.add('checkNotification', (tag) => { + const defaultTags = { created: 'Data created', updated: 'Data saved', deleted: 'Data deleted', - }; - cy.get('.q-notification__message').should('have.text', values[type]); -}); - -Cypress.Commands.add('searchByLabel', (label, value) => { - cy.get(`[label="${label}"] > .q-field > .q-field__inner`).type(`${value}{enter}`); -}); - -Cypress.Commands.add('hasNotify', (text) => { - //last + }; //last + const text = defaultTags[tag] ?? tag; cy.get('.q-notification') .should('be.visible') .last() @@ -297,3 +289,7 @@ Cypress.Commands.add('hasNotify', (text) => { throw new Error(`Notification not found: "${text}"`); }); }); + +Cypress.Commands.add('searchByLabel', (label, value) => { + cy.get(`[label="${label}"] > .q-field > .q-field__inner`).type(`${value}{enter}`); +}); From 02f682ac0b5d153c43339812b41fab0605c861c3 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Fri, 25 Oct 2024 10:53:19 +0200 Subject: [PATCH 090/207] perf: refs #6943 #6943 merge command --- test/cypress/integration/client/clientList.spec.js | 2 +- .../integration/route/agency/agencyWorkCenter.spec.js | 2 +- test/cypress/support/commands.js | 8 +------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index f150fc190..22bca15ac 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -28,7 +28,7 @@ describe('Client list', () => { cy.get('.q-mt-lg > .q-btn--standard').click(); - cy.checkNotification('created'); + cy.checkNotification('Data created'); cy.url().should('include', '/summary'); }); it('Client list search client', () => { diff --git a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js index 311c0130c..fdfcd4286 100644 --- a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js +++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js @@ -11,7 +11,7 @@ describe('AgencyWorkCenter', () => { // create cy.get(createButton).click(); cy.get(workCenterCombobox).type('workCenterOne{enter}'); - cy.checkNotification('created'); + cy.checkNotification('Data created'); // expect error when duplicate cy.get(createButton).click(); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 7d5a44f78..c9b1a748e 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -274,13 +274,7 @@ Cypress.Commands.add('openActions', (row) => { cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); }); -Cypress.Commands.add('checkNotification', (tag) => { - const defaultTags = { - created: 'Data created', - updated: 'Data saved', - deleted: 'Data deleted', - }; //last - const text = defaultTags[tag] ?? tag; +Cypress.Commands.add('checkNotification', (text) => { cy.get('.q-notification') .should('be.visible') .last() From bb51a9e6870af70d95a0b70c6e63e49c1633b749 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Fri, 25 Oct 2024 11:38:00 +0200 Subject: [PATCH 091/207] fix: refs #7943 use summary --- src/pages/Worker/Card/WorkerCard.vue | 2 +- src/pages/Worker/Card/WorkerSummary.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue index 5f9fa0f8e..428731a5c 100644 --- a/src/pages/Worker/Card/WorkerCard.vue +++ b/src/pages/Worker/Card/WorkerCard.vue @@ -6,7 +6,7 @@ import WorkerFilter from '../WorkerFilter.vue'; <template> <VnCard data-key="Worker" - base-url="Workers" + custom-url="Workers/summary" :descriptor="WorkerDescriptor" :filter-panel="WorkerFilter" search-data-key="WorkerList" diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index ed34e771d..4a78afb52 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -45,7 +45,7 @@ onBeforeMount(async () => { ref="summary" :url="`Workers/summary`" :filter="{ where: { id: entityId } }" - data-key="WorkerSummary" + data-key="Worker" > <template #header="{ entity }"> <div>{{ entity.id }} - {{ entity.firstName }} {{ entity.lastName }}</div> From cdb73f7a17588b70d628af92d349ece882aa336b Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Fri, 25 Oct 2024 11:50:20 +0200 Subject: [PATCH 092/207] fix: refs #7943 use correct data-key --- src/pages/Worker/WorkerList.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 7a3f760bc..022cecdc6 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -169,7 +169,7 @@ async function autofillBic(worker) { </script> <template> <VnSearchbar - data-key="Worker" + data-key="WorkerList" :label="t('Search worker')" :info="t('You can search by worker id or name')" /> @@ -191,13 +191,13 @@ async function autofillBic(worker) { /> <RightMenu> <template #right-panel> - <WorkerFilter data-key="Worker" /> + <WorkerFilter data-key="WorkerList" /> </template> </RightMenu> <VnTable v-if="defaultPayMethod" ref="tableRef" - data-key="Worker" + data-key="WorkerList" url="Workers/filter" :create="{ urlCreate: 'Workers/new', From 8edba36a7401bad871b994d2e6f2a870c8ed92d0 Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Fri, 25 Oct 2024 13:46:36 +0200 Subject: [PATCH 093/207] feat: refs #7006 itemType basic data new inputs --- src/pages/ItemType/Card/ItemTypeBasicData.vue | 36 ++++++++++++++++++- src/pages/ItemType/locale/en.yml | 3 ++ src/pages/ItemType/locale/es.yml | 3 ++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/ItemType/Card/ItemTypeBasicData.vue index f4013e126..e447f565b 100644 --- a/src/pages/ItemType/Card/ItemTypeBasicData.vue +++ b/src/pages/ItemType/Card/ItemTypeBasicData.vue @@ -8,12 +8,14 @@ import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; +import VnAvatar from 'src/components/ui/VnAvatar.vue'; const route = useRoute(); const { t } = useI18n(); const categoriesOptions = ref([]); const temperaturesOptions = ref([]); +const itemPackingTypesOptions = ref([]); </script> <template> <FetchData @@ -28,6 +30,16 @@ const temperaturesOptions = ref([]); :filter="{ order: 'name ASC', fields: ['code', 'name'] }" auto-load /> + <FetchData + url="ItemPackingTypes" + @on-fetch="(data) => (itemPackingTypesOptions = data)" + :filter="{ + where: { isActive: true }, + order: 'description ASC', + fields: ['code', 'description'], + }" + auto-load + /> <FormModel :url="`ItemTypes/${route.params.id}`" :url-update="`ItemTypes/${route.params.id}`" @@ -50,7 +62,15 @@ const temperaturesOptions = ref([]); option-label="nickname" option-value="id" hide-selected - ><template #option="scope"> + > + <template #prepend> + <VnAvatar + :worker-id="data.workerFk" + color="primary" + :title="title" + /> + </template> + <template #option="scope"> <QItem v-bind="scope.itemProps"> <QItemSection> <QItemLabel>{{ scope.opt?.name }}</QItemLabel> @@ -82,6 +102,20 @@ const temperaturesOptions = ref([]); /> <VnInput v-model="data.life" :label="t('shared.life')" /> </VnRow> + <VnRow> + <VnSelect + v-model="data.itemPackingTypeFk" + :label="t('shared.itemPackingType')" + :options="itemPackingTypesOptions" + option-value="code" + option-label="description" + hide-selected + /> + <VnInput v-model="data.maxRefs" :label="t('shared.maxRefs')" /> + </VnRow> + <VnRow> + <QCheckbox v-model="data.isFragile" :label="t('shared.fragile')" /> + </VnRow> </template> </FormModel> </template> diff --git a/src/pages/ItemType/locale/en.yml b/src/pages/ItemType/locale/en.yml index 4b203bd68..575d5e402 100644 --- a/src/pages/ItemType/locale/en.yml +++ b/src/pages/ItemType/locale/en.yml @@ -5,6 +5,9 @@ shared: category: Category temperature: Temperature life: Life + itemPackingType: Item packing type + maxRefs: Maximum references + fragile: Fragile summary: id: id life: Life diff --git a/src/pages/ItemType/locale/es.yml b/src/pages/ItemType/locale/es.yml index 43699c332..09ee5a1f7 100644 --- a/src/pages/ItemType/locale/es.yml +++ b/src/pages/ItemType/locale/es.yml @@ -5,6 +5,9 @@ shared: category: Reino temperature: Temperatura life: Vida + itemPackingType: Tipo de embalaje + maxRefs: Referencias máximas + fragile: Frágil summary: id: id code: Código From 211da859bd20cdab9a041bc821ea60b7fb073ae2 Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Fri, 25 Oct 2024 08:57:16 -0300 Subject: [PATCH 094/207] fix: catalog view category and type filter --- src/components/ui/VnFilterPanel.vue | 33 +++++++++++++++++-- src/filters/getParamWhere.js | 12 +++++-- src/pages/Order/Card/OrderCatalog.vue | 35 +++++++++++++++++---- src/pages/Order/Card/OrderCatalogFilter.vue | 26 +++++++++++---- 4 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 43d634ad9..5bdaf150c 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -57,7 +57,6 @@ const $props = defineProps({ }, }); -defineExpose({ search, sanitizer }); const emit = defineEmits([ 'update:modelValue', 'refresh', @@ -170,9 +169,30 @@ const tagsList = computed(() => { return tagList; }); +const formatTags = (tags) => { + const formattedTags = []; + tags.forEach((tag) => { + if (tag.label === 'and') { + tag.value.forEach((item) => { + for (const key in item) { + formattedTags.push({ label: key, value: item[key] }); + } + }); + } else { + formattedTags.push(tag); + } + }); + return formattedTags; +}; + const tags = computed(() => { - return tagsList.value.filter((tag) => !($props.customTags || []).includes(tag.label)); + const filteredTags = tagsList.value.filter( + (tag) => !($props.customTags || []).includes(tag.label) + ); + console.log('formatTags: ', formatTags(filteredTags)); + return formatTags(filteredTags); }); + const customTags = computed(() => tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.label)) ); @@ -193,13 +213,20 @@ function formatValue(value) { function sanitizer(params) { for (const [key, value] of Object.entries(params)) { - if (value && typeof value === 'object') { + if (key === 'and' && Array.isArray(value)) { + value.forEach((item) => { + Object.assign(params, item); + }); + delete params[key]; + } else if (value && typeof value === 'object') { const param = Object.values(value)[0]; if (typeof param == 'string') params[key] = param.replaceAll('%', ''); } } return params; } + +defineExpose({ search, sanitizer, userParams }); </script> <template> diff --git a/src/filters/getParamWhere.js b/src/filters/getParamWhere.js index 48cd9c479..22dd69af1 100644 --- a/src/filters/getParamWhere.js +++ b/src/filters/getParamWhere.js @@ -10,11 +10,19 @@ function parseJSON(str, fallback) { export default function (route, param) { // catch route query params const params = parseJSON(route?.query?.params, {}); - // extract and parse filter from params const { filter: filterStr = '{}' } = params; + const where = parseJSON(filterStr, {})?.where; - if (where && where[param] !== undefined) { + + if (where && !param) { + return where; + } else if (where && where.and) { + const foundParam = where.and.find((p) => p[param]); + if (foundParam) { + return foundParam[param]; + } + } else if (where && where[param]) { return where[param]; } return null; diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue index f9bcca94c..9fee29d7d 100644 --- a/src/pages/Order/Card/OrderCatalog.vue +++ b/src/pages/Order/Card/OrderCatalog.vue @@ -1,13 +1,14 @@ <script setup> import { useStateStore } from 'stores/useStateStore'; import { useRoute, useRouter } from 'vue-router'; -import { onMounted, onUnmounted, ref } from 'vue'; +import { onBeforeMount, onMounted, onUnmounted, ref, computed } from 'vue'; import axios from 'axios'; import { useI18n } from 'vue-i18n'; import VnPaginate from 'components/ui/VnPaginate.vue'; import CatalogItem from 'components/ui/CatalogItem.vue'; import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; +import getParamWhere from 'src/filters/getParamWhere'; const route = useRoute(); const router = useRouter(); @@ -15,17 +16,36 @@ const stateStore = useStateStore(); const { t } = useI18n(); const tags = ref([]); +let catalogParams = { + orderFk: route.params.id, + orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }), +}; + +onBeforeMount(() => { + const whereParams = getParamWhere(route); + if (whereParams) { + const formattedWhereParams = {}; + if (whereParams.and) { + whereParams.and.forEach((item) => { + Object.assign(formattedWhereParams, item); + }); + } else { + Object.assign(formattedWhereParams, whereParams); + } + + catalogParams = { + ...catalogParams, + ...formattedWhereParams, + }; + } +}); + onMounted(() => { stateStore.rightDrawer = true; checkOrderConfirmation(); }); onUnmounted(() => (stateStore.rightDrawer = false)); -const catalogParams = { - orderFk: route.params.id, - orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }), -}; - async function checkOrderConfirmation() { const response = await axios.get(`Orders/${route.params.id}`); if (response.data.isConfirmed === 1) { @@ -61,6 +81,7 @@ function extractValueTags(items) { ); tagValue.value = resultValueTags; } +const autoLoad = computed(() => !!catalogParams.categoryFk); </script> <template> @@ -79,6 +100,7 @@ function extractValueTags(items) { data-key="OrderCatalogList" :tag-value="tagValue" :tags="tags" + :initial-catalog-params="catalogParams" /> </QScrollArea> </QDrawer> @@ -91,6 +113,7 @@ function extractValueTags(items) { :user-params="catalogParams" @on-fetch="extractTags" :update-router="false" + :auto-load="autoLoad" > <template #body="{ rows }"> <div class="catalog-list"> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 6de43e86a..cc3f45391 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -1,5 +1,5 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed, ref, onMounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; @@ -26,9 +26,13 @@ const props = defineProps({ type: Array, required: true, }, + initialCatalogParams: { + type: Object, + default: () => ({}), + }, }); const categoryList = ref(null); -const selectedCategoryFk = ref(getParamWhere(route, 'categoryFk')); +const selectedCategoryFk = ref(null); const typeList = ref([]); const selectedTypeFk = ref(null); const selectedTag = ref(null); @@ -74,6 +78,8 @@ const selectCategory = (params, category, search) => { } else { selectedCategoryFk.value = category?.id; params.categoryFk = category?.id; + params.typeFk = null; + selectedTypeFk.value = null; loadTypes(category?.id); } search(); @@ -86,11 +92,11 @@ const loadTypes = async (categoryFk = selectedCategoryFk.value) => { typeList.value = data; }; -const selectedCategory = computed(() => - (categoryList.value || []).find( +const selectedCategory = computed(() => { + return (categoryList.value || []).find( (category) => category?.id === selectedCategoryFk.value - ) -); + ); +}); function filterFn(val, update) { update(() => { const needle = val.toLowerCase(); @@ -171,6 +177,11 @@ function addOrder(value, field, params) { params.orderBy = JSON.stringify(orderBy); vnFilterPanelRef.value.search(); } + +onMounted(() => { + selectedCategoryFk.value = getParamWhere(route, 'categoryFk'); + selectedTypeFk.value = getParamWhere(route, 'typeFk'); +}); </script> <template> @@ -206,6 +217,8 @@ function addOrder(value, field, params) { removable @remove="removeTagChip(chip, params, searchFn)" > + <pre>{{ chip }}</pre> + <strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong> <span>{{ (JSON.parse(chip).values || []) @@ -384,6 +397,7 @@ function addOrder(value, field, params) { /> </QItem> <QSeparator /> + <pre>{{ params }}</pre> </template> </VnFilterPanel> </template> From 494fc66c06377838c2d23d6f6cf945c91c753f67 Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Fri, 25 Oct 2024 14:14:51 +0200 Subject: [PATCH 095/207] feat: refs #7006 itemType basic data new inputs --- src/pages/Item/ItemTypeList.vue | 15 ++++----------- src/pages/ItemType/Card/ItemTypeBasicData.vue | 1 - 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 2c1153016..13dd56a42 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -7,7 +7,6 @@ import FetchData from 'components/FetchData.vue'; const { t } = useI18n(); const tableRef = ref(); -const workerOptions = ref([]); const ItemCategoriesOptions = ref([]); const columns = computed(() => [ @@ -40,12 +39,12 @@ const columns = computed(() => [ create: true, component: 'select', attrs: { - options: workerOptions.value, - optionLabel: 'firstName', + url: 'Workers/search', + optionLabel: 'nickname', optionValue: 'id', }, - cardVisible: false, - visible: false, + cardVisible: true, + visible: true, }, { align: 'left', @@ -78,12 +77,6 @@ const columns = computed(() => [ </script> <template> - <FetchData - url="Workers" - :filter="{ fields: ['id', 'firstName'], order: ['firstName ASC'] }" - @on-fetch="(data) => (workerOptions = data)" - auto-load - /> <FetchData url="ItemCategories" :filter="{ fields: ['id', 'name'], order: ['name ASC'] }" diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/ItemType/Card/ItemTypeBasicData.vue index e447f565b..1a4a7c9f3 100644 --- a/src/pages/ItemType/Card/ItemTypeBasicData.vue +++ b/src/pages/ItemType/Card/ItemTypeBasicData.vue @@ -58,7 +58,6 @@ const itemPackingTypesOptions = ref([]); :label="t('shared.worker')" sort-by="nickname ASC" :fields="['id', 'nickname']" - :params="{ departmentCodes: ['shopping'] }" option-label="nickname" option-value="id" hide-selected From 1da86900e653a072bbe898f2d75997a5851c59be Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Sun, 27 Oct 2024 13:43:38 +0100 Subject: [PATCH 096/207] fix: refs #7524 e2e & worker module --- src/components/ui/VnRow.vue | 3 -- src/composables/useAdvancedSummary.js | 11 ++++++ src/pages/Ticket/Card/TicketExpedition.vue | 1 + src/pages/Ticket/TicketAdvance.vue | 1 - src/pages/Worker/Card/WorkerBasicData.vue | 36 +++++++++---------- src/pages/Worker/Card/WorkerLocker.vue | 3 +- src/pages/Worker/Card/WorkerSummary.vue | 32 ++++++++--------- src/router/modules/worker.js | 7 ++++ .../ticket/ticketExpedition.spec.js | 12 +++---- .../integration/worker/workerList.spec.js | 2 +- .../integration/worker/workerLocker.spec.js | 11 +++--- test/cypress/support/commands.js | 2 +- 12 files changed, 63 insertions(+), 58 deletions(-) create mode 100644 src/composables/useAdvancedSummary.js diff --git a/src/components/ui/VnRow.vue b/src/components/ui/VnRow.vue index 16bcfab7d..40dabf610 100644 --- a/src/components/ui/VnRow.vue +++ b/src/components/ui/VnRow.vue @@ -1,6 +1,3 @@ -<script setup> -defineProps({ wrap: { type: Boolean, default: false } }); -</script> <template> <div class="vn-row q-gutter-md q-mb-md"> <slot /> diff --git a/src/composables/useAdvancedSummary.js b/src/composables/useAdvancedSummary.js new file mode 100644 index 000000000..98b998d2a --- /dev/null +++ b/src/composables/useAdvancedSummary.js @@ -0,0 +1,11 @@ +import axios from 'axios'; +import { useRole } from './useRole'; + +export async function useAdvancedSummary(model, id, roles = ['hr']) { + if (useRole().hasAny(roles)) { + const { data } = await axios.get(`${model}/advancedSummary`, { + params: { filter: { where: { id } } }, + }); + return Array.isArray(data) ? data[0] : data; + } +} diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue index 8041ad069..d682d0408 100644 --- a/src/pages/Ticket/Card/TicketExpedition.vue +++ b/src/pages/Ticket/Card/TicketExpedition.vue @@ -211,6 +211,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); <template #st-actions> <QBtnGroup push class="q-gutter-x-sm" flat> <VnBtnSelect + data-cy="change-state" :disable="!hasSelectedRows" color="primary" :label="t('globals.changeState')" diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue index 7db2b54b3..bdd980c07 100644 --- a/src/pages/Ticket/TicketAdvance.vue +++ b/src/pages/Ticket/TicketAdvance.vue @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n'; import FetchData from 'components/FetchData.vue'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import VnProgress from 'src/components/common/VnProgressModal.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; import TicketAdvanceFilter from './TicketAdvanceFilter.vue'; diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue index d131fea3e..6a13e3f39 100644 --- a/src/pages/Worker/Card/WorkerBasicData.vue +++ b/src/pages/Worker/Card/WorkerBasicData.vue @@ -1,5 +1,5 @@ <script setup> -import { ref } from 'vue'; +import { ref, onBeforeMount } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import VnInputDate from 'src/components/common/VnInputDate.vue'; @@ -8,32 +8,22 @@ import FormModel from 'src/components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; +import { useAdvancedSummary } from 'src/composables/useAdvancedSummary'; -const route = useRoute(); const { t } = useI18n(); - const educationLevels = ref([]); const countries = ref([]); const maritalStatus = [ { code: 'M', name: t('Married') }, { code: 'S', name: t('Single') }, ]; +const advancedSummary = ref({}); -const workerFilter = { - include: [ - { - relation: 'user', - scope: { - fields: ['name', 'emailVerified'], - include: { relation: 'emailUser', scope: { fields: ['email'] } }, - }, - }, - { relation: 'sip', scope: { fields: ['extension', 'secret'] } }, - { relation: 'department', scope: { include: { relation: 'department' } } }, - ], -}; +onBeforeMount(async () => { + advancedSummary.value = + (await useAdvancedSummary('Workers', +useRoute().params.id)) ?? {}; +}); </script> - <template> <FetchData :filter="{ fields: ['id', 'name'], order: 'name ASC' }" @@ -48,10 +38,16 @@ const workerFilter = { auto-load /> <FormModel - :filter="workerFilter" - :url="`Workers/${route.params.id}`" + :filter="{ where: { id: +$route.params.id } }" + url="Workers/summary" + :url-update="`Workers/${$route.params.id}`" auto-load model="Worker" + @on-fetch=" + async (data) => { + Object.assign(data, advancedSummary); + } + " > <template #form="{ data }"> <VnRow> @@ -134,7 +130,7 @@ const workerFilter = { <VnInput v-model="data.fi" :label="t('fi')" /> <VnInputDate :label="t('birth')" v-model="data.birth" /> </VnRow> - <VnRow> + <VnRow wrap> <QCheckbox size="sm" :label="t('isFreelance')" diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue index 4a19e472c..015bced35 100644 --- a/src/pages/Worker/Card/WorkerLocker.vue +++ b/src/pages/Worker/Card/WorkerLocker.vue @@ -18,7 +18,7 @@ const { store } = useArrayData('Worker'); const entityId = computed(() => useRoute().params.id); const filter = computed(() => ({ where: { - gender: store.data?.sex, + gender: store.data?.[0]?.sex, or: [{ workerFk: null }, { workerFk: entityId.value }], }, })); @@ -51,6 +51,7 @@ const init = async (data) => { > <template #form="{ data }"> <VnSelect + data-cy="locker" :label="t('Locker')" v-model="data.id" :options="lockers" diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index 4a78afb52..0a0694fdf 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -2,7 +2,6 @@ import { ref, onBeforeMount, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import axios from 'axios'; import { dashIfEmpty, toDate } from 'src/filters'; import VnLv from 'src/components/ui/VnLv.vue'; import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; @@ -11,7 +10,7 @@ import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue'; import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue'; -import { useRole } from 'src/composables/useRole'; +import { useAdvancedSummary } from 'src/composables/useAdvancedSummary'; const route = useRoute(); const { t } = useI18n(); @@ -25,18 +24,11 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const basicDataUrl = ref(null); -const isHr = computed(() => useRole().hasAny(['hr'])); const advancedSummary = ref(); onBeforeMount(async () => { - if (isHr.value) { - advancedSummary.value = ( - await axios.get('Workers/advancedSummary', { - params: { filter: { where: { id: entityId.value } } }, - }) - ).data[0]; - basicDataUrl.value = `#/worker/${entityId.value}/basic-data`; - } + advancedSummary.value = await useAdvancedSummary('Workers', entityId.value); + basicDataUrl.value = `#/worker/${entityId.value}/basic-data`; }); </script> @@ -101,21 +93,27 @@ onBeforeMount(async () => { :label="t('worker.summary.seniority')" :value="toDate(worker.seniority)" /> - <VnLv :label="t('worker.summary.fi')" :value="worker.fi" /> - <VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" /> + <VnLv :label="t('worker.summary.fi')" :value="advancedSummary.fi" /> + <VnLv + :label="t('worker.summary.birth')" + :value="toDate(advancedSummary.birth)" + /> <VnLv :label="t('worker.summary.isFreelance')" - :value="worker.isFreelance" + :value="advancedSummary.isFreelance" /> <VnLv :label="t('worker.summary.isSsDiscounted')" - :value="worker.isSsDiscounted" + :value="advancedSummary.isSsDiscounted" /> <VnLv :label="t('worker.summary.hasMachineryAuthorized')" - :value="worker.hasMachineryAuthorized" + :value="advancedSummary.hasMachineryAuthorized" + /> + <VnLv + :label="t('worker.summary.isDisable')" + :value="advancedSummary.isDisable" /> - <VnLv :label="t('worker.summary.isDisable')" :value="worker.isDisable" /> </QCard> <QCard class="vn-one"> <VnTitle :text="t('worker.summary.userData')" /> diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index c2a9e668f..d1feff23d 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -87,6 +87,13 @@ export default { meta: { title: 'basicData', icon: 'vn:settings', + acls: [ + { + model: 'Worker', + props: 'updateAttributes', + accessType: 'WRITE', + }, + ], }, component: () => import('src/pages/Worker/Card/WorkerBasicData.vue'), }, diff --git a/test/cypress/integration/ticket/ticketExpedition.spec.js b/test/cypress/integration/ticket/ticketExpedition.spec.js index 5eb2c1a2a..d4afd401f 100644 --- a/test/cypress/integration/ticket/ticketExpedition.spec.js +++ b/test/cypress/integration/ticket/ticketExpedition.spec.js @@ -11,15 +11,13 @@ describe('Ticket expedtion', () => { it('should change the state', () => { cy.visit('#/ticket/1/expedition'); - cy.intercept('GET', /\/api\/Expeditions\/filter/).as('expeditions'); - cy.intercept('POST', /\/api\/Expeditions\/crud/).as('crud'); - - cy.wait('@expeditions'); + cy.intercept('GET', /\/api\/Expeditions\/filter/).as('show'); + cy.intercept('POST', /\/api\/ExpeditionStates\/addExpeditionState/).as('add'); + cy.wait('@show'); cy.selectRows([1, 2]); - cy.get('#subToolbar [aria-controls]:nth-child(1)').click(); - cy.get('.q-menu .q-item').contains('Perdida').click(); - cy.wait('@crud'); + cy.selectOption('[data-cy="change-state"]', 'Perdida'); + cy.wait('@add'); cy.get(`${tableContent} tr:nth-child(-n+2) ${stateTd}`).each(($el) => { cy.wrap($el).contains('Perdida'); diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js index 8a8bea443..c1c37fd32 100644 --- a/test/cypress/integration/worker/workerList.spec.js +++ b/test/cypress/integration/worker/workerList.spec.js @@ -11,7 +11,7 @@ describe('WorkerList', () => { it('should open the worker summary', () => { cy.get(inputName).type('jessica{enter}'); cy.get(searchBtn).click(); - cy.intercept('GET', /\/api\/Workers\/\d+/).as('worker'); + cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker'); cy.wait('@worker').then(() => cy.get(descriptorTitle).should('include.text', 'Jessica') ); diff --git a/test/cypress/integration/worker/workerLocker.spec.js b/test/cypress/integration/worker/workerLocker.spec.js index 8a169dfb2..c222414fd 100644 --- a/test/cypress/integration/worker/workerLocker.spec.js +++ b/test/cypress/integration/worker/workerLocker.spec.js @@ -1,8 +1,7 @@ describe('WorkerLocker', () => { const productionId = 49; - const lockerCode = '2F'; - const input = '.q-card input'; - const thirdOpt = '[role="listbox"] .q-item:nth-child(1)'; + const lockerCode = '4F'; + const lockerSelect = '[data-cy="locker"]'; beforeEach(() => { cy.viewport(1280, 720); cy.login('productionBoss'); @@ -10,10 +9,8 @@ describe('WorkerLocker', () => { }); it('should allocates a locker', () => { - cy.get(input).click(); - cy.waitForElement('[role="listbox"]'); - cy.get(thirdOpt).click(); + cy.selectOption(lockerSelect, lockerCode); cy.saveCard(); - cy.get(input).invoke('val').should('eq', lockerCode); + cy.get(lockerSelect).invoke('val').should('eq', lockerCode); }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index c9b1a748e..76bdefd27 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -82,7 +82,7 @@ Cypress.Commands.add('getValue', (selector) => { // Fill Inputs Cypress.Commands.add('selectOption', (selector, option) => { cy.waitForElement(selector); - cy.get(selector).find('.q-select__dropdown-icon').click(); + cy.get(selector).click(); cy.get('.q-menu .q-item').contains(option).click(); }); From 0cc0e82aaaba838cbcd6c7ced6d52347af7438d0 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Sun, 27 Oct 2024 14:48:44 +0100 Subject: [PATCH 097/207] feat: refs #8078 add shortcut multi selection --- src/components/VnTable/VnTable.vue | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index c1680bf13..74a96e0e3 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -331,6 +331,16 @@ function handleScroll() { const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) <= 40; if (isAtBottom) CrudModelRef.value.vnPaginateRef.paginate(); } + +function handleSelection({ evt, added, rows: selectedRows }, rows) { + if (evt?.shiftKey && added) { + const rowIndex = selectedRows[0].$index; + for (const row of rows) { + if (row.$index > rowIndex) break; + selected.value.push(row); + } + } +} </script> <template> <QDrawer @@ -431,6 +441,7 @@ function handleScroll() { @virtual-scroll="handleScroll" @row-click="(_, row) => rowClickFunction && rowClickFunction(row)" @update:selected="emit('update:selected', $event)" + @selection="(details) => handleSelection(details, rows)" > <template #top-left v-if="!$props.withoutHeader"> <slot name="top-left"></slot> From c93f152060a9cb37360e35069e39a32ebbeca1c1 Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Sun, 27 Oct 2024 15:27:53 -0300 Subject: [PATCH 098/207] fix: order catalog fixes --- src/pages/Order/Card/OrderCatalog.vue | 22 ++- src/pages/Order/Card/OrderCatalogFilter.vue | 164 +++++++++----------- 2 files changed, 94 insertions(+), 92 deletions(-) diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue index 9fee29d7d..a266fc3d4 100644 --- a/src/pages/Order/Card/OrderCatalog.vue +++ b/src/pages/Order/Card/OrderCatalog.vue @@ -1,7 +1,7 @@ <script setup> import { useStateStore } from 'stores/useStateStore'; import { useRoute, useRouter } from 'vue-router'; -import { onBeforeMount, onMounted, onUnmounted, ref, computed } from 'vue'; +import { onBeforeMount, onMounted, onUnmounted, ref, computed, watch } from 'vue'; import axios from 'axios'; import { useI18n } from 'vue-i18n'; import VnPaginate from 'components/ui/VnPaginate.vue'; @@ -9,11 +9,15 @@ import CatalogItem from 'components/ui/CatalogItem.vue'; import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import getParamWhere from 'src/filters/getParamWhere'; +import { useArrayData } from 'composables/useArrayData'; const route = useRoute(); const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); +const arrayData = useArrayData('OrderCatalogList'); +const store = arrayData.store; +const showFilter = ref(null); const tags = ref([]); let catalogParams = { @@ -37,6 +41,8 @@ onBeforeMount(() => { ...catalogParams, ...formattedWhereParams, }; + } else { + showFilter.value = true; } }); @@ -44,6 +50,7 @@ onMounted(() => { stateStore.rightDrawer = true; checkOrderConfirmation(); }); + onUnmounted(() => (stateStore.rightDrawer = false)); async function checkOrderConfirmation() { @@ -54,6 +61,7 @@ async function checkOrderConfirmation() { } function extractTags(items) { + if (!items || !items.length) return; const resultTags = []; (items || []).forEach((item) => { (item.tags || []).forEach((tag) => { @@ -82,6 +90,14 @@ function extractValueTags(items) { tagValue.value = resultValueTags; } const autoLoad = computed(() => !!catalogParams.categoryFk); + +watch( + () => store.data, + (val) => { + extractTags(val); + }, + { immediate: true } +); </script> <template> @@ -95,7 +111,7 @@ const autoLoad = computed(() => !!catalogParams.categoryFk); :info="t('You can search items by name or id')" /> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> + <QScrollArea v-if="showFilter" class="fit text-grey-8"> <OrderCatalogFilter data-key="OrderCatalogList" :tag-value="tagValue" @@ -111,7 +127,7 @@ const autoLoad = computed(() => !!catalogParams.categoryFk); url="Orders/CatalogFilter" :limit="50" :user-params="catalogParams" - @on-fetch="extractTags" + @on-fetch="showFilter = true" :update-router="false" :auto-load="autoLoad" > diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index cc3f45391..5612399d7 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -26,11 +26,8 @@ const props = defineProps({ type: Array, required: true, }, - initialCatalogParams: { - type: Object, - default: () => ({}), - }, }); + const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); @@ -52,14 +49,6 @@ const orderWayList = ref([ const orderBySelected = ref('relevancy DESC, name'); const orderWaySelected = ref('ASC'); -const createValue = (val, done) => { - if (val.length > 2) { - if (!tagOptions.value.includes(val)) { - done(tagOptions.value, 'add-unique'); - } - tagValues.value.push({ value: val }); - } -}; const resetCategory = () => { selectedCategoryFk.value = null; typeList.value = null; @@ -97,14 +86,7 @@ const selectedCategory = computed(() => { (category) => category?.id === selectedCategoryFk.value ); }); -function filterFn(val, update) { - update(() => { - const needle = val.toLowerCase(); - tagOptions.value = props.tagValue.filter( - (v) => v.toLowerCase().indexOf(needle) > -1 - ); - }); -} + const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); @@ -120,36 +102,36 @@ function exprBuilder(param, value) { } } -const applyTagFilter = (params, search) => { +const applyTags = (params, search) => { if (!tagValues.value?.length) { params.tagGroups = null; search(); return; } - if (!params.tagGroups) { - params.tagGroups = []; - } - params.tagGroups.push( - JSON.stringify({ - values: tagValues.value.filter((obj) => Object.keys(obj).length > 0), - tagSelection: { - ...selectedTag.value, - orgShowField: selectedTag?.value?.name, - }, - tagFk: selectedTag?.value?.tagFk, - }) - ); + + const tagGroups = { + values: [...tagValues.value], + tagFk: selectedTag?.value?.id, + tagSelection: { + name: selectedTag?.value?.name, + }, + }; + + params.tagGroups = tagGroups; search(); - selectedTag.value = null; - tagValues.value = [{}]; }; -const removeTagChip = (selection, params, search) => { - if (params.tagGroups) { - params.tagGroups = (params.tagGroups || []).filter( - (value) => value !== selection - ); +const removeTagGroupParam = (params, search, valIndex = null) => { + if (!params.tagGroups) return; + + if (!valIndex) { + params.tagGroups = null; + tagValues.value = [{}]; + } else { + (tagValues.value || []).splice(valIndex, 1); + params.tagGroups.values.splice(valIndex, 1); } + search(); }; @@ -178,9 +160,37 @@ function addOrder(value, field, params) { vnFilterPanelRef.value.search(); } +const getSelectedTagValues = async (tag) => { + try { + if (!tag?.id) return; + const filter = { + fields: ['value'], + order: 'value ASC', + limit: 30, + }; + + const url = `Tags/${tag?.id}/filterValue`; + console.log('url', url); + const params = { filter: JSON.stringify(filter) }; + const { data } = await axios.get(url, { + params, + }); + tagOptions.value = data; + } catch (err) { + console.error('Error getting selected tag values'); + } +}; + onMounted(() => { selectedCategoryFk.value = getParamWhere(route, 'categoryFk'); selectedTypeFk.value = getParamWhere(route, 'typeFk'); + if (route.query.params && JSON.parse(route.query.params).tagGroups) { + const tagGroups = JSON.parse(route.query.params).tagGroups; + tagValues.value = [...tagGroups.values]; + selectedTag.value = (props.tags || []).find( + (tag) => tag.name === tagGroups.tagSelection.name + ); + } }); </script> @@ -212,19 +222,19 @@ onMounted(() => { <template v-for="tag in customTags" :key="tag.label"> <template v-if="tag.label === 'tagGroups'"> <VnFilterPanelChip - v-for="chip in tag.value" - :key="chip" removable - @remove="removeTagChip(chip, params, searchFn)" + @remove="removeTagGroupParam(params, searchFn)" > - <pre>{{ chip }}</pre> - - <strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong> - <span>{{ - (JSON.parse(chip).values || []) - .map((item) => item.value) - .join(' | ') - }}</span> + <strong class="q-mr-xs"> + {{ tag.value?.tagSelection?.name }}: + </strong> + <span> + {{ + (tag.value?.values || []) + .map((item) => `"${item.value}"`) + .join(', ') + }} + </span> </VnFilterPanelChip> </template> </template> @@ -323,6 +333,7 @@ onMounted(() => { rounded :emit-value="false" use-input + @update:model-value="($event) => getSelectedTagValues($event)" /> </QItemSection> </QItem> @@ -331,16 +342,9 @@ onMounted(() => { :key="value" class="q-mt-md filter-value" > - <FetchData - v-if="selectedTag" - :url="`Tags/${selectedTag}/filterValue`" - limit="30" - auto-load - @on-fetch="(data) => (tagOptions = data)" - /> <VnSelect - v-if="!selectedTag" - :label="t('params.value')" + v-if="!selectedTag?.isFree && tagOptions" + :label="t('components.itemsFilterPanel.value')" v-model="value.value" :options="tagOptions || []" option-value="value" @@ -350,41 +354,23 @@ onMounted(() => { rounded emit-value use-input - class="filter-input" - @new-value="createValue" - @filter="filterFn" - @update:model-value="applyTagFilter(params, searchFn)" - /> - <VnSelect - v-else-if="selectedTag === 1" - :label="t('params.value')" - v-model="value.value" - :options="tagOptions || []" - option-value="value" - option-label="value" - dense - outlined - rounded - emit-value - use-input - class="filter-input" - @new-value="createValue" - @update:model-value="applyTagFilter(params, searchFn)" + :disable="!value" + :is-clearable="false" + @update:model-value="applyTags(params, searchFn)" /> <VnInput v-else - :label="t('params.value')" v-model="value.value" - dense - outlined - rounded - class="filter-input" - @keyup.enter="applyTagFilter(params, searchFn)" + :label="t('components.itemsFilterPanel.value')" + :disable="!value" + is-outlined + :is-clearable="false" + @keyup.enter="applyTags(params, searchFn)" /> <QIcon name="delete" class="filter-icon" - @click="(tagValues || []).splice(index, 1)" + @click="removeTagGroupParam(params, searchFn, index)" /> </QItem> <QItem class="q-mt-lg"> @@ -393,11 +379,11 @@ onMounted(() => { shortcut="+" flat class="filter-icon" + size="md" @click="tagValues.push({})" /> </QItem> <QSeparator /> - <pre>{{ params }}</pre> </template> </VnFilterPanel> </template> From ca6547e174b12865105cd819ccb3f1ccedf47803 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 07:48:11 +0100 Subject: [PATCH 099/207] feat: refs #7970 notify changes --- src/components/ui/VnConfirm.vue | 23 ++++++--- src/pages/Ticket/Card/TicketSale.vue | 76 ++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index 4fa374b62..0fbc55cfb 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -30,10 +30,10 @@ const props = defineProps({ }, }); -defineEmits(['confirm', ...useDialogPluginComponent.emits]); -defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() }); +defineEmits([...useDialogPluginComponent.emits]); -const { dialogRef, onDialogOK } = useDialogPluginComponent(); +const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = + useDialogPluginComponent(); const title = props.title || t('Confirm'); const message = @@ -53,9 +53,13 @@ async function confirm() { } onDialogOK(props.data); } + +function cancel() { + onDialogCancel(); +} </script> <template> - <QDialog ref="dialogRef"> + <QDialog ref="dialogRef" @hide="onDialogHide"> <QCard class="q-pa-sm"> <QCardSection class="row items-center q-pb-none"> <QAvatar @@ -67,7 +71,14 @@ async function confirm() { /> <span class="text-h6">{{ title }}</span> <QSpace /> - <QBtn icon="close" :disable="isLoading" flat round dense v-close-popup /> + <QBtn + icon="close" + :disable="isLoading" + flat + round + dense + @click="cancel()" + /> </QCardSection> <QCardSection class="q-pb-none"> <span v-if="message !== false" v-html="message" /> @@ -81,7 +92,7 @@ async function confirm() { color="primary" :disable="isLoading" flat - v-close-popup + @click="cancel()" /> <QBtn :label="t('globals.confirm')" diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue index c786c67e3..3426db880 100644 --- a/src/pages/Ticket/Card/TicketSale.vue +++ b/src/pages/Ticket/Card/TicketSale.vue @@ -2,6 +2,7 @@ import { onMounted, ref, computed, onUnmounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter, useRoute } from 'vue-router'; +import { useQuasar } from 'quasar'; import FetchData from 'components/FetchData.vue'; import FetchedTags from 'components/ui/FetchedTags.vue'; @@ -23,6 +24,7 @@ import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; import VnTable from 'src/components/VnTable/VnTable.vue'; import VnUsesMana from 'src/components/ui/VnUsesMana.vue'; +import VnConfirm from 'src/components/ui/VnConfirm.vue'; const route = useRoute(); const router = useRouter(); @@ -32,7 +34,7 @@ const { notify } = useNotify(); const { openConfirmationModal } = useVnConfirm(); const editPriceProxyRef = ref(null); const stateBtnDropdownRef = ref(null); - +const quasar = useQuasar(); const arrayData = useArrayData('ticketData'); const { store } = arrayData; const selectedRows = ref([]); @@ -51,6 +53,7 @@ const transfer = ref({ sales: [], }); const tableRef = ref([]); +const canProceed = ref(); watch( () => route.params.id, @@ -214,7 +217,9 @@ const addSale = async (sale) => { } }; -const changeQuantity = (sale) => { +const changeQuantity = async (sale) => { + canProceed.value = await isSalePrepared(sale); + if (!canProceed.value) return; if ( !sale.itemFk || sale.quantity == null || @@ -226,6 +231,8 @@ const changeQuantity = (sale) => { }; const updateConcept = async (sale) => { + canProceed.value = await isSalePrepared(sale); + if (!canProceed.value) return; try { const data = { newConcept: sale.concept }; await axios.post(`Sales/${sale.id}/updateConcept`, data); @@ -286,6 +293,8 @@ const onOpenEditDiscountPopover = async (sale) => { }; const updatePrice = async (sale) => { + canProceed.value = await isSalePrepared(sale); + if (!canProceed.value) return; try { const newPrice = edit.value.price; if (newPrice != null && newPrice != sale.price) { @@ -300,12 +309,18 @@ const updatePrice = async (sale) => { } }; -const changeDiscount = (sale) => { +const changeDiscount = async (sale) => { + canProceed.value = await isSalePrepared(sale); + if (!canProceed.value) return; const newDiscount = edit.value.discount; if (newDiscount != null && newDiscount != sale.discount) updateDiscount([sale]); }; const updateDiscount = async (sales, newDiscount = null) => { + for (const sale of sales) { + const canProceed = await isSalePrepared(sale); + if (!canProceed) return; + } const saleIds = sales.map((sale) => sale.id); const _newDiscount = newDiscount || edit.value.discount; const params = { @@ -433,7 +448,9 @@ onUnmounted(() => (stateStore.rightDrawer = false)); const items = ref([]); const newRow = ref({}); -const updateItem = (row) => { +const updateItem = async (row) => { + canProceed.value = await isSalePrepared(row); + if (!canProceed.value) return; const selectedItem = items.value.find((item) => item.id === row.itemFk); if (selectedItem) { row.item = selectedItem; @@ -476,6 +493,55 @@ const endNewRow = (row) => { } }; +async function isSalePrepared(item) { + const filter = { + params: { + where: { ticketFk: route.params.id }, + order: ['concept ASC', 'quantity DESC'], + }, + }; + const { data } = await axios.get(`SaleTrackings/${route.params.id}/filter`, { + params: { + filter: JSON.stringify(filter), + }, + }); + + const matchingSale = data.find((sale) => sale.itemFk === item.itemFk); + if (!matchingSale) { + return true; + } + + if ( + matchingSale.hasSaleGroupDetail || + matchingSale.isControled || + matchingSale.isPrepared || + matchingSale.isPrevious || + matchingSale.isPreviousSelected + ) { + try { + await new Promise((resolve, reject) => { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: t('Item prepared'), + message: t( + 'This item is already prepared. Do you want to continue?' + ), + data: item, + }, + }) + .onOk(() => resolve(true)) + .onCancel(() => reject(new Error('cancelled'))); + }); + } catch (error) { + tableRef.value.reload(); + return false; + } + } + return true; +} + watch( () => newRow.value.itemFk, (newItemFk) => { @@ -820,4 +886,6 @@ es: You are going to delete lines of the ticket: Vas a eliminar lineas del ticket Add item: Añadir artículo Transfer lines: Transferir líneas + Item prepared: Artículo preparado + This item is already prepared. Do you want to continue?: Este artículo ya esta preparado. Desea continuar? </i18n> From cca255507a593dce4f57fb949f2170dfb2187dd2 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 28 Oct 2024 09:57:25 +0100 Subject: [PATCH 100/207] fix: itemType redirection and fix filters --- src/components/common/VnComponent.vue | 2 +- src/components/ui/VnFilterPanel.vue | 2 +- .../ItemType/Card/ItemTypeBasicData.vue | 0 .../{ => Item}/ItemType/Card/ItemTypeCard.vue | 4 +- .../ItemType/Card/ItemTypeDescriptor.vue | 0 .../{ => Item}/ItemType/Card/ItemTypeLog.vue | 0 .../ItemType/Card/ItemTypeSummary.vue | 0 .../{ => Item}/ItemType/ItemTypeFilter.vue | 35 +++++++ .../{ => Item}/ItemType/ItemTypeSearchbar.vue | 1 + src/pages/{ => Item}/ItemType/locale/en.yml | 0 src/pages/{ => Item}/ItemType/locale/es.yml | 0 src/pages/Item/ItemTypeCreate.vue | 98 ------------------- src/pages/Item/ItemTypeList.vue | 58 +++++++++-- .../Ticket/Card/TicketDescriptorMenu.vue | 1 - src/router/modules/item.js | 8 -- src/router/modules/itemType.js | 9 +- 16 files changed, 93 insertions(+), 125 deletions(-) rename src/pages/{ => Item}/ItemType/Card/ItemTypeBasicData.vue (100%) rename src/pages/{ => Item}/ItemType/Card/ItemTypeCard.vue (75%) rename src/pages/{ => Item}/ItemType/Card/ItemTypeDescriptor.vue (100%) rename src/pages/{ => Item}/ItemType/Card/ItemTypeLog.vue (100%) rename src/pages/{ => Item}/ItemType/Card/ItemTypeSummary.vue (100%) rename src/pages/{ => Item}/ItemType/ItemTypeFilter.vue (57%) rename src/pages/{ => Item}/ItemType/ItemTypeSearchbar.vue (94%) rename src/pages/{ => Item}/ItemType/locale/en.yml (100%) rename src/pages/{ => Item}/ItemType/locale/es.yml (100%) delete mode 100644 src/pages/Item/ItemTypeCreate.vue diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue index bd25c787c..580bcf348 100644 --- a/src/components/common/VnComponent.vue +++ b/src/components/common/VnComponent.vue @@ -1,5 +1,5 @@ <script setup> -import { computed, defineModel } from 'vue'; +import { computed } from 'vue'; const model = defineModel(undefined, { required: true }); const $props = defineProps({ diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 43d634ad9..e902214b2 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -37,7 +37,7 @@ const $props = defineProps({ }, hiddenTags: { type: Array, - default: () => ['filter', 'search', 'or', 'and'], + default: () => ['filter', 'or', 'and'], }, customTags: { type: Array, diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/Item/ItemType/Card/ItemTypeBasicData.vue similarity index 100% rename from src/pages/ItemType/Card/ItemTypeBasicData.vue rename to src/pages/Item/ItemType/Card/ItemTypeBasicData.vue diff --git a/src/pages/ItemType/Card/ItemTypeCard.vue b/src/pages/Item/ItemType/Card/ItemTypeCard.vue similarity index 75% rename from src/pages/ItemType/Card/ItemTypeCard.vue rename to src/pages/Item/ItemType/Card/ItemTypeCard.vue index 9daec7921..0a2706a07 100644 --- a/src/pages/ItemType/Card/ItemTypeCard.vue +++ b/src/pages/Item/ItemType/Card/ItemTypeCard.vue @@ -1,7 +1,7 @@ <script setup> import VnCard from 'components/common/VnCard.vue'; -import ItemTypeDescriptor from 'src/pages/ItemType/Card/ItemTypeDescriptor.vue'; -import ItemTypeFilter from 'src/pages/ItemType/ItemTypeFilter.vue'; +import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue'; +import ItemTypeFilter from 'src/pages/Item/ItemType/ItemTypeFilter.vue'; import ItemTypeSearchbar from '../ItemTypeSearchbar.vue'; </script> <template> diff --git a/src/pages/ItemType/Card/ItemTypeDescriptor.vue b/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue similarity index 100% rename from src/pages/ItemType/Card/ItemTypeDescriptor.vue rename to src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue diff --git a/src/pages/ItemType/Card/ItemTypeLog.vue b/src/pages/Item/ItemType/Card/ItemTypeLog.vue similarity index 100% rename from src/pages/ItemType/Card/ItemTypeLog.vue rename to src/pages/Item/ItemType/Card/ItemTypeLog.vue diff --git a/src/pages/ItemType/Card/ItemTypeSummary.vue b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue similarity index 100% rename from src/pages/ItemType/Card/ItemTypeSummary.vue rename to src/pages/Item/ItemType/Card/ItemTypeSummary.vue diff --git a/src/pages/ItemType/ItemTypeFilter.vue b/src/pages/Item/ItemType/ItemTypeFilter.vue similarity index 57% rename from src/pages/ItemType/ItemTypeFilter.vue rename to src/pages/Item/ItemType/ItemTypeFilter.vue index 2a86795c2..f6fb73098 100644 --- a/src/pages/ItemType/ItemTypeFilter.vue +++ b/src/pages/Item/ItemType/ItemTypeFilter.vue @@ -12,6 +12,39 @@ const props = defineProps({ }); const emit = defineEmits(['search']); +const exprBuilder = (param, value) => { + switch (param) { + case 'name': + return { + name: { like: `%${value}%` }, + }; + case 'code': + return { + code: { like: `%${value}%` }, + }; + case 'search': + if (value) { + if (!isNaN(value)) { + return { id: value }; + } else { + return { + or: [ + { + name: { + like: `%${value}%`, + }, + }, + { + code: { + like: `%${value}%`, + }, + }, + ], + }; + } + } + } +}; </script> <template> @@ -19,6 +52,8 @@ const emit = defineEmits(['search']); :data-key="props.dataKey" :search-button="true" @search="emit('search')" + search-url="table" + :expr-builder="exprBuilder" > <template #tags="{ tag, formatFn }"> <div class="q-gutter-x-xs"> diff --git a/src/pages/ItemType/ItemTypeSearchbar.vue b/src/pages/Item/ItemType/ItemTypeSearchbar.vue similarity index 94% rename from src/pages/ItemType/ItemTypeSearchbar.vue rename to src/pages/Item/ItemType/ItemTypeSearchbar.vue index 749033d43..87903a517 100644 --- a/src/pages/ItemType/ItemTypeSearchbar.vue +++ b/src/pages/Item/ItemType/ItemTypeSearchbar.vue @@ -10,6 +10,7 @@ const { t } = useI18n(); url="ItemTypes" :label="t('Search item type')" :info="t('Search itemType by id, name or code')" + search-url="table" /> </template> <i18n> diff --git a/src/pages/ItemType/locale/en.yml b/src/pages/Item/ItemType/locale/en.yml similarity index 100% rename from src/pages/ItemType/locale/en.yml rename to src/pages/Item/ItemType/locale/en.yml diff --git a/src/pages/ItemType/locale/es.yml b/src/pages/Item/ItemType/locale/es.yml similarity index 100% rename from src/pages/ItemType/locale/es.yml rename to src/pages/Item/ItemType/locale/es.yml diff --git a/src/pages/Item/ItemTypeCreate.vue b/src/pages/Item/ItemTypeCreate.vue deleted file mode 100644 index 60c037510..000000000 --- a/src/pages/Item/ItemTypeCreate.vue +++ /dev/null @@ -1,98 +0,0 @@ -<script setup> -import { reactive, ref } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; - -import FetchData from 'components/FetchData.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import FormModel from 'components/FormModel.vue'; -import VnRow from 'components/ui/VnRow.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; - -const { t } = useI18n(); -const router = useRouter(); - -const newItemTypeForm = reactive({}); - -const categoriesOptions = ref([]); -const temperaturesOptions = ref([]); - -const redirectToItemTypeBasicData = (_, { id }) => { - router.push({ name: 'ItemTypeBasicData', params: { id } }); -}; -</script> - -<template> - <FetchData - url="ItemCategories" - @on-fetch="(data) => (categoriesOptions = data)" - :filter="{ order: 'name ASC', fields: ['id', 'name'] }" - auto-load - /> - <FetchData - url="Temperatures" - @on-fetch="(data) => (temperaturesOptions = data)" - :filter="{ order: 'name ASC', fields: ['code', 'name'] }" - auto-load - /> - <QPage> - <VnSubToolbar /> - <FormModel - url-create="ItemTypes" - model="itemTypeCreate" - :form-initial-data="newItemTypeForm" - observe-form-changes - @on-data-saved="redirectToItemTypeBasicData" - > - <template #form="{ data }"> - <VnRow> - <VnInput v-model="data.code" :label="t('itemType.shared.code')" /> - <VnInput v-model="data.name" :label="t('itemType.shared.name')" /> - </VnRow> - <VnRow> - <VnSelect - url="Workers/search" - v-model="data.workerFk" - :label="t('shared.worker')" - sort-by="nickname ASC" - :fields="['id', 'nickname']" - :params="{ departmentCodes: ['shopping'] }" - option-label="nickname" - option-value="id" - hide-selected - ><template #option="scope"> - <QItem v-bind="scope.itemProps"> - <QItemSection> - <QItemLabel>{{ scope.opt?.name }}</QItemLabel> - <QItemLabel caption - >{{ scope.opt?.nickname }}, - {{ scope.opt?.code }}</QItemLabel - > - </QItemSection> - </QItem> - </template> - </VnSelect> - <VnSelect - v-model="data.categoryFk" - :label="t('itemType.shared.category')" - :options="categoriesOptions" - option-value="id" - option-label="name" - hide-selected - /> - </VnRow> - <VnRow> - <VnSelect - v-model="data.temperatureFk" - :label="t('itemType.shared.temperature')" - :options="temperaturesOptions" - option-value="code" - option-label="name" - hide-selected - /> - </VnRow> - </template> - </FormModel> - </QPage> -</template> diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue index 13dd56a42..149de482d 100644 --- a/src/pages/Item/ItemTypeList.vue +++ b/src/pages/Item/ItemTypeList.vue @@ -1,13 +1,16 @@ <script setup> import { useI18n } from 'vue-i18n'; import { ref, computed } from 'vue'; -import ItemTypeSearchbar from '../ItemType/ItemTypeSearchbar.vue'; +import ItemTypeSearchbar from 'src/pages/Item/ItemType/ItemTypeSearchbar.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import FetchData from 'components/FetchData.vue'; +import RightMenu from 'src/components/common/RightMenu.vue'; +import ItemTypeFilter from './ItemType/ItemTypeFilter.vue'; const { t } = useI18n(); const tableRef = ref(); -const ItemCategoriesOptions = ref([]); +const itemCategoriesOptions = ref([]); +const temperatureOptions = ref([]); const columns = computed(() => [ { @@ -34,7 +37,6 @@ const columns = computed(() => [ }, { align: 'left', - name: 'workerFk', label: t('worker'), create: true, component: 'select', @@ -45,6 +47,19 @@ const columns = computed(() => [ }, cardVisible: true, visible: true, + columnField: { + component: 'userLink', + attrs: ({ row }) => { + return { + workerId: row?.worker?.id, + name: row.worker?.user?.name, + defaultName: true, + }; + }, + }, + columnFilter: { + name: 'workerFk', + }, }, { align: 'left', @@ -53,9 +68,7 @@ const columns = computed(() => [ create: true, component: 'select', attrs: { - options: ItemCategoriesOptions.value, - fields: ['id', 'name'], - order: 'name ASC', + options: itemCategoriesOptions.value, }, cardVisible: false, visible: false, @@ -67,8 +80,7 @@ const columns = computed(() => [ create: true, component: 'select', attrs: { - url: 'Temperatures', - fields: ['id', 'name'], + options: temperatureOptions.value, }, cardVisible: false, visible: false, @@ -80,26 +92,52 @@ const columns = computed(() => [ <FetchData url="ItemCategories" :filter="{ fields: ['id', 'name'], order: ['name ASC'] }" - @on-fetch="(data) => (ItemCategoriesOptions = data)" + @on-fetch="(data) => (itemCategoriesOptions = data)" auto-load /> + <FetchData + url="Temperatures" + :filter="{ fields: ['id', 'name'], order: ['name ASC'] }" + @on-fetch="(data) => (temperatureOptions = data)" + auto-load + /> + <RightMenu> + <template #right-panel> + <ItemTypeFilter data-key="ItemTypeList" /> + </template> + </RightMenu> <ItemTypeSearchbar /> <VnTable ref="tableRef" data-key="ItemTypeList" - :url="`ItemTypes`" + url="ItemTypes" :create="{ urlCreate: 'ItemTypes', title: t('Create ItemTypes'), onDataSaved: () => tableRef.reload(), formInitialData: {}, }" + :user-filter="{ + include: { + relation: 'worker', + scope: { + fields: ['id'], + include: { + relation: 'user', + scope: { + fields: ['id', 'name'], + }, + }, + }, + }, + }" order="name ASC" :columns="columns" auto-load :right-search="false" :is-editable="false" :use-model="true" + redirect="item/item-type" /> </template> diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue index 834fced87..bf4a1efb4 100644 --- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue +++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue @@ -348,7 +348,6 @@ async function hasDocuware() { } async function uploadDocuware(force) { - console.log('force: ', force); if (!force) return quasar .dialog({ diff --git a/src/router/modules/item.js b/src/router/modules/item.js index 2838c3be7..0f810434c 100644 --- a/src/router/modules/item.js +++ b/src/router/modules/item.js @@ -97,14 +97,6 @@ export default { }, component: () => import('src/pages/Item/ItemTypeList.vue'), }, - { - path: 'item-type-list/create', - name: 'ItemTypeCreate', - meta: { - title: 'itemTypeCreate', - }, - component: () => import('src/pages/Item/ItemTypeCreate.vue'), - }, ], }, { diff --git a/src/router/modules/itemType.js b/src/router/modules/itemType.js index 0fd3797e6..1ceecd4cc 100644 --- a/src/router/modules/itemType.js +++ b/src/router/modules/itemType.js @@ -18,7 +18,7 @@ export default { { name: 'ItemTypeCard', path: ':id', - component: () => import('src/pages/ItemType/Card/ItemTypeCard.vue'), + component: () => import('src/pages/Item/ItemType/Card/ItemTypeCard.vue'), redirect: { name: 'ItemTypeSummary' }, children: [ { @@ -28,7 +28,7 @@ export default { title: 'summary', }, component: () => - import('src/pages/ItemType/Card/ItemTypeSummary.vue'), + import('src/pages/Item/ItemType/Card/ItemTypeSummary.vue'), }, { name: 'ItemTypeBasicData', @@ -38,7 +38,7 @@ export default { icon: 'vn:settings', }, component: () => - import('src/pages/ItemType/Card/ItemTypeBasicData.vue'), + import('src/pages/Item/ItemType/Card/ItemTypeBasicData.vue'), }, { path: 'log', @@ -47,7 +47,8 @@ export default { title: 'log', icon: 'vn:History', }, - component: () => import('src/pages/ItemType/Card/ItemTypeLog.vue'), + component: () => + import('src/pages/Item/ItemType/Card/ItemTypeLog.vue'), }, ], }, From bc8a87b267921f339843e6639de268a55a482938 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 28 Oct 2024 09:58:07 +0100 Subject: [PATCH 101/207] chore: typo --- src/components/ui/VnFilterPanel.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index e902214b2..43d634ad9 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -37,7 +37,7 @@ const $props = defineProps({ }, hiddenTags: { type: Array, - default: () => ['filter', 'or', 'and'], + default: () => ['filter', 'search', 'or', 'and'], }, customTags: { type: Array, From df1c123444e577336fed9c5b1c17d093ecf37d68 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 10:39:45 +0100 Subject: [PATCH 102/207] feat: refs #7193 modified parking to use the scope and corrected small errors --- src/i18n/locale/en.yml | 3 +-- src/i18n/locale/es.yml | 3 +-- src/pages/Parking/Card/ParkingCard.vue | 6 ------ src/pages/Parking/Card/ParkingDescriptor.vue | 1 + src/pages/Parking/ParkingList.vue | 4 +--- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index c1748c8ff..24fda7aff 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -278,6 +278,7 @@ globals: RouteExtendedList: Router wasteRecalc: Waste recaclulate operator: Operator + parking: Parking supplier: Supplier created: Created worker: Worker @@ -663,8 +664,6 @@ parking: sector: Sector row: Row column: Column - pageTitles: - parking: Parking searchBar: info: You can search by parking code label: Search parking... diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index bd414a793..1571f7b92 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -282,6 +282,7 @@ globals: medical: Mutua wasteRecalc: Recalcular mermas operator: Operario + parking: Parking supplier: Proveedor created: Fecha creación worker: Trabajador @@ -710,8 +711,6 @@ parking: pickingOrder: Orden de recogida row: Fila column: Columna - pageTitles: - parking: Parking searchBar: info: Puedes buscar por código de parking label: Buscar parking... diff --git a/src/pages/Parking/Card/ParkingCard.vue b/src/pages/Parking/Card/ParkingCard.vue index ad37eb630..337106986 100644 --- a/src/pages/Parking/Card/ParkingCard.vue +++ b/src/pages/Parking/Card/ParkingCard.vue @@ -2,17 +2,11 @@ import VnCard from 'components/common/VnCard.vue'; import ParkingDescriptor from 'pages/Parking/Card/ParkingDescriptor.vue'; import ParkingFilter from 'pages/Parking/ParkingFilter.vue'; - -const filter = { - fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'], - include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }], -}; </script> <template> <VnCard data-key="Parking" base-url="Parkings" - :filter="filter" :descriptor="ParkingDescriptor" :filter-panel="ParkingFilter" search-data-key="ParkingList" diff --git a/src/pages/Parking/Card/ParkingDescriptor.vue b/src/pages/Parking/Card/ParkingDescriptor.vue index b57bfb0cc..d36ea16fc 100644 --- a/src/pages/Parking/Card/ParkingDescriptor.vue +++ b/src/pages/Parking/Card/ParkingDescriptor.vue @@ -29,6 +29,7 @@ const filter = { :url="`Parkings/${entityId}`" title="code" :filter="filter" + :to-module="{ name: 'ParkingList' }" > <template #body="{ entity }"> <VnLv :label="t('globals.code')" :value="entity.code" /> diff --git a/src/pages/Parking/ParkingList.vue b/src/pages/Parking/ParkingList.vue index b6f4e8146..109613383 100644 --- a/src/pages/Parking/ParkingList.vue +++ b/src/pages/Parking/ParkingList.vue @@ -22,7 +22,6 @@ onUnmounted(() => (stateStore.rightDrawer = false)); const filter = { fields: ['id', 'sectorFk', 'code', 'pickingOrder'], - include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }], }; function exprBuilder(param, value) { @@ -55,10 +54,9 @@ function exprBuilder(param, value) { <VnPaginate data-key="ParkingList" url="Parkings" - :filter="filter" + :user-filter="filter" :expr-builder="exprBuilder" :limit="20" - auto-load order="code" > <template #body="{ rows }"> From 2cde8501327333e6f259f8e7d1bea88e1d5be1a9 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 11:37:32 +0100 Subject: [PATCH 103/207] fix: refs #7193 fixed e2e test --- test/cypress/integration/parking/parkingList.spec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cypress/integration/parking/parkingList.spec.js b/test/cypress/integration/parking/parkingList.spec.js index b78a660d1..f1efaa375 100644 --- a/test/cypress/integration/parking/parkingList.spec.js +++ b/test/cypress/integration/parking/parkingList.spec.js @@ -1,5 +1,6 @@ /// <reference types="cypress" /> describe('ParkingList', () => { + const searchbar = '#searchbar input'; const firstCard = '.q-card:nth-child(1)'; const firstChipId = ':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content'; @@ -14,6 +15,7 @@ describe('ParkingList', () => { }); it('should redirect on clicking a parking', () => { + cy.get(searchbar).type('{enter}'); cy.get(firstChipId) .invoke('text') .then((content) => { @@ -24,6 +26,7 @@ describe('ParkingList', () => { }); it('should open the details', () => { + cy.get(searchbar).type('{enter}'); cy.get(firstDetailBtn).click(); cy.get(summaryHeader).contains('Basic data'); }); From 9347bb1ef5384aee2e84f73afa3d3b48b449b500 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 11:44:49 +0100 Subject: [PATCH 104/207] refactor: refs #7970 refactored VnConfirm to emit events --- src/components/ui/VnConfirm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index 0fbc55cfb..c5d2b43f5 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -30,7 +30,7 @@ const props = defineProps({ }, }); -defineEmits([...useDialogPluginComponent.emits]); +defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits]); const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); From 17b1921af6603db83744efc8095c6dbc4eb34141 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 12:21:26 +0100 Subject: [PATCH 105/207] feat: added composable to confirm orders --- src/composables/confirmOrder.js | 22 +++++++++++++++++++++ src/pages/Order/Card/OrderLines.vue | 28 +++++++++++++-------------- src/pages/Order/Card/OrderSummary.vue | 21 +++++++++----------- 3 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 src/composables/confirmOrder.js diff --git a/src/composables/confirmOrder.js b/src/composables/confirmOrder.js new file mode 100644 index 000000000..33e05a1d7 --- /dev/null +++ b/src/composables/confirmOrder.js @@ -0,0 +1,22 @@ +import axios from 'axios'; +import { useQuasar } from 'quasar'; +import { useI18n } from 'vue-i18n'; + +export function confirmOrder() { + const quasar = useQuasar(); + const { t } = useI18n(); + + async function confirm(route) { + const { data } = await axios.post(`Orders/${route}/confirm`); + if (data) { + quasar.notify({ + message: t('globals.confirm'), + type: 'positive', + }); + return data; + } + return null; + } + + return { confirm }; +} diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue index ee883b73a..90586dc15 100644 --- a/src/pages/Order/Card/OrderLines.vue +++ b/src/pages/Order/Card/OrderLines.vue @@ -6,6 +6,7 @@ import { useQuasar } from 'quasar'; import axios from 'axios'; import { useStateStore } from 'stores/useStateStore'; import { useArrayData } from 'composables/useArrayData'; +import { confirmOrder } from 'composables/confirmOrder'; import { toCurrency, toDate } from 'src/filters'; import VnConfirm from 'components/ui/VnConfirm.vue'; @@ -31,7 +32,7 @@ const orderSummary = ref({ }); const getTotalRef = ref(); const getVATRef = ref(); - +const { confirm } = confirmOrder(); const lineFilter = ref({ include: [ { @@ -204,20 +205,17 @@ async function remove(item) { getVATRef.value.fetch(); } -async function confirmOrder() { - await axios.post(`Orders/${route.params.id}/confirm`); - quasar.notify({ - message: t('globals.confirm'), - type: 'positive', - }); - router.push({ - name: 'TicketList', - query: { - table: JSON.stringify({ clientFk: descriptorData.store.data.clientFk }), - }, - }); +async function handleConfirm() { + const result = await confirm(route.params.id); + if (result) { + router.push({ + name: 'TicketList', + query: { + table: JSON.stringify({ clientFk: descriptorData.store.data.clientFk }), + }, + }); + } } - watch( () => router.currentRoute.value.params.id, () => { @@ -314,7 +312,7 @@ watch( </template> </VnTable> <QPageSticky :offset="[20, 20]" v-if="!order?.isConfirmed" style="z-index: 2"> - <QBtn fab icon="check" color="primary" @click="confirmOrder()" /> + <QBtn fab icon="check" color="primary" @click="handleConfirm()" /> <QTooltip> {{ t('confirm') }} </QTooltip> diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index 9bc89ad28..3669fe8d8 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -2,10 +2,9 @@ import { computed, ref } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import { useQuasar } from 'quasar'; -import axios from 'axios'; import { dashIfEmpty, toCurrency, toDateHourMinSec } from 'src/filters'; import { useArrayData } from 'composables/useArrayData'; +import { confirmOrder } from 'composables/confirmOrder'; import VnLv from 'components/ui/VnLv.vue'; import CardSummary from 'components/ui/CardSummary.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -25,8 +24,8 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const summary = ref(); -const quasar = useQuasar(); const descriptorData = useArrayData('orderData'); +const { confirm } = confirmOrder(); const detailsColumns = ref([ { name: 'item', @@ -56,14 +55,12 @@ const detailsColumns = ref([ }, ]); -async function confirmOrder() { - await axios.post(`Orders/${route.params.id}/confirm`); - quasar.notify({ - message: t('globals.confirm'), - type: 'positive', - }); - summary.value.fetch({}); - descriptorData.fetch({}); +async function handleConfirm() { + const result = await confirm(route.params.id); + if (result) { + summary.value.fetch({}); + descriptorData.fetch({}); + } } </script> @@ -84,7 +81,7 @@ async function confirmOrder() { text-color="white" :disabled="isConfirmed" :label="t('order.summary.confirm')" - @click="confirmOrder()" + @click="handleConfirm()" > <QTooltip>{{ t('order.summary.confirmLines') }}</QTooltip> </QBtn> From 3d4ca2bc672a2375a14df8c2f2918b137839ffef Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 12:45:13 +0100 Subject: [PATCH 106/207] refactor: refs #7970 added emit --- src/components/ui/VnConfirm.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index c5d2b43f5..ec9d0f48b 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -30,7 +30,7 @@ const props = defineProps({ }, }); -defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits]); +const emit = defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits]); const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); @@ -55,6 +55,7 @@ async function confirm() { } function cancel() { + emit('cancel'); onDialogCancel(); } </script> From cab5a165d2acb6c4e5d92859e5ed96611029d938 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 28 Oct 2024 12:59:25 +0100 Subject: [PATCH 107/207] refactor: changed confirmOrder directory --- src/{ => pages/Order}/composables/confirmOrder.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => pages/Order}/composables/confirmOrder.js (100%) diff --git a/src/composables/confirmOrder.js b/src/pages/Order/composables/confirmOrder.js similarity index 100% rename from src/composables/confirmOrder.js rename to src/pages/Order/composables/confirmOrder.js From f2803a63136a9478e492d112d4f6f1b6d16b5c73 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 28 Oct 2024 13:08:19 +0100 Subject: [PATCH 108/207] fix: refs #7283 item filters --- src/pages/Item/ItemList.vue | 35 +++++++++++++++++++++------------- src/pages/Item/ItemRequest.vue | 24 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index cca5560fe..c9422a0fe 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -40,6 +40,12 @@ const itemFilter = { fields: ['id', 'name'], }, }, + { + relation: 'production', + scope: { + fields: ['id', 'name'], + }, + }, ], }; const columns = computed(() => [ @@ -161,19 +167,13 @@ const columns = computed(() => [ name: 'intrastat', align: 'left', component: 'select', - attrs: { - url: 'Intrastats', - optionValue: 'description', - optionLabel: 'description', - }, columnFilter: { - name: 'description', + name: 'intrastat', attrs: { url: 'Intrastats', optionValue: 'description', optionLabel: 'description', }, - alias: 'intr', }, columnField: { component: null, @@ -211,14 +211,19 @@ const columns = computed(() => [ label: t('item.list.userName'), name: 'userName', align: 'left', + component: 'select', columnFilter: { name: 'workerFk', attrs: { - url: 'Users', + url: 'VnUsers', optionValue: 'id', - optionLabel: 'userName', + optionLabel: 'nickname', }, }, + + columnField: { + component: null, + }, }, { label: t('item.list.weightByPiece'), @@ -255,9 +260,13 @@ const columns = computed(() => [ name: 'producer', align: 'left', component: 'select', - attrs: { - url: 'Producers', - fields: ['id', 'name'], + columnFilter: { + name: 'producerFk', + attrs: { + url: 'Producers', + optionValue: 'id', + optionLabel: 'name', + }, }, columnField: { component: null, @@ -331,7 +340,7 @@ const columns = computed(() => [ <template #column-userName="{ row }"> <span class="link" @click.stop> {{ row.userName }} - <WorkerDescriptorProxy :id="row.buyerFk" /> + <WorkerDescriptorProxy :id="row.workerFk" /> </span> </template> <template #column-description="{ row }"> diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 450031a0e..7a737dd71 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -70,6 +70,18 @@ const columns = computed(() => [ { label: t('item.buyRequest.requester'), name: 'requesterName', + component: 'select', + columnFilter: { + name: 'requesterFk', + attrs: { + url: 'VnUsers', + optionValue: 'id', + optionLabel: 'nickname', + }, + }, + columnField: { + component: null, + }, columnClass: 'shrink', }, { @@ -88,6 +100,18 @@ const columns = computed(() => [ label: t('item.buyRequest.attender'), name: 'attenderName', align: 'left', + component: 'select', + columnFilter: { + name: 'attenderFk', + attrs: { + url: 'VnUsers', + optionValue: 'id', + optionLabel: 'nickname', + }, + }, + columnField: { + component: null, + }, columnClass: 'shrink', }, { From 965c2f7b20bce7ce702fddb758654b810d94e121 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 28 Oct 2024 13:16:51 +0100 Subject: [PATCH 109/207] fix: refs #7283 preview --- src/pages/Item/ItemList.vue | 2 +- src/pages/Item/ItemRequest.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index c9422a0fe..a6873d10c 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -215,7 +215,7 @@ const columns = computed(() => [ columnFilter: { name: 'workerFk', attrs: { - url: 'VnUsers', + url: 'VnUsers/preview', optionValue: 'id', optionLabel: 'nickname', }, diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 7a737dd71..4122b0c12 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -104,7 +104,7 @@ const columns = computed(() => [ columnFilter: { name: 'attenderFk', attrs: { - url: 'VnUsers', + url: 'VnUsers/preview', optionValue: 'id', optionLabel: 'nickname', }, From d252f6d2a3deb600cc0290a5892c26b614decc76 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 28 Oct 2024 13:22:33 +0100 Subject: [PATCH 110/207] fix: refs #7283 fix preview --- src/pages/Item/ItemRequest.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 4122b0c12..36da0368b 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -74,7 +74,7 @@ const columns = computed(() => [ columnFilter: { name: 'requesterFk', attrs: { - url: 'VnUsers', + url: 'VnUsers/preview', optionValue: 'id', optionLabel: 'nickname', }, From a1105f2ef19b15eb3cc54891b737d4495b20b8a9 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 13:24:46 +0100 Subject: [PATCH 111/207] feat: refs #7524 add front test --- .../pages/Tickets/TicketAdvance.spec.js | 116 ++++++++++++++++++ test/vitest/helper.js | 2 + 2 files changed, 118 insertions(+) create mode 100644 test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js diff --git a/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js b/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js new file mode 100644 index 000000000..6fae2788e --- /dev/null +++ b/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js @@ -0,0 +1,116 @@ +import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import TicketAdvance from 'pages/Ticket/TicketAdvance.vue'; +import { Notify } from 'quasar'; + +describe('TicketAdvance', () => { + let wrapper; + let vm; + + beforeAll(() => { + vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] })); + wrapper = createWrapper(TicketAdvance); + vm = wrapper.vm; + // vm.vnTableRef.value = { reload: vi.fn(), params: {} }; + }); + beforeEach(() => { + Notify.create = vi.fn(); + }); + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('requestComponentUpdate()', () => { + const mockTicket = { + futureId: 1, + futureClientFk: 1, + nickname: 'test', + futureAddressFk: 1, + futureAgencyModeFk: 1, + futureWarehouseFk: 1, + futureCompanyFk: 1, + landed: '2023-01-01', + zoneFk: 1, + }; + const mockParams = { + clientFk: 1, + nickname: 'test', + agencyModeFk: 1, + addressFk: 1, + zoneFk: 1, + warehouseFk: 1, + companyFk: 1, + landed: '2023-01-01', + isDeleted: false, + isWithoutNegatives: false, + newTicket: undefined, + keepPrice: true, + }; + const queryResult = 'tickets/1/componentUpdate'; + + it('should return query and params when ticket has no landed', async () => { + const mockLanded = { landed: '2023-01-01', zoneFk: 1 }; + vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded); + + const { query, params } = await vm.requestComponentUpdate(mockTicket, false); + + expect(query).toBe(queryResult); + expect(params).toEqual(mockParams); + }); + + it('should return query and params when ticket has landed', async () => { + const { query, params } = await vm.requestComponentUpdate(mockTicket, false); + + expect(query).toBe(queryResult); + expect(params).toEqual(mockParams); + }); + }); + + describe('moveTicketsAdvance()', () => { + it('should move tickets and notify success', async () => { + const tickets = [ + { + id: 1, + futureId: 2, + futureShipped: '2023-01-01', + shipped: '2023-01-02', + workerFk: 1, + }, + { + id: 2, + futureId: 3, + futureShipped: '2023-01-01', + shipped: '2023-01-02', + workerFk: 1, + }, + ]; + vm.selectedTickets.value = tickets; + vi.spyOn(axios, 'post').mockResolvedValue({}); + await vm.moveTicketsAdvance(); + + expect(axios.post).toHaveBeenCalledOnce('Tickets/merge', { + tickets: [ + { + originId: 2, + destinationId: 1, + originShipped: '2023-01-01', + destinationShipped: '2023-01-02', + workerFk: 1, + }, + { + originId: 3, + destinationId: 2, + originShipped: '2023-01-01', + destinationShipped: '2023-01-02', + workerFk: 1, + }, + ], + }); + expect(Notify.create).toHaveBeenCalledWith({ + type: 'positive', + message: 'advanceTickets.moveTicketSuccess', + }); + expect(vm.selectedTickets).toEqual([]); + }); + }); +}); diff --git a/test/vitest/helper.js b/test/vitest/helper.js index e201535ec..4bfae5dc8 100644 --- a/test/vitest/helper.js +++ b/test/vitest/helper.js @@ -70,8 +70,10 @@ class FormDataMock { vi.fn(); } } + global.FormData = FormDataMock; global.URL = class URL {}; +global.Date.vnNew = () => new Date(Date.UTC(2001, 0, 1, 11)); export function createWrapper(component, options) { const defaultOptions = { From 15977357d9c4c3e76d79cd5798ee78a222e367ff Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Mon, 28 Oct 2024 14:11:34 +0100 Subject: [PATCH 112/207] refactor: refs #7266 Changed method name --- src/pages/Entry/EntryBuysTableDialog.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Entry/EntryBuysTableDialog.vue b/src/pages/Entry/EntryBuysTableDialog.vue index 0f9be6298..23a6a0021 100644 --- a/src/pages/Entry/EntryBuysTableDialog.vue +++ b/src/pages/Entry/EntryBuysTableDialog.vue @@ -121,7 +121,7 @@ const entriesTableColumns = computed(() => [ :loading="isLoading" @click=" openReport( - `Entries/${props.row.id}/buy-label` + `Entries/${props.row.id}/buy-label-supplier` ) " unelevated From 934b32092bb27eebcbbd298674bb5e5f7e832515 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 14:21:03 +0100 Subject: [PATCH 113/207] chore: refs #7524 fix test --- .../pages/Tickets/TicketAdvance.spec.js | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js b/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js index 6fae2788e..ab1a47544 100644 --- a/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js +++ b/test/vitest/__tests__/pages/Tickets/TicketAdvance.spec.js @@ -2,6 +2,7 @@ import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vite import { createWrapper, axios } from 'app/test/vitest/helper'; import TicketAdvance from 'pages/Ticket/TicketAdvance.vue'; import { Notify } from 'quasar'; +import { nextTick } from 'vue'; describe('TicketAdvance', () => { let wrapper; @@ -11,7 +12,8 @@ describe('TicketAdvance', () => { vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] })); wrapper = createWrapper(TicketAdvance); vm = wrapper.vm; - // vm.vnTableRef.value = { reload: vi.fn(), params: {} }; + vi.spyOn(vm.vnTableRef, 'reload').mockImplementation(() => vi.fn()); + vm.vnTableRef.value = { params: {} }; }); beforeEach(() => { Notify.create = vi.fn(); @@ -29,7 +31,7 @@ describe('TicketAdvance', () => { futureAgencyModeFk: 1, futureWarehouseFk: 1, futureCompanyFk: 1, - landed: '2023-01-01', + landed: '2023-01-02', zoneFk: 1, }; const mockParams = { @@ -40,7 +42,8 @@ describe('TicketAdvance', () => { zoneFk: 1, warehouseFk: 1, companyFk: 1, - landed: '2023-01-01', + landed: '2023-01-02', + shipped: '2023-01-01', isDeleted: false, isWithoutNegatives: false, newTicket: undefined, @@ -49,7 +52,10 @@ describe('TicketAdvance', () => { const queryResult = 'tickets/1/componentUpdate'; it('should return query and params when ticket has no landed', async () => { - const mockLanded = { landed: '2023-01-01', zoneFk: 1 }; + vm.vnTableRef.params.dateToAdvance = '2023-01-01'; + await nextTick(); + + const mockLanded = { landed: '2023-01-02', zoneFk: 1 }; vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded); const { query, params } = await vm.requestComponentUpdate(mockTicket, false); @@ -84,7 +90,7 @@ describe('TicketAdvance', () => { workerFk: 1, }, ]; - vm.selectedTickets.value = tickets; + vm.selectedTickets = tickets; vi.spyOn(axios, 'post').mockResolvedValue({}); await vm.moveTicketsAdvance(); @@ -106,10 +112,8 @@ describe('TicketAdvance', () => { }, ], }); - expect(Notify.create).toHaveBeenCalledWith({ - type: 'positive', - message: 'advanceTickets.moveTicketSuccess', - }); + expect(vm.vnTableRef.reload).toHaveBeenCalled(); + expect(Notify.create).toHaveBeenCalled(); expect(vm.selectedTickets).toEqual([]); }); }); From d5639471cf358c89c9dfb28b3f3b9eb11b2d4a23 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 15:40:36 +0100 Subject: [PATCH 114/207] feat: refs #8078 add tests --- .../__tests__/components/VnTable.spec.js | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/vitest/__tests__/components/VnTable.spec.js diff --git a/test/vitest/__tests__/components/VnTable.spec.js b/test/vitest/__tests__/components/VnTable.spec.js new file mode 100644 index 000000000..d11c2b6c3 --- /dev/null +++ b/test/vitest/__tests__/components/VnTable.spec.js @@ -0,0 +1,47 @@ +import { describe, expect, it, beforeAll, beforeEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import VnTable from 'src/components/VnTable/VnTable.vue'; + +describe('VnTable', () => { + let wrapper; + let vm; + + beforeAll(() => { + wrapper = createWrapper(VnTable, { + propsData: { + columns: [], + }, + }); + vm = wrapper.vm; + }); + + beforeEach(() => (vm.selected = [])); + + describe('handleSelection()', () => { + const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }]; + const selectedRows = [{ $index: 1 }]; + it('should add rows to selected when shift key is pressed and rows are added', () => { + vm.handleSelection( + { evt: { shiftKey: true }, added: true, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([{ $index: 0 }, { $index: 1 }]); + }); + + it('should not add rows to selected when shift key is not pressed', () => { + vm.handleSelection( + { evt: { shiftKey: false }, added: true, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([]); + }); + + it('should not add rows to selected when rows are not added', () => { + vm.handleSelection( + { evt: { shiftKey: true }, added: false, rows: selectedRows }, + rows + ); + expect(vm.selected).toEqual([]); + }); + }); +}); From 7e3e194b465f0ba3abfa4a57aa762f58f63d24c1 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 16:19:13 +0100 Subject: [PATCH 115/207] fix: refs #8078 e2e #7970 --- src/components/ui/VnConfirm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index ec9d0f48b..89726c891 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -31,9 +31,9 @@ const props = defineProps({ }); const emit = defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits]); - const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); +defineExpose({ dialogRef }); const title = props.title || t('Confirm'); const message = From 57488503aa1c9494586f6bf3c1b6b7860e7ccf6b Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 16:19:24 +0100 Subject: [PATCH 116/207] fix: refs #8078 e2e #7970 --- src/pages/Ticket/Card/TicketDescriptorMenu.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue index bf4a1efb4..8efd0f1e1 100644 --- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue +++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue @@ -659,7 +659,7 @@ async function uploadDocuware(force) { </QList> </QMenu> </QItem> - <QItem @click="$refs.weightDialog.show()" v-ripple clickable> + <QItem @click="$refs.weightDialog.dialogRef.show()" v-ripple clickable> <QItemSection avatar> <QIcon name="weight" /> </QItemSection> From 1e16e3312e3e22d0c6170195acd9c3e4670e5b5a Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 28 Oct 2024 16:21:00 +0100 Subject: [PATCH 117/207] fix: refs #8078 improve cy command --- src/components/ui/CardDescriptor.vue | 1 + test/cypress/integration/ticket/ticketDescriptor.spec.js | 4 ++++ test/cypress/support/commands.js | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue index 7f35f0a28..83af77442 100644 --- a/src/components/ui/CardDescriptor.vue +++ b/src/components/ui/CardDescriptor.vue @@ -167,6 +167,7 @@ const toModule = computed(() => icon="more_vert" round size="md" + data-cy="descriptor-more-opts" > <QTooltip> {{ t('components.cardDescriptor.moreOptions') }} diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js index 0ba2723a2..cd9f288f5 100644 --- a/test/cypress/integration/ticket/ticketDescriptor.spec.js +++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js @@ -14,6 +14,8 @@ describe('Ticket descriptor', () => { it('should clone the ticket without warehouse', () => { cy.visit('/#/ticket/1/summary'); + cy.intercept('GET', /\/api\/Tickets\/\d/).as('ticket'); + cy.wait('@ticket'); cy.openActionsDescriptor(); cy.contains(listItem, toCloneOpt).click(); cy.clickConfirm(); @@ -28,6 +30,8 @@ describe('Ticket descriptor', () => { it('should set the weight of the ticket', () => { cy.visit('/#/ticket/10/summary'); + cy.intercept('GET', /\/api\/Tickets\/\d/).as('ticket'); + cy.wait('@ticket'); cy.openActionsDescriptor(); cy.contains(listItem, setWeightOpt).click(); cy.intercept('POST', /\/api\/Tickets\/\d+\/setWeight/).as('weight'); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 76bdefd27..1e9ca93b5 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -261,7 +261,7 @@ Cypress.Commands.add('openActionDescriptor', (opt) => { }); Cypress.Commands.add('openActionsDescriptor', () => { - cy.get('.header > :nth-child(3) > .q-btn__content > .q-icon').click(); + cy.get('[data-cy="descriptor-more-opts"]').click(); }); Cypress.Commands.add('openUserPanel', () => { From 0de4dfd4f8bcf5f55a56a48c5a89fa8f702745e9 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 02:15:02 +0100 Subject: [PATCH 118/207] feat: apply changes for customerModule --- src/components/ui/VnLinkMail.vue | 16 +++ src/pages/Customer/Card/CustomerAddress.vue | 2 +- src/pages/Customer/Card/CustomerBalance.vue | 120 +++++++++++------- src/pages/Customer/Card/CustomerCredits.vue | 4 +- .../Customer/Card/CustomerDescriptor.vue | 38 +++++- .../Customer/Card/CustomerDescriptorMenu.vue | 28 ---- .../Customer/Card/CustomerFiscalData.vue | 7 +- src/pages/Customer/Card/CustomerGreuges.vue | 5 + .../Customer/Card/CustomerRecoveries.vue | 1 + src/pages/Customer/Card/CustomerSummary.vue | 26 +++- src/pages/Customer/CustomerList.vue | 6 +- .../components/CustomerAddressCreate.vue | 15 ++- .../components/CustomerNewPayment.vue | 10 +- .../components/CustomerSummaryTable.vue | 14 +- .../Customer/composables/getClientRisk.js | 12 ++ .../integration/client/clientList.spec.js | 19 ++- test/cypress/support/commands.js | 33 +++-- 17 files changed, 251 insertions(+), 105 deletions(-) create mode 100644 src/components/ui/VnLinkMail.vue create mode 100644 src/pages/Customer/composables/getClientRisk.js diff --git a/src/components/ui/VnLinkMail.vue b/src/components/ui/VnLinkMail.vue new file mode 100644 index 000000000..a54f463f5 --- /dev/null +++ b/src/components/ui/VnLinkMail.vue @@ -0,0 +1,16 @@ +<script setup> +defineProps({ email: { type: [String], default: null } }); +</script> +<template> + <QBtn + v-if="email" + flat + round + icon="email" + size="sm" + color="primary" + padding="none" + :href="`mailto:${email}`" + @click.stop + /> +</template> diff --git a/src/pages/Customer/Card/CustomerAddress.vue b/src/pages/Customer/Card/CustomerAddress.vue index 166c33e1a..294e49cc8 100644 --- a/src/pages/Customer/Card/CustomerAddress.vue +++ b/src/pages/Customer/Card/CustomerAddress.vue @@ -27,7 +27,7 @@ const addressFilter = { 'isLogifloraAllowed', 'postalCode', ], - order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'], + order: ['isDefaultAddress DESC', 'isActive DESC', 'id DESC', 'nickname ASC'], include: [ { relation: 'observations', diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue index f148194f8..f6fc3eed2 100644 --- a/src/pages/Customer/Card/CustomerBalance.vue +++ b/src/pages/Customer/Card/CustomerBalance.vue @@ -5,7 +5,7 @@ import { useRoute } from 'vue-router'; import { useAcl } from 'src/composables/useAcl'; import axios from 'axios'; import { useQuasar } from 'quasar'; -import FetchData from 'components/FetchData.vue'; +import { getClientRisk } from '../composables/getClientRisk'; import { toCurrency, toDate, toDateHourMin } from 'src/filters'; import { useState } from 'composables/useState'; @@ -16,7 +16,7 @@ import { useVnConfirm } from 'composables/useVnConfirm'; import VnTable from 'components/VnTable/VnTable.vue'; import VnInput from 'components/common/VnInput.vue'; import VnSubToolbar from 'components/ui/VnSubToolbar.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; +import VnFilter from 'components/VnTable/VnFilter.vue'; import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue'; import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; @@ -25,7 +25,7 @@ const { openConfirmationModal } = useVnConfirm(); const { sendEmail, openReport } = usePrintService(); const { t } = useI18n(); const { hasAny } = useAcl(); -const currentBalance = ref({}); + const quasar = useQuasar(); const route = useRoute(); const state = useState(); @@ -33,28 +33,53 @@ const stateStore = useStateStore(); const user = state.getUser(); const clientRisk = ref([]); -const companies = ref([]); const tableRef = ref(); -const companyId = ref(user.value.companyFk); +const companyId = ref(); +const companyUser = ref(user.value.companyFk); const balances = ref([]); const vnFilterRef = ref({}); const filter = computed(() => { return { clientId: route.params.id, - companyId: companyId.value ?? user.value.companyFk, + companyId: companyId.value ?? companyUser.value, }; }); +const companyFilterColumn = { + align: 'left', + name: 'companyId', + label: t('Company'), + component: 'select', + attrs: { + url: 'Companies', + optionLabel: 'code', + optionValue: 'id', + sortBy: 'code', + }, + columnFilter: { + event: { + remove: () => (companyId.value = null), + 'update:modelValue': (newCompanyFk) => { + if (!newCompanyFk) return; + vnFilterRef.value.addFilter(newCompanyFk); + companyUser.value = newCompanyFk; + }, + blur: () => !companyId.value && (companyId.value = companyUser.value), + }, + }, + visible: false, +}; + const columns = computed(() => [ { - align: 'right', + align: 'left', name: 'payed', label: t('Date'), format: ({ payed }) => toDate(payed), cardVisible: true, }, { - align: 'right', + align: 'left', name: 'created', label: t('Creation date'), format: ({ created }) => toDateHourMin(created), @@ -65,7 +90,12 @@ const columns = computed(() => [ label: t('Employee'), columnField: { component: 'userLink', - attrs: ({ row }) => ({ workerId: row.workerFk, name: row.userName }), + attrs: ({ row }) => { + return { + workerId: row.workerFk, + name: row.userName, + }; + }, }, cardVisible: true, }, @@ -77,13 +107,13 @@ const columns = computed(() => [ class: 'extend', }, { - align: 'right', + align: 'left', name: 'bankFk', label: t('Bank'), cardVisible: true, }, { - align: 'right', + align: 'left', name: 'debit', label: t('Debit'), format: ({ debit }) => debit && toCurrency(debit), @@ -136,20 +166,37 @@ const columns = computed(() => [ onBeforeMount(() => { stateStore.rightDrawer = true; + companyId.value = companyUser.value; }); -async function getCurrentBalance(data) { - currentBalance.value[companyId.value] = { - amount: 0, - code: companies.value.find((c) => c.id === companyId.value)?.code, +async function getClientRisks() { + const filter = { + where: { clientFk: route.params.id, companyFk: companyUser.value }, }; + const { data } = await getClientRisk(filter); + clientRisk.value = data; + return clientRisk.value; +} - for (const balance of data) { - currentBalance.value[balance.companyFk] = { - code: balance.company.code, - amount: balance.amount, - }; +async function getCurrentBalance() { + const currentBalance = (await getClientRisks()).find((balance) => { + return balance.companyFk === companyId.value; + }); + return currentBalance && currentBalance.amount; +} + +async function onFetch(data) { + balances.value = []; + for (const [index, balance] of data.entries()) { + if (index === 0) { + balance.balance = await getCurrentBalance(); + continue; + } + const previousBalance = data[index - 1]; + balance.balance = + previousBalance?.balance - (previousBalance?.debit - previousBalance?.credit); } + balances.value = data; } const showNewPaymentDialog = () => { @@ -169,43 +216,25 @@ const showBalancePdf = ({ id }) => { </script> <template> - <FetchData - url="Companies" - auto-load - @on-fetch="(data) => (companies = data)" - ></FetchData> - <FetchData - v-if="companies.length > 0" - url="clientRisks" - :filter="{ - include: { relation: 'company', scope: { fields: ['code'] } }, - where: { clientFk: route.params.id }, - }" - auto-load - @on-fetch="getCurrentBalance" - ></FetchData> - <VnSubToolbar class="q-mb-md"> <template #st-data> <div class="column justify-center q-px-md q-py-sm"> <span class="text-bold">{{ t('Total by company') }}</span> - <div class="row justify-center"> - {{ currentBalance[companyId]?.code }}: - {{ toCurrency(currentBalance[companyId]?.amount) }} + <div class="row justify-center" v-if="clientRisk?.length"> + {{ clientRisk[0].company.code }}: + {{ toCurrency(clientRisk[0].amount) }} </div> </div> </template> <template #st-actions> <div> - <VnSelect - :label="t('Company')" + <VnFilter ref="vnFilterRef" v-model="companyId" data-key="CustomerBalance" - :options="companies" - option-label="code" - option-value="id" - ></VnSelect> + :column="companyFilterColumn" + search-url="balance" + /> </div> </template> </VnSubToolbar> @@ -219,6 +248,7 @@ const showBalancePdf = ({ id }) => { :right-search="false" :is-editable="false" :column-search="false" + @on-fetch="onFetch" :disable-option="{ card: true }" auto-load > diff --git a/src/pages/Customer/Card/CustomerCredits.vue b/src/pages/Customer/Card/CustomerCredits.vue index 377d95412..1fa7047e5 100644 --- a/src/pages/Customer/Card/CustomerCredits.vue +++ b/src/pages/Customer/Card/CustomerCredits.vue @@ -49,7 +49,9 @@ const columns = computed(() => [ name: 'credit', create: true, visible: false, - attrs: { + columnCreate: { + component: 'number', + required: true, autofocus: true, }, }, diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue index 43103bd68..40166aefe 100644 --- a/src/pages/Customer/Card/CustomerDescriptor.vue +++ b/src/pages/Customer/Card/CustomerDescriptor.vue @@ -150,7 +150,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit </QCardActions> </template> <template #actions="{ entity }"> - <QCardActions class="flex justify-center"> + <QCardActions class="flex justify-center" style="padding-inline: 0"> <QBtn :to="{ name: 'TicketList', @@ -168,6 +168,23 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit > <QTooltip>{{ t('Customer ticket list') }}</QTooltip> </QBtn> + <QBtn + :to="{ + name: 'TicketList', + query: { + table: JSON.stringify({ + clientFk: entity.id, + }), + createForm: JSON.stringify({ clientId: entity.id }), + }, + }" + size="md" + color="primary" + target="_blank" + icon="vn:ticketAdd" + > + <QTooltip>{{ t('New ticket') }}</QTooltip> + </QBtn> <QBtn :to="{ name: 'InvoiceOutList', @@ -179,6 +196,23 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit > <QTooltip>{{ t('Customer invoice out list') }}</QTooltip> </QBtn> + <QBtn + :to="{ + name: 'OrderList', + query: { + table: JSON.stringify({ + clientFk: entity.id, + }), + createForm: JSON.stringify({ clientFk: entity.id }), + }, + }" + size="md" + target="_blank" + icon="vn:basketadd" + color="primary" + > + <QTooltip>{{ t('New order') }}</QTooltip> + </QBtn> <QBtn :to="{ name: 'AccountSummary', @@ -215,6 +249,8 @@ es: Go to module index: Ir al índice del módulo Customer ticket list: Listado de tickets del cliente Customer invoice out list: Listado de facturas del cliente + New order: Nuevo pedido + New ticket: Nuevo ticket Go to user: Ir al usuario Go to supplier: Ir al proveedor Customer unpaid: Cliente impago diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue index 89b10a4fe..a0fbc7f7b 100644 --- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue +++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue @@ -8,9 +8,6 @@ import { useQuasar } from 'quasar'; import useNotify from 'src/composables/useNotify'; import VnSmsDialog from 'src/components/common/VnSmsDialog.vue'; -import TicketCreateDialog from 'src/pages/Ticket/TicketCreateDialog.vue'; -import OrderCreateDialog from 'src/pages/Order/Card/OrderCreateDialog.vue'; -import { ref } from 'vue'; const $props = defineProps({ customer: { @@ -43,34 +40,9 @@ const sendSms = async (payload) => { notify(error.message, 'positive'); } }; - -const ticketCreateFormDialog = ref(null); -const openTicketCreateForm = () => { - ticketCreateFormDialog.value.show(); -}; -const orderCreateFormDialog = ref(null); -const openOrderCreateForm = () => { - orderCreateFormDialog.value.show(); -}; </script> <template> - <QItem v-ripple clickable @click="openTicketCreateForm()"> - <QItemSection> - {{ t('globals.pageTitles.createTicket') }} - <QDialog ref="ticketCreateFormDialog"> - <TicketCreateDialog /> - </QDialog> - </QItemSection> - </QItem> - <QItem v-ripple clickable @click="openOrderCreateForm()"> - <QItemSection> - {{ t('globals.pageTitles.createOrder') }} - <QDialog ref="orderCreateFormDialog"> - <OrderCreateDialog :client-fk="customer.id" /> - </QDialog> - </QItemSection> - </QItem> <QItem v-ripple clickable> <QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection> </QItem> diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue index 1f5775715..6c5086149 100644 --- a/src/pages/Customer/Card/CustomerFiscalData.vue +++ b/src/pages/Customer/Card/CustomerFiscalData.vue @@ -53,11 +53,11 @@ function handleLocation(data, location) { </QIcon> </template> </VnInput> - <VnInput :label="t('Tax number')" clearable v-model="data.fi" /> + <VnInput :label="t('Tax number')" clearable v-model="data.fi" required /> </VnRow> <VnRow> - <VnInput :label="t('Street')" clearable v-model="data.street" /> + <VnInput :label="t('Street')" clearable v-model="data.street" required /> </VnRow> <VnRow> @@ -68,6 +68,7 @@ function handleLocation(data, location) { option-label="vat" option-value="id" v-model="data.sageTaxTypeFk" + :required="data.isTaxDataChecked" /> <VnSelect :label="t('Sage transaction type')" @@ -76,6 +77,7 @@ function handleLocation(data, location) { option-label="transaction" option-value="id" v-model="data.sageTransactionTypeFk" + :required="data.isTaxDataChecked" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -96,6 +98,7 @@ function handleLocation(data, location) { :roles-allowed-to-create="['deliveryAssistant', 'administrative']" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]" :location="data" + :required="true" @update:model-value="(location) => handleLocation(data, location)" /> </VnRow> diff --git a/src/pages/Customer/Card/CustomerGreuges.vue b/src/pages/Customer/Card/CustomerGreuges.vue index 1d8b8585f..dcf297d12 100644 --- a/src/pages/Customer/Card/CustomerGreuges.vue +++ b/src/pages/Customer/Card/CustomerGreuges.vue @@ -80,6 +80,11 @@ const columns = computed(() => [ align: 'left', name: 'amount', label: t('Amount'), + columnCreate: { + component: 'number', + autofocus: true, + required: true, + }, format: ({ amount }) => toCurrency(amount), create: true, }, diff --git a/src/pages/Customer/Card/CustomerRecoveries.vue b/src/pages/Customer/Card/CustomerRecoveries.vue index 48576ca20..3a8cffff8 100644 --- a/src/pages/Customer/Card/CustomerRecoveries.vue +++ b/src/pages/Customer/Card/CustomerRecoveries.vue @@ -56,6 +56,7 @@ const columns = computed(() => [ label: t('Period'), create: true, ...componentColumn('number'), + required: true, }, { align: 'left', diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 8b5f0f2c2..8e41119ef 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -1,13 +1,15 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed, ref, onMounted } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import VnUserLink from 'src/components/ui/VnUserLink.vue'; import { toCurrency, toPercentage, toDate } from 'src/filters'; import CardSummary from 'components/ui/CardSummary.vue'; +import { getUrl } from 'src/composables/getUrl'; import VnLv from 'src/components/ui/VnLv.vue'; import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; +import VnLinkMail from 'src/components/ui/VnLinkMail.vue'; import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; import VnRow from 'src/components/ui/VnRow.vue'; @@ -25,6 +27,11 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const customer = computed(() => summary.value.entity); const summary = ref(); +const clientUrl = ref(); + +onMounted(async () => { + clientUrl.value = (await getUrl('client/')) + entityId.value + '/'; +}); const balanceDue = computed(() => { return ( @@ -67,6 +74,7 @@ const sumRisk = ({ clientRisks }) => { ref="summary" :url="`Clients/${entityId}/summary`" data-key="CustomerSummary" + module-name="Customer" > <template #body="{ entity }"> <QCard class="vn-one"> @@ -89,7 +97,11 @@ const sumRisk = ({ clientRisks }) => { <VnLinkPhone :phone-number="entity.mobile" /> </template> </VnLv> - <VnLv :label="t('customer.summary.email')" :value="entity.email" copy /> + <VnLv :value="entity.email" copy + ><template #label> + {{ t('customer.summary.email') }} + <VnLinkMail email="entity.email"></VnLinkMail> </template + ></VnLv> <VnLv :label="t('customer.summary.salesPerson')" :value="entity?.salesPersonUser?.name" @@ -166,7 +178,7 @@ const sumRisk = ({ clientRisks }) => { <QCard class="vn-one"> <VnTitle :url="`#/customer/${entityId}/billing-data`" - :text="t('customer.summary.payMethodFk')" + :text="t('customer.summary.billingData')" /> <VnLv :label="t('customer.summary.payMethod')" @@ -222,6 +234,7 @@ const sumRisk = ({ clientRisks }) => { </QCard> <QCard class="vn-one" v-if="entity.account"> <VnTitle + target="_blank" :url="`${grafanaUrl}/d/adjlxzv5yjt34d/analisis-de-clientes-7c-crm?orgId=1&var-clientFk=${entityId}`" :text="t('customer.summary.businessData')" icon="vn:grafana" @@ -235,6 +248,7 @@ const sumRisk = ({ clientRisks }) => { :value="toCurrency(entity?.mana?.mana)" /> <VnLv + v-if="entity.claimsRatio" :label="t('customer.summary.priceIncreasingRate')" :value="toPercentage(priceIncreasingRate)" /> @@ -243,12 +257,14 @@ const sumRisk = ({ clientRisks }) => { :value="toCurrency(entity?.averageInvoiced?.invoiced)" /> <VnLv + v-if="entity.claimsRatio" :label="t('customer.summary.claimRate')" :value="toPercentage(claimRate)" /> </QCard> <QCard class="vn-one" v-if="entity.account"> <VnTitle + target="_blank" :url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`" :text="t('customer.summary.payMethodFk')" icon="vn:grafana" @@ -268,10 +284,12 @@ const sumRisk = ({ clientRisks }) => { /> <VnLv + v-if="entity.creditInsurance" :label="t('customer.summary.securedCredit')" :value="toCurrency(entity.creditInsurance)" :info="t('customer.summary.securedCreditInfo')" /> + <VnLv :label="t('customer.summary.balance')" :value="toCurrency(sumRisk(entity)) || toCurrency(0)" @@ -301,7 +319,7 @@ const sumRisk = ({ clientRisks }) => { :value="entity.recommendedCredit" /> </QCard> - <QCard> + <QCard class="vn-one"> <VnTitle :text="t('Latest tickets')" /> <CustomerSummaryTable /> </QCard> diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue index 63f5149e8..815ec57fa 100644 --- a/src/pages/Customer/CustomerList.vue +++ b/src/pages/Customer/CustomerList.vue @@ -68,7 +68,6 @@ const columns = computed(() => [ fields: ['id', 'name'], where: { role: 'salesPerson' }, optionFilter: 'firstName', - useLike: false, }, create: false, columnField: { @@ -429,9 +428,10 @@ function handleLocation(data, location) { :params="{ departmentCodes: ['VT', 'shopping'], }" - :fields="['id', 'nickname']" + :fields="['id', 'nickname', 'code']" sort-by="nickname ASC" - :use-like="false" + option-label="nickname" + option-value="id" emit-value auto-load > diff --git a/src/pages/Customer/components/CustomerAddressCreate.vue b/src/pages/Customer/components/CustomerAddressCreate.vue index 659114744..e3fef8e5f 100644 --- a/src/pages/Customer/components/CustomerAddressCreate.vue +++ b/src/pages/Customer/components/CustomerAddressCreate.vue @@ -85,15 +85,26 @@ function handleLocation(data, location) { <QCheckbox :label="t('Default')" v-model="data.isDefaultAddress" /> <VnRow> - <VnInput :label="t('Consignee')" clearable v-model="data.nickname" /> + <VnInput + :label="t('Consignee')" + required + clearable + v-model="data.nickname" + /> - <VnInput :label="t('Street address')" clearable v-model="data.street" /> + <VnInput + :label="t('Street address')" + clearable + v-model="data.street" + required + /> </VnRow> <VnLocation :rules="validate('Worker.postcode')" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]" v-model="data.location" + :required="true" @update:model-value="(location) => handleLocation(data, location)" /> diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue index 16dd28767..291f28642 100644 --- a/src/pages/Customer/components/CustomerNewPayment.vue +++ b/src/pages/Customer/components/CustomerNewPayment.vue @@ -3,7 +3,7 @@ import { onBeforeMount, reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; - +import { getClientRisk } from '../composables/getClientRisk'; import { useDialogPluginComponent } from 'quasar'; import { usePrintService } from 'composables/usePrintService'; @@ -158,9 +158,7 @@ async function getAmountPaid() { }, }; - const { data } = await axios(`ClientRisks`, { - params: { filter: JSON.stringify(filter) }, - }); + const { data } = await getClientRisk(filter); initialData.amountPaid = (data?.length && data[0].amount) || undefined; } </script> @@ -241,7 +239,7 @@ async function getAmountPaid() { </QItem> </template> </VnSelect> - <VnInput + <VnInputNumber :label="t('Amount')" :required="true" @update:model-value="calculateFromAmount($event)" @@ -254,7 +252,7 @@ async function getAmountPaid() { {{ t('Compensation') }} </div> <VnRow> - <VnInput + <VnInputNumber :label="t('Compensation account')" clearable v-model="data.compensationAccount" diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue index e9bb36be7..745cbf29e 100644 --- a/src/pages/Customer/components/CustomerSummaryTable.vue +++ b/src/pages/Customer/components/CustomerSummaryTable.vue @@ -63,7 +63,7 @@ const columns = computed(() => [ }, { align: 'left', - format: (row) => row.agencyMode.name, + format: (row) => dashIfEmpty(row.agencyMode?.name), columnClass: 'expand', label: t('Agency'), }, @@ -111,7 +111,11 @@ const columns = computed(() => [ { title: t('customer.summary.goToLines'), icon: 'vn:lines', - action: ({ id }) => router.push({ params: { id }, name: 'TicketSale' }), + action: ({ id }) => + window.open( + router.resolve({ params: { id }, name: 'TicketSale' }).href, + '_blank' + ), isPrimary: true, }, { @@ -150,6 +154,8 @@ const setShippedColor = (date) => { if (difference == 0) return 'warning'; if (difference < 0) return 'success'; }; +const rowClick = ({ id }) => + window.open(router.resolve({ params: { id }, name: 'TicketSummary' }).href, '_blank'); const getItemPackagingType = (ticketSales) => { if (!ticketSales?.length) return '-'; @@ -177,13 +183,15 @@ const getItemPackagingType = (ticketSales) => { :column-search="false" url="Tickets" :columns="columns" - search-url="tickets" + append-params="false" :without-header="true" auto-load + :row-click="rowClick" order="shipped DESC, id" :disable-option="{ card: true, table: true }" class="full-width" :disable-infinite-scroll="true" + search-url="tickets" > <template #column-nickname="{ row }"> <span class="link"> diff --git a/src/pages/Customer/composables/getClientRisk.js b/src/pages/Customer/composables/getClientRisk.js new file mode 100644 index 000000000..ebaf545ee --- /dev/null +++ b/src/pages/Customer/composables/getClientRisk.js @@ -0,0 +1,12 @@ +import axios from 'axios'; + +export async function getClientRisk(_filter) { + const filter = { + ..._filter, + include: { relation: 'company', scope: { fields: ['code'] } }, + }; + + return await axios(`ClientRisks`, { + params: { filter: JSON.stringify(filter) }, + }); +} diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 22bca15ac..93e53b9f6 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -28,7 +28,7 @@ describe('Client list', () => { cy.get('.q-mt-lg > .q-btn--standard').click(); - cy.checkNotification('Data created'); + cy.checkNotification('created'); cy.url().should('include', '/summary'); }); it('Client list search client', () => { @@ -43,4 +43,21 @@ describe('Client list', () => { cy.url().should('include', `/customer/${id}/summary`); }); }); + + it('Client founded create ticket', () => { + const search = 'Jessica Jones'; + cy.searchByLabel('Name', search); + cy.clickButtonsDescriptor(2); + cy.waitForElement('#formModel'); + cy.waitForElement('.q-form'); + cy.checkValueForm(1, search); + }); + it('Client founded create order', () => { + const search = 'Jessica Jones'; + cy.searchByLabel('Name', search); + cy.clickButtonsDescriptor(4); + cy.waitForElement('#formModel'); + cy.waitForElement('.q-form'); + cy.checkValueForm(2, search); + }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 76bdefd27..6fea4559a 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -264,6 +264,12 @@ Cypress.Commands.add('openActionsDescriptor', () => { cy.get('.header > :nth-child(3) > .q-btn__content > .q-icon').click(); }); +Cypress.Commands.add('clickButtonsDescriptor', (id) => { + cy.get(`.actions > .q-card__actions> .q-btn:nth-child(${id})`) + .invoke('removeAttr', 'target') + .click(); +}); + Cypress.Commands.add('openUserPanel', () => { cy.get( '.column > .q-avatar > .q-avatar__content > .q-img > .q-img__container > .q-img__image' @@ -274,14 +280,25 @@ Cypress.Commands.add('openActions', (row) => { cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); }); -Cypress.Commands.add('checkNotification', (text) => { - cy.get('.q-notification') - .should('be.visible') - .last() - .then(($lastNotification) => { - if (!Cypress.$($lastNotification).text().includes(text)) - throw new Error(`Notification not found: "${text}"`); - }); +Cypress.Commands.add('checkNotification', (type) => { + const values = { + created: 'Data created', + updated: 'Data saved', + deleted: 'Data deleted', + }; + cy.get('.q-notification__message').should('have.text', values[type]); +}); + +Cypress.Commands.add('checkValueForm', (id, search) => { + cy.get( + `.grid-create > :nth-child(${id}) > .q-field__inner>.q-field__control> .q-field__control-container>.q-field__native >.q-field__input` + ).should('have.value', search); +}); + +Cypress.Commands.add('checkValueSelectForm', (id, search) => { + cy.get( + `.grid-create > :nth-child(${id}) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container>.q-field__native>.q-field__input` + ).should('have.value', search); }); Cypress.Commands.add('searchByLabel', (label, value) => { From 0b2c404ab336d4e0b663b4cdc41b3fb0b772b7a8 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 02:15:21 +0100 Subject: [PATCH 119/207] perf: minor bugs detected --- src/components/VnTable/VnTable.vue | 4 ++++ src/components/common/VnTitle.vue | 2 +- src/components/ui/CardSummary.vue | 20 +++----------------- src/composables/useArrayData.js | 7 ++++--- src/filters/index.js | 2 ++ src/filters/isDialogOpened.js | 3 +++ 6 files changed, 17 insertions(+), 21 deletions(-) create mode 100644 src/filters/isDialogOpened.js diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index c1680bf13..cdf450966 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -73,6 +73,10 @@ const $props = defineProps({ type: Boolean, default: false, }, + appendParams: { + type: Boolean, + default: true, + }, hasSubToolbar: { type: Boolean, default: null, diff --git a/src/components/common/VnTitle.vue b/src/components/common/VnTitle.vue index 1fbd43972..89dd8cd0c 100644 --- a/src/components/common/VnTitle.vue +++ b/src/components/common/VnTitle.vue @@ -8,7 +8,7 @@ defineProps({ <template> <div :class="$q.screen.gt.md ? 'q-pb-lg' : 'q-pb-md'"> <div class="header-link" :style="{ cursor: url ? 'pointer' : 'default' }"> - <a :href="url" :class="url ? 'link' : 'color-vn-text'"> + <a :href="url" :class="url ? 'link' : 'color-vn-text'" v-bind="$attrs"> {{ text }} <QIcon v-if="url" :name="icon" /> </a> diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue index 11dcbee3b..f469aa799 100644 --- a/src/components/ui/CardSummary.vue +++ b/src/components/ui/CardSummary.vue @@ -4,6 +4,7 @@ import { useRoute } from 'vue-router'; import SkeletonSummary from 'components/ui/SkeletonSummary.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import { useArrayData } from 'src/composables/useArrayData'; +import { isDialogOpened } from 'src/filters'; const props = defineProps({ url: { @@ -58,22 +59,6 @@ async function fetch() { emit('onFetch', Array.isArray(data) ? data[0] : data); isLoading.value = false; } - -const showRedirectToSummaryIcon = computed(() => { - const exist = existSummary(route.matched); - return !isSummary.value && route.meta.moduleName && exist; -}); - -function existSummary(routes) { - const hasSummary = routes.some((r) => r.name === `${route.meta.moduleName}Summary`); - if (hasSummary) return hasSummary; - for (const current of routes) { - if (current.path != '/' && current.children) { - const exist = existSummary(current.children); - if (exist) return exist; - } - } -} </script> <template> @@ -84,7 +69,7 @@ function existSummary(routes) { <div class="summaryHeader bg-primary q-pa-sm text-weight-bolder"> <slot name="header-left"> <router-link - v-if="showRedirectToSummaryIcon" + v-if="isDialogOpened()" class="header link" :to="{ name: `${moduleName ?? route.meta.moduleName}Summary`, @@ -118,6 +103,7 @@ function existSummary(routes) { .cardSummary { width: 100%; + max-height: 70vh; .summaryHeader { text-align: center; font-size: 20px; diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index a2eaa649a..0a060e4c6 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -3,6 +3,7 @@ import { useRouter, useRoute } from 'vue-router'; import axios from 'axios'; import { useArrayDataStore } from 'stores/useArrayDataStore'; import { buildFilter } from 'filters/filterPanel'; +import { isDialogOpened } from 'src/filters'; const arrayDataStore = useArrayDataStore(); @@ -114,8 +115,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { for (const row of response.data) store.data.push(row); } else { store.data = response.data; - if (!document.querySelectorAll('[role="dialog"][aria-modal="true"]').length) - updateRouter && updateStateParams(); + if (!isDialogOpened()) updateRouter && updateStateParams(); } store.isLoading = false; @@ -249,7 +249,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { function updateStateParams() { if (!route) return; const newUrl = { path: route.path, query: { ...(route.query ?? {}) } }; - newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter); + if (store.appendParams) + newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter); if (store.navigate) { const { customRouteRedirectName, searchText } = store.navigate; diff --git a/src/filters/index.js b/src/filters/index.js index 5f08f19c7..ce5c44706 100644 --- a/src/filters/index.js +++ b/src/filters/index.js @@ -12,8 +12,10 @@ import dateRange from './dateRange'; import toHour from './toHour'; import dashOrCurrency from './dashOrCurrency'; import getParamWhere from './getParamWhere'; +import isDialogOpened from './isDialogOpened'; export { + isDialogOpened, toLowerCase, toLowerCamel, toDate, diff --git a/src/filters/isDialogOpened.js b/src/filters/isDialogOpened.js new file mode 100644 index 000000000..9d6f3895e --- /dev/null +++ b/src/filters/isDialogOpened.js @@ -0,0 +1,3 @@ +export default function isDialogOpened(query = '[role="dialog"]') { + return document.querySelectorAll(query).length > 0; +} From 4b00ab877c9d1a8455e368087cd74dff85f1dab0 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 02:26:35 +0100 Subject: [PATCH 120/207] perf: use required instead :required="true" --- src/components/common/VnInput.vue | 10 +++++----- src/components/common/VnInputDate.vue | 9 +++++---- src/components/common/VnInputNumber.vue | 7 ++++++- src/components/common/VnInputTime.vue | 7 ++++--- src/components/common/VnLocation.vue | 14 ++++++++++++-- src/components/common/VnSelect.vue | 11 ++++++----- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 1246eedcd..4534ae4a0 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -2,6 +2,7 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useValidator } from 'src/composables/useValidator'; +import { useAttrs } from 'vue'; const emit = defineEmits([ 'update:modelValue', @@ -29,10 +30,11 @@ const $props = defineProps({ }, }); const { validations } = useValidator(); +const $attrs = useAttrs(); const { t } = useI18n(); -const requiredFieldRule = (val) => validations().required($attrs.required, val); - +const isRequired = computed(() => Object.keys($attrs).includes('required')); +const requiredFieldRule = (val) => validations().required(isRequired.value, val); const vnInputRef = ref(null); const value = computed({ get() { @@ -60,8 +62,6 @@ const focus = () => { defineExpose({ focus, }); -import { useAttrs } from 'vue'; -const $attrs = useAttrs(); const mixinRules = [ requiredFieldRule, @@ -85,7 +85,7 @@ const mixinRules = [ v-model="value" v-bind="{ ...$attrs, ...styleAttrs }" :type="$attrs.type" - :class="{ required: $attrs.required }" + :class="{ required: isRequired }" @keyup.enter="emit('keyup.enter')" :clearable="false" :rules="mixinRules" diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue index 1aa797ab7..87833f411 100644 --- a/src/components/common/VnInputDate.vue +++ b/src/components/common/VnInputDate.vue @@ -6,6 +6,8 @@ import { useAttrs } from 'vue'; import VnDate from './VnDate.vue'; const model = defineModel({ type: [String, Date] }); +const $attrs = useAttrs(); +const { t } = useI18n(); const $props = defineProps({ isOutlined: { type: Boolean, @@ -19,15 +21,14 @@ const $props = defineProps({ import { useValidator } from 'src/composables/useValidator'; const { validations } = useValidator(); -const { t } = useI18n(); -const requiredFieldRule = (val) => validations().required($attrs.required, val); +const isRequired = computed(() => Object.keys($attrs).includes('required')); +const requiredFieldRule = (val) => validations().required(isRequired.value, val); const vnInputDateRef = ref(null); const dateFormat = 'DD/MM/YYYY'; const isPopupOpen = ref(); const hover = ref(); const mask = ref(); -const $attrs = useAttrs(); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; @@ -104,7 +105,7 @@ const manageDate = (date) => { :mask="mask" placeholder="dd/mm/aaaa" v-bind="{ ...$attrs, ...styleAttrs }" - :class="{ required: $attrs.required }" + :class="{ required: isRequired }" :rules="mixinRules" :clearable="false" @click="isPopupOpen = true" diff --git a/src/components/common/VnInputNumber.vue b/src/components/common/VnInputNumber.vue index ef4bb7512..1cad6c245 100644 --- a/src/components/common/VnInputNumber.vue +++ b/src/components/common/VnInputNumber.vue @@ -1,8 +1,13 @@ <script setup> import VnInput from 'src/components/common/VnInput.vue'; +import { ref } from 'vue'; +import { useAttrs } from 'vue'; + const model = defineModel({ type: [Number, String] }); +const $attrs = useAttrs(); +const step = ref($attrs.step || 0.01); </script> <template> - <VnInput v-bind="$attrs" v-model.number="model" type="number" /> + <VnInput v-bind="$attrs" v-model.number="model" type="number" :step="step" /> </template> diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue index 6d69bc4a5..13e90e021 100644 --- a/src/components/common/VnInputTime.vue +++ b/src/components/common/VnInputTime.vue @@ -6,6 +6,7 @@ import { useValidator } from 'src/composables/useValidator'; import VnTime from './VnTime.vue'; const { validations } = useValidator(); +const { t } = useI18n(); const $attrs = useAttrs(); const model = defineModel({ type: String }); const props = defineProps({ @@ -20,8 +21,8 @@ const props = defineProps({ }); const vnInputTimeRef = ref(null); const initialDate = ref(model.value ?? Date.vnNew()); -const { t } = useI18n(); -const requiredFieldRule = (val) => validations().required($attrs.required, val); +const isRequired = computed(() => Object.keys($attrs).includes('required')); +const requiredFieldRule = (val) => validations().required(isRequired.value, val); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; const dateFormat = 'HH:mm'; const isPopupOpen = ref(); @@ -78,7 +79,7 @@ function dateToTime(newDate) { placeholder="--:--" v-model="formattedTime" v-bind="{ ...$attrs, ...styleAttrs }" - :class="{ required: $attrs.required }" + :class="{ required: isRequired }" style="min-width: 100px" :rules="mixinRules" @click="isPopupOpen = false" diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index 5f94c466a..7c6e46fdd 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -2,10 +2,14 @@ import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue'; import { useI18n } from 'vue-i18n'; -import { ref } from 'vue'; +import { computed, ref } from 'vue'; const { t } = useI18n(); const emit = defineEmits(['update:model-value', 'update:options']); +const { validations } = useValidator(); +import { useAttrs } from 'vue'; +import { useValidator } from 'src/composables/useValidator'; +const $attrs = useAttrs(); const props = defineProps({ location: { type: Object, @@ -13,6 +17,10 @@ const props = defineProps({ }, }); +const isRequired = computed(() => Object.keys($attrs).includes('required')); +const requiredFieldRule = (val) => validations().required(isRequired.value, val); + +const mixinRules = [requiredFieldRule]; const locationProperties = [ 'postcode', (obj) => @@ -69,11 +77,13 @@ const handleModelValue = (data) => { :label="t('Location')" :placeholder="t('search_by_postalcode')" :input-debounce="300" - :class="{ required: $attrs.required }" + :class="{ required: isRequired }" v-bind="$attrs" clearable :emit-value="false" :tooltip="t('Create new location')" + :rules="mixinRules" + :lazy-rules="true" > <template #form> <CreateNewPostcode diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index b0aa648c1..4a4730784 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -4,7 +4,8 @@ import { useI18n } from 'vue-i18n'; import FetchData from 'src/components/FetchData.vue'; import { useValidator } from 'src/composables/useValidator'; const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); - +const $attrs = useAttrs(); +const { t } = useI18n(); const $props = defineProps({ modelValue: { type: [String, Number, Object], @@ -88,9 +89,9 @@ const $props = defineProps({ }, }); const { validations } = useValidator(); -const requiredFieldRule = (val) => validations().required($attrs.required, val); -const $attrs = useAttrs(); -const { t } = useI18n(); + +const isRequired = computed(() => Object.keys($attrs).includes('required')); +const requiredFieldRule = (val) => validations().required(isRequired.value, val); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; const { optionLabel, optionValue, optionFilter, optionFilterValue, options, modelValue } = toRefs($props); @@ -257,7 +258,7 @@ defineExpose({ opts: myOptions }); :fill-input="nullishToTrue($attrs['fill-input'])" ref="vnSelectRef" lazy-rules - :class="{ required: $attrs.required }" + :class="{ required: isRequired }" :rules="mixinRules" virtual-scroll-slice-size="options.length" hide-bottom-space From d2680b0a1fcccef8b3b5daa9a2ee6b12ddacad34 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 02:38:44 +0100 Subject: [PATCH 121/207] test: fix arrayData --- src/composables/useArrayData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 0a060e4c6..e33cb8b78 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -249,7 +249,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { function updateStateParams() { if (!route) return; const newUrl = { path: route.path, query: { ...(route.query ?? {}) } }; - if (store.appendParams) + if (store?.appendParams ?? true) newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter); if (store.navigate) { From 96f894cc6c6b9be2dc235323a0a874a86b548eb3 Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Tue, 29 Oct 2024 08:17:18 +0100 Subject: [PATCH 122/207] fix: refs #7283 filter --- src/pages/Item/ItemList.vue | 2 +- src/pages/Item/ItemRequest.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index a6873d10c..a480cfff6 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -215,7 +215,7 @@ const columns = computed(() => [ columnFilter: { name: 'workerFk', attrs: { - url: 'VnUsers/preview', + url: 'TicketRequests/getItemTypeWorker', optionValue: 'id', optionLabel: 'nickname', }, diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue index 36da0368b..61156640e 100644 --- a/src/pages/Item/ItemRequest.vue +++ b/src/pages/Item/ItemRequest.vue @@ -104,7 +104,7 @@ const columns = computed(() => [ columnFilter: { name: 'attenderFk', attrs: { - url: 'VnUsers/preview', + url: 'TicketRequests/getItemTypeWorker', optionValue: 'id', optionLabel: 'nickname', }, From 42fbdff5bd2e4d4e00d4514b35b861440e032ac1 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 29 Oct 2024 08:48:06 +0100 Subject: [PATCH 123/207] test: fix e2e --- src/components/ui/VnConfirm.vue | 1 + test/cypress/integration/outLogin/logout.spec.js | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index ec9d0f48b..0abfc84bc 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -34,6 +34,7 @@ const emit = defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); +defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() }); const title = props.title || t('Confirm'); const message = diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/outLogin/logout.spec.js index 8d4e90aac..d6c33a65b 100644 --- a/test/cypress/integration/outLogin/logout.spec.js +++ b/test/cypress/integration/outLogin/logout.spec.js @@ -13,7 +13,7 @@ describe('Logout', () => { }); describe('not user', () => { beforeEach(() => { - cy.intercept('GET', '**DefaultViewConfigs**', { + cy.intercept('GET', '**StarredModules**', { statusCode: 401, body: { error: { @@ -29,10 +29,7 @@ describe('Logout', () => { it('when token not exists', () => { cy.get('.q-list > [href="#/item"]').click(); - cy.get('.q-notification__message').should( - 'have.text', - 'Authorization Required' - ); + cy.checkNotification('Authorization Required'); }); }); }); From 5663064dd8ca211f328e96e0bba902685cec0f9a Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Tue, 29 Oct 2024 09:23:49 +0100 Subject: [PATCH 124/207] refactor: modified composable --- src/pages/Order/Card/OrderLines.vue | 7 +++++-- src/pages/Order/Card/OrderSummary.vue | 9 +++++++-- src/pages/Order/composables/confirmOrder.js | 21 ++------------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue index 90586dc15..58c5c9551 100644 --- a/src/pages/Order/Card/OrderLines.vue +++ b/src/pages/Order/Card/OrderLines.vue @@ -6,7 +6,7 @@ import { useQuasar } from 'quasar'; import axios from 'axios'; import { useStateStore } from 'stores/useStateStore'; import { useArrayData } from 'composables/useArrayData'; -import { confirmOrder } from 'composables/confirmOrder'; +import { confirm } from 'src/pages/Order/composables/confirmOrder'; import { toCurrency, toDate } from 'src/filters'; import VnConfirm from 'components/ui/VnConfirm.vue'; @@ -32,7 +32,6 @@ const orderSummary = ref({ }); const getTotalRef = ref(); const getVATRef = ref(); -const { confirm } = confirmOrder(); const lineFilter = ref({ include: [ { @@ -208,6 +207,10 @@ async function remove(item) { async function handleConfirm() { const result = await confirm(route.params.id); if (result) { + quasar.notify({ + message: t('globals.dataSaved'), + type: 'positive', + }); router.push({ name: 'TicketList', query: { diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index 3669fe8d8..032af1993 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -2,9 +2,10 @@ import { computed, ref } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; +import { useQuasar } from 'quasar'; import { dashIfEmpty, toCurrency, toDateHourMinSec } from 'src/filters'; import { useArrayData } from 'composables/useArrayData'; -import { confirmOrder } from 'composables/confirmOrder'; +import { confirm } from 'src/pages/Order/composables/confirmOrder'; import VnLv from 'components/ui/VnLv.vue'; import CardSummary from 'components/ui/CardSummary.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -24,8 +25,8 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const summary = ref(); +const quasar = useQuasar(); const descriptorData = useArrayData('orderData'); -const { confirm } = confirmOrder(); const detailsColumns = ref([ { name: 'item', @@ -58,6 +59,10 @@ const detailsColumns = ref([ async function handleConfirm() { const result = await confirm(route.params.id); if (result) { + quasar.notify({ + message: t('globals.dataSaved'), + type: 'positive', + }); summary.value.fetch({}); descriptorData.fetch({}); } diff --git a/src/pages/Order/composables/confirmOrder.js b/src/pages/Order/composables/confirmOrder.js index 33e05a1d7..b9eb5d7ac 100644 --- a/src/pages/Order/composables/confirmOrder.js +++ b/src/pages/Order/composables/confirmOrder.js @@ -1,22 +1,5 @@ import axios from 'axios'; -import { useQuasar } from 'quasar'; -import { useI18n } from 'vue-i18n'; -export function confirmOrder() { - const quasar = useQuasar(); - const { t } = useI18n(); - - async function confirm(route) { - const { data } = await axios.post(`Orders/${route}/confirm`); - if (data) { - quasar.notify({ - message: t('globals.confirm'), - type: 'positive', - }); - return data; - } - return null; - } - - return { confirm }; +export async function confirm(routeId) { + return await axios.post(`Orders/${routeId}/confirm`); } From 77cb2d84be6cb11f02effc49371a0ac70e580df2 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 29 Oct 2024 09:38:40 +0100 Subject: [PATCH 125/207] fix: refs #8078 handleSelection --- src/components/VnTable/VnTable.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 74a96e0e3..a15ba2f47 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -335,8 +335,9 @@ function handleScroll() { function handleSelection({ evt, added, rows: selectedRows }, rows) { if (evt?.shiftKey && added) { const rowIndex = selectedRows[0].$index; + selected.value.length = 0; for (const row of rows) { - if (row.$index > rowIndex) break; + if (row.$index == rowIndex) break; selected.value.push(row); } } @@ -440,7 +441,6 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) { :virtual-scroll="isTableMode" @virtual-scroll="handleScroll" @row-click="(_, row) => rowClickFunction && rowClickFunction(row)" - @update:selected="emit('update:selected', $event)" @selection="(details) => handleSelection(details, rows)" > <template #top-left v-if="!$props.withoutHeader"> From 19a7e526059a6b41cd7fb5902f0502aed294b4bd Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 29 Oct 2024 09:39:56 +0100 Subject: [PATCH 126/207] fix: refs #8078 handleSelection --- src/components/VnTable/VnTable.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index a15ba2f47..1e949120f 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -441,6 +441,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) { :virtual-scroll="isTableMode" @virtual-scroll="handleScroll" @row-click="(_, row) => rowClickFunction && rowClickFunction(row)" + @update:selected="emit('update:selected', $event)" @selection="(details) => handleSelection(details, rows)" > <template #top-left v-if="!$props.withoutHeader"> From e39f85ff4bcd45993a65fba6b01a9ef1aac30df8 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 29 Oct 2024 09:56:06 +0100 Subject: [PATCH 127/207] fix: refs #8078 improve handleSelection --- src/components/VnTable/VnTable.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 1e949120f..dc8671369 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -335,10 +335,13 @@ function handleScroll() { function handleSelection({ evt, added, rows: selectedRows }, rows) { if (evt?.shiftKey && added) { const rowIndex = selectedRows[0].$index; - selected.value.length = 0; + const selectedIndexes = new Set(selected.value.map((row) => row.$index)); for (const row of rows) { if (row.$index == rowIndex) break; - selected.value.push(row); + if (!selectedIndexes.has(row.$index)) { + selected.value.push(row); + selectedIndexes.add(row.$index); + } } } } From 476ef1dedd7907586b27d80433427f2faf6fefe4 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Tue, 29 Oct 2024 13:14:42 +0100 Subject: [PATCH 128/207] feat: refs #7206 added inactive label and corrected minor errors --- src/components/ui/VnConfirm.vue | 1 + .../components/CustomerSummaryTable.vue | 2 +- src/pages/Order/Card/OrderCreateDialog.vue | 1 - src/pages/Order/OrderList.vue | 32 ++++++++++++++++--- src/pages/Ticket/Card/TicketSummary.vue | 5 --- src/pages/Ticket/TicketList.vue | 29 +++++++++++------ 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index ec9d0f48b..d6b1ac0a3 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -31,6 +31,7 @@ const props = defineProps({ }); const emit = defineEmits(['confirm', 'cancel', ...useDialogPluginComponent.emits]); +defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() }); const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue index e9bb36be7..e9e30506b 100644 --- a/src/pages/Customer/components/CustomerSummaryTable.vue +++ b/src/pages/Customer/components/CustomerSummaryTable.vue @@ -63,7 +63,7 @@ const columns = computed(() => [ }, { align: 'left', - format: (row) => row.agencyMode.name, + format: (row, dashIfEmpty) => dashIfEmpty(row.agencyMode?.name), columnClass: 'expand', label: t('Agency'), }, diff --git a/src/pages/Order/Card/OrderCreateDialog.vue b/src/pages/Order/Card/OrderCreateDialog.vue index bcc62aa43..1239d195b 100644 --- a/src/pages/Order/Card/OrderCreateDialog.vue +++ b/src/pages/Order/Card/OrderCreateDialog.vue @@ -10,7 +10,6 @@ import VnSelect from 'components/common/VnSelect.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import { useDialogPluginComponent } from 'quasar'; import { reactive } from 'vue'; -import FetchData from 'components/FetchData.vue'; const { t } = useI18n(); const state = useState(); diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue index 6b6b41828..e01790c6b 100644 --- a/src/pages/Order/OrderList.vue +++ b/src/pages/Order/OrderList.vue @@ -233,7 +233,20 @@ onMounted(() => { v-model="data.clientFk" :label="t('module.customer')" @update:model-value="(id) => fetchClientAddress(id, data)" - /> + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt.name }} + </QItemLabel> + <QItemLabel caption> + {{ `#${scope.opt.id}` }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> <VnSelect v-model="data.addressId" :options="addressesList" @@ -245,10 +258,21 @@ onMounted(() => { <template #option="scope"> <QItem v-bind="scope.itemProps"> <QItemSection> - <QItemLabel> - {{ scope.opt?.nickname }}: {{ scope.opt?.street }}, - {{ scope.opt?.city }}</QItemLabel + <QItemLabel + :class="{ + 'color-vn-label': !scope.opt?.isActive, + }" > + {{ + `${ + !scope.opt?.isActive + ? t('basicData.inactive') + : '' + } ` + }} + {{ scope.opt?.nickname }}: {{ scope.opt?.street }}, + {{ scope.opt?.city }} + </QItemLabel> </QItemSection> </QItem> </template> diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index 5fb99b849..61751357c 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -19,7 +19,6 @@ import VnTitle from 'src/components/common/VnTitle.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; -import TicketDescriptorMenu from './TicketDescriptorMenu.vue'; import VnToSummary from 'src/components/ui/VnToSummary.vue'; const route = useRoute(); @@ -87,10 +86,6 @@ async function changeState(value) { function toTicketUrl(section) { return '#/ticket/' + entityId.value + '/' + section; } -function isOnTicketCard() { - const currentPath = route.path; - return currentPath.startsWith('/ticket'); -} </script> <template> diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index dd1f2d69a..4317efb83 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -268,8 +268,7 @@ const fetchAddresses = async (formData) => { if (!formData.clientId) return; const filter = { - fields: ['nickname', 'street', 'city', 'id'], - where: { isActive: true }, + fields: ['nickname', 'street', 'city', 'id', 'isActive'], order: 'nickname ASC', }; const params = { filter: JSON.stringify(filter) }; @@ -635,24 +634,36 @@ function setReference(data) { </VnRow> <VnRow> <VnSelect - url="Addresses" - :label="t('ticket.create.address')" + :label="t('basicData.address')" v-model="data.addressId" :options="addressesOptions" option-value="id" option-label="nickname" hide-selected + map-options :disable="!data.clientId" + :sort-by="'isActive DESC'" @update:model-value="() => fetchAvailableAgencies(data)" > <template #option="scope"> <QItem v-bind="scope.itemProps"> <QItemSection> - <QItemLabel> - {{ scope.opt.nickname }} - </QItemLabel> - <QItemLabel caption> - {{ `${scope.opt.street}, ${scope.opt.city}` }} + <QItemLabel + :class="{ + 'color-vn-label': !scope.opt?.isActive, + }" + > + {{ + `${ + !scope.opt?.isActive + ? t('basicData.inactive') + : '' + } ` + }} + <span> + {{ scope.opt?.nickname }}: + {{ scope.opt?.street }}, {{ scope.opt?.city }} + </span> </QItemLabel> </QItemSection> </QItem> From 282999c49e52e5e36369d82b28b5a55ba3469c3c Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Tue, 29 Oct 2024 13:23:15 +0100 Subject: [PATCH 129/207] fix: refs #7206 deleted duplicate code --- src/components/ui/VnConfirm.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index 081812093..d6b1ac0a3 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -35,7 +35,6 @@ defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.h const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent(); -defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() }); const title = props.title || t('Confirm'); const message = From bf4bee0f95145b04edf4710eacfba75b5fb2c3ac Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 29 Oct 2024 14:07:34 +0100 Subject: [PATCH 130/207] feat(VnSelect): refs #7136 add scroll --- src/components/common/VnSelect.vue | 50 ++++++++++++++++++--------- src/pages/Customer/CustomerFilter.vue | 3 +- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index b0aa648c1..5dc9fc74b 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -1,7 +1,7 @@ <script setup> import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue'; import { useI18n } from 'vue-i18n'; -import FetchData from 'src/components/FetchData.vue'; +import { useArrayData } from 'src/composables/useArrayData'; import { useValidator } from 'src/composables/useValidator'; const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); @@ -86,7 +86,12 @@ const $props = defineProps({ type: Boolean, default: false, }, + dataKey: { + type: String, + default: null, + }, }); + const { validations } = useValidator(); const requiredFieldRule = (val) => validations().required($attrs.required, val); const $attrs = useAttrs(); @@ -97,14 +102,14 @@ const { optionLabel, optionValue, optionFilter, optionFilterValue, options, mode const myOptions = ref([]); const myOptionsOriginal = ref([]); const vnSelectRef = ref(); -const dataRef = ref(); const lastVal = ref(); const noOneText = t('globals.noOne'); const noOneOpt = ref({ [optionValue.value]: false, [optionLabel.value]: noOneText, }); - +const isLoading = ref(false); +const useURL = computed(() => $props.url); const value = computed({ get() { return $props.modelValue; @@ -114,6 +119,9 @@ const value = computed({ emit('update:modelValue', value); }, }); +const arrayDataKey = + $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label); +const arrayData = useArrayData(arrayDataKey, { url: $props.url, searchUrl: false }); watch(options, (newValue) => { setOptions(newValue); @@ -128,7 +136,7 @@ watch(modelValue, async (newValue) => { onMounted(() => { setOptions(options.value); - if ($props.url && $props.modelValue && !findKeyInOptions()) + if (useURL.value && $props.modelValue && !findKeyInOptions()) fetchFilter($props.modelValue); if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300); }); @@ -166,7 +174,7 @@ function filter(val, options) { } async function fetchFilter(val) { - if (!$props.url || !dataRef.value) return; + if (!$props.url) return; const { fields, include, sortBy, limit } = $props; const key = @@ -188,8 +196,8 @@ async function fetchFilter(val) { const fetchOptions = { where, include, limit }; if (fields) fetchOptions.fields = fields; if (sortBy) fetchOptions.order = sortBy; - - return dataRef.value.fetch(fetchOptions); + arrayData.reset(['skip', 'filter.skip', 'page']); + return (await arrayData.applyFilter({ filter: fetchOptions }))?.data; } async function filterHandler(val, update) { @@ -229,20 +237,25 @@ function nullishToTrue(value) { const getVal = (val) => ($props.useLike ? { like: `%${val}%` } : val); +async function onScroll({ to, direction, from, index }) { + const lastIndex = myOptions.value.length - 1; + + if (from === 0 && index === 0) return; + if (!useURL.value && !$props.fetchRef) return; + if (direction === 'decrease') return; + if (to === lastIndex && arrayData.store.hasMoreData && !isLoading.value) { + isLoading.value = true; + await arrayData.loadMore(); + setOptions(arrayData.store.data); + vnSelectRef.value.scrollTo(lastIndex); + isLoading.value = false; + } +} + defineExpose({ opts: myOptions }); </script> <template> - <FetchData - ref="dataRef" - :url="$props.url" - @on-fetch="(data) => setOptions(data)" - :where="where || { [optionValue]: value }" - :limit="limit" - :sort-by="sortBy" - :fields="fields" - :params="params" - /> <QSelect v-model="value" :options="myOptions" @@ -261,6 +274,9 @@ defineExpose({ opts: myOptions }); :rules="mixinRules" virtual-scroll-slice-size="options.length" hide-bottom-space + :input-debounce="useURL ? '300' : '0'" + :loading="isLoading" + @virtual-scroll="onScroll" > <template v-if="isClearable" #append> <QIcon diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue index 6c50cc9df..02e07249a 100644 --- a/src/pages/Customer/CustomerFilter.vue +++ b/src/pages/Customer/CustomerFilter.vue @@ -53,7 +53,7 @@ defineProps({ <QItemSection> <VnSelect url="Workers/activeWithInheritedRole" - :filter="{ where: { role: 'salesPerson' } }" + :where="{ role: 'salesPerson' }" auto-load :label="t('Salesperson')" v-model="params.salesPersonFk" @@ -67,7 +67,6 @@ defineProps({ dense outlined rounded - :input-debounce="0" /> </QItemSection> </QItem> From ed8225bf6c0285ef9f89af4ae8d1706b3edbc555 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 14:23:06 +0100 Subject: [PATCH 131/207] feat: #7782 waitUntil domContentLoad --- .../vnComponent/vnLocation.spec.js | 2 +- test/cypress/support/commands.js | 12 +++- test/cypress/support/waitUntil.js | 59 +++++++++++++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 test/cypress/support/waitUntil.js diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index c1b0cf929..924b16adc 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -12,7 +12,7 @@ describe('VnLocation', () => { cy.viewport(1280, 720); cy.login('developer'); cy.visit('/#/supplier/567/fiscal-data', { timeout: 7000 }); - cy.waitForElement('.q-card'); + cy.domContentLoad(); cy.get(createLocationButton).click(); }); it('should filter provinces based on selected country', () => { diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 76bdefd27..5bb89ecf9 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -27,6 +27,10 @@ // DO NOT REMOVE // Imports Quasar Cypress AE predefined commands // import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress'; +Cypress.Commands.add('waitUntil', { prevSubject: 'optional' }, require('./waitUntil')); +Cypress.Commands.add('resetDB', () => { + cy.exec('pnpm run resetDatabase'); +}); Cypress.Commands.add('login', (user) => { //cy.visit('/#/login'); cy.request({ @@ -50,10 +54,12 @@ Cypress.Commands.add('login', (user) => { }); }); -Cypress.Commands.add('waitForElement', (element, timeout = 5000) => { - cy.get(element, { timeout }).should('be.visible'); +Cypress.Commands.add('domContentLoad', (element, timeout = 5000) => { + cy.waitUntil(() => cy.document().then((doc) => doc.readyState === 'complete')); +}); +Cypress.Commands.add('waitForElement', (element, timeout = 5000) => { + cy.waitUntil(() => cy.get(element).then(($el) => $el.is(':visible'))); }); - Cypress.Commands.add('getValue', (selector) => { cy.get(selector).then(($el) => { if ($el.find('.q-checkbox__inner').length > 0) { diff --git a/test/cypress/support/waitUntil.js b/test/cypress/support/waitUntil.js new file mode 100644 index 000000000..5fb47a2d8 --- /dev/null +++ b/test/cypress/support/waitUntil.js @@ -0,0 +1,59 @@ +const waitUntil = (subject, checkFunction, originalOptions = {}) => { + if (!(checkFunction instanceof Function)) { + throw new Error( + '`checkFunction` parameter should be a function. Found: ' + checkFunction + ); + } + + const defaultOptions = { + // base options + interval: 200, + timeout: 5000, + errorMsg: 'Timed out retrying', + + // log options + description: 'waitUntil', + log: true, + customMessage: undefined, + logger: Cypress.log, + verbose: false, + customCheckMessage: undefined, + }; + const options = { ...defaultOptions, ...originalOptions }; + + // filter out a falsy passed "customMessage" value + options.customMessage = [options.customMessage, originalOptions].filter(Boolean); + + const endTime = Date.now() + options.timeout; + + const check = (result) => { + if (result) { + return result; + } + if (Date.now() >= endTime) { + const msg = + options.errorMsg instanceof Function + ? options.errorMsg(result, options) + : options.errorMsg; + throw new Error(msg); + } + cy.wait(options.interval, { log: false }).then(() => { + return resolveValue(); + }); + }; + + const resolveValue = () => { + const result = checkFunction(subject); + + const isAPromise = Boolean(result && result.then); + if (isAPromise) { + return result.then(check); + } else { + return check(result); + } + }; + + return resolveValue(); +}; + +export default waitUntil; From b817aa92c2b4f09dd4c282d2313551acf8f5be0b Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 14:23:22 +0100 Subject: [PATCH 132/207] feat: #7782 npm run resetDatabase --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a61c8f21a..71e95667c 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,11 @@ "private": true, "packageManager": "pnpm@8.15.1", "scripts": { + "resetDatabase": "cd ../salix && gulp docker", "lint": "eslint --ext .js,.vue ./", "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "test:e2e": "cypress open", - "test:e2e:ci": "cd ../salix && gulp docker && cd ../salix-front && cypress run", + "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run", "test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test:unit": "vitest", "test:unit:ci": "vitest run", From 2090b78ce6005df77178925f6e04a3b8c39bce86 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 14:25:34 +0100 Subject: [PATCH 133/207] feat: #7782 cypress.config watchForFileChanges --- cypress.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress.config.js b/cypress.config.js index e2046d6c4..1b3e0190f 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -11,6 +11,7 @@ module.exports = defineConfig({ video: false, specPattern: 'test/cypress/integration/**/*.spec.js', experimentalRunAllSpecs: true, + watchForFileChanges: true, component: { componentFolder: 'src', testFiles: '**/*.spec.js', From fbbbc331a951734b09cc7bd084209facdb1143cb Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 14:27:24 +0100 Subject: [PATCH 134/207] feat: #7782 add cypress report --- cypress.config.js | 9 ++ package.json | 1 + pnpm-lock.yaml | 379 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 380 insertions(+), 9 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 1b3e0190f..f8e771093 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -12,12 +12,21 @@ module.exports = defineConfig({ specPattern: 'test/cypress/integration/**/*.spec.js', experimentalRunAllSpecs: true, watchForFileChanges: true, + reporter: 'cypress-mochawesome-reporter', + reporterOptions: { + charts: true, + reportPageTitle: 'Cypress Inline Reporter', + embeddedScreenshots: true, + reportDir: 'test/cypress/reports', + inlineAssets: true, + }, component: { componentFolder: 'src', testFiles: '**/*.spec.js', supportFile: 'test/cypress/support/unit.js', }, setupNodeEvents(on, config) { + require('cypress-mochawesome-reporter/plugin')(on); // implement node event listeners here }, }, diff --git a/package.json b/package.json index 71e95667c..e2e75f253 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@vue/test-utils": "^2.4.4", "autoprefixer": "^10.4.14", "cypress": "^13.6.6", + "cypress-mochawesome-reporter": "^3.8.2", "eslint": "^8.41.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-cypress": "^2.13.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e336c39bb..83dfa0469 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,6 +70,9 @@ devDependencies: cypress: specifier: ^13.6.6 version: 13.6.6 + cypress-mochawesome-reporter: + specifier: ^3.8.2 + version: 3.8.2(cypress@13.6.6)(mocha@10.7.3) eslint: specifier: ^8.41.0 version: 8.56.0 @@ -829,8 +832,8 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 10.0.0-beta.5 - '@intlify/shared': 10.0.0-beta.5 + '@intlify/message-compiler': 10.0.0 + '@intlify/shared': 10.0.0 jsonc-eslint-parser: 1.4.1 source-map: 0.6.1 vue-i18n: 9.9.1(vue@3.4.19) @@ -844,11 +847,11 @@ packages: '@intlify/message-compiler': 9.9.1 '@intlify/shared': 9.9.1 - /@intlify/message-compiler@10.0.0-beta.5: - resolution: {integrity: sha512-hLLchnM1dmtSEruerkzvU9vePsLqBXz3RU85SCx/Vd12fFQiymP+/5Rn9MJ8MyfLmIOLDEx4PRh+/GkIQP6oog==} + /@intlify/message-compiler@10.0.0: + resolution: {integrity: sha512-OcaWc63NC/9p1cMdgoNKBj4d61BH8sUW1Hfs6YijTd9656ZR4rNqXAlRnBrfS5ABq0vjQjpa8VnyvH9hK49yBw==} engines: {node: '>= 16'} dependencies: - '@intlify/shared': 10.0.0-beta.5 + '@intlify/shared': 10.0.0 source-map-js: 1.0.2 dev: true @@ -859,8 +862,8 @@ packages: '@intlify/shared': 9.9.1 source-map-js: 1.0.2 - /@intlify/shared@10.0.0-beta.5: - resolution: {integrity: sha512-g9bq5Y1bOcC9qxtNk4UWtF3sXm6Wh0fGISb7vD5aLyF7yQv7ZFjxQjJzBP2GqG/9+PAGYutqjP1GGadNqFtyAQ==} + /@intlify/shared@10.0.0: + resolution: {integrity: sha512-6ngLfI7DOTew2dcF9WMJx+NnMWghMBhIiHbGg+wRvngpzD5KZJZiJVuzMsUQE1a5YebEmtpTEfUrDp/NqVGdiw==} engines: {node: '>= 16'} dev: true @@ -884,7 +887,7 @@ packages: optional: true dependencies: '@intlify/bundle-utils': 4.0.0(vue-i18n@9.9.1) - '@intlify/shared': 10.0.0-beta.5 + '@intlify/shared': 10.0.0 '@rollup/pluginutils': 4.2.1 '@vue/compiler-sfc': 3.4.19 debug: 4.3.4(supports-color@8.1.1) @@ -1999,6 +2002,10 @@ packages: dependencies: fill-range: 7.0.1 + /browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true + /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -2106,6 +2113,16 @@ packages: upper-case: 1.1.3 dev: true + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + /camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} @@ -2255,6 +2272,22 @@ packages: engines: {node: '>= 10'} dev: true + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2558,6 +2591,23 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /cypress-mochawesome-reporter@3.8.2(cypress@13.6.6)(mocha@10.7.3): + resolution: {integrity: sha512-oJZkNzhNmN9ZD+LmZyFuPb8aWaIijyHyqYh52YOBvR6B6ckfJNCHP3A98a+/nG0H4t46CKTNwo+wNpMa4d2kjA==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + cypress: '>=6.2.0' + dependencies: + commander: 10.0.1 + cypress: 13.6.6 + fs-extra: 10.1.0 + mochawesome: 7.1.3(mocha@10.7.3) + mochawesome-merge: 4.3.0 + mochawesome-report-generator: 6.2.0 + transitivePeerDependencies: + - mocha + dev: true + /cypress@13.6.6: resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} @@ -2627,6 +2677,10 @@ packages: time-zone: 1.0.0 dev: true + /dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dev: true + /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dev: true @@ -2676,6 +2730,29 @@ packages: ms: 2.1.2 supports-color: 8.1.1 + /debug@4.3.7(supports-color@8.1.1): + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + dev: true + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -2758,6 +2835,11 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + /diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + dev: true + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -3550,6 +3632,14 @@ packages: transitivePeerDependencies: - supports-color + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -3646,6 +3736,15 @@ packages: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: true + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + /fs-extra@11.2.0: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} @@ -3654,6 +3753,15 @@ packages: jsonfile: 6.1.0 universalify: 2.0.1 + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -3675,6 +3783,10 @@ packages: dev: true optional: true + /fsu@1.1.1: + resolution: {integrity: sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==} + dev: true + /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -3775,6 +3887,18 @@ packages: once: 1.4.0 path-is-absolute: 1.0.1 + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + /global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} @@ -4189,6 +4313,11 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + /is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -4361,6 +4490,12 @@ packages: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} dev: true + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: @@ -4452,6 +4587,13 @@ packages: engines: {node: '>=14'} dev: true + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4486,10 +4628,26 @@ packages: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: true + /lodash.isempty@4.4.0: + resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + dev: true + + /lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + dev: true + + /lodash.isobject@3.0.2: + resolution: {integrity: sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==} + dev: true + /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} dev: true + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + /lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} dev: true @@ -4552,6 +4710,13 @@ packages: wrap-ansi: 6.2.0 dev: true + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: @@ -4722,6 +4887,79 @@ packages: ufo: 1.4.0 dev: true + /mocha@10.7.3: + resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} + engines: {node: '>= 14.0.0'} + hasBin: true + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.3.7(supports-color@8.1.1) + diff: 5.2.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.1.6 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + dev: true + + /mochawesome-merge@4.3.0: + resolution: {integrity: sha512-1roR6g+VUlfdaRmL8dCiVpKiaUhbPVm1ZQYUM6zHX46mWk+tpsKVZR6ba98k2zc8nlPvYd71yn5gyH970pKBSw==} + engines: {node: '>=10.0.0'} + hasBin: true + dependencies: + fs-extra: 7.0.1 + glob: 7.2.3 + yargs: 15.4.1 + dev: true + + /mochawesome-report-generator@6.2.0: + resolution: {integrity: sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==} + hasBin: true + dependencies: + chalk: 4.1.2 + dateformat: 4.6.3 + escape-html: 1.0.3 + fs-extra: 10.1.0 + fsu: 1.1.1 + lodash.isfunction: 3.0.9 + opener: 1.5.2 + prop-types: 15.8.1 + tcomb: 3.2.29 + tcomb-validation: 3.4.1 + validator: 13.11.0 + yargs: 17.7.2 + dev: true + + /mochawesome@7.1.3(mocha@10.7.3): + resolution: {integrity: sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==} + peerDependencies: + mocha: '>=7' + dependencies: + chalk: 4.1.2 + diff: 5.2.0 + json-stringify-safe: 5.0.1 + lodash.isempty: 4.4.0 + lodash.isfunction: 3.0.9 + lodash.isobject: 3.0.2 + lodash.isstring: 4.0.1 + mocha: 10.7.3 + mochawesome-report-generator: 6.2.0 + strip-ansi: 6.0.1 + uuid: 8.3.2 + dev: true + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4870,6 +5108,11 @@ packages: is-wsl: 2.2.0 dev: false + /opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + dev: true + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4915,6 +5158,13 @@ packages: engines: {node: '>=12.20'} dev: false + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -4929,6 +5179,13 @@ packages: yocto-queue: 1.0.0 dev: true + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -4950,6 +5207,11 @@ packages: aggregate-error: 3.1.0 dev: true + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + /package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} @@ -5139,6 +5401,14 @@ packages: engines: {node: '>=0.4.0'} dev: false + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -5242,6 +5512,10 @@ packages: strip-json-comments: 2.0.1 dev: false + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: true @@ -5328,6 +5602,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -5573,6 +5851,10 @@ packages: transitivePeerDependencies: - supports-color + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + /set-function-length@1.2.1: resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} @@ -5829,6 +6111,16 @@ packages: readable-stream: 3.6.2 dev: true + /tcomb-validation@3.4.1: + resolution: {integrity: sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==} + dependencies: + tcomb: 3.2.29 + dev: true + + /tcomb@3.2.29: + resolution: {integrity: sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==} + dev: true + /text-extensions@2.4.0: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} @@ -6048,6 +6340,11 @@ packages: crypto-random-string: 4.0.0 dev: false + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -6137,7 +6434,6 @@ packages: /validator@13.11.0: resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} engines: {node: '>= 0.10'} - dev: false /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} @@ -6484,6 +6780,10 @@ packages: engines: {node: '>=12'} dev: true + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -6511,6 +6811,10 @@ packages: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} dev: true + /workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -6559,6 +6863,10 @@ packages: engines: {node: '>=12'} dev: true + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -6584,11 +6892,64 @@ packages: engines: {node: '>= 6'} dev: true + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} dev: true + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: true + /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} From 4de23c31b3f34f1849c4300e93729b244db9e01d Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 29 Oct 2024 15:01:49 +0100 Subject: [PATCH 135/207] feat: use composable to unify logic --- src/components/common/VnInput.vue | 13 +++++-------- src/components/common/VnInputDate.vue | 7 +++---- src/components/common/VnInputTime.vue | 6 ++---- src/components/common/VnLocation.vue | 12 ++++-------- src/components/common/VnSelect.vue | 6 ++---- src/composables/useRequired.js | 13 +++++++++++++ 6 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 src/composables/useRequired.js diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 4534ae4a0..769e7ca44 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -1,9 +1,11 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed, ref, useAttrs } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useValidator } from 'src/composables/useValidator'; -import { useAttrs } from 'vue'; +import { useRequired } from 'src/composables/useRequired'; +const $attrs = useAttrs(); +const { isRequired, requiredFieldRule } = useRequired($attrs); +const { t } = useI18n(); const emit = defineEmits([ 'update:modelValue', 'update:options', @@ -29,12 +31,7 @@ const $props = defineProps({ default: true, }, }); -const { validations } = useValidator(); -const $attrs = useAttrs(); -const { t } = useI18n(); -const isRequired = computed(() => Object.keys($attrs).includes('required')); -const requiredFieldRule = (val) => validations().required(isRequired.value, val); const vnInputRef = ref(null); const value = computed({ get() { diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue index 87833f411..b822092a5 100644 --- a/src/components/common/VnInputDate.vue +++ b/src/components/common/VnInputDate.vue @@ -4,10 +4,13 @@ import { date } from 'quasar'; import { useI18n } from 'vue-i18n'; import { useAttrs } from 'vue'; import VnDate from './VnDate.vue'; +import { useRequired } from 'src/composables/useRequired'; +const { isRequired, requiredFieldRule } = useRequired($attrs); const model = defineModel({ type: [String, Date] }); const $attrs = useAttrs(); const { t } = useI18n(); + const $props = defineProps({ isOutlined: { type: Boolean, @@ -18,11 +21,7 @@ const $props = defineProps({ default: true, }, }); -import { useValidator } from 'src/composables/useValidator'; -const { validations } = useValidator(); -const isRequired = computed(() => Object.keys($attrs).includes('required')); -const requiredFieldRule = (val) => validations().required(isRequired.value, val); const vnInputDateRef = ref(null); const dateFormat = 'DD/MM/YYYY'; diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue index 13e90e021..a0967fdf6 100644 --- a/src/components/common/VnInputTime.vue +++ b/src/components/common/VnInputTime.vue @@ -2,10 +2,10 @@ import { computed, ref, useAttrs } from 'vue'; import { useI18n } from 'vue-i18n'; import { date } from 'quasar'; -import { useValidator } from 'src/composables/useValidator'; import VnTime from './VnTime.vue'; +import { useRequired } from 'src/composables/useRequired'; -const { validations } = useValidator(); +const { isRequired, requiredFieldRule } = useRequired($attrs); const { t } = useI18n(); const $attrs = useAttrs(); const model = defineModel({ type: String }); @@ -21,8 +21,6 @@ const props = defineProps({ }); const vnInputTimeRef = ref(null); const initialDate = ref(model.value ?? Date.vnNew()); -const isRequired = computed(() => Object.keys($attrs).includes('required')); -const requiredFieldRule = (val) => validations().required(isRequired.value, val); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; const dateFormat = 'HH:mm'; const isPopupOpen = ref(); diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index 7c6e46fdd..16f9fd580 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -2,13 +2,12 @@ import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue'; import { useI18n } from 'vue-i18n'; -import { computed, ref } from 'vue'; +import { ref } from 'vue'; +import { useAttrs } from 'vue'; +import { useRequired } from 'src/composables/useRequired'; const { t } = useI18n(); const emit = defineEmits(['update:model-value', 'update:options']); -const { validations } = useValidator(); - -import { useAttrs } from 'vue'; -import { useValidator } from 'src/composables/useValidator'; +const { isRequired, requiredFieldRule } = useRequired($attrs); const $attrs = useAttrs(); const props = defineProps({ location: { @@ -17,9 +16,6 @@ const props = defineProps({ }, }); -const isRequired = computed(() => Object.keys($attrs).includes('required')); -const requiredFieldRule = (val) => validations().required(isRequired.value, val); - const mixinRules = [requiredFieldRule]; const locationProperties = [ 'postcode', diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 4a4730784..662efcfe9 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -2,10 +2,11 @@ import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue'; import { useI18n } from 'vue-i18n'; import FetchData from 'src/components/FetchData.vue'; -import { useValidator } from 'src/composables/useValidator'; +import { useRequired } from 'src/composables/useRequired'; const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); const $attrs = useAttrs(); const { t } = useI18n(); +const { isRequired, requiredFieldRule } = useRequired($attrs); const $props = defineProps({ modelValue: { type: [String, Number, Object], @@ -88,10 +89,7 @@ const $props = defineProps({ default: false, }, }); -const { validations } = useValidator(); -const isRequired = computed(() => Object.keys($attrs).includes('required')); -const requiredFieldRule = (val) => validations().required(isRequired.value, val); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; const { optionLabel, optionValue, optionFilter, optionFilterValue, options, modelValue } = toRefs($props); diff --git a/src/composables/useRequired.js b/src/composables/useRequired.js new file mode 100644 index 000000000..e650c91f5 --- /dev/null +++ b/src/composables/useRequired.js @@ -0,0 +1,13 @@ +import { useValidator } from 'src/composables/useValidator'; + +export function useRequired($attrs) { + const { validations } = useValidator(); + + const isRequired = Object.keys($attrs).includes('required'); + const requiredFieldRule = (val) => validations().required(isRequired, val); + + return { + isRequired, + requiredFieldRule, + }; +} From 1761cc23e0166f3c94c4e7b8e72c8883301bb347 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 30 Oct 2024 08:29:04 +0100 Subject: [PATCH 136/207] feat: use composable to unify logic --- src/components/common/VnInputDate.vue | 2 +- src/components/common/VnInputTime.vue | 2 +- src/components/common/VnLocation.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue index b822092a5..fcc04ddf7 100644 --- a/src/components/common/VnInputDate.vue +++ b/src/components/common/VnInputDate.vue @@ -6,9 +6,9 @@ import { useAttrs } from 'vue'; import VnDate from './VnDate.vue'; import { useRequired } from 'src/composables/useRequired'; +const $attrs = useAttrs(); const { isRequired, requiredFieldRule } = useRequired($attrs); const model = defineModel({ type: [String, Date] }); -const $attrs = useAttrs(); const { t } = useI18n(); const $props = defineProps({ diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue index a0967fdf6..6724c00b5 100644 --- a/src/components/common/VnInputTime.vue +++ b/src/components/common/VnInputTime.vue @@ -5,9 +5,9 @@ import { date } from 'quasar'; import VnTime from './VnTime.vue'; import { useRequired } from 'src/composables/useRequired'; +const $attrs = useAttrs(); const { isRequired, requiredFieldRule } = useRequired($attrs); const { t } = useI18n(); -const $attrs = useAttrs(); const model = defineModel({ type: String }); const props = defineProps({ timeOnly: { diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index 16f9fd580..6de402a26 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -7,8 +7,8 @@ import { useAttrs } from 'vue'; import { useRequired } from 'src/composables/useRequired'; const { t } = useI18n(); const emit = defineEmits(['update:model-value', 'update:options']); -const { isRequired, requiredFieldRule } = useRequired($attrs); const $attrs = useAttrs(); +const { isRequired, requiredFieldRule } = useRequired($attrs); const props = defineProps({ location: { type: Object, From d627c1f698d5bab8a5368b65d049b17d2bd3f2ae Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Sun, 3 Nov 2024 10:29:03 -0300 Subject: [PATCH 137/207] fix: order catalog --- src/components/common/VnSelect.vue | 2 +- src/components/ui/VnFilterPanel.vue | 1 - .../Order/Card/CatalogFilterValueDialog.vue | 150 +++++++++++ src/pages/Order/Card/OrderCatalogFilter.vue | 234 ++++++------------ 4 files changed, 231 insertions(+), 156 deletions(-) create mode 100644 src/pages/Order/Card/CatalogFilterValueDialog.vue diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index b0aa648c1..1b3c94bfc 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -120,7 +120,7 @@ watch(options, (newValue) => { }); watch(modelValue, async (newValue) => { - if (!myOptions.value.some((option) => option[optionValue.value] == newValue)) + if (!myOptions?.value?.some((option) => option[optionValue.value] == newValue)) await fetchFilter(newValue); if ($props.noOne) myOptions.value.unshift(noOneOpt.value); diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 5bdaf150c..a8aca49dd 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -189,7 +189,6 @@ const tags = computed(() => { const filteredTags = tagsList.value.filter( (tag) => !($props.customTags || []).includes(tag.label) ); - console.log('formatTags: ', formatTags(filteredTags)); return formatTags(filteredTags); }); diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue new file mode 100644 index 000000000..8e4a9315a --- /dev/null +++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue @@ -0,0 +1,150 @@ +<script setup> +import { ref } from 'vue'; +import { useI18n } from 'vue-i18n'; +import axios from 'axios'; +import VnSelect from 'components/common/VnSelect.vue'; +import VnInput from 'src/components/common/VnInput.vue'; + +const props = defineProps({ + tags: { + type: Array, + default: () => [], + }, +}); + +const emit = defineEmits(['applyTags']); +const { t } = useI18n(); + +const tagValues = ref([{}]); +const tagOptions = ref([]); +const selectedTag = ref(null); + +const applyTags = () => { + if (tagValues.value.some((tag) => !tag.value)) return; + const tagInfo = { + values: [...tagValues.value], + tagFk: selectedTag?.value?.id, + tagSelection: { + name: selectedTag?.value?.name, + }, + }; + emit('applyTags', tagInfo); +}; + +const removeTagGroupParam = (valIndex = null) => { + if (!valIndex) { + tagValues.value = [{}]; + } else { + (tagValues.value || []).splice(valIndex, 1); + } +}; + +const getSelectedTagValues = async (tag) => { + try { + if (!tag?.id) return; + const filter = { + fields: ['value'], + order: 'value ASC', + limit: 30, + }; + + const url = `Tags/${tag?.id}/filterValue`; + const params = { filter: JSON.stringify(filter) }; + const { data } = await axios.get(url, { + params, + }); + tagOptions.value = data; + } catch (err) { + console.error('Error getting selected tag values'); + } +}; +</script> + +<template> + <QForm @submit="applyTags(tagValues)" class="all-pointer-events"> + <QCard class="q-pa-sm column q-pa-lg"> + <VnSelect + :label="t('params.tag')" + v-model="selectedTag" + :options="props.tags || []" + option-value="id" + option-label="name" + dense + outlined + class="q-mb-md" + rounded + :emit-value="false" + use-input + @update:model-value="($event) => getSelectedTagValues($event)" + /> + <div + v-for="(value, index) in tagValues" + :key="value" + class="filter-value column align-left" + > + <div class="col row q-mb-md"> + <VnSelect + v-if="!selectedTag?.isFree && tagOptions" + :label="t('components.itemsFilterPanel.value')" + v-model="value.value" + :options="tagOptions || []" + option-value="value" + option-label="value" + dense + outlined + rounded + emit-value + use-input + :disable="!value" + :is-clearable="false" + class="col" + /> + <VnInput + v-else + v-model="value.value" + :label="t('components.itemsFilterPanel.value')" + :disable="!value" + is-outlined + :is-clearable="false" + class="col" + /> + <QIcon + name="delete" + class="filter-icon col-2" + @click="removeTagGroupParam(index)" + /> + </div> + </div> + <QBtn + icon="add_circle" + shortcut="+" + flat + class="filter-icon q-mb-md" + size="md" + dense + @click="tagValues.push({})" + /> + <QBtn color="primary" type="submit"> + {{ t('search') }} + </QBtn> + </QCard> + </QForm> +</template> + +<style scoped lang="scss"> +.filter-icon { + font-size: 24px; + color: $primary; + padding: 0 4px; + cursor: pointer; +} +</style> + +<i18n> +en: + params: + tag: Tag +es: + params: + tag: Etiqueta +</i18n> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 5612399d7..28c54c120 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -9,6 +9,7 @@ import VnSelect from 'components/common/VnSelect.vue'; import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; +import CatalogFilterValueDialog from 'src/pages/Order/Card/CatalogFilterValueDialog.vue'; const { t } = useI18n(); @@ -28,13 +29,13 @@ const props = defineProps({ }, }); +const showValueFilterDialog = ref(false); const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); const selectedTypeFk = ref(null); -const selectedTag = ref(null); -const tagValues = ref([{}]); -const tagOptions = ref([]); +const generalSearchParam = ref(null); + const vnFilterPanelRef = ref(); const orderByList = ref([ { id: 'relevancy DESC, name', name: t('params.relevancy'), priority: 999 }, @@ -49,20 +50,17 @@ const orderWayList = ref([ const orderBySelected = ref('relevancy DESC, name'); const orderWaySelected = ref('ASC'); -const resetCategory = () => { +const resetCategory = (params, search) => { selectedCategoryFk.value = null; typeList.value = null; -}; - -const clearFilter = (key) => { - if (key === 'categoryFk') { - resetCategory(); - } + params.categoryFk = null; + params.typeFk = null; + search(); }; const selectCategory = (params, category, search) => { if (params.categoryFk === category?.id) { - resetCategory(); + resetCategory(params, search); params.categoryFk = null; } else { selectedCategoryFk.value = category?.id; @@ -102,37 +100,28 @@ function exprBuilder(param, value) { } } -const applyTags = (params, search) => { - if (!tagValues.value?.length) { +const applyTags = (tagInfo, params, search) => { + if (!tagInfo || !tagInfo.values.length) { params.tagGroups = null; search(); + toggleValueFilterDialog(); return; } - const tagGroups = { - values: [...tagValues.value], - tagFk: selectedTag?.value?.id, - tagSelection: { - name: selectedTag?.value?.name, - }, - }; - - params.tagGroups = tagGroups; + if (!params.tagGroups) params.tagGroups = []; + params.tagGroups.push(tagInfo); search(); + toggleValueFilterDialog(); }; const removeTagGroupParam = (params, search, valIndex = null) => { - if (!params.tagGroups) return; - if (!valIndex) { params.tagGroups = null; - tagValues.value = [{}]; + search(); } else { - (tagValues.value || []).splice(valIndex, 1); - params.tagGroups.values.splice(valIndex, 1); + params.tagGroups.splice(valIndex, 1); + search(); } - - search(); }; const setCategoryList = (data) => { @@ -160,37 +149,13 @@ function addOrder(value, field, params) { vnFilterPanelRef.value.search(); } -const getSelectedTagValues = async (tag) => { - try { - if (!tag?.id) return; - const filter = { - fields: ['value'], - order: 'value ASC', - limit: 30, - }; - - const url = `Tags/${tag?.id}/filterValue`; - console.log('url', url); - const params = { filter: JSON.stringify(filter) }; - const { data } = await axios.get(url, { - params, - }); - tagOptions.value = data; - } catch (err) { - console.error('Error getting selected tag values'); - } +const toggleValueFilterDialog = () => { + showValueFilterDialog.value = !showValueFilterDialog.value; }; onMounted(() => { selectedCategoryFk.value = getParamWhere(route, 'categoryFk'); selectedTypeFk.value = getParamWhere(route, 'typeFk'); - if (route.query.params && JSON.parse(route.query.params).tagGroups) { - const tagGroups = JSON.parse(route.query.params).tagGroups; - tagValues.value = [...tagGroups.values]; - selectedTag.value = (props.tags || []).find( - (tag) => tag.name === tagGroups.tagSelection.name - ); - } }); </script> @@ -202,15 +167,11 @@ onMounted(() => { :hidden-tags="['orderFk', 'orderBy']" :un-removable-params="['orderFk', 'orderBy']" :expr-builder="exprBuilder" - :custom-tags="['tagGroups']" - @remove="clearFilter" + :custom-tags="['tagGroups', 'categoryFk']" :redirect="false" > <template #tags="{ tag, formatFn }"> - <strong v-if="tag.label === 'categoryFk'"> - {{ t(selectedCategory?.name || '') }} - </strong> - <strong v-else-if="tag.label === 'typeFk'"> + <strong v-if="tag.label === 'typeFk'"> {{ t(selectedType?.name || '') }} </strong> <div v-else class="q-gutter-x-xs"> @@ -219,24 +180,33 @@ onMounted(() => { </div> </template> <template #customTags="{ tags: customTags, params, searchFn }"> - <template v-for="tag in customTags" :key="tag.label"> - <template v-if="tag.label === 'tagGroups'"> - <VnFilterPanelChip - removable - @remove="removeTagGroupParam(params, searchFn)" - > - <strong class="q-mr-xs"> - {{ tag.value?.tagSelection?.name }}: - </strong> - <span> - {{ - (tag.value?.values || []) - .map((item) => `"${item.value}"`) - .join(', ') - }} - </span> - </VnFilterPanelChip> - </template> + <template v-for="customTag in customTags" :key="customTag.label"> + <VnFilterPanelChip + v-for="(tag, valIndex) in Array.isArray(customTag.value) + ? customTag.value + : 1" + :key="valIndex" + removable + @remove=" + customTag.label === 'categoryFk' + ? resetCategory(params, searchFn) + : removeTagGroupParam(params, searchFn, valIndex) + " + > + <strong v-if="customTag.label === 'categoryFk'"> + {{ t(selectedCategory?.name || '') }} + </strong> + <strong v-if="tag?.tagSelection?.name" class="q-mr-xs"> + {{ tag.tagSelection.name }}: + </strong> + <span> + {{ + (tag?.values || []) + .map((item) => `"${item.value}"`) + .join(', ') + }} + </span> + </VnFilterPanelChip> </template> </template> <template #body="{ params, searchFn }"> @@ -320,70 +290,43 @@ onMounted(() => { </QItemSection> </QItem> <QSeparator /> - <QItem class="q-mt-md"> - <QItemSection> - <VnSelect - :label="t('params.tag')" - v-model="selectedTag" - :options="props.tags || []" - option-value="id" - option-label="name" - dense - outlined - rounded - :emit-value="false" - use-input - @update:model-value="($event) => getSelectedTagValues($event)" - /> - </QItemSection> - </QItem> - <QItem - v-for="(value, index) in tagValues" - :key="value" - class="q-mt-md filter-value" - > - <VnSelect - v-if="!selectedTag?.isFree && tagOptions" - :label="t('components.itemsFilterPanel.value')" - v-model="value.value" - :options="tagOptions || []" - option-value="value" - option-label="value" - dense - outlined - rounded - emit-value - use-input - :disable="!value" - :is-clearable="false" - @update:model-value="applyTags(params, searchFn)" - /> + + <QItem class="q-mt-lg"> <VnInput - v-else - v-model="value.value" :label="t('components.itemsFilterPanel.value')" - :disable="!value" is-outlined :is-clearable="false" - @keyup.enter="applyTags(params, searchFn)" - /> - <QIcon - name="delete" - class="filter-icon" - @click="removeTagGroupParam(params, searchFn, index)" - /> - </QItem> - <QItem class="q-mt-lg"> - <QBtn - icon="add_circle" - shortcut="+" - flat - class="filter-icon" - size="md" - @click="tagValues.push({})" - /> + v-model="generalSearchParam" + @keyup.enter=" + applyTags( + { values: [{ value: generalSearchParam }] }, + params, + searchFn + ) + " + > + <template #prepend> + <QIcon name="search" /> + </template> + <template #append> + <QBtn + icon="add_circle" + shortcut="+" + flat + color="primary" + size="md" + @click="toggleValueFilterDialog()" + /> + </template> + </VnInput> </QItem> <QSeparator /> + <QDialog v-model="showValueFilterDialog"> + <CatalogFilterValueDialog + :tags="tags" + @apply-tags="($event) => applyTags($event, params, searchFn)" + /> + </QDialog> </template> </VnFilterPanel> </template> @@ -416,23 +359,6 @@ onMounted(() => { cursor: pointer; } } - -.filter-icon { - font-size: 24px; - color: $primary; - padding: 0 4px; - cursor: pointer; -} - -.filter-input { - flex-shrink: 1; - min-width: 0; -} - -.filter-value { - display: flex; - align-items: center; -} </style> <i18n> From 08204aa5f085d9045644a7048d537ab70b9737f0 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 4 Nov 2024 13:02:39 +0100 Subject: [PATCH 138/207] refactor(InvoiceInBasicData): use VnDms --- src/components/FormModel.vue | 1 + src/components/common/VnDms.vue | 9 +- .../InvoiceIn/Card/InvoiceInBasicData.vue | 440 ++++-------------- src/pages/InvoiceIn/Card/InvoiceInCard.vue | 17 + 4 files changed, 114 insertions(+), 353 deletions(-) diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index 9ac2d38a5..c668769e5 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -272,6 +272,7 @@ defineExpose({ hasChanges, reset, fetch, + formData, }); </script> <template> diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 920b7f137..946cd8264 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -31,6 +31,10 @@ const $props = defineProps({ type: String, default: null, }, + description: { + type: String, + default: null, + }, }); const warehouses = ref(); @@ -43,7 +47,8 @@ const dms = ref({}); onMounted(() => { defaultData(); if (!$props.formInitialData) - dms.value.description = t($props.model + 'Description', dms.value); + dms.value.description = + $props.description ?? t($props.model + 'Description', dms.value); }); function onFileChange(files) { dms.value.hasFileAttached = !!files; @@ -54,7 +59,6 @@ function mapperDms(data) { const formData = new FormData(); const { files } = data; if (files) formData.append(files?.name, files); - delete data.files; const dms = { hasFile: !!data.hasFile, @@ -78,6 +82,7 @@ async function save() { const body = mapperDms(dms.value); const response = await axios.post(getUrl(), body[0], body[1]); emit('onDataSaved', body[1].params, response); + delete dms.value.files; return response; } diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue index c9468557f..f9498f52e 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue @@ -3,8 +3,6 @@ import { ref, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; -import axios from 'axios'; -import { useArrayData } from 'src/composables/useArrayData'; import { downloadFile } from 'src/composables/downloadFile'; import FormModel from 'components/FormModel.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; @@ -12,15 +10,15 @@ import FetchData from 'src/components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInput from 'src/components/common/VnInput.vue'; +import VnDms from 'src/components/common/VnDms.vue'; +import VnConfirm from 'src/components/ui/VnConfirm.vue'; +import axios from 'axios'; -const quasar = useQuasar(); const { t } = useI18n(); -const dms = ref({}); const route = useRoute(); +const quasar = useQuasar(); const editDownloadDisabled = ref(false); -const arrayData = useArrayData(); -const invoiceIn = computed(() => arrayData.store.data); const userConfig = ref(null); const invoiceId = computed(() => +route.params.id); @@ -36,98 +34,25 @@ const warehousesRef = ref(); const allowTypesRef = ref(); const allowedContentTypes = ref([]); const sageWithholdings = ref([]); -const inputFileRef = ref(); -const editDmsRef = ref(); -const createDmsRef = ref(); +const documentDialogRef = ref({}); +const invoiceInRef = ref({}); -async function checkFileExists(dmsId) { - if (!dmsId) return; - try { - await axios.get(`Dms/${dmsId}`, { fields: ['id'] }); - editDownloadDisabled.value = false; - } catch (e) { - editDownloadDisabled.value = true; - } -} - -async function setEditDms(dmsId) { - const { data } = await axios.get(`Dms/${dmsId}`); - dms.value = { - warehouseId: data.warehouseFk, - companyId: data.companyFk, - dmsTypeId: data.dmsTypeFk, - ...data, - }; - - if (!allowedContentTypes.value.length) await allowTypesRef.value.fetch(); - - editDmsRef.value.show(); -} - -async function setCreateDms() { - const { data } = await axios.get('DmsTypes/findOne', { - where: { code: 'invoiceIn' }, - }); - dms.value = { - reference: invoiceIn.value.supplierRef, - warehouseId: userConfig.value.warehouseFk, - companyId: userConfig.value.companyFk, - dmsTypeId: data.id, - description: invoiceIn.value.supplier.name, - hasFile: true, - hasFileAttached: true, - files: null, - }; - - createDmsRef.value.show(); -} - -async function onSubmit() { - try { - const isEdit = !!dms.value.id; - const errors = { - companyId: `The company can't be empty`, - warehouseId: `The warehouse can't be empty`, - dmsTypeId: `The DMS Type can't be empty`, - description: `The description can't be empty`, - }; - - Object.keys(errors).forEach((key) => { - if (!dms.value[key]) throw Error(t(errors[key])); +function deleteFile(dmsFk) { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: t('globals.confirmDeletion'), + message: t('globals.confirmDeletionMessage'), + }, + }) + .onOk(async () => { + await axios.post(`dms/${dmsFk}/removeFile`); + invoiceInRef.value.formData.dmsFk = null; + invoiceInRef.value.formData.dms = undefined; + invoiceInRef.value.hasChanges = true; + invoiceInRef.value.save(); }); - - if (!isEdit && !dms.value.files) throw Error(t(`The files can't be empty`)); - - const formData = new FormData(); - - if (dms.value.files) { - for (let i = 0; i < dms.value.files.length; i++) - formData.append(dms.value.files[i].name, dms.value.files[i]); - dms.value.hasFileAttached = true; - } - const url = isEdit ? `dms/${dms.value.id}/updateFile` : 'Dms/uploadFile'; - const { data } = await axios.post(url, formData, { - params: dms.value, - }); - - if (data.length) invoiceIn.value.dmsFk = data[0].id; - - if (!isEdit) { - createDmsRef.value.hide(); - } else { - editDmsRef.value.hide(); - } - - quasar.notify({ - message: t('globals.dataSaved'), - type: 'positive', - }); - } catch (error) { - quasar.notify({ - message: t(`${error.message}`), - type: 'negative', - }); - } } </script> <template> @@ -181,10 +106,12 @@ async function onSubmit() { @on-fetch="(data) => (sageWithholdings = data)" /> <FormModel + ref="invoiceInRef" model="InvoiceIn" :go-to="`/invoice-in/${invoiceId}/vat`" - auto-load :url-update="`InvoiceIns/${invoiceId}/updateInvoiceIn`" + @on-fetch="(data) => (documentDialogRef.supplierName = data.supplier.nickname)" + auto-load > <template #form="{ data }"> <VnRow> @@ -242,16 +169,18 @@ async function onSubmit() { </QItem> </template> </VnSelect> - <VnInput - :label="t('Document')" - v-model="data.dmsFk" - clearable - clear-icon="close" - @update:model-value="checkFileExists(data.dmsFk)" - > - <template #prepend> + + <div class="row no-wrap"> + <VnInput + :label="t('Document')" + v-model="data.dmsFk" + clearable + clear-icon="close" + class="full-width" + :disable="true" + /> + <div v-if="data.dmsFk" class="row no-wrap q-pa-xs q-gutter-x-xs"> <QBtn - v-if="data.dmsFk" :class="{ 'no-pointer-events': editDownloadDisabled, }" @@ -262,33 +191,51 @@ async function onSubmit() { round @click="downloadFile(data.dmsFk)" /> - </template> - <template #append> <QBtn :class="{ 'no-pointer-events': editDownloadDisabled, }" :disable="editDownloadDisabled" - v-if="data.dmsFk" icon="edit" round padding="xs" - @click="setEditDms(data.dmsFk)" + @click=" + () => { + documentDialogRef.show = true; + documentDialogRef.dms = data.dms; + } + " > <QTooltip>{{ t('Edit document') }}</QTooltip> </QBtn> <QBtn - v-else - icon="add_circle" - round - shortcut="+" + :class="{ + 'no-pointer-events': editDownloadDisabled, + }" + :disable="editDownloadDisabled" + icon="delete" + :title="t('Delete file')" padding="xs" - @click="setCreateDms()" - > - <QTooltip>{{ t('Create document') }}</QTooltip> - </QBtn> - </template> - </VnInput> + round + @click="deleteFile(data.dmsFk)" + /> + </div> + <QBtn + v-else + icon="add_circle" + round + shortcut="+" + padding="xs" + @click=" + () => { + documentDialogRef.show = true; + delete documentDialogRef.dms; + } + " + > + <QTooltip>{{ t('Create document') }}</QTooltip> + </QBtn> + </div> </VnRow> <VnRow> <VnSelect @@ -319,237 +266,28 @@ async function onSubmit() { </VnRow> </template> </FormModel> - <QDialog ref="editDmsRef"> - <QForm @submit="onSubmit()" class="all-pointer-events"> - <QCard class="q-pa-sm"> - <QCardSection class="row items-center q-pb-none"> - <span class="text-primary text-h6"> - <QIcon name="edit" class="q-mr-xs" /> - {{ t('Edit document') }} - </span> - <QSpace /> - <QBtn icon="close" flat round dense v-close-popup /> - </QCardSection> - <QCardSection class="q-py-none"> - <QItem> - <VnInput - class="full-width q-pa-xs" - :label="t('Reference')" - v-model="dms.reference" - clearable - clear-icon="close" - /> - <VnSelect - class="full-width q-pa-xs" - :label="t('Company')" - v-model="dms.companyId" - :options="companies" - option-value="id" - option-label="code" - :required="true" - /> - </QItem> - <QItem> - <VnSelect - class="full-width q-pa-xs" - :label="t('Warehouse')" - v-model="dms.warehouseId" - :options="warehouses" - option-value="id" - option-label="name" - :required="true" - /> - <VnSelect - class="full-width q-pa-xs" - :label="t('Type')" - v-model="dms.dmsTypeId" - :options="dmsTypes" - option-value="id" - option-label="name" - :required="true" - /> - </QItem> - <QItem> - <VnInput - :label="t('Description')" - v-model="dms.description" - :required="true" - type="textarea" - class="full-width q-pa-xs" - size="lg" - autogrow - clearable - clear-icon="close" - /> - </QItem> - <QItem> - <QFile - ref="inputFileRef" - class="full-width q-pa-xs" - :label="t('File')" - v-model="dms.files" - multiple - :accept="allowedContentTypes.join(',')" - clearable - clear-icon="close" - > - <template #append> - <QBtn - icon="attach_file_add" - flat - round - padding="xs" - @click="inputFileRef.pickFiles()" - > - <QTooltip> - {{ t('globals.selectFile') }} - </QTooltip> - </QBtn> - <QBtn icon="info" flat round padding="xs"> - <QTooltip max-width="30rem"> - {{ - `${t( - 'Allowed content types' - )}: ${allowedContentTypes.join(', ')}` - }} - </QTooltip> - </QBtn> - </template> - </QFile> - </QItem> - <QItem> - <QCheckbox - :label="t('Generate identifier for original file')" - v-model="dms.hasFile" - /> - </QItem> - </QCardSection> - <QCardActions class="justify-end"> - <QBtn - flat - :label="t('globals.close')" - color="primary" - v-close-popup - /> - <QBtn :label="t('globals.save')" color="primary" @click="onSubmit" /> - </QCardActions> - </QCard> - </QForm> - </QDialog> - <QDialog ref="createDmsRef"> - <QForm @submit="onSubmit()" class="all-pointer-events"> - <QCard class="q-pa-sm"> - <QCardSection class="row items-center q-pb-none"> - <span class="text-primary text-h6"> - <QIcon name="edit" class="q-mr-xs" /> - {{ t('Create document') }} - </span> - <QSpace /> - <QBtn icon="close" flat round dense v-close-popup /> - </QCardSection> - <QCardSection class="q-pb-none"> - <QItem> - <VnInput - class="full-width q-pa-xs" - :label="t('Reference')" - v-model="dms.reference" - /> - <VnSelect - class="full-width q-pa-xs" - :label="`${t('Company')}*`" - v-model="dms.companyId" - :options="companies" - option-value="id" - option-label="code" - :required="true" - /> - </QItem> - <QItem> - <VnSelect - class="full-width q-pa-xs" - :label="`${t('Warehouse')}*`" - v-model="dms.warehouseId" - :options="warehouses" - option-value="id" - option-label="name" - :required="true" - /> - <VnSelect - class="full-width q-pa-xs" - :label="`${t('Type')}*`" - v-model="dms.dmsTypeId" - :options="dmsTypes" - option-value="id" - option-label="name" - :required="true" - /> - </QItem> - <QItem> - <VnInput - class="full-width q-pa-xs" - type="textarea" - size="lg" - autogrow - :label="`${t('Description')}*`" - v-model="dms.description" - clearable - clear-icon="close" - :rules="[(val) => val.length || t('Required field')]" - /> - </QItem> - <QItem> - <QFile - ref="inputFileRef" - class="full-width q-pa-xs" - :label="t('File')" - v-model="dms.files" - multiple - :accept="allowedContentTypes.join(',')" - clearable - clear-icon="close" - > - <template #append> - <QBtn - icon="attach_file_add" - flat - round - padding="xs" - @click="inputFileRef.pickFiles()" - > - <QTooltip> - {{ t('globals.selectFile') }} - </QTooltip> - </QBtn> - <QBtn icon="info" flat round padding="xs"> - <QTooltip max-width="30rem"> - {{ - `${t( - 'Allowed content types' - )}: ${allowedContentTypes.join(', ')}` - }} - </QTooltip> - </QBtn> - </template> - </QFile> - </QItem> - <QItem> - <QCheckbox - :label="t('Generate identifier for original file')" - v-model="dms.hasFile" - /> - </QItem> - </QCardSection> - <QCardActions align="right"> - <QBtn - flat - :label="t('globals.close')" - color="primary" - v-close-popup - /> - <QBtn :label="t('globals.save')" color="primary" @click="onSubmit" /> - </QCardActions> - </QCard> - </QForm> + <QDialog v-model="documentDialogRef.show"> + <VnDms + model="dms" + default-dms-code="invoiceIn" + :form-initial-data="documentDialogRef.dms" + :url=" + documentDialogRef.dms + ? `Dms/${documentDialogRef.dms.id}/updateFile` + : 'Dms/uploadFile' + " + :description="documentDialogRef.supplierName" + @on-data-saved=" + (_, { data }) => { + let dmsData = data; + if (Array.isArray(data)) dmsData = data[0]; + invoiceInRef.formData.dmsFk = dmsData.id; + invoiceInRef.formData.dms = dmsData; + invoiceInRef.hasChanges = true; + invoiceInRef.save(); + } + " + /> </QDialog> </template> <style lang="scss" scoped> diff --git a/src/pages/InvoiceIn/Card/InvoiceInCard.vue b/src/pages/InvoiceIn/Card/InvoiceInCard.vue index 0fe2a2368..b16183e52 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInCard.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInCard.vue @@ -20,6 +20,23 @@ const filter = { { relation: 'invoiceInDueDay' }, { relation: 'company' }, { relation: 'currency' }, + { + relation: 'dms', + scope: { + fields: [ + 'dmsTypeFk', + 'reference', + 'hardCopyNumber', + 'workerFk', + 'description', + 'hasFile', + 'file', + 'created', + 'companyFk', + 'warehouseFk', + ], + }, + }, ], }; From e050a077d4fdb77e62598c9466eb282fcb67e189 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 4 Nov 2024 13:41:37 +0100 Subject: [PATCH 139/207] test: refactor e2e --- src/components/common/VnDms.vue | 1 + src/components/ui/VnConfirm.vue | 1 + .../InvoiceIn/Card/InvoiceInBasicData.vue | 7 +++- .../invoiceIn/invoiceInBasicData.spec.js | 33 +++++++++++-------- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 946cd8264..3f9e65740 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -170,6 +170,7 @@ function addDefaultData(data) { @update:model-value="onFileChange(dms.files)" class="required" :display-value="dms.file" + data-cy="VnDms_inputFile" > <template #append> <QIcon diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue index d6b1ac0a3..0b1913383 100644 --- a/src/components/ui/VnConfirm.vue +++ b/src/components/ui/VnConfirm.vue @@ -103,6 +103,7 @@ function cancel() { @click="confirm()" unelevated autofocus + data-cy="VnConfirm_confirm" /> </QCardActions> </QCard> diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue index f9498f52e..209681b7c 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue @@ -179,7 +179,11 @@ function deleteFile(dmsFk) { class="full-width" :disable="true" /> - <div v-if="data.dmsFk" class="row no-wrap q-pa-xs q-gutter-x-xs"> + <div + v-if="data.dmsFk" + class="row no-wrap q-pa-xs q-gutter-x-xs" + data-cy="dms-buttons" + > <QBtn :class="{ 'no-pointer-events': editDownloadDisabled, @@ -232,6 +236,7 @@ function deleteFile(dmsFk) { delete documentDialogRef.dms; } " + data-cy="dms-create" > <QTooltip>{{ t('Create document') }}</QTooltip> </QBtn> diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js index e1939fe5a..2016fca6d 100644 --- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js @@ -2,9 +2,8 @@ describe('InvoiceInBasicData', () => { const formInputs = '.q-form > .q-card input'; const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select'; - const documentBtns = '.q-form .q-field button'; + const documentBtns = '[data-cy="dms-buttons"] button'; const dialogInputs = '.q-dialog input'; - const dialogActionBtns = '.q-card__actions button'; beforeEach(() => { cy.login('developer'); @@ -21,27 +20,35 @@ describe('InvoiceInBasicData', () => { cy.get(formInputs).eq(1).invoke('val').should('eq', '4739'); }); - it('should edit the dms data', () => { + it('should edit, remove and create the dms data', () => { const firtsInput = 'Ticket:65'; const secondInput = "I don't know what posting here!"; + //edit cy.get(documentBtns).eq(1).click(); cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`); cy.get('textarea').type(`{selectall}${secondInput}`); - cy.get(dialogActionBtns).eq(1).click(); - + cy.get('[data-cy="FormModelPopup_save"]').click(); cy.get(documentBtns).eq(1).click(); cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput); cy.get('textarea').invoke('val').should('eq', secondInput); - }); + cy.get('[data-cy="FormModelPopup_save"]').click(); + cy.checkNotification('Data saved'); - it('should throw an error creating a new dms if a file is not attached', () => { - cy.get(formInputs).eq(7).type('{selectall}{backspace}'); - cy.get(documentBtns).eq(0).click(); - cy.get(dialogActionBtns).eq(1).click(); - cy.get('.q-notification__message').should( - 'have.text', - "The files can't be empty" + //remove + cy.get(documentBtns).eq(2).click(); + cy.get('[data-cy="VnConfirm_confirm"]').click(); + cy.checkNotification('Data saved'); + + //create + cy.get('[data-cy="dms-create"]').eq(0).click(); + cy.get('[data-cy="VnDms_inputFile"').selectFile( + 'test/cypress/fixtures/image.jpg', + { + force: true, + } ); + cy.get('[data-cy="FormModelPopup_save"]').click(); + cy.checkNotification('Data saved'); }); }); From 1f9d850fbeff23c8d44367704f9945c15920a709 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 5 Nov 2024 10:02:29 +0100 Subject: [PATCH 140/207] chore: refs #8078 rollback ref --- src/pages/Ticket/Card/TicketDescriptorMenu.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue index 8efd0f1e1..bf4a1efb4 100644 --- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue +++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue @@ -659,7 +659,7 @@ async function uploadDocuware(force) { </QList> </QMenu> </QItem> - <QItem @click="$refs.weightDialog.dialogRef.show()" v-ripple clickable> + <QItem @click="$refs.weightDialog.show()" v-ripple clickable> <QItemSection avatar> <QIcon name="weight" /> </QItemSection> From 86e6bef90f18d98c391a2046c9223a140e289f59 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 5 Nov 2024 10:37:35 +0100 Subject: [PATCH 141/207] chore: refs #8078 fiz tests --- test/vitest/__tests__/components/VnTable.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/vitest/__tests__/components/VnTable.spec.js b/test/vitest/__tests__/components/VnTable.spec.js index d11c2b6c3..162df727d 100644 --- a/test/vitest/__tests__/components/VnTable.spec.js +++ b/test/vitest/__tests__/components/VnTable.spec.js @@ -20,12 +20,12 @@ describe('VnTable', () => { describe('handleSelection()', () => { const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }]; const selectedRows = [{ $index: 1 }]; - it('should add rows to selected when shift key is pressed and rows are added', () => { + it('should add rows to selected when shift key is pressed and rows are added except last one', () => { vm.handleSelection( { evt: { shiftKey: true }, added: true, rows: selectedRows }, rows ); - expect(vm.selected).toEqual([{ $index: 0 }, { $index: 1 }]); + expect(vm.selected).toEqual([{ $index: 0 }]); }); it('should not add rows to selected when shift key is not pressed', () => { From 4a95a0e39ae71f8ae8210bfe1d4cabc6021d9e0e Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 5 Nov 2024 11:59:38 +0100 Subject: [PATCH 142/207] chore: refs #7273 sticky add btn & refactor --- src/pages/Item/Card/ItemTags.vue | 37 +++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue index 6f31d0cf8..e59085402 100644 --- a/src/pages/Item/Card/ItemTags.vue +++ b/src/pages/Item/Card/ItemTags.vue @@ -109,7 +109,11 @@ const insertTag = (rows) => { > <template #body="{ rows, validate }"> <QCard class="q-px-lg q-pt-md q-pb-sm"> - <VnRow v-for="(row, index) in rows" :key="index"> + <VnRow + v-for="(row, index) in rows" + :key="index" + class="items-center" + > <VnSelect :label="t('itemTags.tag')" :options="tagOptions" @@ -153,13 +157,14 @@ const insertTag = (rows) => { :required="true" :rules="validate('itemTag.priority')" /> - <div class="row justify-center items-center" style="flex: 0"> + <div class="row justify-center" style="flex: 0"> <QIcon @click="itemTagsRef.remove([row])" class="fill-icon-on-hover" color="primary" name="delete" size="sm" + dense > <QTooltip> {{ t('itemTags.removeTag') }} @@ -167,22 +172,20 @@ const insertTag = (rows) => { </QIcon> </div> </VnRow> - <VnRow class="justify-center items-center"> - <QBtn - @click="insertTag(rows)" - class="cursor-pointer" - color="primary" - flat - icon="add" - shortcut="+" - style="flex: 0" - > - <QTooltip> - {{ t('itemTags.addTag') }} - </QTooltip> - </QBtn> - </VnRow> </QCard> + <QPageSticky position="bottom-right" :offset="[25, 25]"> + <QBtn + @click="insertTag(rows)" + color="primary" + icon="add" + shortcut="+" + fab + > + <QTooltip> + {{ t('itemTags.addTag') }} + </QTooltip> + </QBtn> + </QPageSticky> </template> </CrudModel> </QPage> From 9959fbf005f9576fda495ac7b8bcd04542c617ef Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 5 Nov 2024 12:23:11 +0100 Subject: [PATCH 143/207] fix: refs #7273 use same filter --- src/pages/Item/ItemList.vue | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue index a480cfff6..f789d2cd0 100644 --- a/src/pages/Item/ItemList.vue +++ b/src/pages/Item/ItemList.vue @@ -12,6 +12,8 @@ import ItemSummary from '../Item/Card/ItemSummary.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; import { cloneItem } from 'src/pages/Item/composables/cloneItem'; +import RightMenu from 'src/components/common/RightMenu.vue'; +import ItemListFilter from './ItemListFilter.vue'; const entityId = computed(() => route.params.id); const { openCloneDialog } = cloneItem(); @@ -311,6 +313,11 @@ const columns = computed(() => [ :label="t('item.searchbar.label')" :info="t('You can search by id')" /> + <RightMenu> + <template #right-panel> + <ItemListFilter data-key="ItemList" /> + </template> + </RightMenu> <VnTable ref="tableRef" data-key="ItemList" @@ -329,6 +336,7 @@ const columns = computed(() => [ auto-load redirect="Item" :is-editable="false" + :right-search="false" :filer="itemFilter" > <template #column-id="{ row }"> From abd7b76636c53f69c5d4ff6e0cec87f037170fa8 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 5 Nov 2024 13:50:25 +0100 Subject: [PATCH 144/207] feat(VnInput): empty to null --- src/components/common/VnInput.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 1246eedcd..93cf332a3 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -27,6 +27,10 @@ const $props = defineProps({ type: Boolean, default: true, }, + emptyToNull: { + type: Boolean, + default: true, + }, }); const { validations } = useValidator(); @@ -39,6 +43,7 @@ const value = computed({ return $props.modelValue; }, set(value) { + if ($props.emptyToNull && value === '') value = null; emit('update:modelValue', value); }, }); From a2bbf4474d4a801ece1cb52d57f61f55ecfe2ebb Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 6 Nov 2024 13:52:59 +0100 Subject: [PATCH 145/207] fix(InvoiceOutGlobal): parallelism --- src/pages/InvoiceOut/InvoiceOutGlobalForm.vue | 7 ++-- src/stores/invoiceOutGlobal.js | 37 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue index 5bcb21001..e85f1f44c 100644 --- a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue +++ b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue @@ -13,7 +13,7 @@ const { t } = useI18n(); const invoiceOutGlobalStore = useInvoiceOutGlobalStore(); // invoiceOutGlobalStore state and getters -const { initialDataLoading, formInitialData, invoicing, status } = +const { initialDataLoading, formInitialData, status } = storeToRefs(invoiceOutGlobalStore); // invoiceOutGlobalStore actions @@ -151,9 +151,8 @@ onMounted(async () => { rounded /> </div> - <QBtn - v-if="!invoicing" + v-if="!getStatus || getStatus === 'stopping'" :label="t('invoiceOut')" type="submit" color="primary" @@ -163,7 +162,7 @@ onMounted(async () => { dense /> <QBtn - v-if="invoicing" + v-else :label="t('stop')" color="primary" class="q-mt-md full-width" diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js index 42acac013..b17f41564 100644 --- a/src/stores/invoiceOutGlobal.js +++ b/src/stores/invoiceOutGlobal.js @@ -93,7 +93,7 @@ export const useInvoiceOutGlobalStore = defineStore({ async makeInvoice(formData, clientsToInvoice) { this.invoicing = true; - this.status = 'packageInvoicing'; + const promises = []; try { this.printer = formData.printer; const params = { @@ -118,10 +118,11 @@ export const useInvoiceOutGlobalStore = defineStore({ ); throw new Error("There aren't addresses to invoice"); } - - for (const address of this.addresses) { - await this.invoiceClient(address, formData); + this.status = 'invoicing'; + for (let index = 0; index < this.parallelism; index++) { + promises.push(this.invoiceClient(formData, index)); } + await Promise.all(promises); } catch (err) { this.handleError(err); } @@ -171,17 +172,15 @@ export const useInvoiceOutGlobalStore = defineStore({ } }, - async invoiceClient(address, formData) { + async invoiceClient(formData, index) { + const address = this.addresses[index]; + if (!address || !this.status || this.status == 'stopping') { + this.status = 'stopping'; + this.invoicing = false; + return; + } + console.log('address: ', address); try { - if (this.nRequests === this.parallelism || this.isInvoicing) return; - - if (this.status === 'stopping') { - if (this.nRequests) return; - this.invoicing = false; - this.status = 'done'; - return; - } - const params = { clientId: address.clientId, addressId: address.id, @@ -191,13 +190,11 @@ export const useInvoiceOutGlobalStore = defineStore({ serialType: formData.serialType, }; - this.status = 'invoicing'; this.invoicing = true; const { data } = await axios.post('InvoiceOuts/invoiceClient', params); if (data) await this.makePdfAndNotify(data, address); - this.addressIndex++; this.isInvoicing = false; } catch (err) { if (err?.response?.status >= 400 && err?.response?.status < 500) { @@ -205,13 +202,16 @@ export const useInvoiceOutGlobalStore = defineStore({ return; } else { this.invoicing = false; - this.status = 'done'; notify( 'invoiceOut.globalInvoices.errors.criticalInvoiceError', 'negative' ); throw new Error('Critical invoicing error, process stopped'); } + } finally { + this.addressIndex++; + if (this.status != 'stopping') + await this.invoiceClient(formData, this.addressIndex); } }, @@ -234,7 +234,6 @@ export const useInvoiceOutGlobalStore = defineStore({ handleError(err) { this.invoicing = false; - this.status = null; throw err; }, @@ -279,7 +278,7 @@ export const useInvoiceOutGlobalStore = defineStore({ return 0; } let porcentaje = (state.addressIndex / this.getNAddresses) * 100; - return porcentaje; + return porcentaje?.toFixed(2); }, getAddressNumber(state) { return state.addressIndex; From ead241e7daa826608dfe522349f4691a06dbc2c9 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 6 Nov 2024 13:53:58 +0100 Subject: [PATCH 146/207] chore: remove console.log --- src/stores/invoiceOutGlobal.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js index b17f41564..35f834f3d 100644 --- a/src/stores/invoiceOutGlobal.js +++ b/src/stores/invoiceOutGlobal.js @@ -179,7 +179,6 @@ export const useInvoiceOutGlobalStore = defineStore({ this.invoicing = false; return; } - console.log('address: ', address); try { const params = { clientId: address.clientId, From 2bf7fa46ca8a546e4e5fb379b502407e55c92d0f Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 7 Nov 2024 12:53:17 +0100 Subject: [PATCH 147/207] perf: remove appendParams --- src/components/VnTable/VnTable.vue | 6 +----- src/composables/useArrayData.js | 3 +-- src/pages/Customer/components/CustomerSummaryTable.vue | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index cdf450966..a4948156a 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -62,7 +62,7 @@ const $props = defineProps({ default: 'flex-one', }, searchUrl: { - type: String, + type: [String, Boolean], default: 'table', }, isEditable: { @@ -73,10 +73,6 @@ const $props = defineProps({ type: Boolean, default: false, }, - appendParams: { - type: Boolean, - default: true, - }, hasSubToolbar: { type: Boolean, default: null, diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index e33cb8b78..747c6ab64 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -247,9 +247,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { } function updateStateParams() { - if (!route) return; const newUrl = { path: route.path, query: { ...(route.query ?? {}) } }; - if (store?.appendParams ?? true) + if (store?.searchUrl) newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter); if (store.navigate) { diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue index 745cbf29e..59e82e252 100644 --- a/src/pages/Customer/components/CustomerSummaryTable.vue +++ b/src/pages/Customer/components/CustomerSummaryTable.vue @@ -183,7 +183,6 @@ const getItemPackagingType = (ticketSales) => { :column-search="false" url="Tickets" :columns="columns" - append-params="false" :without-header="true" auto-load :row-click="rowClick" @@ -191,7 +190,7 @@ const getItemPackagingType = (ticketSales) => { :disable-option="{ card: true, table: true }" class="full-width" :disable-infinite-scroll="true" - search-url="tickets" + :search-url="false" > <template #column-nickname="{ row }"> <span class="link"> From e210ad7de4d0eaff62cdcd176fdef8026003adac Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 7 Nov 2024 13:06:33 +0100 Subject: [PATCH 148/207] Merge branch 'dev' into fix_customer_issues --- src/pages/Customer/components/CustomerSummaryTable.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue index e0ef6a5ef..59e82e252 100644 --- a/src/pages/Customer/components/CustomerSummaryTable.vue +++ b/src/pages/Customer/components/CustomerSummaryTable.vue @@ -63,11 +63,7 @@ const columns = computed(() => [ }, { align: 'left', -<<<<<<< HEAD format: (row) => dashIfEmpty(row.agencyMode?.name), -======= - format: (row, dashIfEmpty) => dashIfEmpty(row.agencyMode?.name), ->>>>>>> dev columnClass: 'expand', label: t('Agency'), }, From 0b5be9e67fef0e164c3d6ca5c429892263d8c1d4 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Thu, 7 Nov 2024 17:19:35 +0100 Subject: [PATCH 149/207] chore: correct checkNotification --- test/cypress/support/commands.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 73c786680..b536121b1 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -280,13 +280,14 @@ Cypress.Commands.add('openActions', (row) => { cy.get('tbody > tr').eq(row).find('.actions > .q-btn').click(); }); -Cypress.Commands.add('checkNotification', (type) => { - const values = { - created: 'Data created', - updated: 'Data saved', - deleted: 'Data deleted', - }; - cy.get('.q-notification__message').should('have.text', values[type]); +Cypress.Commands.add('checkNotification', (text) => { + cy.get('.q-notification') + .should('be.visible') + .last() + .then(($lastNotification) => { + if (!Cypress.$($lastNotification).text().includes(text)) + throw new Error(`Notification not found: "${text}"`); + }); }); Cypress.Commands.add('checkValueForm', (id, search) => { From 498a52a3e5a78c4e8c8f7c58a3cc4b655ca33cac Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Thu, 7 Nov 2024 19:07:03 -0300 Subject: [PATCH 150/207] refactor: small change --- src/pages/Order/Card/CatalogFilterValueDialog.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue index 8e4a9315a..ada0c2889 100644 --- a/src/pages/Order/Card/CatalogFilterValueDialog.vue +++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue @@ -66,7 +66,7 @@ const getSelectedTagValues = async (tag) => { <VnSelect :label="t('params.tag')" v-model="selectedTag" - :options="props.tags || []" + :options="props.tags" option-value="id" option-label="name" dense From 52a2250acc721f80a9a5e5d85dd4b9bad99ea1df Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Thu, 7 Nov 2024 19:16:06 -0300 Subject: [PATCH 151/207] refactor: apply QPopupProxy --- src/pages/Order/Card/OrderCatalogFilter.vue | 22 ++++++++------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 28c54c120..27023262e 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -29,7 +29,6 @@ const props = defineProps({ }, }); -const showValueFilterDialog = ref(false); const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); @@ -104,14 +103,12 @@ const applyTags = (tagInfo, params, search) => { if (!tagInfo || !tagInfo.values.length) { params.tagGroups = null; search(); - toggleValueFilterDialog(); return; } if (!params.tagGroups) params.tagGroups = []; params.tagGroups.push(tagInfo); search(); - toggleValueFilterDialog(); }; const removeTagGroupParam = (params, search, valIndex = null) => { @@ -149,10 +146,6 @@ function addOrder(value, field, params) { vnFilterPanelRef.value.search(); } -const toggleValueFilterDialog = () => { - showValueFilterDialog.value = !showValueFilterDialog.value; -}; - onMounted(() => { selectedCategoryFk.value = getParamWhere(route, 'categoryFk'); selectedTypeFk.value = getParamWhere(route, 'typeFk'); @@ -315,18 +308,19 @@ onMounted(() => { flat color="primary" size="md" - @click="toggleValueFilterDialog()" /> + <QPopupProxy> + <CatalogFilterValueDialog + :tags="tags" + @apply-tags=" + ($event) => applyTags($event, params, searchFn) + " + /> + </QPopupProxy> </template> </VnInput> </QItem> <QSeparator /> - <QDialog v-model="showValueFilterDialog"> - <CatalogFilterValueDialog - :tags="tags" - @apply-tags="($event) => applyTags($event, params, searchFn)" - /> - </QDialog> </template> </VnFilterPanel> </template> From 8bff7fc1d617bf1e5d2c06115248232fe673cd4c Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Thu, 7 Nov 2024 21:09:39 -0300 Subject: [PATCH 152/207] fix: reset category --- src/pages/Order/Card/OrderCatalogFilter.vue | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 27023262e..532c79322 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -10,10 +10,8 @@ import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; import VnInput from 'src/components/common/VnInput.vue'; import getParamWhere from 'src/filters/getParamWhere'; import CatalogFilterValueDialog from 'src/pages/Order/Card/CatalogFilterValueDialog.vue'; +import { useArrayData } from 'composables/useArrayData'; -const { t } = useI18n(); - -const route = useRoute(); const props = defineProps({ dataKey: { type: String, @@ -29,6 +27,11 @@ const props = defineProps({ }, }); +const { t } = useI18n(); +const route = useRoute(); + +const arrayData = useArrayData(props.dataKey); + const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); @@ -54,7 +57,8 @@ const resetCategory = (params, search) => { typeList.value = null; params.categoryFk = null; params.typeFk = null; - search(); + arrayData.store.userFilter = null; + removeTagGroupParam(params, search); }; const selectCategory = (params, category, search) => { From a467c44b91ec3c80d45cfa5dc68a9e7479dcf144 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Fri, 8 Nov 2024 11:51:13 +0100 Subject: [PATCH 153/207] feat: refs #6818 saysimple integration --- src/components/ui/VnLinkPhone.vue | 19 ++++++++++++++++--- src/pages/Customer/Card/CustomerSummary.vue | 7 ++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 3ce0b7aa6..490dd838e 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -1,16 +1,29 @@ <script setup> -defineProps({ phoneNumber: { type: [String, Number], default: null } }); +import { useAttrs } from 'vue'; +const props = defineProps({ + phoneNumber: { type: [String, Number], default: null }, + channel: { type: Number, default: 1320 }, +}); + +const config = { + sip: { icon: 'phone_in_talk', href: `sip:${props.phoneNumber}` }, + 'say-simple': { + icon: 'help', // 'whatsapp', + href: `https://verdnatura.saysimple.io/start-conversation?customerIdentity=%2B${props.phoneNumber}&channelId=${props.channel}`, + }, +}; +const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; </script> <template> <QBtn v-if="phoneNumber" flat round - icon="phone" + :icon="config[type].icon" size="sm" color="primary" padding="none" - :href="`sip:${phoneNumber}`" + :href="config[type].href" @click.stop /> </template> diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 8e41119ef..4cc6057e8 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -95,6 +95,11 @@ const sumRisk = ({ clientRisks }) => { <template #label> {{ t('customer.summary.mobile') }} <VnLinkPhone :phone-number="entity.mobile" /> + <VnLinkPhone + say-simple + :phone-number="entity.mobile" + :channel="entity.country?.saySimpleCountry?.channel" + /> </template> </VnLv> <VnLv :value="entity.email" copy @@ -142,7 +147,7 @@ const sumRisk = ({ clientRisks }) => { <VnLv v-if="entity.country" :label="t('customer.summary.country')" - :value="entity.country.country" + :value="entity.country.name" /> <VnLv :label="t('customer.summary.street')" :value="entity.street" /> </QCard> From 3825dc385134071cea196a2f640bbd43609b1eee Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Fri, 8 Nov 2024 11:54:04 +0100 Subject: [PATCH 154/207] feat: disabled buttons --- .../Order/Card/CatalogFilterValueDialog.vue | 43 ++++++++++++------- src/pages/Order/Card/OrderCatalogFilter.vue | 13 ++++-- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue index ada0c2889..28e235f6a 100644 --- a/src/pages/Order/Card/CatalogFilterValueDialog.vue +++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue @@ -63,6 +63,15 @@ const getSelectedTagValues = async (tag) => { <template> <QForm @submit="applyTags(tagValues)" class="all-pointer-events"> <QCard class="q-pa-sm column q-pa-lg"> + <QBtn + round + color="primary" + style="position: absolute; z-index: 1; right: 0; top: 0" + icon="search" + type="submit" + > + </QBtn> + <VnSelect :label="t('params.tag')" v-model="selectedTag" @@ -77,6 +86,16 @@ const getSelectedTagValues = async (tag) => { use-input @update:model-value="($event) => getSelectedTagValues($event)" /> + <QBtn + icon="add_circle" + shortcut="+" + flat + class="filter-icon q-mb-md" + size="md" + dense + :disabled="!selectedTag || !tagValues[0].value" + @click="tagValues.unshift({})" + /> <div v-for="(value, index) in tagValues" :key="value" @@ -95,7 +114,7 @@ const getSelectedTagValues = async (tag) => { rounded emit-value use-input - :disable="!value" + :disable="!value || !selectedTag" :is-clearable="false" class="col" /> @@ -108,25 +127,19 @@ const getSelectedTagValues = async (tag) => { :is-clearable="false" class="col" /> - <QIcon - name="delete" + <QBtn + icon="delete" + size="md" + outlined + dense + rounded + flat class="filter-icon col-2" + :disabled="!value.value" @click="removeTagGroupParam(index)" /> </div> </div> - <QBtn - icon="add_circle" - shortcut="+" - flat - class="filter-icon q-mb-md" - size="md" - dense - @click="tagValues.push({})" - /> - <QBtn color="primary" type="submit"> - {{ t('search') }} - </QBtn> </QCard> </QForm> </template> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index 532c79322..f684db03e 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -35,6 +35,7 @@ const arrayData = useArrayData(props.dataKey); const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); +const tagsValues = ref([]); const selectedTypeFk = ref(null); const generalSearchParam = ref(null); @@ -289,9 +290,12 @@ onMounted(() => { <QSeparator /> <QItem class="q-mt-lg"> - <VnInput + <VnSelect :label="t('components.itemsFilterPanel.value')" - is-outlined + :options="props.tagValue" + dense + outlined + rounded :is-clearable="false" v-model="generalSearchParam" @keyup.enter=" @@ -305,7 +309,7 @@ onMounted(() => { <template #prepend> <QIcon name="search" /> </template> - <template #append> + <template #after> <QBtn icon="add_circle" shortcut="+" @@ -315,6 +319,7 @@ onMounted(() => { /> <QPopupProxy> <CatalogFilterValueDialog + style="display: inline-block" :tags="tags" @apply-tags=" ($event) => applyTags($event, params, searchFn) @@ -322,7 +327,7 @@ onMounted(() => { /> </QPopupProxy> </template> - </VnInput> + </VnSelect> </QItem> <QSeparator /> </template> From 3bae121ed74f6078ed2ccf8769443646487baf5d Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Fri, 8 Nov 2024 13:04:40 +0100 Subject: [PATCH 155/207] fix: refs #6818 use right icon --- src/components/ui/VnLinkPhone.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 490dd838e..a69cb4509 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -6,7 +6,7 @@ const props = defineProps({ }); const config = { - sip: { icon: 'phone_in_talk', href: `sip:${props.phoneNumber}` }, + sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { icon: 'help', // 'whatsapp', href: `https://verdnatura.saysimple.io/start-conversation?customerIdentity=%2B${props.phoneNumber}&channelId=${props.channel}`, From c1d623622def8b6c576322c7b6c2da673b6fed93 Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Fri, 8 Nov 2024 10:11:15 -0300 Subject: [PATCH 156/207] refactor: remove unused variable --- src/pages/Order/Card/OrderCatalogFilter.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index f684db03e..e4868006c 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -35,7 +35,6 @@ const arrayData = useArrayData(props.dataKey); const categoryList = ref(null); const selectedCategoryFk = ref(null); const typeList = ref([]); -const tagsValues = ref([]); const selectedTypeFk = ref(null); const generalSearchParam = ref(null); From ade90afd0391a303ea1e15b675f1ebfe01af2d98 Mon Sep 17 00:00:00 2001 From: wbuezas <wbuezas@verdnatura.es> Date: Fri, 8 Nov 2024 10:13:35 -0300 Subject: [PATCH 157/207] refactor: change keyup.enter for update:model-value --- src/pages/Order/Card/OrderCatalogFilter.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index e4868006c..758639f69 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -297,7 +297,7 @@ onMounted(() => { rounded :is-clearable="false" v-model="generalSearchParam" - @keyup.enter=" + @update:model-value=" applyTags( { values: [{ value: generalSearchParam }] }, params, From 7fb3e71688f874ab6ca76c24bedc139ed890dc08 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Fri, 8 Nov 2024 17:41:27 +0100 Subject: [PATCH 158/207] feat: refs #6818 fetch url & default channel --- src/components/ui/VnLinkPhone.vue | 36 +++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index a69cb4509..a7b2d9b77 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -1,18 +1,38 @@ <script setup> -import { useAttrs } from 'vue'; +import { reactive, useAttrs, onBeforeMount, capitalize } from 'vue'; +import axios from 'axios'; const props = defineProps({ phoneNumber: { type: [String, Number], default: null }, - channel: { type: Number, default: 1320 }, + channel: { type: Number, default: null }, }); -const config = { +const config = reactive({ sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { icon: 'help', // 'whatsapp', - href: `https://verdnatura.saysimple.io/start-conversation?customerIdentity=%2B${props.phoneNumber}&channelId=${props.channel}`, + href: null, }, -}; +}); const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; + +onBeforeMount(async () => { + let url; + let channel = props.channel; + if (type === 'say-simple') + url = (await axios.get('SaySimpleConfigs/findOne')).data.url; + if (!props.channel) + channel = ( + await axios.get('SaySimpleCountries/findOne', { + params: { + filter: { fields: ['channel'], where: { countryFk: 0 } }, + }, + }) + ).data?.channel; + + config[ + 'say-simple' + ].href = `${url}?customerIdentity=%2B${props.phoneNumber}&channelId=${channel}`; +}); </script> <template> <QBtn @@ -25,5 +45,9 @@ const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; padding="none" :href="config[type].href" @click.stop - /> + > + <QTooltip> + {{ capitalize(type).replace('-', '') }} + </QTooltip> + </QBtn> </template> From 777ac58f047e9becdb7892dc941820b4be494b3c Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 11 Nov 2024 10:31:41 +0100 Subject: [PATCH 159/207] feat(Supplier): add companySize --- src/i18n/locale/en.yml | 4 +++ src/i18n/locale/es.yml | 4 +++ src/pages/Supplier/Card/SupplierBasicData.vue | 32 ++++++++++++++----- src/pages/Supplier/Card/SupplierSummary.vue | 16 ++++++++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index a6065e451..c54d80530 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -106,6 +106,9 @@ globals: weight: Weight error: Ups! Something went wrong recalc: Recalculate + small: Small + medium: Medium + big: Big pageTitles: logIn: Login addressEdit: Update address @@ -942,6 +945,7 @@ supplier: isActive: Active isPayMethodChecked: PayMethod checked note: Notes + size: Size fiscalData: name: Social name * nif: Tax number * diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 6f01f7dd1..8ee3c7d90 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -108,6 +108,9 @@ globals: weight: Peso error: ¡Ups! Algo salió mal recalc: Recalcular + small: Pequeño/a + medium: Mediano/a + big: Grande pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario @@ -940,6 +943,7 @@ supplier: isActive: Activo isPayMethodChecked: Método de pago validado note: Notas + size: Tamaño fiscalData: name: Razón social * nif: NIF/CIF * diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue index 52964557d..ab8f9a4b1 100644 --- a/src/pages/Supplier/Card/SupplierBasicData.vue +++ b/src/pages/Supplier/Card/SupplierBasicData.vue @@ -1,5 +1,4 @@ <script setup> -import { ref } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import FormModel from 'components/FormModel.vue'; @@ -9,8 +8,11 @@ import VnSelect from 'src/components/common/VnSelect.vue'; const route = useRoute(); const { t } = useI18n(); - -const workersOptions = ref([]); +const companySizes = [ + { id: 'small', name: t('globals.small'), size: '1-5' }, + { id: 'medium', name: t('globals.medium'), size: '6-50' }, + { id: 'big', name: t('globals.big'), size: '>50' }, +]; </script> <template> <FormModel @@ -31,11 +33,6 @@ const workersOptions = ref([]); <VnSelect :label="t('supplier.basicData.workerFk')" v-model="data.workerFk" - :options="workersOptions" - option-value="id" - option-label="name" - hide-selected - map-options url="Workers/search" sort-by="nickname ASC" :rules="validate('supplier.workerFk')" @@ -58,6 +55,24 @@ const workersOptions = ref([]); </QItem> </template> </VnSelect> + <VnSelect + :label="t('supplier.basicData.size')" + v-model="data.companySize" + :options="companySizes" + sort-by="nickname ASC" + :rules="validate('supplier.workerFk')" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt?.name }}</QItemLabel> + <QItemLabel caption> + {{ scope.opt?.size }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> </VnRow> <VnRow> <QCheckbox @@ -88,4 +103,5 @@ const workersOptions = ref([]); <i18n> es: Responsible for approving invoices: Responsable de aprobar las facturas + Small(1-5), Medium(6-50), Big(> 50): Pequeño(1-5), Mediano(6-50), Grande(> 50) </i18n> diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue index 5791db1eb..2ce5a7dce 100644 --- a/src/pages/Supplier/Card/SupplierSummary.vue +++ b/src/pages/Supplier/Card/SupplierSummary.vue @@ -65,6 +65,22 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`; <span> {{ dashIfEmpty(supplier.note) }} </span> </template> </VnLv> + <VnLv + :label="t('supplier.basicData.size')" + :value="supplier.companySize" + class="q-mb-xs" + > + <template #value> + <span> + {{ + dashIfEmpty( + supplier.companySize && + t('globals.' + supplier.companySize) + ) + }} + </span> + </template> + </VnLv> <QCheckbox :label="t('supplier.summary.verified')" v-model="supplier.isSerious" From 07e7cbc3551db7c7fe5c3e9ad67a7cbcc8939031 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Mon, 11 Nov 2024 16:36:18 +0100 Subject: [PATCH 160/207] feat: refs #6839 module searching --- src/components/LeftMenu.vue | 77 ++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index 03fe11a85..6e0ae5907 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -1,6 +1,6 @@ <script setup> import axios from 'axios'; -import { onMounted, watch, ref, reactive } from 'vue'; +import { onMounted, watch, ref, reactive, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { QSeparator, useQuasar } from 'quasar'; import { useRoute } from 'vue-router'; @@ -9,6 +9,7 @@ import { toLowerCamel } from 'src/filters'; import routes from 'src/router/modules'; import LeftMenuItem from './LeftMenuItem.vue'; import LeftMenuItemGroup from './LeftMenuItemGroup.vue'; +import VnInput from './common/VnInput.vue'; const { t } = useI18n(); const route = useRoute(); @@ -22,7 +23,32 @@ const props = defineProps({ }, }); +const items = ref([]); const expansionItemElements = reactive({}); +const pinnedModules = computed(() => { + const map = new Map(); + items.value.forEach((item) => item.isPinned && map.set(item.name, item)); + return map; +}); +const search = ref(null); + +const filteredItems = computed(() => { + if (!search.value) return items.value; + return items.value.filter((item) => { + const locale = t(item.title).toLowerCase(); + return locale.includes(search.value.toLowerCase()); + }); +}); + +const filteredPinnedModules = computed(() => { + if (!search.value) return pinnedModules.value; + const map = new Map(); + for (const [key, pinnedModule] of pinnedModules.value) { + const locale = t(pinnedModule.title).toLowerCase(); + if (locale.includes(search.value.toLowerCase())) map.set(key, pinnedModule); + } + return map; +}); onMounted(async () => { await navigation.fetchPinned(); @@ -66,8 +92,6 @@ function addChildren(module, route, parent) { } } -const items = ref([]); - function getRoutes() { if (props.source === 'main') { const modules = Object.assign([], navigation.getModules().value); @@ -129,15 +153,44 @@ const handleItemExpansion = (itemName) => { <QList padding class="column-max-width"> <template v-if="$props.source === 'main'"> <template v-if="$route?.matched[1]?.name === 'Dashboard'"> - <QItem class="header"> - <QItemSection avatar> - <QIcon name="view_module" /> - </QItemSection> - <QItemSection> {{ t('globals.modules') }}</QItemSection> + <QItem class="q-pb-md"> + <VnInput + v-model="search" + :label="t('Search modules')" + class="full-width" + filled + dense + /> </QItem> <QSeparator /> - <template v-for="item in items" :key="item.name"> - <template v-if="item.children"> + <template v-if="filteredPinnedModules.size"> + <LeftMenuItem + v-for="[key, pinnedModule] of filteredPinnedModules" + :key="key" + :item="pinnedModule" + group="modules" + > + <template #side> + <QBtn + v-if="pinnedModule.isPinned === true" + @click="togglePinned(pinnedModule, $event)" + icon="remove_circle" + size="xs" + flat + round + > + <QTooltip> + {{ t('components.leftMenu.removeFromPinned') }} + </QTooltip> + </QBtn> + </template> + </LeftMenuItem> + <QSeparator /> + </template> + <template v-for="item in filteredItems" :key="item.name"> + <template + v-if="item.children && !filteredPinnedModules.has(item.name)" + > <LeftMenuItem :item="item" group="modules"> <template #side> <QBtn @@ -256,3 +309,7 @@ const handleItemExpansion = (itemName) => { color: var(--vn-label-color); } </style> +<i18n> + es: + Search modules: Buscar módulos +</i18n> From 40ecd6e3584a94627b714c9dd474975cc3d3187e Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Tue, 12 Nov 2024 08:28:02 +0100 Subject: [PATCH 161/207] refactor: refs #7950 Created cmr model --- src/pages/Route/Cmr/CmrList.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue index ede271960..b3eaf3b48 100644 --- a/src/pages/Route/Cmr/CmrList.vue +++ b/src/pages/Route/Cmr/CmrList.vue @@ -116,7 +116,7 @@ function getApiUrl() { return new URL(window.location).origin; } function getCmrUrl(value) { - return `${getApiUrl()}/api/Routes/${value}/cmr?access_token=${token}`; + return `${getApiUrl()}/api/Cmrs/${value}/print?access_token=${token}`; } function downloadPdfs() { if (!selectedRows.value.length) { @@ -129,7 +129,7 @@ function downloadPdfs() { let cmrs = []; for (let value of selectedRows.value) cmrs.push(value.cmrFk); // prettier-ignore - return window.open(`${getApiUrl()}/api/Routes/downloadCmrsZip?ids=${cmrs.join(',')}&access_token=${token}`); + return window.open(`${getApiUrl()}/api/Cmrs/downloadZip?ids=${cmrs.join(',')}&access_token=${token}`); } </script> <template> @@ -149,7 +149,7 @@ function downloadPdfs() { <VnTable ref="tableRef" data-key="CmrList" - url="Routes/cmrs" + url="Cmrs/filter" :columns="columns" :right-search="true" default-mode="table" From 700701f0554c7b06985f31e9dcecc8ad51056de0 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 12 Nov 2024 10:10:26 +0100 Subject: [PATCH 162/207] refactor: refs #6818 channel logic --- src/components/ui/VnLinkPhone.vue | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index a7b2d9b77..3b3153ac3 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -9,29 +9,33 @@ const props = defineProps({ const config = reactive({ sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { - icon: 'help', // 'whatsapp', + icon: 'help', // 'whatsapp icon #6818', href: null, + channel: props.channel, }, }); const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; onBeforeMount(async () => { let url; - let channel = props.channel; - if (type === 'say-simple') - url = (await axios.get('SaySimpleConfigs/findOne')).data.url; - if (!props.channel) - channel = ( - await axios.get('SaySimpleCountries/findOne', { - params: { - filter: { fields: ['channel'], where: { countryFk: 0 } }, - }, - }) - ).data?.channel; + let { channel } = config[type]; + if (type === 'sip') return; - config[ - 'say-simple' - ].href = `${url}?customerIdentity=%2B${props.phoneNumber}&channelId=${channel}`; + if (type === 'say-simple') { + url = (await axios.get('SaySimpleConfigs/findOne')).data.url; + if (!channel) + channel = ( + await axios.get('SaySimpleCountries/findOne', { + params: { + filter: { fields: ['channel'], where: { countryFk: 0 } }, + }, + }) + ).data?.channel; + + config[ + type + ].href = `${url}?customerIdentity=%2B${props.phoneNumber}&channelId=${channel}`; + } }); </script> <template> From 81b35aa75b03bab9c35effc1a09056945d86304d Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 12 Nov 2024 10:11:26 +0100 Subject: [PATCH 163/207] chore: refs #6818 add spaces --- src/components/ui/VnLinkPhone.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 3b3153ac3..51694b8eb 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -19,9 +19,9 @@ const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; onBeforeMount(async () => { let url; let { channel } = config[type]; - if (type === 'sip') return; - if (type === 'say-simple') { + if (type === 'sip') return; + else if (type === 'say-simple') { url = (await axios.get('SaySimpleConfigs/findOne')).data.url; if (!channel) channel = ( From efd66ea02af6ce995b2e08f15552bad4cfb3a0d5 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 12 Nov 2024 11:08:45 +0100 Subject: [PATCH 164/207] feat: refs #6919 sync entry data --- src/pages/Entry/Card/EntryBasicData.vue | 3 +- src/pages/Entry/Card/EntryCard.vue | 45 +++++++++++++++++ src/pages/Entry/Card/EntryDescriptor.vue | 62 ++---------------------- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index 3288616fb..07f4426ba 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -44,9 +44,8 @@ const onFilterTravelSelected = (formData, id) => { auto-load /> <FormModel - :url="`Entries/${route.params.id}`" :url-update="`Entries/${route.params.id}`" - model="entry" + model="Entry" auto-load :clear-store-on-unmount="false" > diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue index 436f5b9cd..f05f76b50 100644 --- a/src/pages/Entry/Card/EntryCard.vue +++ b/src/pages/Entry/Card/EntryCard.vue @@ -2,11 +2,56 @@ import VnCard from 'components/common/VnCard.vue'; import EntryDescriptor from './EntryDescriptor.vue'; import EntryFilter from '../EntryFilter.vue'; + +const filter = { + include: [ + { + relation: 'travel', + scope: { + fields: [ + 'id', + 'landed', + 'shipped', + 'agencyModeFk', + 'warehouseOutFk', + 'daysInForward', + ], + include: [ + { + relation: 'agency', + scope: { + fields: ['name'], + }, + }, + { + relation: 'warehouseOut', + scope: { + fields: ['name'], + }, + }, + { + relation: 'warehouseIn', + scope: { + fields: ['name'], + }, + }, + ], + }, + }, + { + relation: 'supplier', + scope: { + fields: ['id', 'nickname'], + }, + }, + ], +}; </script> <template> <VnCard data-key="Entry" base-url="Entries" + :filter="filter" :descriptor="EntryDescriptor" :filter-panel="EntryFilter" search-data-key="EntryList" diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index d66185aa9..37b0aa62d 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -1,11 +1,10 @@ <script setup> -import { ref, computed, watch, onMounted } from 'vue'; +import { ref, computed, onMounted } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; -import useCardDescription from 'src/composables/useCardDescription'; import { toDate } from 'src/filters'; import { usePrintService } from 'composables/usePrintService'; @@ -25,50 +24,6 @@ const { openReport } = usePrintService(); const entryDescriptorRef = ref(null); const url = ref(); -const entryFilter = { - include: [ - { - relation: 'travel', - scope: { - fields: [ - 'id', - 'landed', - 'shipped', - 'agencyModeFk', - 'warehouseOutFk', - 'daysInForward', - ], - include: [ - { - relation: 'agency', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseOut', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseIn', - scope: { - fields: ['name'], - }, - }, - ], - }, - }, - { - relation: 'supplier', - scope: { - fields: ['id', 'nickname'], - }, - }, - ], -}; - const entityId = computed(() => { return $props.id || route.params.id; }); @@ -76,10 +31,6 @@ onMounted(async () => { url.value = await getUrl(''); }); -const data = ref(useCardDescription()); -const setData = (entity) => - (data.value = useCardDescription(entity.supplier?.nickname, entity.id)); - const getEntryRedirectionFilter = (entry) => { let entryTravel = entry && entry.travel; @@ -104,8 +55,6 @@ const getEntryRedirectionFilter = (entry) => { const showEntryReport = () => { openReport(`Entries/${route.params.id}/entry-order-pdf`); }; - -watch; </script> <template> @@ -113,11 +62,8 @@ watch; ref="entryDescriptorRef" module="Entry" :url="`Entries/${entityId}`" - :filter="entryFilter" - :title="data.title" - :subtitle="data.subtitle" - @on-fetch="setData" - data-key="entry" + title="supplier.nickname" + data-key="Entry" > <template #menu="{ entity }"> <QItem v-ripple clickable @click="showEntryReport(entity)"> @@ -165,7 +111,7 @@ watch; <template #actions="{ entity }"> <QCardActions> <QBtn - :to="`/supplier/${entity.supplier.id}`" + :to="`/supplier/${entity.supplier?.id}`" size="md" icon="vn:supplier" color="primary" From b4d76536617094d00959fa7ca68960172ce6eba6 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 12 Nov 2024 11:15:34 +0100 Subject: [PATCH 165/207] refactor: refs #6919 export filter --- src/pages/Entry/Card/EntryCard.vue | 45 +----------------------- src/pages/Entry/Card/EntryDescriptor.vue | 2 ++ src/pages/Entry/Card/EntryFilter.js | 43 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 44 deletions(-) create mode 100644 src/pages/Entry/Card/EntryFilter.js diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue index f05f76b50..3f2596338 100644 --- a/src/pages/Entry/Card/EntryCard.vue +++ b/src/pages/Entry/Card/EntryCard.vue @@ -2,50 +2,7 @@ import VnCard from 'components/common/VnCard.vue'; import EntryDescriptor from './EntryDescriptor.vue'; import EntryFilter from '../EntryFilter.vue'; - -const filter = { - include: [ - { - relation: 'travel', - scope: { - fields: [ - 'id', - 'landed', - 'shipped', - 'agencyModeFk', - 'warehouseOutFk', - 'daysInForward', - ], - include: [ - { - relation: 'agency', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseOut', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseIn', - scope: { - fields: ['name'], - }, - }, - ], - }, - }, - { - relation: 'supplier', - scope: { - fields: ['id', 'nickname'], - }, - }, - ], -}; +import filter from './EntryFilter.js'; </script> <template> <VnCard diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index 37b0aa62d..794f791ae 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -9,6 +9,7 @@ import VnLv from 'src/components/ui/VnLv.vue'; import { toDate } from 'src/filters'; import { usePrintService } from 'composables/usePrintService'; import { getUrl } from 'src/composables/getUrl'; +import filter from './EntryFilter.js'; const $props = defineProps({ id: { @@ -62,6 +63,7 @@ const showEntryReport = () => { ref="entryDescriptorRef" module="Entry" :url="`Entries/${entityId}`" + :filter="filter" title="supplier.nickname" data-key="Entry" > diff --git a/src/pages/Entry/Card/EntryFilter.js b/src/pages/Entry/Card/EntryFilter.js new file mode 100644 index 000000000..3ff62cf27 --- /dev/null +++ b/src/pages/Entry/Card/EntryFilter.js @@ -0,0 +1,43 @@ +export default { + include: [ + { + relation: 'travel', + scope: { + fields: [ + 'id', + 'landed', + 'shipped', + 'agencyModeFk', + 'warehouseOutFk', + 'daysInForward', + ], + include: [ + { + relation: 'agency', + scope: { + fields: ['name'], + }, + }, + { + relation: 'warehouseOut', + scope: { + fields: ['name'], + }, + }, + { + relation: 'warehouseIn', + scope: { + fields: ['name'], + }, + }, + ], + }, + }, + { + relation: 'supplier', + scope: { + fields: ['id', 'nickname'], + }, + }, + ], +}; From 3f15c3cce00f7005237e4a79005ccbe3fad545f6 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 12 Nov 2024 14:35:55 +0100 Subject: [PATCH 166/207] feat(VnSelect): order data equal salix --- src/components/common/VnSelect.vue | 3 ++ src/utils/dataByOrder.js | 53 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/utils/dataByOrder.js diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 32dbbd641..4622f1cb0 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -3,6 +3,8 @@ import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue'; import { useI18n } from 'vue-i18n'; import FetchData from 'src/components/FetchData.vue'; import { useRequired } from 'src/composables/useRequired'; +import dataByOrder from 'src/utils/dataByOrder'; + const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); const $attrs = useAttrs(); const { t } = useI18n(); @@ -138,6 +140,7 @@ function findKeyInOptions() { } function setOptions(data) { + data = dataByOrder(data, $props.sortBy); myOptions.value = JSON.parse(JSON.stringify(data)); myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); emit('update:options', data); diff --git a/src/utils/dataByOrder.js b/src/utils/dataByOrder.js new file mode 100644 index 000000000..72b55ac11 --- /dev/null +++ b/src/utils/dataByOrder.js @@ -0,0 +1,53 @@ +function orderData(data, order) { + if (typeof order === 'string') order = [order]; + if (Array.isArray(order)) { + let orderComp = []; + + for (let field of order) { + let split = field.split(/\s+/); + orderComp.push({ + field: split[0], + way: split[1] === 'DESC' ? -1 : 1, + }); + } + + return data.sort((a, b) => sortFunc(a, b, orderComp)); + } else if (typeof order === 'function') return data.sort(data); + return data; +} + +function sortFunc(a, b, order) { + for (let i of order) { + let compRes = compareFunc(a[i.field], b[i.field]) * i.way; + if (compRes !== 0) return compRes; + } + + return 0; +} + +function compareFunc(a, b) { + if (a === b) return 0; + let aType = typeof a; + if (aType === typeof b) { + switch (aType) { + case 'string': + return a.localeCompare(b); + case 'number': + return a - b; + case 'boolean': + return a ? 1 : -1; + case 'object': + if (a instanceof Date && b instanceof Date) + return a.getTime() - b.getTime(); + } + } + + if (a === undefined) return -1; + if (b === undefined) return 1; + if (a === null) return -1; + if (b === null) return 1; + + return a > b ? 1 : -1; +} + +export default orderData; From 83be57a0c4dc88180c52fb08e71de9071c305d83 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 12 Nov 2024 15:01:17 +0100 Subject: [PATCH 167/207] chore: refs #6818 drop useless code & comment --- src/components/ui/VnLinkPhone.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 51694b8eb..11339859e 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -9,7 +9,7 @@ const props = defineProps({ const config = reactive({ sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { - icon: 'help', // 'whatsapp icon #6818', + icon: 'help', href: null, channel: props.channel, }, @@ -20,8 +20,7 @@ onBeforeMount(async () => { let url; let { channel } = config[type]; - if (type === 'sip') return; - else if (type === 'say-simple') { + if (type === 'say-simple') { url = (await axios.get('SaySimpleConfigs/findOne')).data.url; if (!channel) channel = ( From 8269037faad5288ce36146f99e03c372724292c6 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 13 Nov 2024 07:21:42 +0100 Subject: [PATCH 168/207] chore: perf --- src/utils/dataByOrder.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/dataByOrder.js b/src/utils/dataByOrder.js index 72b55ac11..1bdedb8a1 100644 --- a/src/utils/dataByOrder.js +++ b/src/utils/dataByOrder.js @@ -1,4 +1,5 @@ function orderData(data, order) { + if (typeof order === 'function') return data.sort(data); if (typeof order === 'string') order = [order]; if (Array.isArray(order)) { let orderComp = []; @@ -12,13 +13,13 @@ function orderData(data, order) { } return data.sort((a, b) => sortFunc(a, b, orderComp)); - } else if (typeof order === 'function') return data.sort(data); + } return data; } function sortFunc(a, b, order) { - for (let i of order) { - let compRes = compareFunc(a[i.field], b[i.field]) * i.way; + for (let { field, way } of order) { + let compRes = compareFunc(a[field], b[field]) * way; if (compRes !== 0) return compRes; } From 9291c4dd6acc5d12217f8d4d65688d37afc6edc6 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Wed, 13 Nov 2024 11:50:08 +0100 Subject: [PATCH 169/207] feat: refs #6818 add icon --- src/components/ui/VnLinkPhone.vue | 2 +- src/pages/Customer/Card/CustomerSummary.vue | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 11339859e..3b63889e1 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -9,7 +9,7 @@ const props = defineProps({ const config = reactive({ sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { - icon: 'help', + icon: 'vn:saysimple', href: null, channel: props.channel, }, diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 4cc6057e8..555d490d7 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -99,6 +99,7 @@ const sumRisk = ({ clientRisks }) => { say-simple :phone-number="entity.mobile" :channel="entity.country?.saySimpleCountry?.channel" + class="q-ml-xs" /> </template> </VnLv> From c2b6b816a42a90df7d9d0bd8c675bcc853430a59 Mon Sep 17 00:00:00 2001 From: guillermo <guillermo@verdnatura.es> Date: Thu, 14 Nov 2024 08:04:06 +0100 Subject: [PATCH 170/207] fix: refs #7283 Account image resolution --- src/pages/Account/Card/AccountDescriptor.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue index 4571ee8ab..3156f8e1e 100644 --- a/src/pages/Account/Card/AccountDescriptor.vue +++ b/src/pages/Account/Card/AccountDescriptor.vue @@ -54,7 +54,7 @@ const hasAccount = ref(false); </template> <template #before> <!-- falla id :id="entityId.value" collection="user" size="160x160" --> - <VnImg :id="entityId" collection="user" resolution="160x160" class="photo"> + <VnImg :id="entityId" collection="user" resolution="520x520" class="photo"> <template #error> <div class="absolute-full picture text-center q-pa-md flex flex-center" From ef415d080adcd580d92634778bb8a135c9af0b38 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 08:19:19 +0100 Subject: [PATCH 171/207] feat: refs #7308 #7308 remove warnings related to useSession --- src/boot/quasar.js | 2 ++ src/composables/useSession.js | 8 ++++++-- src/router/index.js | 8 +++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 01fe68d8b..1cc2e82cf 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -1,6 +1,7 @@ import { boot } from 'quasar/wrappers'; import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; +import { setupAxios } from 'src/boot/axios'; import useNotify from 'src/composables/useNotify.js'; import { CanceledError } from 'axios'; @@ -48,4 +49,5 @@ export default boot(({ app }) => { notify(message ?? 'globals.error', 'negative', 'error'); }; + setupAxios(); }); diff --git a/src/composables/useSession.js b/src/composables/useSession.js index 633a30bb0..5097a1fee 100644 --- a/src/composables/useSession.js +++ b/src/composables/useSession.js @@ -8,9 +8,13 @@ import useNotify from './useNotify'; import { useTokenConfig } from './useTokenConfig'; const TOKEN_MULTIMEDIA = 'tokenMultimedia'; const TOKEN = 'token'; - +let router; +export default { + setup() { + router = useRouter(); + }, +}; export function useSession() { - const router = useRouter(); const { notify } = useNotify(); let isCheckingToken = false; let intervalId = null; diff --git a/src/router/index.js b/src/router/index.js index 18541c0b2..5ed8ad9ed 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -14,8 +14,8 @@ import { useUserConfig } from 'src/composables/useUserConfig'; import { useTokenConfig } from 'src/composables/useTokenConfig'; import { useAcl } from 'src/composables/useAcl'; -const state = useState(); -const session = useSession(); +let state, session; + const { t, te } = i18n.global; const createHistory = process.env.SERVER @@ -43,8 +43,10 @@ const Router = createRouter({ * with the Router instance. */ export { Router }; -export default route(function (/* { store, ssrContext } */) { +export default route((/* { store, ssrContext } */) => { Router.beforeEach(async (to, from, next) => { + state = useState(); + session = useSession(); const { isLoggedIn } = session; const outLayout = Router.options.routes[0].children.map((r) => r.name); if (!isLoggedIn() && !outLayout.includes(to.name)) { From 590d495dbddfeb6b252e2967c259394ef80f6b2a Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 08:19:41 +0100 Subject: [PATCH 172/207] test: refs #7308 #7308 axios.spec.js --- src/boot/axios.js | 19 +++++--- test/vitest/__tests__/boot/axios.spec.js | 62 ++++++++++++++++++------ 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/boot/axios.js b/src/boot/axios.js index aee38e887..5da26a404 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -4,9 +4,8 @@ import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; import { useStateQueryStore } from 'src/stores/useStateQueryStore'; -const session = useSession(); -const { notify } = useNotify(); -const stateQuery = useStateQueryStore(); +let session, notify, stateQuery; + const baseUrl = '/api/'; axios.defaults.baseURL = baseUrl; @@ -51,9 +50,15 @@ const onResponseError = (error) => { return Promise.reject(error); }; -axios.interceptors.request.use(onRequest, onRequestError); -axios.interceptors.response.use(onResponse, onResponseError); -axiosNoError.interceptors.request.use(onRequest); -axiosNoError.interceptors.response.use(onResponse); +export function setupAxios() { + session = useSession(); + notify = useNotify().notify; + stateQuery = useStateQueryStore(); + + axios.interceptors.request.use(onRequest, onRequestError); + axios.interceptors.response.use(onResponse, onResponseError); + axiosNoError.interceptors.request.use(onRequest); + axiosNoError.interceptors.response.use(onResponse); +} export { onRequest, onResponseError, axiosNoError }; diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js index 19d396ec5..dc321a658 100644 --- a/test/vitest/__tests__/boot/axios.spec.js +++ b/test/vitest/__tests__/boot/axios.spec.js @@ -1,23 +1,53 @@ -import { Notify } from 'quasar'; -import { onRequest, onResponseError } from 'src/boot/axios'; -import { describe, expect, it, vi } from 'vitest'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { setupAxios, onRequest, onResponseError } from 'src/boot/axios'; +import { useSession } from 'src/composables/useSession'; +import useNotify from 'src/composables/useNotify'; +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; -vi.mock('src/composables/useSession', () => ({ - useSession: () => ({ - getToken: () => 'DEFAULT_TOKEN', - isLoggedIn: () => vi.fn(), - destroy: () => vi.fn(), - }), -})); +vi.mock('src/composables/useSession'); +vi.mock('src/composables/useNotify'); +vi.mock('src/stores/useStateQueryStore'); -vi.mock('src/stores/useStateQueryStore', () => ({ - useStateQueryStore: () => ({ - add: () => vi.fn(), - remove: () => vi.fn(), - }), -})); +// vi.mock('src/composables/useSession', () => ({ +// useSession: () => ({ +// getToken: () => 'DEFAULT_TOKEN', +// isLoggedIn: () => vi.fn(), +// destroy: () => vi.fn(), +// }), +// })); + +// vi.mock('src/stores/useStateQueryStore', () => ({ +// useStateQueryStore: () => ({ +// add: () => vi.fn(), +// remove: () => vi.fn(), +// }), +// })); describe('Axios boot', () => { + let sessionMock, notifyMock, stateQueryMock; + + beforeEach(() => { + sessionMock = { + getToken: vi.fn().mockReturnValue('DEFAULT_TOKEN'), + isLoggedIn: vi.fn().mockReturnValue(true), + destroy: vi.fn(), + }; + + notifyMock = { + notify: vi.fn(), + }; + + stateQueryMock = { + add: vi.fn(), + remove: vi.fn(), + }; + + useSession.mockReturnValue(sessionMock); + useNotify.mockReturnValue(notifyMock); + useStateQueryStore.mockReturnValue(stateQueryMock); + + setupAxios(); + }); describe('onRequest()', async () => { it('should set the "Authorization" property on the headers', async () => { const config = { headers: {} }; From b0bb09e9a66f619fee6621f633577f76566e4440 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 09:03:18 +0100 Subject: [PATCH 173/207] perf: refs #7308 #7308 remove comments --- test/vitest/__tests__/boot/axios.spec.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js index dc321a658..3c59dbc48 100644 --- a/test/vitest/__tests__/boot/axios.spec.js +++ b/test/vitest/__tests__/boot/axios.spec.js @@ -8,21 +8,6 @@ vi.mock('src/composables/useSession'); vi.mock('src/composables/useNotify'); vi.mock('src/stores/useStateQueryStore'); -// vi.mock('src/composables/useSession', () => ({ -// useSession: () => ({ -// getToken: () => 'DEFAULT_TOKEN', -// isLoggedIn: () => vi.fn(), -// destroy: () => vi.fn(), -// }), -// })); - -// vi.mock('src/stores/useStateQueryStore', () => ({ -// useStateQueryStore: () => ({ -// add: () => vi.fn(), -// remove: () => vi.fn(), -// }), -// })); - describe('Axios boot', () => { let sessionMock, notifyMock, stateQueryMock; From 2bcd7061cb00f7450f005d18e774dc5ffbedc0a0 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 09:50:00 +0000 Subject: [PATCH 174/207] revert e57a253c6f649382da187d1129449d265fb26d3b revert Merge pull request '#7308 Remove console warnings' (!928) from 7308-warning_inject into dev Reviewed-on: https://gitea.verdnatura.es/verdnatura/salix-front/pulls/928 Reviewed-by: Alex Moreno <alexm@verdnatura.es> --- src/boot/axios.js | 19 ++++----- src/boot/quasar.js | 2 - src/composables/useSession.js | 8 +--- src/router/index.js | 8 ++-- test/vitest/__tests__/boot/axios.spec.js | 49 ++++++++---------------- 5 files changed, 29 insertions(+), 57 deletions(-) diff --git a/src/boot/axios.js b/src/boot/axios.js index 5da26a404..aee38e887 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -4,8 +4,9 @@ import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; import { useStateQueryStore } from 'src/stores/useStateQueryStore'; -let session, notify, stateQuery; - +const session = useSession(); +const { notify } = useNotify(); +const stateQuery = useStateQueryStore(); const baseUrl = '/api/'; axios.defaults.baseURL = baseUrl; @@ -50,15 +51,9 @@ const onResponseError = (error) => { return Promise.reject(error); }; -export function setupAxios() { - session = useSession(); - notify = useNotify().notify; - stateQuery = useStateQueryStore(); - - axios.interceptors.request.use(onRequest, onRequestError); - axios.interceptors.response.use(onResponse, onResponseError); - axiosNoError.interceptors.request.use(onRequest); - axiosNoError.interceptors.response.use(onResponse); -} +axios.interceptors.request.use(onRequest, onRequestError); +axios.interceptors.response.use(onResponse, onResponseError); +axiosNoError.interceptors.request.use(onRequest); +axiosNoError.interceptors.response.use(onResponse); export { onRequest, onResponseError, axiosNoError }; diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 1cc2e82cf..01fe68d8b 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -1,7 +1,6 @@ import { boot } from 'quasar/wrappers'; import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; -import { setupAxios } from 'src/boot/axios'; import useNotify from 'src/composables/useNotify.js'; import { CanceledError } from 'axios'; @@ -49,5 +48,4 @@ export default boot(({ app }) => { notify(message ?? 'globals.error', 'negative', 'error'); }; - setupAxios(); }); diff --git a/src/composables/useSession.js b/src/composables/useSession.js index 5097a1fee..633a30bb0 100644 --- a/src/composables/useSession.js +++ b/src/composables/useSession.js @@ -8,13 +8,9 @@ import useNotify from './useNotify'; import { useTokenConfig } from './useTokenConfig'; const TOKEN_MULTIMEDIA = 'tokenMultimedia'; const TOKEN = 'token'; -let router; -export default { - setup() { - router = useRouter(); - }, -}; + export function useSession() { + const router = useRouter(); const { notify } = useNotify(); let isCheckingToken = false; let intervalId = null; diff --git a/src/router/index.js b/src/router/index.js index 5ed8ad9ed..18541c0b2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -14,8 +14,8 @@ import { useUserConfig } from 'src/composables/useUserConfig'; import { useTokenConfig } from 'src/composables/useTokenConfig'; import { useAcl } from 'src/composables/useAcl'; -let state, session; - +const state = useState(); +const session = useSession(); const { t, te } = i18n.global; const createHistory = process.env.SERVER @@ -43,10 +43,8 @@ const Router = createRouter({ * with the Router instance. */ export { Router }; -export default route((/* { store, ssrContext } */) => { +export default route(function (/* { store, ssrContext } */) { Router.beforeEach(async (to, from, next) => { - state = useState(); - session = useSession(); const { isLoggedIn } = session; const outLayout = Router.options.routes[0].children.map((r) => r.name); if (!isLoggedIn() && !outLayout.includes(to.name)) { diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js index 3c59dbc48..19d396ec5 100644 --- a/test/vitest/__tests__/boot/axios.spec.js +++ b/test/vitest/__tests__/boot/axios.spec.js @@ -1,38 +1,23 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { setupAxios, onRequest, onResponseError } from 'src/boot/axios'; -import { useSession } from 'src/composables/useSession'; -import useNotify from 'src/composables/useNotify'; -import { useStateQueryStore } from 'src/stores/useStateQueryStore'; +import { Notify } from 'quasar'; +import { onRequest, onResponseError } from 'src/boot/axios'; +import { describe, expect, it, vi } from 'vitest'; -vi.mock('src/composables/useSession'); -vi.mock('src/composables/useNotify'); -vi.mock('src/stores/useStateQueryStore'); +vi.mock('src/composables/useSession', () => ({ + useSession: () => ({ + getToken: () => 'DEFAULT_TOKEN', + isLoggedIn: () => vi.fn(), + destroy: () => vi.fn(), + }), +})); + +vi.mock('src/stores/useStateQueryStore', () => ({ + useStateQueryStore: () => ({ + add: () => vi.fn(), + remove: () => vi.fn(), + }), +})); describe('Axios boot', () => { - let sessionMock, notifyMock, stateQueryMock; - - beforeEach(() => { - sessionMock = { - getToken: vi.fn().mockReturnValue('DEFAULT_TOKEN'), - isLoggedIn: vi.fn().mockReturnValue(true), - destroy: vi.fn(), - }; - - notifyMock = { - notify: vi.fn(), - }; - - stateQueryMock = { - add: vi.fn(), - remove: vi.fn(), - }; - - useSession.mockReturnValue(sessionMock); - useNotify.mockReturnValue(notifyMock); - useStateQueryStore.mockReturnValue(stateQueryMock); - - setupAxios(); - }); describe('onRequest()', async () => { it('should set the "Authorization" property on the headers', async () => { const config = { headers: {} }; From c4a4f7fcd632bbc99d9a46c4ff546f6e64a2c7f1 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Thu, 14 Nov 2024 11:20:16 +0100 Subject: [PATCH 175/207] refactor: refs #6818 change channel source --- src/components/ui/VnLinkPhone.vue | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index 3b63889e1..4c045968f 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -17,19 +17,12 @@ const config = reactive({ const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; onBeforeMount(async () => { - let url; let { channel } = config[type]; if (type === 'say-simple') { - url = (await axios.get('SaySimpleConfigs/findOne')).data.url; - if (!channel) - channel = ( - await axios.get('SaySimpleCountries/findOne', { - params: { - filter: { fields: ['channel'], where: { countryFk: 0 } }, - }, - }) - ).data?.channel; + const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne')) + .data; + if (!channel) channel = defaultChannel; config[ type From ecf131ba78847e8eb8c0f02bff45f3e495da9a8b Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 12:06:12 +0100 Subject: [PATCH 176/207] feat: move buttons to DescriptorMenu --- .../Customer/Card/CustomerDescriptor.vue | 34 -------------- .../Customer/Card/CustomerDescriptorMenu.vue | 44 +++++++++++++++++++ src/pages/Ticket/TicketList.vue | 12 ++--- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue index 974b05181..e46d2cb29 100644 --- a/src/pages/Customer/Card/CustomerDescriptor.vue +++ b/src/pages/Customer/Card/CustomerDescriptor.vue @@ -174,23 +174,6 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit > <QTooltip>{{ t('Customer ticket list') }}</QTooltip> </QBtn> - <QBtn - :to="{ - name: 'TicketList', - query: { - table: JSON.stringify({ - clientFk: entity.id, - }), - createForm: JSON.stringify({ clientId: entity.id }), - }, - }" - size="md" - color="primary" - target="_blank" - icon="vn:ticketAdd" - > - <QTooltip>{{ t('New ticket') }}</QTooltip> - </QBtn> <QBtn :to="{ name: 'InvoiceOutList', @@ -202,23 +185,6 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit > <QTooltip>{{ t('Customer invoice out list') }}</QTooltip> </QBtn> - <QBtn - :to="{ - name: 'OrderList', - query: { - table: JSON.stringify({ - clientFk: entity.id, - }), - createForm: JSON.stringify({ clientFk: entity.id }), - }, - }" - size="md" - target="_blank" - icon="vn:basketadd" - color="primary" - > - <QTooltip>{{ t('New order') }}</QTooltip> - </QBtn> <QBtn :to="{ name: 'AccountSummary', diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue index 7af415820..5ef217a31 100644 --- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue +++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue @@ -40,9 +40,53 @@ const sendSms = async (payload) => { notify(error.message, 'positive'); } }; + +const openTicketCreateForm = () => { + const query = { + table: { + clientFk: $props.customer.id, + }, + createForm: { + clientId: $props.customer.id, + addressId: $props.customer.defaultAddressFk, + }, + }; + openWindow('ticket', query); +}; +const openOrderCreateForm = () => { + const query = { + table: { + clientFk: $props.customer.id, + }, + createForm: { + clientFk: $props.customer.id, + addressId: $props.customer.defaultAddressFk, + }, + }; + openWindow('order', query); +}; + +const openWindow = (type, { createForm, table }) => { + window.open( + `/#/${type}/list?createForm=${JSON.stringify(createForm)}&table=${JSON.stringify( + table + )}`, + '_blank' + ); +}; </script> <template> + <QItem v-ripple clickable @click="openTicketCreateForm()"> + <QItemSection> + {{ t('globals.pageTitles.createTicket') }} + </QItemSection> + </QItem> + <QItem v-ripple clickable @click="openOrderCreateForm()"> + <QItemSection> + {{ t('globals.pageTitles.createOrder') }} + </QItemSection> + </QItem> <QItem v-ripple clickable> <QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection> </QItem> diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index a3876a1a6..0685217ac 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -45,6 +45,13 @@ const userParams = { from: null, to: null, }; + +onMounted(() => { + initializeFromQuery(); + stateStore.rightDrawer = true; + if (!route.query.createForm) return; + onClientSelected(JSON.parse(route.query.createForm)); +}); // Método para inicializar las variables desde la query string const initializeFromQuery = () => { const query = route.query.table ? JSON.parse(route.query.table) : {}; @@ -301,11 +308,6 @@ const getDateColor = (date) => { if (comparation < 0) return 'bg-success'; }; -onMounted(() => { - initializeFromQuery(); - stateStore.rightDrawer = true; -}); - async function makeInvoice(ticket) { const ticketsIds = ticket.map((item) => item.id); const { data } = await axios.post(`Tickets/invoiceTicketsAndPdf`, { ticketsIds }); From 291e97e540b7a16e7fa6587fe233d5e648b2e853 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 14 Nov 2024 12:48:33 +0100 Subject: [PATCH 177/207] feat: #6943 use openURL quasar --- src/composables/useOpenURL.js | 8 ++++ .../Customer/Card/CustomerDescriptorMenu.vue | 40 +++++++------------ 2 files changed, 22 insertions(+), 26 deletions(-) create mode 100644 src/composables/useOpenURL.js diff --git a/src/composables/useOpenURL.js b/src/composables/useOpenURL.js new file mode 100644 index 000000000..008774c20 --- /dev/null +++ b/src/composables/useOpenURL.js @@ -0,0 +1,8 @@ +import { openURL } from 'quasar'; +const defaultWindowFeatures = { + noopener: true, + noreferrer: true, +}; +export default function (url, windowFeatures = defaultWindowFeatures, fn = undefined) { + openURL(url, fn, windowFeatures); +} diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue index 5ef217a31..aeaeaef57 100644 --- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue +++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue @@ -6,8 +6,8 @@ import axios from 'axios'; import { useQuasar } from 'quasar'; import useNotify from 'src/composables/useNotify'; - import VnSmsDialog from 'src/components/common/VnSmsDialog.vue'; +import useOpenURL from 'src/composables/useOpenURL'; const $props = defineProps({ customer: { @@ -15,7 +15,6 @@ const $props = defineProps({ required: true, }, }); - const { notify } = useNotify(); const { t } = useI18n(); const quasar = useQuasar(); @@ -41,48 +40,37 @@ const sendSms = async (payload) => { } }; -const openTicketCreateForm = () => { +const openCreateForm = (type) => { const query = { table: { clientFk: $props.customer.id, }, createForm: { - clientId: $props.customer.id, addressId: $props.customer.defaultAddressFk, }, }; - openWindow('ticket', query); -}; -const openOrderCreateForm = () => { - const query = { - table: { - clientFk: $props.customer.id, - }, - createForm: { - clientFk: $props.customer.id, - addressId: $props.customer.defaultAddressFk, - }, + const clientFk = { + ticket: 'clientId', + order: 'clientFk', }; - openWindow('order', query); -}; + const key = clientFk[type]; + if (!key) return; + query.createForm[key] = $props.customer.id; -const openWindow = (type, { createForm, table }) => { - window.open( - `/#/${type}/list?createForm=${JSON.stringify(createForm)}&table=${JSON.stringify( - table - )}`, - '_blank' - ); + const params = Object.entries(query) + .map(([key, value]) => `${key}=${JSON.stringify(value)}`) + .join('&'); + useOpenURL(`/#/${type}/list?${params}`); }; </script> <template> - <QItem v-ripple clickable @click="openTicketCreateForm()"> + <QItem v-ripple clickable @click="openCreateForm('ticket')"> <QItemSection> {{ t('globals.pageTitles.createTicket') }} </QItemSection> </QItem> - <QItem v-ripple clickable @click="openOrderCreateForm()"> + <QItem v-ripple clickable @click="openCreateForm('order')"> <QItemSection> {{ t('globals.pageTitles.createOrder') }} </QItemSection> From 7224860c5cd5359dd04685e58aefb04c6b7dce55 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Thu, 14 Nov 2024 13:51:39 +0100 Subject: [PATCH 178/207] feat: refs #6839 normalize search --- src/components/LeftMenu.vue | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index 6e0ae5907..b02c0d014 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -34,18 +34,26 @@ const search = ref(null); const filteredItems = computed(() => { if (!search.value) return items.value; + const normalizedSearch = normalize(search.value); return items.value.filter((item) => { - const locale = t(item.title).toLowerCase(); - return locale.includes(search.value.toLowerCase()); + const locale = normalize(t(item.title)); + return locale.includes(normalizedSearch); }); }); const filteredPinnedModules = computed(() => { if (!search.value) return pinnedModules.value; + const normalizedSearch = search.value + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); const map = new Map(); for (const [key, pinnedModule] of pinnedModules.value) { - const locale = t(pinnedModule.title).toLowerCase(); - if (locale.includes(search.value.toLowerCase())) map.set(key, pinnedModule); + const locale = t(pinnedModule.title) + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); + if (locale.includes(normalizedSearch)) map.set(key, pinnedModule); } return map; }); @@ -147,6 +155,13 @@ async function togglePinned(item, event) { const handleItemExpansion = (itemName) => { expansionItemElements[itemName].scrollToLastElement(); }; + +function normalize(text) { + return text + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); +} </script> <template> From 59b40fed45f18c0847c73f102fb409904583c03d Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Thu, 14 Nov 2024 15:57:01 +0100 Subject: [PATCH 179/207] feat: refs #7874 improve vn-notes ui --- src/components/ui/VnNotes.vue | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index b395b3934..2164f668e 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -65,15 +65,8 @@ onBeforeRouteLeave((to, from, next) => { auto-load @on-fetch="(data) => (observationTypes = data)" /> - <QCard class="q-pa-xs q-mb-xl full-width" v-if="$props.addNote"> - <QCardSection horizontal> - <VnAvatar :worker-id="currentUser.id" size="md" /> - <div class="full-width row justify-between q-pa-xs"> - <VnUserLink :name="t('New note')" :worker-id="currentUser.id" /> - {{ t('globals.now') }} - </div> - </QCardSection> - <QCardSection class="q-px-xs q-my-none q-py-none"> + <QCard class="q-pa-xs q-mb-lg full-width" v-if="$props.addNote"> + <QCardSection class="q-px-xs q-mt-sm q-py-none"> <VnRow class="full-width"> <VnSelect :label="t('Observation type')" @@ -144,7 +137,7 @@ onBeforeRouteLeave((to, from, next) => { <div class="full-width row justify-between q-pa-xs"> <div> <VnUserLink - :name="`${note.worker.user.nickname}`" + :name="`${note.worker.user.name}`" :worker-id="note.worker.id" /> <QBadge From 8e0b098756ecb29e3b0e4c6707dcb8a5588b0f51 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Thu, 14 Nov 2024 16:01:09 +0100 Subject: [PATCH 180/207] fix: refs #7874 add title --- src/components/ui/VnNotes.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index 2164f668e..dbcb2f3fe 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -66,7 +66,10 @@ onBeforeRouteLeave((to, from, next) => { @on-fetch="(data) => (observationTypes = data)" /> <QCard class="q-pa-xs q-mb-lg full-width" v-if="$props.addNote"> - <QCardSection class="q-px-xs q-mt-sm q-py-none"> + <QCardSection horizontal> + {{ t('New note') }} + </QCardSection> + <QCardSection class="q-px-xs q-my-none q-py-none"> <VnRow class="full-width"> <VnSelect :label="t('Observation type')" From 2bc219a09b8b059d0468510b910e1d9b5561b2bb Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 18 Nov 2024 06:59:09 +0100 Subject: [PATCH 181/207] refactor: refs #8185 modified LeftMenu to avoid duplicates --- src/components/LeftMenu.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index 6e0ae5907..3bbb5b046 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -22,7 +22,7 @@ const props = defineProps({ default: 'main', }, }); - +const initialized = ref(false); const items = ref([]); const expansionItemElements = reactive({}); const pinnedModules = computed(() => { @@ -53,11 +53,13 @@ const filteredPinnedModules = computed(() => { onMounted(async () => { await navigation.fetchPinned(); getRoutes(); + initialized.value = true; }); watch( () => route.matched, () => { + if (!initialized.value) return; items.value = []; getRoutes(); }, From f52095a2fcb6b7fbd783e09456996f5a927f9a43 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Mon, 18 Nov 2024 10:57:49 +0100 Subject: [PATCH 182/207] Merge branch 'test' into solveConflicts_test_to_dev --- src/pages/Claim/ClaimFilter.vue | 2 +- .../Card/BasicData/TicketBasicDataForm.vue | 109 +++++++----------- src/pages/Ticket/TicketList.vue | 59 ++++++---- 3 files changed, 77 insertions(+), 93 deletions(-) diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue index dc25fe4a0..f7e2ffbf6 100644 --- a/src/pages/Claim/ClaimFilter.vue +++ b/src/pages/Claim/ClaimFilter.vue @@ -23,7 +23,7 @@ defineExpose({ states }); <template> <FetchData url="ClaimStates" @on-fetch="(data) => (states = data)" auto-load /> - <VnFilterPanel :data-key="props.dataKey" :search-button="true" search-url="table"> + <VnFilterPanel :data-key="props.dataKey" :search-button="true"> <template #tags="{ tag, formatFn }"> <div class="q-gutter-x-xs"> <strong>{{ t(`params.${tag.label}`) }}: </strong> diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue index 8c6d454c0..1fc54f486 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue @@ -16,12 +16,9 @@ import { useAcl } from 'src/composables/useAcl'; import { useValidator } from 'src/composables/useValidator'; import { toTimeFormat } from 'filters/date.js'; -const $props = defineProps({ - formData: { - type: Object, - required: true, - default: () => ({}), - }, +const formData = defineModel({ + type: Object, + required: true, }); const emit = defineEmits(['updateForm']); @@ -40,7 +37,6 @@ const agenciesOptions = ref([]); const zonesOptions = ref([]); const addresses = ref([]); const zoneSelectRef = ref(); -const formData = ref($props.formData); watch( () => formData.value, @@ -69,47 +65,28 @@ const zoneWhere = computed(() => { : {}; }); -const getLanded = async (params) => { - try { - const validParams = - shipped.value && addressId.value && agencyModeId.value && warehouseId.value; - if (!validParams) return; +async function getLanded(params) { + getDate(`Agencies/getLanded`, params); +} - formData.value.zoneFk = null; - zonesOptions.value = []; - const { data } = await axios.get(`Agencies/getLanded`, { params }); - if (data) { - formData.value.zoneFk = data.zoneFk; - formData.value.landed = data.landed; - formData.value.shipped = params.shipped; - } - } catch (error) { - console.error(error); - notify(t('basicData.noDeliveryZoneAvailable'), 'negative'); +async function getShipped(params) { + getDate(`Agencies/getShipped`, params); +} + +async function getDate(query, params) { + for (const param in params) { + if (!params[param]) return; } -}; -const getShipped = async (params) => { - try { - const validParams = - landed.value && addressId.value && agencyModeId.value && warehouseId.value; - if (!validParams) return; + formData.value.zoneFk = null; + zonesOptions.value = []; + const { data } = await axios.get(query, { params }); + if (!data) return notify(t('basicData.noDeliveryZoneAvailable'), 'negative'); - formData.value.zoneFk = null; - zonesOptions.value = []; - const { data } = await axios.get(`Agencies/getShipped`, { params }); - if (data) { - formData.value.zoneFk = data.zoneFk; - formData.value.landed = params.landed; - formData.value.shipped = data.shipped; - } else { - notify(t('basicData.noDeliveryZoneAvailable'), 'negative'); - } - } catch (error) { - console.error(error); - notify(t('basicData.noDeliveryZoneAvailable'), 'negative'); - } -}; + formData.value.zoneFk = data.zoneFk; + if (data.landed) formData.value.landed = data.landed; + if (data.shipped) formData.value.shipped = data.shipped; +} const onChangeZone = async (zoneId) => { formData.value.agencyModeFk = null; @@ -177,18 +154,26 @@ const clientId = computed({ }, }); -const landed = computed({ - get: () => formData.value?.landed, - set: (val) => { - formData.value.landed = val; - getShipped({ - landed: val, +function addDateParams(obj) { + return { + ...obj, + ...{ addressFk: formData.value?.addressFk, agencyModeFk: formData.value?.agencyModeFk, warehouseFk: formData.value?.warehouseFk, - }); - }, -}); + }, + }; +} + +async function setLanded(landed) { + if (!landed) return; + getShipped(addDateParams({ landed })); +} + +async function setShipped(shipped) { + if (!shipped) return; + getLanded(addDateParams({ shipped })); +} const agencyModeId = computed({ get: () => formData.value.agencyModeFk, @@ -236,21 +221,6 @@ const warehouseId = computed({ }, }); -const shipped = computed({ - get: () => formData.value?.shipped, - set: (val) => { - if (new Date(formData.value?.shipped).toDateString() != val.toDateString()) - val.setHours(0, 0, 0, 0); - formData.value.shipped = val; - getLanded({ - shipped: val, - addressFk: formData.value?.addressFk, - agencyModeFk: formData.value?.agencyModeFk, - warehouseFk: formData.value?.warehouseFk, - }); - }, -}); - const onFormModelInit = () => { if (formData.value?.clientFk) clientAddressesList(formData.value?.clientFk); }; @@ -451,18 +421,21 @@ async function getZone(options) { v-model="formData.shipped" :required="true" :rules="validate('ticketList.shipped')" + @update:model-value="setShipped" /> <VnInputTime :label="t('basicData.shippedHour')" v-model="formData.shipped" :required="true" :rules="validate('basicData.shippedHour')" + @update:model-value="setShipped" /> <VnInputDate :label="t('basicData.landed')" v-model="formData.landed" :required="true" :rules="validate('basicData.landed')" + @update:model-value="setLanded" /> </VnRow> </QForm> diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index 0685217ac..aae6f80a7 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -1,7 +1,7 @@ <script setup> import axios from 'axios'; import { computed, ref, onMounted } from 'vue'; -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import { useStateStore } from 'stores/useStateStore'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; @@ -18,12 +18,13 @@ import RightMenu from 'src/components/common/RightMenu.vue'; import TicketFilter from './TicketFilter.vue'; import VnInput from 'src/components/common/VnInput.vue'; import FetchData from 'src/components/FetchData.vue'; -import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue'; -import ZoneDescriptorProxy from '../Zone/Card/ZoneDescriptorProxy.vue'; +import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; +import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import { toTimeFormat } from 'src/filters/date'; -import InvoiceOutDescriptorProxy from '../InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; +import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; const route = useRoute(); +const router = useRouter(); const { t } = useI18n(); const { viewSummary } = useSummaryDialog(); const tableRef = ref(); @@ -40,23 +41,18 @@ from.setDate(from.getDate() - 7); const to = Date.vnNew(); to.setHours(23, 59, 0, 0); to.setDate(to.getDate() + 1); - const userParams = { from: null, to: null, }; - onMounted(() => { initializeFromQuery(); stateStore.rightDrawer = true; if (!route.query.createForm) return; onClientSelected(JSON.parse(route.query.createForm)); }); -// Método para inicializar las variables desde la query string const initializeFromQuery = () => { const query = route.query.table ? JSON.parse(route.query.table) : {}; - - // Asigna los valores a las variables correspondientes from.value = query.from || from.toISOString(); to.value = query.to || to.toISOString(); Object.assign(userParams, { from, to }); @@ -213,13 +209,19 @@ const columns = computed(() => [ { title: t('components.smartCard.viewSummary'), icon: 'preview', - isPrimary: true, - action: (row) => viewSummary(row.id, TicketSummary), + action: (row, evt) => { + if (evt && evt.ctrlKey) { + const url = router.resolve({ + params: { id: row.id }, + name: 'TicketCard', + }).href; + window.open(url, '_blank'); + } else viewSummary(row.id, TicketSummary); + }, }, ], }, ]); - function redirectToLines(id) { const url = `#/ticket/${id}/sale`; window.open(url, '_blank'); @@ -456,24 +458,24 @@ function setReference(data) { auto-load /> <VnSearchbar - data-key="Ticket" + data-key="TicketList" :label="t('Search ticket')" :info="t('You can search by ticket id or alias')" /> <RightMenu> <template #right-panel> - <TicketFilter data-key="Ticket" /> + <TicketFilter data-key="TicketList" /> </template> </RightMenu> <VnTable ref="tableRef" - data-key="Ticket" + data-key="TicketList" url="Tickets/filter" :create="{ urlCreate: 'Tickets/new', title: t('ticketList.createTicket'), onDataSaved: ({ id }) => tableRef.redirect(id), - formInitialData: {}, + formInitialData: { clientId: null }, }" default-mode="table" :order="['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id']" @@ -575,17 +577,17 @@ function setReference(data) { </span> </template> <template #column-stateFk="{ row }"> - <span v-if="getColor(row)"> - <QChip :class="getColor(row)" dense square> - {{ row.state }} - </QChip> - </span> - <span v-else-if="row.state === 'Entregado'"> + <span v-if="row.refFk"> <span class="link" @click.stop> {{ row.refFk }} <InvoiceOutDescriptorProxy :id="row.invoiceOutId" /> </span> </span> + <span v-else-if="getColor(row)"> + <QChip :class="getColor(row)" dense square> + {{ row.state }} + </QChip> + </span> <span v-else> {{ row.state }} </span> @@ -617,6 +619,7 @@ function setReference(data) { option-value="id" option-label="name" hide-selected + required @update:model-value="(client) => onClientSelected(data)" :sort-by="'id ASC'" > @@ -643,6 +646,7 @@ function setReference(data) { option-label="nickname" hide-selected map-options + required :disable="!data.clientId" :sort-by="'isActive DESC'" @update:model-value="() => fetchAvailableAgencies(data)" @@ -693,6 +697,7 @@ function setReference(data) { option-value="id" option-label="name" hide-selected + required @update:model-value="() => fetchAvailableAgencies(data)" /> </div> @@ -706,7 +711,6 @@ function setReference(data) { option-value="agencyModeFk" option-label="agencyMode" hide-selected - :disable="!data.clientId || !data.landed || !data.warehouseId" /> </div> </VnRow> @@ -842,7 +846,14 @@ function setReference(data) { </QTooltip> </QPageSticky> </template> - +<style scoped> +.disabled, +.disabled *, +[disabled], +[disabled] * { + cursor: pointer !important; +} +</style> <i18n> es: Search ticket: Buscar ticket From 0c0b9ca648426bc8aaa91ad46b5902dd178e70ac Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 18 Nov 2024 12:27:07 +0100 Subject: [PATCH 183/207] fix: changed route.query --- src/filters/getParamWhere.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filters/getParamWhere.js b/src/filters/getParamWhere.js index 22dd69af1..ef00a93ae 100644 --- a/src/filters/getParamWhere.js +++ b/src/filters/getParamWhere.js @@ -9,7 +9,7 @@ function parseJSON(str, fallback) { } export default function (route, param) { // catch route query params - const params = parseJSON(route?.query?.params, {}); + const params = parseJSON(route?.query?.table, {}); // extract and parse filter from params const { filter: filterStr = '{}' } = params; From 8d997b5a7a0f2030d2dc78c251e079861608cc72 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 19 Nov 2024 07:59:48 +0100 Subject: [PATCH 184/207] build: refs #8144 change package version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e2e75f253..0ee43ce12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "24.44.0", + "version": "24.48.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", @@ -64,4 +64,4 @@ "vite": "^5.1.4", "vitest": "^0.31.1" } -} +} \ No newline at end of file From 38ccf464b761e4724c5688a6e01af39a16c07d59 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 19 Nov 2024 11:52:00 +0100 Subject: [PATCH 185/207] fix: refs #7323 locale #7396 --- src/i18n/locale/en.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index ae7007c32..531b3bc14 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -583,15 +583,15 @@ worker: role: Role sipExtension: Extension locker: Locker - fiDueDate: Fecha de caducidad del DNI - sex: Sexo - seniority: Antigüedad + fiDueDate: FI due date + sex: Sex + seniority: Seniority fi: DNI/NIE/NIF - birth: Fecha de nacimiento - isFreelance: Autónomo + birth: Birth + isFreelance: Freelance isSsDiscounted: Bonificación SS - hasMachineryAuthorized: Autorizado para llevar maquinaria - isDisable: Trabajador desactivado + hasMachineryAuthorized: Machinery authorized + isDisable: Disable notificationsManager: activeNotifications: Active notifications availableNotifications: Available notifications From 1faab668b16baceb6ebec80c9075b1e38ff12acd Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Tue, 19 Nov 2024 11:53:33 +0100 Subject: [PATCH 186/207] fix: refs #7323 show advanced fields --- src/i18n/locale/es.yml | 6 +++--- src/pages/Worker/Card/WorkerSummary.vue | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index eb0978ddd..9bfa43c49 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -579,9 +579,9 @@ worker: newWorker: Nuevo trabajador summary: boss: Jefe - phoneExtension: Extensión de teléfono - entPhone: Teléfono de empresa - personalPhone: Teléfono personal + phoneExtension: Ext. de teléfono + entPhone: Tel. de empresa + personalPhone: Tel. personal noBoss: Sin jefe userData: Datos de usuario userId: ID del usuario diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index 93866b79f..496f1ca16 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -75,10 +75,10 @@ onBeforeMount(async () => { <VnLinkPhone :phone-number="worker.phone" /> </template> </VnLv> - <VnLv :value="worker.client?.phone"> + <VnLv :value="advancedSummary?.client?.phone"> <template #label> {{ t('worker.summary.personalPhone') }} - <VnLinkPhone :phone-number="worker.client?.phone" /> + <VnLinkPhone :phone-number="advancedSummary?.client?.phone" /> </template> </VnLv> </QCard> @@ -86,12 +86,12 @@ onBeforeMount(async () => { <VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" /> <VnLv :label="t('worker.summary.fiDueDate')" - :value="toDate(worker.fiDueDate)" + :value="toDate(advancedSummary.fiDueDate)" /> <VnLv :label="t('worker.summary.sex')" :value="worker.sex" /> <VnLv :label="t('worker.summary.seniority')" - :value="toDate(worker.seniority)" + :value="toDate(advancedSummary.seniority)" /> <VnLv :label="t('worker.summary.fi')" :value="advancedSummary.fi" /> <VnLv From 5515f55bf69d3f2121410d28bdf5f35c4f9557b0 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 19 Nov 2024 12:51:05 +0100 Subject: [PATCH 187/207] test: fix e2e --- .../integration/client/clientList.spec.js | 31 ++++++++++++++----- .../vnComponent/vnLocation.spec.js | 6 ++-- test/cypress/support/commands.js | 6 ++-- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 93e53b9f6..b87ddff3b 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -6,7 +6,11 @@ describe('Client list', () => { cy.visit('/#/customer/list', { timeout: 5000, onBeforeLoad(win) { - cy.stub(win, 'open'); + cy.stub(win, 'open') + .callsFake((url) => { + return win.open.wrappedMethod.call(win, url, '_self'); + }) + .as('Open'); }, }); }); @@ -44,20 +48,31 @@ describe('Client list', () => { }); }); - it('Client founded create ticket', () => { + it.only('Client founded create ticket', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); - cy.clickButtonsDescriptor(2); + cy.openActionDescriptor('Create ticket'); cy.waitForElement('#formModel'); - cy.waitForElement('.q-form'); - cy.checkValueForm(1, search); + cy.waitForElement('.q-form', { timeout: 5000 }); + cy.checkValueSelectForm(1, 1110); + cy.checkValueSelectForm(2, search); + // cy.get('@Open').should('have.been.calledOnceWithExactly', [ + // '/#/ticket/list?table={"clientFk":1110}&createForm={"addressId":10,"clientId":1110}', + // '_blank', + // 'noopener,noreferrer', + // ]); }); - it('Client founded create order', () => { + it.only('Client founded create order', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); - cy.clickButtonsDescriptor(4); + cy.openActionDescriptor('New order'); cy.waitForElement('#formModel'); - cy.waitForElement('.q-form'); + cy.waitForElement('.q-form', { timeout: 5000 }); + cy.checkValueForm(1, 1110); cy.checkValueForm(2, search); + // cy.get('@Open').should( + // 'have.been.calledOnceWithExactly', + // '"/#/order/list?table={"clientFk":1110}&createForm={"addressId":10,"clientFk":1110}", "_blank", "noopener,noreferrer"' + // ); }); }); diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 924b16adc..29e1f868f 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -15,10 +15,10 @@ describe('VnLocation', () => { cy.domContentLoad(); cy.get(createLocationButton).click(); }); - it('should filter provinces based on selected country', () => { + it.only('shoul d filter provinces based on selected country', () => { // Select a country cy.selectOption( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(5)> ${createForm.sufix}`, + `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, 'Ecuador' ); // Verify that provinces are filtered @@ -32,7 +32,7 @@ describe('VnLocation', () => { ).should('have.length', 1); }); - it('should filter towns based on selected province', () => { + it.only('should filter towns based on selected province', () => { // Select a country cy.selectOption( `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 34aadad1d..b92bbe269 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -295,16 +295,16 @@ Cypress.Commands.add('checkNotification', (text) => { throw new Error(`Notification not found: "${text}"`); }); }); - +// :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container Cypress.Commands.add('checkValueForm', (id, search) => { cy.get( - `.grid-create > :nth-child(${id}) > .q-field__inner>.q-field__control> .q-field__control-container>.q-field__native >.q-field__input` + `.grid-create > :nth-child(${id}) > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > .q-field__input` ).should('have.value', search); }); Cypress.Commands.add('checkValueSelectForm', (id, search) => { cy.get( - `.grid-create > :nth-child(${id}) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container>.q-field__native>.q-field__input` + `.grid-create > :nth-child(${id}) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > .q-field__input` ).should('have.value', search); }); From 65100fcf256f9c19494088c9c2b3d48422c8970b Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 19 Nov 2024 13:45:44 +0100 Subject: [PATCH 188/207] test: fix e2e --- test/cypress/integration/vnComponent/vnLocation.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 29e1f868f..0ee453aa0 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -15,7 +15,7 @@ describe('VnLocation', () => { cy.domContentLoad(); cy.get(createLocationButton).click(); }); - it.only('shoul d filter provinces based on selected country', () => { + it('should filter provinces based on selected country', () => { // Select a country cy.selectOption( `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, @@ -32,7 +32,7 @@ describe('VnLocation', () => { ).should('have.length', 1); }); - it.only('should filter towns based on selected province', () => { + it('should filter towns based on selected province', () => { // Select a country cy.selectOption( `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, From f43e974bbc595758ab316156b8e9f68d340b70f3 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Tue, 19 Nov 2024 14:14:50 +0100 Subject: [PATCH 189/207] fix: worker test e2e --- src/pages/Worker/WorkerList.vue | 2 +- test/cypress/support/commands.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 022cecdc6..71df273c1 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -306,7 +306,7 @@ async function autofillBic(worker) { </VnRow> <VnRow> <VnInput - :label="t('worker.create.street')" + :label="t('globals.street')" :model-value="uppercaseStreetModel(data).get()" @update:model-value="uppercaseStreetModel(data).set" :disable="data.isFreelance" diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 8d48dc71a..0e0cd7d07 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -100,7 +100,6 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => { case 'select': cy.wrap(el).type(val); cy.get('.q-menu .q-item').contains(val).click(); - cy.get('body').click(); break; case 'date': cy.wrap(el).type(val.split('-').join('')); From 8714980595e0cfa62e24b7a38f0553ad5c2290fa Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 19 Nov 2024 14:28:43 +0100 Subject: [PATCH 190/207] fix(VnSelect): setOptions when applyFilter --- src/components/common/VnSelect.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 227ff9465..f24f054a5 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -202,7 +202,10 @@ async function fetchFilter(val) { if (fields) fetchOptions.fields = fields; if (sortBy) fetchOptions.order = sortBy; arrayData.reset(['skip', 'filter.skip', 'page']); - return (await arrayData.applyFilter({ filter: fetchOptions }))?.data; + + const { data } = await arrayData.applyFilter({ filter: fetchOptions }); + setOptions(data); + return data; } async function filterHandler(val, update) { From 5f7fd91272c4a870de82ef8c42ef50166d7ad1e7 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Tue, 19 Nov 2024 14:41:07 +0100 Subject: [PATCH 191/207] feat: add /reports in gitignore --- test/cypress/.gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cypress/.gitignore b/test/cypress/.gitignore index 3f91dd465..8d940320e 100644 --- a/test/cypress/.gitignore +++ b/test/cypress/.gitignore @@ -1,2 +1,2 @@ -videos/* -screenshots/* \ No newline at end of file +reports/* +screenshots/* From b4ee19bcde76c9d44568b7742aeab673fdf61b50 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 19 Nov 2024 15:56:27 +0100 Subject: [PATCH 192/207] test: #8162 fix clientList spec --- .../integration/client/clientList.spec.js | 18 +++++----- .../vnComponent/vnLocation.spec.js | 35 ++++++------------- 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index b87ddff3b..b3ac9d3df 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -15,7 +15,7 @@ describe('Client list', () => { }); }); - it('Client list create new client', () => { + it.only('Client list create new client', () => { cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click(); const data = { Name: { val: 'Name 1' }, @@ -24,9 +24,9 @@ describe('Client list', () => { 'Web user': { val: 'user_test_1' }, Street: { val: 'C/ STREET 1' }, Email: { val: 'user.test@1.com' }, - 'Business type': { val: 'Otros', type: 'select' }, - 'Sales person': { val: 'salesboss', type: 'select' }, + 'Sales person': { val: 'employee', type: 'select' }, Location: { val: '46000, Valencia(Province one), España', type: 'select' }, + 'Business type': { val: 'Otros', type: 'select' }, }; cy.fillInForm(data); @@ -48,13 +48,13 @@ describe('Client list', () => { }); }); - it.only('Client founded create ticket', () => { + it('Client founded create ticket', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); cy.openActionDescriptor('Create ticket'); cy.waitForElement('#formModel'); - cy.waitForElement('.q-form', { timeout: 5000 }); - cy.checkValueSelectForm(1, 1110); + cy.waitForElement('.q-form'); + cy.checkValueSelectForm(1, search); cy.checkValueSelectForm(2, search); // cy.get('@Open').should('have.been.calledOnceWithExactly', [ // '/#/ticket/list?table={"clientFk":1110}&createForm={"addressId":10,"clientId":1110}', @@ -62,13 +62,13 @@ describe('Client list', () => { // 'noopener,noreferrer', // ]); }); - it.only('Client founded create order', () => { + it('Client founded create order', () => { const search = 'Jessica Jones'; cy.searchByLabel('Name', search); cy.openActionDescriptor('New order'); cy.waitForElement('#formModel'); - cy.waitForElement('.q-form', { timeout: 5000 }); - cy.checkValueForm(1, 1110); + cy.waitForElement('.q-form'); + cy.checkValueForm(1, search); cy.checkValueForm(2, search); // cy.get('@Open').should( // 'have.been.calledOnceWithExactly', diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 0ee453aa0..70c88b26f 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -7,6 +7,9 @@ describe('VnLocation', () => { prefix: '.q-dialog__inner > .column > #formModel > .q-card', sufix: ' .q-field__inner > .q-field__control', }; + const countrySelector = `${createForm.prefix} > :nth-child(5) > :nth-child(3) > ${createForm.sufix}`; + const provinceSelector = `${createForm.prefix} > :nth-child(5) > :nth-child(2) > ${createForm.sufix}`; + const citySelector = `${createForm.prefix} > :nth-child(4) > :nth-child(2) > ${createForm.sufix}`; describe('CreateFormDialog ', () => { beforeEach(() => { cy.viewport(1280, 720); @@ -17,45 +20,29 @@ describe('VnLocation', () => { }); it('should filter provinces based on selected country', () => { // Select a country - cy.selectOption( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, - 'Ecuador' - ); + cy.selectOption(countrySelector, 'Ecuador'); // Verify that provinces are filtered - cy.get( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}` - ).should('have.length', 1); + cy.get(countrySelector).should('have.length', 1); // Verify that towns are filtered - cy.get( - `${createForm.prefix} > :nth-child(4) > .q-field:nth-child(3)> ${createForm.sufix}` - ).should('have.length', 1); + cy.get(citySelector).should('have.length', 1); }); it('should filter towns based on selected province', () => { // Select a country - cy.selectOption( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}`, - 'Ecuador' - ); + cy.selectOption(countrySelector, 'Ecuador'); // Verify that provinces are filtered - cy.get( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(3)> ${createForm.sufix}` - ).should('have.length', 1); + cy.get(provinceSelector).should('have.length', 1); // Verify that towns are filtered - cy.get( - `${createForm.prefix} > :nth-child(4) > .q-field:nth-child(3)> ${createForm.sufix}` - ).should('have.length', 1); + cy.get(citySelector).should('have.length', 1); }); it('should pass selected country', () => { // Select a country const country = 'Ecuador'; const province = 'Province five'; - cy.selectOption( - `${createForm.prefix} > :nth-child(5) > .q-field:nth-child(5)> ${createForm.sufix}`, - country - ); + + cy.selectOption(countrySelector, country); cy.selectOption( `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix}`, province From 67a5800a6668af882d976182272706176776dc98 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 20 Nov 2024 07:57:45 +0100 Subject: [PATCH 193/207] fix: logout spec --- test/cypress/integration/outLogin/logout.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/outLogin/logout.spec.js index d6c33a65b..bcdacec78 100644 --- a/test/cypress/integration/outLogin/logout.spec.js +++ b/test/cypress/integration/outLogin/logout.spec.js @@ -28,7 +28,7 @@ describe('Logout', () => { }); it('when token not exists', () => { - cy.get('.q-list > [href="#/item"]').click(); + cy.get('.q-list').first().should('be.visible').click(); cy.checkNotification('Authorization Required'); }); }); From 3ba8402dfde616ec0a2a7430ad78acfccf62d755 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 20 Nov 2024 08:01:50 +0100 Subject: [PATCH 194/207] fix: vnSearchbar spec --- test/cypress/integration/vnComponent/vnSearchBar.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cypress/integration/vnComponent/vnSearchBar.spec.js b/test/cypress/integration/vnComponent/vnSearchBar.spec.js index 580199bc3..b8621118c 100644 --- a/test/cypress/integration/vnComponent/vnSearchBar.spec.js +++ b/test/cypress/integration/vnComponent/vnSearchBar.spec.js @@ -5,6 +5,7 @@ describe('VnSearchBar', () => { const idGap = '.q-item > .q-item__label'; const vnTableRow = '.q-virtual-scroll__content'; beforeEach(() => { + cy.viewport(1280, 720); cy.login('developer'); cy.visit('#/customer/list'); }); From 1fb927488a2df2a312cb06dee4f9880ef014db7e Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 09:26:33 +0100 Subject: [PATCH 195/207] test: #8162 fix clientList spec --- test/cypress/integration/client/clientList.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index b3ac9d3df..37983cc70 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -15,7 +15,7 @@ describe('Client list', () => { }); }); - it.only('Client list create new client', () => { + it('Client list create new client', () => { cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click(); const data = { Name: { val: 'Name 1' }, From e10ee5e6c77d4dceff48d9eaf0e97a7694461adb Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 09:26:40 +0100 Subject: [PATCH 196/207] test: #8162 fix vnLocation spec --- test/cypress/integration/vnComponent/vnLocation.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 70c88b26f..70a943688 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -107,7 +107,7 @@ describe('VnLocation', () => { cy.get(inputLocation).should('have.value', postCodeLabel); }); - it('Create postCode', () => { + it.only('Create postCode', () => { const postCode = '1234475'; const province = 'Valencia'; cy.get(createLocationButton).click(); From 226f604f9d1f27b2a9bc9b6bc92cd1a72ee12c50 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 09:37:47 +0100 Subject: [PATCH 197/207] test: #8162 fix vnLocation spec --- test/cypress/integration/vnComponent/vnLocation.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 70a943688..70c88b26f 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -107,7 +107,7 @@ describe('VnLocation', () => { cy.get(inputLocation).should('have.value', postCodeLabel); }); - it.only('Create postCode', () => { + it('Create postCode', () => { const postCode = '1234475'; const province = 'Valencia'; cy.get(createLocationButton).click(); From 9da04881841c5fc269f7fdeab4ed8f7f91790f0b Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 10:03:23 +0100 Subject: [PATCH 198/207] feat: remove comments --- test/cypress/integration/client/clientList.spec.js | 9 --------- .../integration/vnComponent/vnLocation.spec.js | 13 ------------- test/cypress/support/commands.js | 2 +- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index 37983cc70..431ac0548 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -56,11 +56,6 @@ describe('Client list', () => { cy.waitForElement('.q-form'); cy.checkValueSelectForm(1, search); cy.checkValueSelectForm(2, search); - // cy.get('@Open').should('have.been.calledOnceWithExactly', [ - // '/#/ticket/list?table={"clientFk":1110}&createForm={"addressId":10,"clientId":1110}', - // '_blank', - // 'noopener,noreferrer', - // ]); }); it('Client founded create order', () => { const search = 'Jessica Jones'; @@ -70,9 +65,5 @@ describe('Client list', () => { cy.waitForElement('.q-form'); cy.checkValueForm(1, search); cy.checkValueForm(2, search); - // cy.get('@Open').should( - // 'have.been.calledOnceWithExactly', - // '"/#/order/list?table={"clientFk":1110}&createForm={"addressId":10,"clientFk":1110}", "_blank", "noopener,noreferrer"' - // ); }); }); diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 70c88b26f..ef08af679 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -19,26 +19,17 @@ describe('VnLocation', () => { cy.get(createLocationButton).click(); }); it('should filter provinces based on selected country', () => { - // Select a country cy.selectOption(countrySelector, 'Ecuador'); - // Verify that provinces are filtered cy.get(countrySelector).should('have.length', 1); - - // Verify that towns are filtered cy.get(citySelector).should('have.length', 1); }); it('should filter towns based on selected province', () => { - // Select a country cy.selectOption(countrySelector, 'Ecuador'); - // Verify that provinces are filtered cy.get(provinceSelector).should('have.length', 1); - - // Verify that towns are filtered cy.get(citySelector).should('have.length', 1); }); it('should pass selected country', () => { - // Select a country const country = 'Ecuador'; const province = 'Province five'; @@ -67,13 +58,11 @@ describe('VnLocation', () => { cy.get(locationOptions).should('have.length.at.least', 5); }); it('input filter location as "al"', function () { - // cy.get(inputLocation).click(); cy.get(inputLocation).clear(); cy.get(inputLocation).type('al'); cy.get(locationOptions).should('have.length.at.least', 4); }); it('input filter location as "ecuador"', function () { - // cy.get(inputLocation).click(); cy.get(inputLocation).clear(); cy.get(inputLocation).type('ecuador'); cy.get(locationOptions).should('have.length.at.least', 1); @@ -129,7 +118,6 @@ describe('VnLocation', () => { const province = 'Saskatchew'; cy.get(createLocationButton).click(); cy.get(dialogInputs).eq(0).type(postCode); - // city create button cy.get( `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(2) > .q-icon` ).click(); @@ -138,7 +126,6 @@ describe('VnLocation', () => { cy.get('#q-portal--dialog--3 .q-btn--standard').click(); cy.get('#q-portal--dialog--1 .q-btn--standard').click(); cy.waitForElement('.q-form'); - checkVnLocation(postCode, province); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index d4b2486e7..add41db57 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -294,7 +294,7 @@ Cypress.Commands.add('checkNotification', (text) => { throw new Error(`Notification not found: "${text}"`); }); }); -// :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container + Cypress.Commands.add('checkValueForm', (id, search) => { cy.get( `.grid-create > :nth-child(${id}) > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > .q-field__input` From deb6467af8ed5072dc714cc459ca036b3803302e Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 10:05:10 +0100 Subject: [PATCH 199/207] feat: remove comments --- test/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index add41db57..1765b9043 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -297,7 +297,7 @@ Cypress.Commands.add('checkNotification', (text) => { Cypress.Commands.add('checkValueForm', (id, search) => { cy.get( - `.grid-create > :nth-child(${id}) > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > .q-field__input` + `.grid-create > :nth-child(${id}) > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > .q-field__input` ).should('have.value', search); }); From d6aedad38e49ee64b2a6b2f49a107b3b5975a67d Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Wed, 20 Nov 2024 10:07:03 +0100 Subject: [PATCH 200/207] perf: use const in VnLocation --- test/cypress/integration/vnComponent/vnLocation.spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index ef08af679..aeb938c6f 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -19,13 +19,15 @@ describe('VnLocation', () => { cy.get(createLocationButton).click(); }); it('should filter provinces based on selected country', () => { - cy.selectOption(countrySelector, 'Ecuador'); + const country = 'Ecuador'; + cy.selectOption(countrySelector, country); cy.get(countrySelector).should('have.length', 1); cy.get(citySelector).should('have.length', 1); }); it('should filter towns based on selected province', () => { - cy.selectOption(countrySelector, 'Ecuador'); + const country = 'Ecuador'; + cy.selectOption(countrySelector, country); cy.get(provinceSelector).should('have.length', 1); cy.get(citySelector).should('have.length', 1); }); From 7039b68bba8d540be53d5f19ff3cdfc24ef508f1 Mon Sep 17 00:00:00 2001 From: jorgep <jorgep@verdnatura.es> Date: Wed, 20 Nov 2024 17:23:40 +0100 Subject: [PATCH 201/207] fix: refs #7874 show name --- src/pages/Claim/Card/ClaimNotes.vue | 2 +- src/pages/Worker/Card/WorkerNotes.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Claim/Card/ClaimNotes.vue b/src/pages/Claim/Card/ClaimNotes.vue index a4d11e9f6..134ee33ab 100644 --- a/src/pages/Claim/Card/ClaimNotes.vue +++ b/src/pages/Claim/Card/ClaimNotes.vue @@ -25,7 +25,7 @@ const claimFilter = computed(() => { include: { relation: 'user', scope: { - fields: ['id', 'nickname'], + fields: ['id', 'nickname', 'name'], }, }, }, diff --git a/src/pages/Worker/Card/WorkerNotes.vue b/src/pages/Worker/Card/WorkerNotes.vue index c15b1dfab..4f123206b 100644 --- a/src/pages/Worker/Card/WorkerNotes.vue +++ b/src/pages/Worker/Card/WorkerNotes.vue @@ -15,7 +15,7 @@ const filter = { include: { relation: 'user', scope: { - fields: ['id', 'nickname'], + fields: ['id', 'nickname', 'name'], }, }, }, From e5434e743613a0595df2af9aac285b5d7a1f6e91 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Thu, 21 Nov 2024 09:08:52 +0000 Subject: [PATCH 202/207] warmfix: ItemLastEntries to date --- src/pages/Item/Card/ItemLastEntries.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue index 5c0251ea8..22fb9adc7 100644 --- a/src/pages/Item/Card/ItemLastEntries.vue +++ b/src/pages/Item/Card/ItemLastEntries.vue @@ -170,7 +170,7 @@ onMounted(async () => { from.value = getDate(_from, 'from'); const _to = Date.vnNew(); _to.setDate(_to.getDate() + 10); - to.value = getDate(Date.vnNew(), 'to'); + to.value = getDate(_to, 'to'); updateFilter(); From 5268140d8bc229dfa59bd67baabb4f8de35800b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= <carlosap@verdnatura.es> Date: Thu, 21 Nov 2024 15:51:27 +0100 Subject: [PATCH 203/207] feat: refs#8087 Redadas en travel --- src/i18n/locale/en.yml | 1 + src/i18n/locale/es.yml | 1 + src/pages/Entry/EntryList.vue | 2 +- src/pages/Travel/Card/TravelBasicData.vue | 12 +++---- src/pages/Travel/Card/TravelCard.vue | 29 +--------------- src/pages/Travel/Card/TravelDescriptor.vue | 39 ++-------------------- src/pages/Travel/Card/TravelFilter.js | 29 ++++++++++++++++ src/pages/Travel/Card/TravelSummary.vue | 9 +++++ src/pages/Travel/TravelList.vue | 6 ++-- 9 files changed, 53 insertions(+), 75 deletions(-) create mode 100644 src/pages/Travel/Card/TravelFilter.js diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 60f460b9d..613046f86 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -767,6 +767,7 @@ travel: hb: HB basicData: daysInForward: Days in forward + isRaid: Raid thermographs: temperature: Temperature destination: Destination diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index c6ab57dd7..58ddc98ef 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -761,6 +761,7 @@ travel: hb: HB basicData: daysInForward: Días redada + isRaid: Redada thermographs: temperature: Temperatura destination: Destino diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 38bf09b53..3487f86c0 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -221,7 +221,7 @@ onMounted(async () => { t('entry.list.tableVisibleColumns.isExcludedFromAvailable') }}</QTooltip> </QIcon> - <QIcon v-if="!!row.daysInForward" name="vn:net" color="primary"> + <QIcon v-if="!!row.isRaid" name="vn:net" color="primary"> <QTooltip> {{ t('globals.raid', { daysInForward: row.daysInForward }) diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index c3a13907a..faf408989 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -21,12 +21,7 @@ const agenciesOptions = ref([]); @on-fetch="(data) => (agenciesOptions = data)" auto-load /> - <FormModel - :url="`Travels/${route.params.id}`" - :url-update="`Travels/${route.params.id}`" - model="Travel" - auto-load - > + <FormModel :url-update="`Travels/${route.params.id}`" model="Travel" auto-load> <template #form="{ data }"> <VnRow> <VnInput v-model="data.ref" :label="t('globals.reference')" /> @@ -78,6 +73,7 @@ const agenciesOptions = ref([]); </VnInput> </VnRow> <VnRow> + <QCheckbox v-model="data.isRaid" :label="t('travel.basicData.isRaid')" /> <QCheckbox :label="t('travel.summary.delivered')" v-model="data.isDelivered" @@ -93,7 +89,7 @@ const agenciesOptions = ref([]); <i18n> es: - raidDays: Al rellenarlo, generamos una redada. Indica los días que un travel se moverá automáticamente en el tiempo + raidDays: Si se marca "Redada", la fecha de entrega se moverá automáticamente los días indicados (incluido 0). Si se deja vacio, la fecha no cambiará en: - raidDays: When filling, a raid is generated. Enter the number of days the travel will automatically forward in time + raidDays: If "Raid" is checked, the landing date will automatically shift by the specified number of days (including 0). If left empty, the date will stay the same. </i18n> diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue index 44bd9d430..50cecef34 100644 --- a/src/pages/Travel/Card/TravelCard.vue +++ b/src/pages/Travel/Card/TravelCard.vue @@ -1,34 +1,7 @@ <script setup> import VnCard from 'components/common/VnCard.vue'; import TravelDescriptor from './TravelDescriptor.vue'; - -const filter = { - fields: [ - 'id', - 'ref', - 'shipped', - 'landed', - 'totalEntries', - 'warehouseInFk', - 'warehouseOutFk', - 'cargoSupplierFk', - 'agencyModeFk', - ], - include: [ - { - relation: 'warehouseIn', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseOut', - scope: { - fields: ['name'], - }, - }, - ], -}; +import filter from './TravelFilter.js'; </script> <template> <VnCard diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue index 295b47fa0..9d00d371a 100644 --- a/src/pages/Travel/Card/TravelDescriptor.vue +++ b/src/pages/Travel/Card/TravelDescriptor.vue @@ -7,6 +7,7 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import useCardDescription from 'src/composables/useCardDescription'; import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue'; +import filter from './TravelFilter.js'; import { toDate } from 'src/filters'; @@ -21,35 +22,6 @@ const $props = defineProps({ const route = useRoute(); const { t } = useI18n(); -const filter = { - fields: [ - 'id', - 'ref', - 'shipped', - 'landed', - 'totalEntries', - 'warehouseInFk', - 'warehouseOutFk', - 'cargoSupplierFk', - 'agencyModeFk', - 'daysInForward', - ], - include: [ - { - relation: 'warehouseIn', - scope: { - fields: ['name'], - }, - }, - { - relation: 'warehouseOut', - scope: { - fields: ['name'], - }, - }, - ], -}; - const entityId = computed(() => { return $props.id || route.params.id; }); @@ -65,7 +37,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. :title="data.title" :subtitle="data.subtitle" :filter="filter" - data-key="travelData" + data-key="Travel" @on-fetch="setData" > <template #menu="{ entity }"> @@ -80,12 +52,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. </template> <template #icons="{ entity }"> <QCardActions class="q-gutter-x-md"> - <QIcon - v-if="entity.daysInForward" - name="vn:net" - color="primary" - size="xs" - > + <QIcon v-if="entity.isRaid" name="vn:net" color="primary" size="xs"> <QTooltip> {{ t('globals.raid', { daysInForward: entity.daysInForward }) diff --git a/src/pages/Travel/Card/TravelFilter.js b/src/pages/Travel/Card/TravelFilter.js new file mode 100644 index 000000000..f5f4520fd --- /dev/null +++ b/src/pages/Travel/Card/TravelFilter.js @@ -0,0 +1,29 @@ +export default { + fields: [ + 'id', + 'ref', + 'shipped', + 'landed', + 'totalEntries', + 'warehouseInFk', + 'warehouseOutFk', + 'cargoSupplierFk', + 'agencyModeFk', + 'isRaid', + 'daysInForward', + ], + include: [ + { + relation: 'warehouseIn', + scope: { + fields: ['name'], + }, + }, + { + relation: 'warehouseOut', + scope: { + fields: ['name'], + }, + }, + ], +}; diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index d720abd11..5ed7da996 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -268,6 +268,11 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; :label="t('globals.warehouseOut')" :value="travel.warehouseOut?.name" /> + <QCheckbox + :label="t('travel.basicData.isRaid')" + v-model="travel.isRaid" + :disable="true" + /> <QCheckbox :label="t('travel.summary.delivered')" v-model="travel.isDelivered" @@ -286,6 +291,10 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; :label="t('globals.warehouseIn')" :value="travel.warehouseIn?.name" /> + <VnLv + :label="t('travel.basicData.daysInForward')" + :value="travel?.daysInForward" + /> <QCheckbox :label="t('travel.summary.received')" v-model="travel.isReceived" diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index ee1427cf0..852003a95 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -227,10 +227,12 @@ const columns = computed(() => [ > <template #column-status="{ row }"> <div class="row"> - <QIcon v-if="!!row.daysInForward" name="vn:net" color="primary"> + <QIcon v-if="!!row.isRaid" name="vn:net" color="primary"> <QTooltip> {{ - t('globals.raid', { daysInForward: row.daysInForward }) + t('globals.raid', { + daysInForward: row.daysInForward, + }) }}</QTooltip > </QIcon> From 14d2ddfa835205c72483585e7d719b4528523dc9 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Fri, 22 Nov 2024 12:40:07 +0100 Subject: [PATCH 204/207] fix: merge errors --- src/components/ui/VnFilterPanel.vue | 2 -- src/pages/Order/Card/OrderCatalogFilter.vue | 5 ----- 2 files changed, 7 deletions(-) diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index bf1fcfdb9..b188bde48 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -227,8 +227,6 @@ function sanitizer(params) { } return params; } - -defineExpose({ search, sanitizer, userParams }); </script> <template> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index b839be55e..6202a6f90 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -143,11 +143,6 @@ function addOrder(value, field, params) { params.orderBy = JSON.stringify(orderBy); vnFilterPanelRef.value.search(); } - -onMounted(() => { - selectedCategoryFk.value = getParamWhere(route, 'categoryFk'); - selectedTypeFk.value = getParamWhere(route, 'typeFk'); -}); </script> <template> From 01ffb663f1f5921f87908cdbffaa3d531a8782cf Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Fri, 22 Nov 2024 15:14:03 +0100 Subject: [PATCH 205/207] fix(ClaimList): stateCode orderBy priority --- src/pages/Claim/ClaimList.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue index 6d85817dc..d561a69f7 100644 --- a/src/pages/Claim/ClaimList.vue +++ b/src/pages/Claim/ClaimList.vue @@ -95,6 +95,7 @@ const columns = computed(() => [ optionLabel: 'description', }, }, + orderBy: 'priority', }, { align: 'right', From 594fc60eece8c40a66cd807f63ae87d45aaaa568 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Mon, 25 Nov 2024 14:49:10 +0100 Subject: [PATCH 206/207] chore: refs #8231 add changelog --- CHANGELOG.md | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88abb9ae0..03812d252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,189 @@ +# Version 24.48 - 2024-11-25 + +### Added 🆕 + +- chore: correct checkNotification (fix_customer_issues) by:alexm +- chore: perf (warmFix_order_equalSalix) by:alexm +- chore: refs #6818 add spaces by:jorgep +- chore: refs #6818 drop useless code & comment by:jorgep +- chore: refs #7273 sticky add btn & refactor by:jorgep +- chore: refs #7524 fix test by:jorgep +- chore: refs #8039 not required by:alexm +- chore: refs #8078 fiz tests by:jorgep +- chore: refs #8078 rollback ref by:jorgep +- chore: remove console.log (warmFix_invoiceOut_Global) by:alexm +- chore: typo (fix_itemType-redirection) by:alexm +- feat: #6943 use openURL quasar by:Javier Segarra +- feat: #7782 add cypress report by:Javier Segarra +- feat: #7782 cypress.config watchForFileChanges by:Javier Segarra +- feat: #7782 npm run resetDatabase by:Javier Segarra +- feat: #7782 waitUntil domContentLoad by:Javier Segarra +- feat: added composable to confirm orders by:Jon +- feat: add /reports in gitignore (warmFix_reports_in_gitignore) by:alexm +- feat: apply changes for customerModule by:Javier Segarra +- feat: disabled buttons by:Javier Segarra +- feat: move buttons to DescriptorMenu by:Javier Segarra +- feat: refs #6818 add icon by:jorgep +- feat: refs #6818 fetch url & default channel by:jorgep +- feat: refs #6818 saysimple integration by:jorgep +- feat: refs #6839 module searching (6839-addSearchMenu) by:jorgep +- feat: refs #6839 normalize search by:jorgep +- feat: refs #6919 sync entry data by:jorgep +- feat: refs #7006 itemType basic data new inputs by:guillermo +- feat: refs #7006 itemTypeLog added by:guillermo +- feat: refs #7193 modified parking to use the scope and corrected small errors by:Jon +- feat: refs #7206 added inactive label and corrected minor errors by:Jon +- feat: refs #7308 #7308 remove warnings related to useSession by:Javier Segarra +- feat: refs #7349 usa back con permisos by:jgallego +- feat: refs #7524 add front test by:jorgep +- feat: refs #7874 improve vn-notes ui by:jorgep +- feat: refs #7970 notify changes by:Jon +- feat(): refs #8039 canceledError not notify by:alexm +- feat: refs #8039 notify error unify by:alexm +- feat: refs #8039 show duplicate request in local by:alexm +- feat: refs #8078 add shortcut multi selection by:jorgep +- feat: refs #8078 add tests by:jorgep +- feat: refs#8087 Redadas en travel by:Carlos Andrés +- feat: refs #8087 Traspasar redadas a travels by:Carlos Andrés +- feat: remove comments by:Javier Segarra +- feat(Supplier): add companySize by:alexm +- feat: use composable to unify logic by:Javier Segarra +- feat(VnInput): empty to null by:alexm +- feat(VnSelect): order data equal salix by:alexm +- feat(VnSelect): refs #7136 add scroll (7136-vnSelect_paginate_simplify_2) by:alexm + +### Changed 📦 + +- chore: perf (warmFix_order_equalSalix) by:alexm +- chore: refs #7273 sticky add btn & refactor by:jorgep +- fix: better performance (warmFix_accountAcls) by:alexm +- perf: minor bugs detected by:Javier Segarra +- perf: refs #6943 #6943 merge command by:Javier Segarra +- perf: refs #7283 #7283 declare composable inst4ead code duplicated by:Javier Segarra +- perf: refs #7283 #7283 handle composable i18n by:Javier Segarra +- perf: refs #7283 #7283 handle i18n by:Javier Segarra +- perf: refs #7283 #7283 i18n params by:Javier Segarra +- perf: refs #7308 #7308 remove comments by:Javier Segarra +- perf: remove appendParams by:Javier Segarra +- perf: use const in VnLocation by:Javier Segarra +- perf: use required instead :required="true" by:Javier Segarra +- refactor: apply QPopupProxy by:wbuezas +- refactor: changed confirmOrder directory by:Jon +- refactor: change keyup.enter for update:model-value by:wbuezas +- refactor(InvoiceInBasicData): use VnDms by:alexm +- refactor: modified composable by:Jon +- refactor: refs #6818 change channel source by:jorgep +- refactor: refs #6818 channel logic by:jorgep +- refactor: refs #6919 export filter by:jorgep +- refactor: refs #7132 1st wave of changes in global translations files by:Jon +- refactor: refs #7132 account's module translations by:Jon +- refactor: refs #7132 customer's module translations by:Jon +- refactor: refs #7132 deleted pageTitles repeated by:Jon +- refactor: refs #7132 delete duplicate translations' keys by:Jon +- refactor: refs #7132 deleted useless code by:Jon +- refactor: refs #7132 global translations files changed by:Jon +- refactor: refs #7266 Changed method name by:guillermo +- refactor: refs #7950 Created cmr model by:guillermo +- refactor: refs #7970 added emit by:Jon +- refactor: refs #7970 refactored VnConfirm to emit events by:Jon +- refactor: refs #8185 modified LeftMenu to avoid duplicates by:Jon +- refactor: remove unused variable by:wbuezas +- refactor: revert catalog changes by:Jon +- refactor: small change by:wbuezas +- test: refactor e2e by:alexm +- test: refs #8039 add hasNotify and, refactor: agencyWorkCenter test by:alexm + +### Fixed 🛠️ + +- chore: refs #7524 fix test by:jorgep +- fix: better performance (warmFix_accountAcls) by:alexm +- fix: catalog view category and type filter by:wbuezas +- fix: category and tags filters by:Jon +- fix: changed route.query by:Jon +- fix: change type vnput by:Javier Segarra +- fix(ClaimList): stateCode orderBy priority by:alexm +- fix: entryFilters by:carlossa +- fix: filter panel by:Jon +- fix(InvoiceOutGlobal): parallelism by:alexm +- fix: itemBotanical by:Javier Segarra +- fix: itemType redirection and fix filters by:alexm +- fix: logout spec (warmFix_logout.spec) by:alexm +- fix: merge errors by:alexm +- fix: order catalog by:wbuezas +- fix: order catalog fixes by:wbuezas +- fix: refs #6818 use right icon by:jorgep +- fix: refs #6896 fixed module problems by:Jon +- fix: refs #7193 fixed e2e test by:Jon +- fix: refs #7206 deleted duplicate code by:Jon +- fix: refs #7273 use same filter by:jorgep +- fix: refs #7283 #7283 bugs by:Javier Segarra +- fix: refs #7283 #7283 ItemDiary subToolbar by:Javier Segarra +- fix: refs #7283 #7283 ItemSummary bugs by:Javier Segarra +- fix: refs #7283 Account image resolution by:guillermo +- fix: refs #7283 css by:jorgep +- fix: refs #7283 filter by:carlossa +- fix: refs #7283 fix image by:carlossa +- fix: refs #7283 fix pr by:carlossa +- fix: refs #7283 fix preview by:carlossa +- fix: refs #7283 fix required by:carlossa +- fix: refs #7283 item filters by:carlossa +- fix: refs #7283 itemtype fix by:carlossa +- fix: refs #7283 order translation by:carlossa +- fix: refs #7283 preview by:carlossa +- fix: refs #7283 tooltips !Item by:Javier Segarra +- fix: refs #7306 clean warning by:carlossa +- fix: refs #7310 clean warning by:carlossa +- fix: refs #7323 locale #7396 by:jorgep +- fix: refs #7323 show advanced fields by:jorgep +- fix: refs #7349 dependencia no usada by:jgallego +- fix: refs #7524 e2e & worker module by:jorgep +- fix: refs #7874 add title by:jorgep +- fix: refs #7874 show name by:jorgep +- fix: refs #7943 use correct data-key by:jorgep +- fix: refs #7943 use summary by:jorgep +- fix: refs #8039 bad tests by:alexm +- fix: refs #8039 o not handle unnecessary errors by:alexm +- fix: refs #8078 e2e #7970 by:jorgep +- fix: refs #8078 handleSelection by:jorgep +- fix: refs #8078 improve cy command (8078-enableMultiSelection) by:jorgep +- fix: refs #8078 improve handleSelection by:jorgep +- fix: reset category by:wbuezas +- fix: tag chips by:Jon +- fix: vnSearchbar spec (warmFix_vnSearchBar.spec) by:alexm +- fix(VnSelect): setOptions when applyFilter by:alexm +- fix: worker test e2e by:Jon +- Merge branch 'dev' into fix_customer_issues by:Javier Segarra +- refactor: revert catalog changes by:Jon +- refs #7283 fix conflicts by:carlossa +- refs #7283 fix descriptorproxy by:carlossa +- refs #7283 fixedPrice by:carlossa +- refs #7283 fixedPrices by:carlossa +- refs #7283 fix itemFixed by:carlossa +- refs #7283 fix itemFixedPrice by:carlossa +- refs #7283 fix itemMigration by:carlossa +- refs #7283 fix itemMigration list filters by:carlossa +- refs #7283 fix items by:carlossa +- refs #7283 fix items error get images by:carlossa +- refs #7283 fix items images by:carlossa +- refs #7283 fix request by:carlossa +- refs #7283 fix searchbar by:carlossa +- refs #7283 fix viewSummary by:carlossa +- refs #7283 fix yml list basicData by:carlossa +- refs #7283 itemRequest fix by:carlossa +- refs #7283 itemRequest fix deny by:carlossa +- refs #7283 itemRequest fix reload by:carlossa +- refs #72983 fix filters by:carlossa +- revert: commit by:Javier Segarra +- revert e57a253c6f649382da187d1129449d265fb26d3b by:Javier Segarra +- test: #8162 fix clientList spec by:Javier Segarra +- test: #8162 fix vnLocation spec by:Javier Segarra +- test: fix arrayData by:Javier Segarra +- test: fix e2e by:alexm +- test: fix e2e by:Javier Segarra +- test: refs #8039 fix WorkerNotification e2e by:alexm +- test: refs #8039 fix ZoneWarehouse e2e by:alexm +- warmfix: ItemLastEntries to date (origin/warmfix_itemLastEntriesFilter) by:Javier Segarra + # Version 24.40 - 2024-10-02 ### Added 🆕 From 2ead484026c2ed48fea357c742ca9dcbe745983c Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Mon, 25 Nov 2024 14:59:26 +0100 Subject: [PATCH 207/207] test: refs #8231 fix VnLocation --- test/cypress/integration/vnComponent/vnLocation.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index aeb938c6f..06c23f4ee 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -103,12 +103,12 @@ describe('VnLocation', () => { const province = 'Valencia'; cy.get(createLocationButton).click(); cy.get('.q-card > h1').should('have.text', 'New postcode'); - cy.get(dialogInputs).eq(0).clear(); - cy.get(dialogInputs).eq(0).type(postCode); cy.selectOption( `${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix}`, province ); + cy.get(dialogInputs).eq(0).clear(); + cy.get(dialogInputs).eq(0).type(postCode); cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(`${createForm.prefix}`).should('not.exist'); cy.waitForElement('.q-form');