@@ -396,7 +425,6 @@ watchEffect(selectedRows);
:label="
t('invoiceOutList.tableVisibleColumns.taxArea')
"
- :options="taxAreasOptions"
option-label="code"
option-value="code"
/>
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
index b062678a0..432cd07d7 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
@@ -8,7 +8,7 @@ import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import { useArrayData } from 'src/composables/useArrayData';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
-import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
@@ -115,18 +115,16 @@ const columns = computed(() => [
},
{
align: 'left',
- label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
- name: 'workerName',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
component: 'select',
attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- where: { role: 'salesPerson' },
+ url: 'Departments',
},
columnField: {
component: null,
},
- format: (row, dashIfEmpty) => dashIfEmpty(row.workerName),
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
]);
@@ -198,10 +196,10 @@ const downloadCSV = async () => {
-
+
- {{ row.workerName }}
-
+ {{ row.departmentName }}
+
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
index cd9836bb7..b24c8b247 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
@@ -20,7 +20,7 @@ const props = defineProps({
@@ -129,12 +129,15 @@ const props = defineProps({
-
diff --git a/src/pages/InvoiceOut/locale/en.yml b/src/pages/InvoiceOut/locale/en.yml
index 17d198351..9d6a4a244 100644
--- a/src/pages/InvoiceOut/locale/en.yml
+++ b/src/pages/InvoiceOut/locale/en.yml
@@ -1,6 +1,7 @@
invoiceOut:
search: Search invoice
searchInfo: You can search by invoice reference
+ externalRef: External Ref.
params:
id: ID
company: Company
@@ -12,7 +13,6 @@ invoiceOut:
isActive: Active
hasToInvoice: Has to invoice
hasVerifiedData: Verified data
- workerName: Worker
isTaxDataChecked: Verified data
amount: Amount
clientFk: Client
@@ -26,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Has PDF
search: Contains
+ departmentFk: Department
card:
issued: Issued
customerCard: Customer card
diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml
index 3df95d6b2..f9448cd9b 100644
--- a/src/pages/InvoiceOut/locale/es.yml
+++ b/src/pages/InvoiceOut/locale/es.yml
@@ -1,6 +1,7 @@
invoiceOut:
search: Buscar factura emitida
searchInfo: Puedes buscar por referencia de la factura
+ externalRef: Ref. externa
params:
id: ID
company: Empresa
@@ -12,7 +13,6 @@ invoiceOut:
isActive: Activo
hasToInvoice: Debe facturar
hasVerifiedData: Datos verificados
- workerName: Comercial
isTaxDataChecked: Datos comprobados
amount: Importe
clientFk: Cliente
@@ -26,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Tiene PDF
search: Contiene
+ departmentFk: Departamento
card:
issued: Fecha emisión
customerCard: Ficha del cliente
diff --git a/src/pages/Item/Card/ItemBarcode.vue b/src/pages/Item/Card/ItemBarcode.vue
index 590b524cd..53b4514b7 100644
--- a/src/pages/Item/Card/ItemBarcode.vue
+++ b/src/pages/Item/Card/ItemBarcode.vue
@@ -94,6 +94,7 @@ const submit = async (rows) => {
icon="add_circle"
v-shortcut="'+'"
flat
+ data-cy="addBarcode_input"
>
{{ t('Add barcode') }}
diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue
index 610b77a02..ddd21fe36 100644
--- a/src/pages/Item/Card/ItemCard.vue
+++ b/src/pages/Item/Card/ItemCard.vue
@@ -1,9 +1,9 @@
- {
const scrollToToday = async () => {
await nextTick();
- const todayCell = document.querySelector(`td[data-date="${today.toISOString()}"]`);
- if (todayCell) {
- todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
- }
-};
-
-const formatDateForAttribute = (dateValue) => {
- if (dateValue instanceof Date) return date.formatDate(dateValue, 'YYYY-MM-DD');
- return dateValue;
+ const todayCell = document.querySelector(
+ `td[data-date="${date.formatDate(today, 'YYYY-MM-DD')}"]`,
+ );
+ if (todayCell) todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
};
async function updateWarehouse(warehouseFk) {
@@ -242,7 +237,7 @@ async function updateWarehouse(warehouseFk) {
-
+
[
columnClass: 'expand',
},
{
+ align: 'left',
label: t('item.buyRequest.requester'),
name: 'requesterName',
component: 'select',
@@ -77,6 +79,19 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
+ {
+ align: 'left',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
+ },
+ columnField: {
+ component: null,
+ },
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
+ },
{
label: t('item.buyRequest.requested'),
name: 'quantity',
@@ -107,6 +122,7 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
+
{
label: t('globals.item'),
name: 'item',
@@ -226,7 +242,6 @@ const onDenyAccept = (_, responseData) => {
order="shipped ASC, isOk ASC"
:columns="columns"
:user-params="userParams"
- :is-editable="true"
:right-search="false"
auto-load
:disable-option="{ card: true }"
@@ -263,6 +278,12 @@ const onDenyAccept = (_, responseData) => {
+
+
+ {{ row.departmentName }}
+
+
+
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index c2a63ddd9..a29203df3 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -221,7 +221,7 @@ en:
attenderFk: Atender
clientFk: Client id
warehouseFk: Warehouse
- requesterFk: Salesperson
+ requesterFk: Requester
from: From
to: To
mine: For me
@@ -239,7 +239,7 @@ es:
attenderFk: Comprador
clientFk: Id cliente
warehouseFk: Almacén
- requesterFk: Comercial
+ requesterFk: Solicitante
from: Desde
to: Hasta
mine: Para mi
diff --git a/src/pages/Item/ItemType/Card/ItemTypeCard.vue b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
index 84e810de5..bd41b1be2 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeCard.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
@@ -1,11 +1,11 @@
- {
:filter="filter"
title="code"
data-key="ItemType"
+ :to-module="{ name: 'ItemTypeList' }"
>
diff --git a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
index 3b63c4b63..ba294e144 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
@@ -7,6 +7,7 @@ import filter from './ItemTypeFilter.js';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
onUpdated(() => summaryRef.value.fetch());
@@ -62,13 +63,10 @@ async function setItemTypeData(data) {
-
+
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index 9d27fc96e..ff8df26d4 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -84,7 +84,7 @@ item:
attenderFk: Atender
clientFk: Client id
warehouseFk: Warehouse
- requesterFk: Salesperson
+ requesterFk: Requester
from: From
to: To
mine: For me
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 935f5160b..7b768d0cb 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -93,7 +93,7 @@ item:
attenderFk: Comprador
clientFk: Id cliente
warehouseFk: Almacén
- requesterFk: Comercial
+ requesterFk: Solicitante
from: Desde
to: Hasta
mine: Para mi
diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
index c1958cdcb..278b0b26f 100644
--- a/src/pages/Monitor/MonitorClients.vue
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -31,7 +31,7 @@ function exprBuilder(param, value) {
switch (param) {
case 'clientFk':
return { [`c.id`]: value };
- case 'salesPersonFk':
+ case 'departmentFk':
return { [`c.${param}`]: value };
}
}
@@ -62,25 +62,17 @@ const columns = computed(() => [
columnFilter: false,
},
{
- label: t('salesClientsTable.salesPerson'),
- name: 'salesPersonFk',
- field: 'salesPerson',
align: 'left',
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
+ },
columnField: {
component: null,
},
- optionFilter: 'firstName',
- columnFilter: {
- component: 'select',
- attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- sortBy: 'nickname ASC',
- where: { role: 'salesPerson' },
- useLike: false,
- },
- },
- columnClass: 'no-padding',
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('salesClientsTable.client'),
@@ -128,9 +120,9 @@ const columns = computed(() => [
-
-
-
+
+
+
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
index 873f8abb4..2679f7224 100644
--- a/src/pages/Monitor/MonitorOrders.vue
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -1,9 +1,9 @@
default-mode="table"
auto-load
:row-click="({ id }) => openTab(id)"
+ :row-ctrl-click="(_, { id }) => openTab(id)"
:disable-option="{ card: true }"
:user-params="{ from, to, scopeDays: 0 }"
>
@@ -436,10 +436,10 @@ const openTab = (id) =>
-
-
-
-
+
+
+
+
diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml
index 496c8761a..a9ce36ffd 100644
--- a/src/pages/Monitor/locale/en.yml
+++ b/src/pages/Monitor/locale/en.yml
@@ -7,7 +7,6 @@ salesClientsTable:
to: To
date: Date
hour: Hour
- salesPerson: Salesperson
client: Client
salesOrdersTable:
delete: Delete
@@ -22,7 +21,7 @@ salesTicketsTable:
notVisible: Not visible
purchaseRequest: Purchase request
clientFrozen: Client frozen
- risk: Risk
+ risk: Excess risk
componentLack: Component lack
tooLittle: Ticket too little
identifier: Identifier
diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml
index f6a29879f..6086eda6b 100644
--- a/src/pages/Monitor/locale/es.yml
+++ b/src/pages/Monitor/locale/es.yml
@@ -7,7 +7,6 @@ salesClientsTable:
to: Hasta
date: Fecha
hour: Hora
- salesPerson: Comercial
client: Cliente
salesOrdersTable:
delete: Eliminar
@@ -22,7 +21,7 @@ salesTicketsTable:
notVisible: No visible
purchaseRequest: Petición de compra
clientFrozen: Cliente congelado
- risk: Riesgo
+ risk: Exceso de riesgo
componentLack: Faltan componentes
tooLittle: Ticket demasiado pequeño
identifier: Identificador
diff --git a/src/pages/Order/Card/OrderBasicData.vue b/src/pages/Order/Card/OrderBasicData.vue
index 9c02d7494..73b8b6fc8 100644
--- a/src/pages/Order/Card/OrderBasicData.vue
+++ b/src/pages/Order/Card/OrderBasicData.vue
@@ -64,17 +64,7 @@ const orderFilter = {
{
relation: 'client',
scope: {
- fields: [
- 'salesPersonFk',
- 'name',
- 'isActive',
- 'isFreezed',
- 'isTaxDataChecked',
- ],
- include: {
- relation: 'salesPersonUser',
- scope: { fields: ['id', 'name'] },
- },
+ fields: ['name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
},
},
],
@@ -167,7 +157,7 @@ const onClientChange = async (clientId) => {
!data.isConfirmed &&
agencyList?.length &&
agencyList.some(
- (agency) => agency.agencyModeFk === data.agency_id
+ (agency) => agency.agencyModeFk === data.agency_id,
)
? data.agencyModeFk
: null
diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue
index ad5c73a87..7dab307a0 100644
--- a/src/pages/Order/Card/OrderCard.vue
+++ b/src/pages/Order/Card/OrderCard.vue
@@ -1,11 +1,11 @@
- {
+onMounted(async () => {
stateStore.rightDrawer = true;
checkOrderConfirmation();
+
+ if (
+ arrayData.store.userParams &&
+ Object.keys(arrayData.store.userParams).some((key) => !key.startsWith('order'))
+ ) {
+ await arrayData.fetch({});
+ }
});
+onUnmounted(() => {
+ arrayData.destroy();
+});
+
+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}%` } };
+ }
+}
+
async function checkOrderConfirmation() {
const response = await axios.get(`Orders/${route.params.id}`);
if (response.data.isConfirmed === 1) {
@@ -96,6 +121,7 @@ watch(
:tag-value="tagValue"
:tags="tags"
:initial-catalog-params="catalogParams"
+ :arrayData
/>
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 76e608983..d16a92017 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -24,6 +24,10 @@ const props = defineProps({
type: Array,
required: true,
},
+ arrayData: {
+ type: Object,
+ required: true,
+ },
});
const { t } = useI18n();
@@ -74,17 +78,6 @@ const loadTypes = async (id) => {
typeList.value = data;
};
-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 applyTags = (tagInfo, params, search) => {
if (!tagInfo || !tagInfo.values.length) {
params.tagGroups = null;
@@ -152,9 +145,8 @@ function addOrder(value, field, params) {
:data-key="props.dataKey"
:hidden-tags="['filter', 'orderFk', 'orderBy']"
:unremovable-params="['orderFk', 'orderBy']"
- :expr-builder="exprBuilder"
:custom-tags="['tagGroups', 'categoryFk']"
- :redirect="false"
+ :arrayData
>
diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue
index 0d18864dc..f34549c1e 100644
--- a/src/pages/Order/Card/OrderDescriptor.vue
+++ b/src/pages/Order/Card/OrderDescriptor.vue
@@ -8,7 +8,7 @@ import filter from './OrderFilter.js';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import FetchData from 'components/FetchData.vue';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
const DEFAULT_ITEMS = 0;
@@ -66,11 +66,11 @@ const total = ref(0);
:label="t('globals.state')"
:value="getConfirmationValue(entity.isConfirmed)"
/>
-
+
- {{ entity?.client?.salesPersonUser?.name || '-' }}
-
+ {{ entity?.client?.department?.name || '-' }}
+
diff --git a/src/pages/Order/Card/OrderFilter.js b/src/pages/Order/Card/OrderFilter.js
index 3e521b92c..d45578529 100644
--- a/src/pages/Order/Card/OrderFilter.js
+++ b/src/pages/Order/Card/OrderFilter.js
@@ -10,14 +10,14 @@ export default {
relation: 'client',
scope: {
fields: [
- 'salesPersonFk',
+ 'departmentFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
- relation: 'salesPersonUser',
+ relation: 'department',
scope: { fields: ['id', 'name'] },
},
},
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index c387be241..42578423f 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -6,7 +6,6 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
-import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
const props = defineProps({
@@ -62,15 +61,15 @@ const sourceList = ref([]);
outlined
rounded
/>
-
import { useI18n } from 'vue-i18n';
-import { computed, ref, onMounted } from 'vue';
+import { computed, ref, onMounted, watch } from 'vue';
import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
import { toDateTimeFormat } from 'src/filters/date';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@@ -10,12 +10,13 @@ import axios from 'axios';
import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
import OrderFilter from './Card/OrderFilter.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
-import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnSection from 'src/components/common/VnSection.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
+import { getAddresses } from '../Customer/composables/getAddresses';
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
@@ -24,6 +25,11 @@ const agencyList = ref([]);
const route = useRoute();
const addressOptions = ref([]);
const dataKey = 'OrderList';
+const formInitialData = ref({
+ active: true,
+ addressId: null,
+ clientFk: null,
+});
const columns = computed(() => [
{
@@ -53,22 +59,17 @@ const columns = computed(() => [
},
{
align: 'left',
- name: 'salesPersonFk',
- label: t('module.salesPerson'),
- columnFilter: {
- component: 'select',
- inWhere: true,
- attrs: {
- url: 'Workers/activeWithInheritedRole',
- fields: ['id', 'name'],
- where: { role: 'salesPerson' },
- useLike: false,
- optionValue: 'id',
- optionLabel: 'name',
- optionFilter: 'firstName',
- },
+ name: 'departmentFk',
+ label: t('customer.summary.team'),
+ component: 'select',
+ attrs: {
+ url: 'Departments',
},
- format: (row) => row?.name,
+ create: true,
+ columnField: {
+ component: null,
+ },
+ format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'center',
@@ -147,27 +148,61 @@ const columns = computed(() => [
],
},
]);
-onMounted(() => {
- if (!route.query.createForm) return;
- const clientId = route.query.createForm;
- const id = JSON.parse(clientId);
- fetchClientAddress(id.clientFk);
+onMounted(async () => {
+ if (!route.query) return;
+ if (route.query?.createForm) {
+ await onClientSelected(JSON.parse(route.query?.createForm));
+ } else if (route.query?.table) {
+ const query = JSON.parse(route.query?.table);
+ const clientFk = query?.clientFk;
+ if (clientFk) await onClientSelected({ clientFk });
+ }
+ if (tableRef.value) tableRef.value.create.formInitialData = formInitialData.value;
});
-async function fetchClientAddress(id, formData = {}) {
- const { data } = await axios.get(
- `Clients/${id}/addresses?filter[order]=isActive DESC`
- );
+watch(
+ () => route.query.table,
+ async (newValue) => {
+ if (newValue) {
+ const clientFk = +JSON.parse(newValue)?.clientFk;
+ if (clientFk) await onClientSelected({ clientFk });
+ if (tableRef.value)
+ tableRef.value.create.formInitialData = formInitialData.value;
+ }
+ },
+);
+
+async function onClientSelected({ clientFk }, formData = {}) {
+ if (!clientFk) {
+ addressOptions.value = [];
+ formData.defaultAddressFk = null;
+ formData.addressId = null;
+ return;
+ }
+ const { data } = await getAddresses(clientFk);
addressOptions.value = data;
- formData.addressId = data.defaultAddressFk;
- fetchAgencies(formData);
+ formData.defaultAddressFk = data[0].client.defaultAddressFk;
+ formData.addressId = formData.defaultAddressFk;
+ formInitialData.value = { ...formData, clientFk };
+ await fetchAgencies(formData);
}
-async function fetchAgencies({ landed, addressId }) {
- if (!landed || !addressId) return (agencyList.value = []);
+async function fetchAgencies(formData) {
+ const { landed, addressId } = formData;
+ if (!landed || !addressId) {
+ formData.defaultAddressFk = formInitialData.value.defaultAddressFk;
+
+ return (agencyList.value = []);
+ }
const { data } = await axios.get('Agencies/landsThatDay', {
- params: { addressFk: addressId, landed },
+ params: {
+ filter: JSON.stringify({
+ order: ['name ASC', 'agencyMode DESC', 'agencyModeFk ASC'],
+ }),
+ addressFk: addressId,
+ landed,
+ },
});
agencyList.value = data;
}
@@ -181,6 +216,11 @@ const getDateColor = (date) => {
if (difference == 0) return 'bg-warning';
if (difference < 0) return 'bg-success';
};
+
+const isDefaultAddress = (opt, data) => {
+ const addressId = data.defaultAddressFk ?? data.addressId;
+ return addressId === opt.id && opt.isActive;
+};
@@ -206,11 +246,7 @@ const getDateColor = (date) => {
onDataSaved: (url) => {
tableRef.redirect(`${url}/catalog`);
},
- formInitialData: {
- active: true,
- addressId: null,
- clientFk: null,
- },
+ formInitialData,
}"
:user-params="{ showEmpty: false }"
:columns="columns"
@@ -223,10 +259,10 @@ const getDateColor = (date) => {
-
+
- {{ row?.name }}
-
+ {{ row?.departmentName }}
+
@@ -242,7 +278,9 @@ const getDateColor = (date) => {
:include="{ relation: 'addresses' }"
v-model="data.clientFk"
:label="t('module.customer')"
- @update:model-value="(id) => fetchClientAddress(id, data)"
+ @update:model-value="
+ (id) => onClientSelected({ clientFk: id }, data)
+ "
>
@@ -258,6 +296,7 @@ const getDateColor = (date) => {
{
@update:model-value="() => fetchAgencies(data)"
>
-
+
+
+
+
fetchAgencies(data)"
/>
[
},
{
align: 'left',
- label: t('isOwn'),
+ label: t('agency.isOwn'),
name: 'isOwn',
component: 'checkbox',
+ columnFilter: {
+ inWhere: true,
+ },
cardVisible: true,
},
{
align: 'left',
- label: t('isAnyVolumeAllowed'),
+ label: t('agency.isAnyVolumeAllowed'),
name: 'isAnyVolumeAllowed',
component: 'checkbox',
+ columnFilter: {
+ inWhere: true,
+ },
cardVisible: true,
},
{
@@ -58,9 +67,10 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('Client ticket list'),
+ title: t('globals.pageTitles.summary'),
icon: 'preview',
- action: (row) => navigate(row.id),
+ action: (row) => viewSummary(row?.id, AgencySummary),
+ isPrimary: true,
},
],
},
@@ -82,7 +92,7 @@ const columns = computed(() => [
[
justify-content: center;
}
-
- es:
- isOwn: Tiene propietario
- isAnyVolumeAllowed: Permite cualquier volumen
- en:
- isOwn: Has owner
- isAnyVolumeAllowed: Allows any volume
-
diff --git a/src/pages/Route/Agency/Card/AgencyBasicData.vue b/src/pages/Route/Agency/Card/AgencyBasicData.vue
index 4270b136c..4f8f17163 100644
--- a/src/pages/Route/Agency/Card/AgencyBasicData.vue
+++ b/src/pages/Route/Agency/Card/AgencyBasicData.vue
@@ -21,7 +21,7 @@ const warehouses = ref([]);
@on-fetch="(data) => (warehouses = data)"
auto-load
/>
-
+
diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
index 7dc31f8ba..c21298470 100644
--- a/src/pages/Route/Agency/Card/AgencyCard.vue
+++ b/src/pages/Route/Agency/Card/AgencyCard.vue
@@ -1,7 +1,7 @@
-
+
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptor.vue b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
index a0472c6c3..46aa44be9 100644
--- a/src/pages/Route/Agency/Card/AgencyDescriptor.vue
+++ b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
@@ -17,7 +17,7 @@ const props = defineProps({
const { t } = useI18n();
const route = useRoute();
const entityId = computed(() => props.id || route.params.id);
-const { store } = useArrayData('Parking');
+const { store } = useArrayData();
const card = computed(() => store.data);
@@ -26,6 +26,7 @@ const card = computed(() => store.data);
:url="`Agencies/${entityId}`"
:title="card?.name"
:subtitle="props.id"
+ :to-module="{ name: 'RouteAgency' }"
>
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue b/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue
new file mode 100644
index 000000000..e5c1249b2
--- /dev/null
+++ b/src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/pages/Route/Agency/Card/AgencySummary.vue b/src/pages/Route/Agency/Card/AgencySummary.vue
index 71a6d1066..ab274939a 100644
--- a/src/pages/Route/Agency/Card/AgencySummary.vue
+++ b/src/pages/Route/Agency/Card/AgencySummary.vue
@@ -6,29 +6,31 @@ import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'components/ui/VnLv.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
+import VnCheckbox from 'components/common/VnCheckbox.vue';
+const route = useRoute();
const $props = defineProps({ id: { type: Number, default: 0 } });
const { t } = useI18n();
-const entityId = computed(() => $props.id || useRoute().params.id);
+const entityId = computed(() => $props.id || route.params.id);
-
+
{{ agency.name }}
-
-
diff --git a/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js b/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js
index ccf7872cb..99966569c 100644
--- a/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js
+++ b/src/pages/Route/Agency/composables/__tests__/getAgencies.spec.js
@@ -27,14 +27,17 @@ describe('getAgencies', () => {
landed: 'true',
};
const filter = {
- fields: ['nickname', 'street', 'city', 'id'],
+ fields: ['name', 'street', 'city', 'id'],
where: { isActive: true },
- order: 'nickname ASC',
+ order: ['name ASC'],
};
await getAgencies(formData, null, filter);
- expect(axios.get).toHaveBeenCalledWith('Agencies/getAgenciesWithWarehouse', generateParams(formData, filter));
+ expect(axios.get).toHaveBeenCalledWith(
+ 'Agencies/getAgenciesWithWarehouse',
+ generateParams(formData, filter),
+ );
});
it('should not call API when formData is missing required landed field', async () => {
@@ -64,19 +67,19 @@ describe('getAgencies', () => {
it('should return options and agency when default agency is found', async () => {
const formData = { warehouseId: '123', addressId: '456', landed: 'true' };
const client = { defaultAddress: { agencyModeFk: 'Agency1' } };
-
+
const { options, agency } = await getAgencies(formData, client);
-
+
expect(options).toEqual(response.data);
expect(agency).toEqual(response.data[0]);
- });
+ });
- it('should return options and agency when client is not provided', async () => {
+ it('should return options and agency when client is not provided', async () => {
const formData = { warehouseId: '123', addressId: '456', landed: 'true' };
-
+
const { options, agency } = await getAgencies(formData);
-
+
expect(options).toEqual(response.data);
expect(agency).toBeNull();
- });
+ });
});
diff --git a/src/pages/Route/Agency/composables/getAgencies.js b/src/pages/Route/Agency/composables/getAgencies.js
index 850f87456..180ac943e 100644
--- a/src/pages/Route/Agency/composables/getAgencies.js
+++ b/src/pages/Route/Agency/composables/getAgencies.js
@@ -1,14 +1,14 @@
import axios from 'axios';
-import agency from 'src/router/modules/agency';
export async function getAgencies(formData, client, _filter = {}) {
if (!formData.warehouseId || !formData.addressId || !formData.landed) return;
-
+
const filter = {
- ..._filter
+ ..._filter,
+ order: ['name ASC'],
};
- let defaultAgency = null;
+ let agency = null;
let params = {
filter: JSON.stringify(filter),
warehouseFk: formData.warehouseId,
@@ -16,11 +16,15 @@ export async function getAgencies(formData, client, _filter = {}) {
landed: formData.landed,
};
- const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params });
+ const { data: options } = await axios.get('Agencies/getAgenciesWithWarehouse', {
+ params,
+ });
- if(data && client) {
- defaultAgency = data.find((agency) => agency.agencyModeFk === client.defaultAddress.agencyModeFk );
- };
-
- return {options: data, agency: defaultAgency}
+ if (options && client) {
+ agency = options.find(
+ ({ agencyModeFk }) => agencyModeFk === client.defaultAddress.agencyModeFk,
+ );
+ }
+
+ return { options, agency };
}
diff --git a/src/pages/Route/Agency/locale/en.yml b/src/pages/Route/Agency/locale/en.yml
index 93f8b4aaa..78a687f2e 100644
--- a/src/pages/Route/Agency/locale/en.yml
+++ b/src/pages/Route/Agency/locale/en.yml
@@ -1,11 +1,12 @@
agency:
search: Search agency
- searchInfo: You can search by name
+ searchInfo: You can search by name and by id
isOwn: Own
isAnyVolumeAllowed: Any volume allowed
+ removeItem: Agency removed successfully
notification:
- removeItemError: Error removing agency
- removeItem: WorkCenter removed successfully
+ removeItemError: Error removing work center
+ removeItem: Work center removed successfully
pageTitles:
agency: Agency
searchBar:
diff --git a/src/pages/Route/Agency/locale/es.yml b/src/pages/Route/Agency/locale/es.yml
index 1efed0e9c..b6237a9f7 100644
--- a/src/pages/Route/Agency/locale/es.yml
+++ b/src/pages/Route/Agency/locale/es.yml
@@ -1,15 +1,14 @@
agency:
search: Buscar agencia
- searchInfo: Puedes buscar por nombre
+ searchInfo: Puedes buscar por nombre y por id
isOwn: Propio
isAnyVolumeAllowed: Cualquier volumen
removeItem: Agencia eliminada correctamente
notification:
- removeItemError: Error al eliminar la agencia
+ removeItemError: Error al eliminar la el centro de trabajo
removeItem: Centro de trabajo eliminado correctamente
pageTitles:
agency: Agencia
searchBar:
info: Puedes buscar por nombre o id
label: Buscar agencia...
-
diff --git a/src/pages/Route/Card/RouteAutonomousFilter.vue b/src/pages/Route/Card/RouteAutonomousFilter.vue
index 3be409ec9..f70f60e1c 100644
--- a/src/pages/Route/Card/RouteAutonomousFilter.vue
+++ b/src/pages/Route/Card/RouteAutonomousFilter.vue
@@ -44,8 +44,7 @@ const exprBuilder = (param, value) => {
(agencyList = data)"
auto-load
/>
diff --git a/src/pages/Route/Card/RouteCard.vue b/src/pages/Route/Card/RouteCard.vue
index c178dc6bf..b71f7d088 100644
--- a/src/pages/Route/Card/RouteCard.vue
+++ b/src/pages/Route/Card/RouteCard.vue
@@ -1,10 +1,10 @@
- {
const filter = {
where: { routeFk: $props.id ? $props.id : route.params.id },
};
- const { data } = await axios.get('Tickets/findOne', {
+ const { data } = await axios.get('Tickets/filter', {
params: {
filter: JSON.stringify(filter),
},
});
- zoneId.value = data.zoneFk;
+
+ if (!data.length) return;
+ const firstRecord = data[0];
+
+ zoneId.value = firstRecord.zoneFk;
const { data: zoneData } = await axios.get(`Zones/${zoneId.value}`);
zone.value = zoneData.name;
};
diff --git a/src/pages/Route/Card/RouteDescriptorProxy.vue b/src/pages/Route/Card/RouteDescriptorProxy.vue
index 1ff39a51e..7553469f3 100644
--- a/src/pages/Route/Card/RouteDescriptorProxy.vue
+++ b/src/pages/Route/Card/RouteDescriptorProxy.vue
@@ -7,6 +7,10 @@ const $props = defineProps({
type: Number,
required: true,
},
+ summary: {
+ type: Object,
+ default: null,
+ },
});
diff --git a/src/pages/Route/Card/RouteFilter.vue b/src/pages/Route/Card/RouteFilter.vue
index 21858102b..cb5158517 100644
--- a/src/pages/Route/Card/RouteFilter.vue
+++ b/src/pages/Route/Card/RouteFilter.vue
@@ -25,7 +25,7 @@ const emit = defineEmits(['search']);
>
- {{ t(`params.${tag.label}`) }}:
+ {{ t(`route.params.${tag.label}`) }}:
{{ formatFn(tag.value) }}
@@ -33,6 +33,7 @@ const emit = defineEmits(['search']);
@@ -146,7 +147,7 @@ const emit = defineEmits(['search']);
@@ -154,38 +155,3 @@ const emit = defineEmits(['search']);
-
-
-en:
- params:
- warehouseFk: Warehouse
- description: Description
- m3: m³
- scopeDays: Days Onward
- vehicleFk: Vehicle
- agencyModeFk: Agency
- workerFk: Worker
- from: From
- to: To
- Served: Served
-es:
- params:
- warehouseFk: Almacén
- description: Descripción
- m3: m³
- scopeDays: Días en adelante
- vehicleFk: Vehículo
- agencyModeFk: Agencia
- workerFk: Trabajador
- from: Desde
- to: Hasta
- Warehouse: Almacén
- Description: Descripción
- Vehicle: Vehículo
- Agency: Agencia
- Worker: Trabajador
- From: Desde
- To: Hasta
- Served: Servida
- Days Onward: Días en adelante
-
diff --git a/src/pages/Route/Card/RouteSummary.vue b/src/pages/Route/Card/RouteSummary.vue
index 3051972b2..f68628095 100644
--- a/src/pages/Route/Card/RouteSummary.vue
+++ b/src/pages/Route/Card/RouteSummary.vue
@@ -135,7 +135,7 @@ const ticketColumns = ref([
@@ -168,7 +168,7 @@ const ticketColumns = ref([
{{ value }}
@@ -230,7 +230,7 @@ const ticketColumns = ref([
-
+
{{ value }}
@@ -238,7 +238,7 @@ const ticketColumns = ref([
-
+
{{ value }}
diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue
index b3eaf3b48..d0683e481 100644
--- a/src/pages/Route/Cmr/CmrList.vue
+++ b/src/pages/Route/Cmr/CmrList.vue
@@ -2,28 +2,38 @@
import { onBeforeMount, onMounted, computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
+import { useRoute } from 'vue-router';
import { useSession } from 'src/composables/useSession';
import { toDateHourMin } from 'filters/index';
import { useStateStore } from 'src/stores/useStateStore';
-import axios from 'axios';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
+const route = useRoute();
const { t } = useI18n();
const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia();
const state = useStateStore();
-const warehouses = ref([]);
const selectedRows = ref([]);
+const dataKey = 'CmrList';
+const shipped = Date.vnNew();
+shipped.setHours(0, 0, 0, 0);
+shipped.setDate(shipped.getDate() - 1);
+const userParams = {
+ shipped: null,
+};
+
+
const columns = computed(() => [
{
align: 'left',
name: 'cmrFk',
- label: t('route.cmr.list.cmrFk'),
+ label: t('route.cmr.params.cmrFk'),
chip: {
condition: () => true,
},
@@ -32,62 +42,67 @@ const columns = computed(() => [
{
align: 'center',
name: 'hasCmrDms',
- label: t('route.cmr.list.hasCmrDms'),
+ label: t('route.cmr.params.hasCmrDms'),
component: 'checkbox',
cardVisible: true,
},
{
align: 'left',
- label: t('route.cmr.list.ticketFk'),
+ label: t('route.cmr.params.ticketFk'),
name: 'ticketFk',
},
{
align: 'left',
- label: t('route.cmr.list.routeFk'),
+ label: t('route.cmr.params.routeFk'),
name: 'routeFk',
},
{
align: 'left',
- label: t('route.cmr.list.clientFk'),
+ label: t('route.cmr.params.clientFk'),
name: 'clientFk',
},
{
align: 'right',
- label: t('route.cmr.list.country'),
+ label: t('route.cmr.params.countryFk'),
name: 'countryFk',
- cardVisible: true,
+ component: 'select',
attrs: {
url: 'countries',
fields: ['id', 'name'],
- optionLabel: 'name',
- optionValue: 'id',
},
columnFilter: {
- inWhere: true,
- component: 'select',
+ name: 'countryFk',
+ attrs: {
+ url: 'countries',
+ fields: ['id', 'name'],
+ },
},
format: ({ countryName }) => countryName,
},
{
align: 'right',
- label: t('route.cmr.list.shipped'),
+ label: t('route.cmr.params.shipped'),
name: 'shipped',
cardVisible: true,
- columnFilter: {
- component: 'date',
- inWhere: true,
- },
+ component: 'date',
format: ({ shipped }) => toDateHourMin(shipped),
},
{
align: 'right',
+ label: t('route.cmr.params.warehouseFk'),
name: 'warehouseFk',
- label: t('globals.warehouse'),
- columnFilter: {
- component: 'select',
- },
+ component: 'select',
attrs: {
- options: warehouses.value,
+ url: 'warehouses',
+ fields: ['id', 'name'],
+ },
+ columnFilter: {
+ inWhere: true,
+ name: 'warehouseFk',
+ attrs: {
+ url: 'warehouses',
+ fields: ['id', 'name'],
+ },
},
format: ({ warehouseName }) => warehouseName,
},
@@ -96,7 +111,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('Ver cmr'),
+ title: t('route.cmr.params.viewCmr'),
icon: 'visibility',
isPrimary: true,
action: (row) => window.open(getCmrUrl(row?.cmrFk), '_blank'),
@@ -105,13 +120,17 @@ const columns = computed(() => [
},
]);
-onBeforeMount(async () => {
- const { data } = await axios.get('Warehouses');
- warehouses.value = data;
+onBeforeMount(() => {
+ initializeFromQuery();
});
onMounted(() => (state.rightDrawer = true));
+const initializeFromQuery = () => {
+ const query = route.query.table ? JSON.parse(route.query.table) : {};
+ shipped.value = query.shipped || shipped.toISOString();
+ Object.assign(userParams, { shipped });
+};
function getApiUrl() {
return new URL(window.location).origin;
}
@@ -133,6 +152,11 @@ function downloadPdfs() {
}
+
- {{ t('route.cmr.list.downloadCmrs') }}
+ {{ t('route.cmr.params.downloadCmrs') }}
{
-import VnCardBeta from 'components/common/VnCardBeta.vue';
+import VnCard from 'components/common/VnCard.vue';
import RoadmapDescriptor from 'pages/Route/Roadmap/RoadmapDescriptor.vue';
-
+
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptor.vue b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
index baa864a15..bc9230eda 100644
--- a/src/pages/Route/Roadmap/RoadmapDescriptor.vue
+++ b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
@@ -15,6 +15,10 @@ const $props = defineProps({
required: false,
default: null,
},
+ summary: {
+ type: Object,
+ default: null,
+ },
});
const route = useRoute();
@@ -26,7 +30,13 @@ const entityId = computed(() => {
-
+
diff --git a/src/pages/Route/RouteAutonomous.vue b/src/pages/Route/RouteAutonomous.vue
index 3047cdf86..15db2a55f 100644
--- a/src/pages/Route/RouteAutonomous.vue
+++ b/src/pages/Route/RouteAutonomous.vue
@@ -13,6 +13,7 @@ import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
import RouteDescriptorProxy from 'pages/Route/Card/RouteDescriptorProxy.vue';
import InvoiceInDescriptorProxy from 'pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
+import AgencyDescriptorProxy from 'pages/Route/Agency/Card/AgencyDescriptorProxy.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import VnDms from 'components/common/VnDms.vue';
import VnTable from 'components/VnTable/VnTable.vue';
@@ -236,10 +237,16 @@ onUnmounted(() => (stateStore.rightDrawer = false));
selection: 'multiple',
}"
>
-
+
- {{ row.routeFk }}
-
+ {{ row?.agencyModeName }}
+
+
+
+
+
+ {{ row?.agencyAgreement }}
+
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index a7e192765..b905cfde8 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -38,7 +38,7 @@ const routeFilter = {
};
const columns = computed(() => [
{
- align: 'center',
+ align: 'right',
name: 'id',
label: 'Id',
chip: {
@@ -46,11 +46,11 @@ const columns = computed(() => [
},
isId: true,
columnFilter: false,
+ width: '25px',
},
{
- align: 'center',
name: 'workerFk',
- label: t('route.Worker'),
+ label: t('globals.worker'),
create: true,
component: 'select',
attrs: {
@@ -71,9 +71,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.workerUserName),
},
{
- align: 'center',
name: 'agencyModeFk',
- label: t('route.Agency'),
+ label: t('globals.agency'),
isTitle: true,
cardVisible: true,
create: true,
@@ -90,9 +89,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.agencyName),
},
{
- align: 'center',
name: 'vehicleFk',
- label: t('route.Vehicle'),
+ label: t('globals.vehicle'),
cardVisible: true,
create: true,
component: 'select',
@@ -111,9 +109,8 @@ const columns = computed(() => [
format: (row, dashIfEmpty) => dashIfEmpty(row.vehiclePlateNumber),
},
{
- align: 'center',
name: 'dated',
- label: t('route.Date'),
+ label: t('globals.date'),
columnFilter: false,
cardVisible: true,
create: true,
@@ -122,9 +119,8 @@ const columns = computed(() => [
dated === '0000-00-00' ? dashIfEmpty(null) : toDate(dated),
},
{
- align: 'center',
name: 'from',
- label: t('route.From'),
+ label: t('globals.from'),
visible: false,
cardVisible: true,
create: true,
@@ -132,9 +128,8 @@ const columns = computed(() => [
format: ({ from }) => toDate(from),
},
{
- align: 'center',
name: 'to',
- label: t('route.To'),
+ label: t('globals.to'),
visible: false,
cardVisible: true,
create: true,
@@ -142,30 +137,31 @@ const columns = computed(() => [
format: ({ date }) => toDate(date),
},
{
- align: 'center',
+ align: 'right',
name: 'm3',
label: 'm3',
cardVisible: true,
columnClass: 'shrink',
+ width: '50px',
},
{
- align: 'center',
name: 'started',
label: t('route.hourStarted'),
component: 'time',
columnFilter: false,
format: ({ started }) => toHour(started),
+ width: '50px',
},
{
- align: 'center',
name: 'finished',
label: t('route.hourFinished'),
component: 'time',
columnFilter: false,
format: ({ finished }) => toHour(finished),
+ width: '50px',
},
{
- align: 'center',
+ align: 'right',
name: 'kmStart',
label: t('route.KmStart'),
columnClass: 'shrink',
@@ -173,7 +169,7 @@ const columns = computed(() => [
visible: false,
},
{
- align: 'center',
+ align: 'right',
name: 'kmEnd',
label: t('route.KmEnd'),
columnClass: 'shrink',
@@ -181,16 +177,15 @@ const columns = computed(() => [
visible: false,
},
{
- align: 'center',
+ align: 'left',
name: 'description',
- label: t('route.Description'),
+ label: t('globals.description'),
isTitle: true,
create: true,
component: 'input',
field: 'description',
},
{
- align: 'center',
name: 'isOk',
label: t('route.Served'),
component: 'checkbox',
@@ -202,7 +197,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('route.Add tickets'),
+ title: t('route.addTicket'),
icon: 'vn:ticketAdd',
action: (row) => openTicketsDialog(row?.id),
isPrimary: true,
@@ -214,7 +209,7 @@ const columns = computed(() => [
isPrimary: true,
},
{
- title: t('route.Route summary'),
+ title: t('route.routeSummary'),
icon: 'arrow_forward',
action: (row) => navigate(row?.id),
isPrimary: true,
@@ -276,11 +271,13 @@ const openTicketsDialog = (id) => {
- {{ t('route.Select the starting date') }}
+
+ {{ t('route.extendedList.selectStartingDate') }}
+
@@ -288,7 +285,7 @@ const openTicketsDialog = (id) => {
@@ -335,29 +332,34 @@ const openTicketsDialog = (id) => {
- {{ t('route.Clone Selected Routes') }}
+ {{ t('route.extendedList.cloneSelectedRoutes') }}
- {{ t('route.Download selected routes as PDF') }}
+ {{
+ t('route.extendedList.downloadSelectedRoutes')
+ }}
- {{ t('route.Mark as served') }}
+ {{ t('route.extendedList.markServed') }}
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index 5723e2f0d..64e3abcd5 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -3,14 +3,18 @@ import { computed, ref, markRaw } from 'vue';
import { useI18n } from 'vue-i18n';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { toHour } from 'src/filters';
+import { useRouter } from 'vue-router';
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import AgencyDescriptorProxy from 'src/pages/Route/Agency/Card/AgencyDescriptorProxy.vue';
+import VehicleDescriptorProxy from 'src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
+const router = useRouter();
const { viewSummary } = useSummaryDialog();
const tableRef = ref([]);
const dataKey = 'RouteList';
@@ -24,6 +28,14 @@ const routeFilter = {
},
],
};
+
+function redirectToTickets(id) {
+ router.push({
+ name: 'RouteTickets',
+ params: { id },
+ });
+}
+
const columns = computed(() => [
{
align: 'right',
@@ -34,25 +46,21 @@ const columns = computed(() => [
condition: () => true,
},
columnFilter: false,
+ width: '25px',
},
{
align: 'left',
name: 'workerFk',
- label: t('route.Worker'),
+ label: t('globals.worker'),
component: markRaw(VnSelectWorker),
create: true,
- cardVisible: true,
format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
columnFilter: false,
- },
- {
- align: 'left',
- name: 'agencyName',
- label: t('route.Agency'),
cardVisible: true,
+ width: '100px',
},
{
- label: t('route.Agency'),
+ label: t('globals.agency'),
name: 'agencyModeFk',
component: 'select',
attrs: {
@@ -64,19 +72,13 @@ const columns = computed(() => [
},
},
create: true,
- columnFilter: false,
- visible: false,
- },
- {
- align: 'left',
- name: 'vehiclePlateNumber',
- label: t('route.Vehicle'),
+ columnFilter: true,
cardVisible: true,
+ visible: true,
},
{
name: 'vehicleFk',
- label: t('route.Vehicle'),
- cardVisible: true,
+ label: t('globals.vehicle'),
component: 'select',
attrs: {
url: 'vehicles',
@@ -89,29 +91,32 @@ const columns = computed(() => [
},
},
create: true,
- columnFilter: false,
- visible: false,
+ columnFilter: true,
+ cardVisible: true,
+ visible: true,
},
{
- align: 'left',
+ align: 'center',
name: 'started',
label: t('route.hourStarted'),
cardVisible: true,
columnFilter: false,
- format: (row) => toHour(row.started),
+ format: ({ started }) => toHour(started),
+ width: '50px',
},
{
- align: 'left',
+ align: 'center',
name: 'finished',
label: t('route.hourFinished'),
cardVisible: true,
columnFilter: false,
- format: (row) => toHour(row.started),
+ format: ({ finished }) => toHour(finished),
+ width: '50px',
},
{
align: 'left',
name: 'description',
- label: t('route.Description'),
+ label: t('globals.description'),
cardVisible: true,
isTitle: true,
create: true,
@@ -119,7 +124,6 @@ const columns = computed(() => [
columnFilter: false,
},
{
- align: 'left',
name: 'isOk',
label: t('route.Served'),
component: 'checkbox',
@@ -130,6 +134,12 @@ const columns = computed(() => [
align: 'right',
name: 'tableActions',
actions: [
+ {
+ title: t('globals.pageTitles.tickets'),
+ icon: 'vn:ticket',
+ action: (row) => redirectToTickets(row?.id),
+ isPrimary: true,
+ },
{
title: t('components.smartCard.viewSummary'),
icon: 'preview',
@@ -155,9 +165,10 @@ const columns = computed(() => [
+
+
+ {{ row?.agencyName }}
+
+
+
+
+
+ {{ row?.vehiclePlateNumber }}
+
+
+
diff --git a/src/pages/Route/RouteRoadmap.vue b/src/pages/Route/RouteRoadmap.vue
index 23b1b1d5b..c981b86a5 100644
--- a/src/pages/Route/RouteRoadmap.vue
+++ b/src/pages/Route/RouteRoadmap.vue
@@ -2,13 +2,11 @@
import { useI18n } from 'vue-i18n';
import { computed, ref } from 'vue';
import { dashIfEmpty } from 'src/filters';
-import { toDate, toDateHourMin } from 'filters/index';
+import { toDate, toDateHourMin, toCurrency } from 'filters/index';
import { useQuasar } from 'quasar';
import { useSummaryDialog } from 'composables/useSummaryDialog';
-import toCurrency from 'filters/toCurrency';
import axios from 'axios';
-import VnSearchbar from 'components/ui/VnSearchbar.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import RoadmapSummary from 'pages/Route/Roadmap/RoadmapSummary.vue';
@@ -17,6 +15,8 @@ import VnInputDate from 'components/common/VnInputDate.vue';
import VnInputTime from 'src/components/common/VnInputTime.vue';
import VnSection from 'src/components/common/VnSection.vue';
import RoadmapFilter from './Roadmap/RoadmapFilter.vue';
+import VehicleDescriptorProxy from 'src/pages/Route/Vehicle/Card/VehicleDescriptorProxy.vue';
+import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
const { viewSummary } = useSummaryDialog();
const { t } = useI18n();
@@ -33,7 +33,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'name',
- label: t('Roadmap'),
+ label: t('route.roadmap.roadmap'),
create: true,
cardVisible: true,
columnFilter: {
@@ -41,9 +41,9 @@ const columns = computed(() => [
},
},
{
- align: 'left',
+ align: 'center',
name: 'etd',
- label: t('ETD'),
+ label: t('route.roadmap.etd'),
component: 'date',
columnFilter: {
inWhere: true,
@@ -54,7 +54,7 @@ const columns = computed(() => [
{
align: 'left',
name: 'supplierFk',
- label: t('Carrier'),
+ label: t('route.roadmap.carrier'),
component: 'select',
attrs: {
url: 'suppliers',
@@ -65,21 +65,21 @@ const columns = computed(() => [
},
{
name: 'tractorPlate',
- label: t('Plate'),
+ label: t('route.roadmap.vehicle'),
field: (row) => row.tractorPlate,
sortable: true,
align: 'left',
},
{
name: 'price',
- label: t('Price'),
- field: (row) => toCurrency(row.price),
+ label: t('route.roadmap.price'),
+ format: ({ price }) => toCurrency(price),
sortable: true,
- align: 'left',
+ align: 'right',
},
{
name: 'observations',
- label: t('Observations'),
+ label: t('route.roadmap.observations'),
field: (row) => dashIfEmpty(row.observations),
sortable: true,
align: 'left',
@@ -89,7 +89,7 @@ const columns = computed(() => [
name: 'tableActions',
actions: [
{
- title: t('Ver cmr'),
+ title: t('route.roadmap.seeCmr'),
icon: 'preview',
isPrimary: true,
action: (row) => viewSummary(row?.id, RoadmapSummary),
@@ -124,8 +124,8 @@ function confirmRemove() {
.dialog({
component: VnConfirm,
componentProps: {
- title: t('Selected roadmaps will be removed'),
- message: t('Are you sure you want to continue?'),
+ title: t('route.roadmap.selectedRoadmapsRemoved'),
+ message: t('route.roadmap.areYouSure'),
promise: removeSelection,
},
})
@@ -157,15 +157,24 @@ function exprBuilder(param, value) {
- {{ t('Select the estimated date of departure (ETD)') }}
+ {{ t('route.roadmap.selectEtd') }}
-
+
-
+
{{ t('globals.clone') }}
@@ -181,7 +190,7 @@ function exprBuilder(param, value) {
:disable="!selectedRows?.length"
@click="isCloneDialogOpen = true"
>
- {{ t('Clone Selected Routes') }}
+ {{ t('route.roadmap.cloneSelected') }}
- {{ t('Delete roadmap(s)') }}
+ {{ t('route.roadmap.deleteRoadmap') }}
@@ -222,7 +231,7 @@ function exprBuilder(param, value) {
redirect="route/roadmap"
:create="{
urlCreate: 'Roadmaps',
- title: t('Create routemap'),
+ title: t('route.roadmap.createRoadmap'),
onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: {},
}"
@@ -232,7 +241,10 @@ function exprBuilder(param, value) {
{{ toDateHourMin(row.etd) }}
- {{ row.supplierFk }}
+
+ {{ row.driverName }}
+
+
@@ -251,21 +263,3 @@ function exprBuilder(param, value) {
gap: 12px;
}
-
-es:
- Create routemap: Crear troncal
- Search roadmaps: Buscar troncales
- You can search by roadmap reference: Puedes buscar por referencia del troncal
- Delete roadmap(s): Eliminar troncal(es)
- Selected roadmaps will be removed: Los troncales seleccionadas serán eliminados
- Are you sure you want to continue?: ¿Seguro que quieres continuar?
- The date can't be empty: La fecha no puede estar vacía
- Clone Selected Routes: Clonar rutas seleccionadas
- Create roadmap: Crear troncal
- Roadmap: Troncal
- Carrier: Transportista
- Plate: Matrícula
- Price: Precio
- Observations: Observaciones
- Select the estimated date of departure (ETD): Selecciona la fecha estimada de salida
-
diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue
index adc7dfdaa..5e28bb689 100644
--- a/src/pages/Route/RouteTickets.vue
+++ b/src/pages/Route/RouteTickets.vue
@@ -30,16 +30,16 @@ const columns = computed(() => [
align: 'center',
},
{
- name: 'street',
- label: t('Street'),
- field: (row) => row?.street,
+ name: 'client',
+ label: t('Client'),
+ field: (row) => row?.nickname,
sortable: false,
align: 'left',
},
{
- name: 'city',
- label: t('City'),
- field: (row) => row?.city,
+ name: 'street',
+ label: t('Street'),
+ field: (row) => row?.street,
sortable: false,
align: 'left',
},
@@ -51,9 +51,9 @@ const columns = computed(() => [
align: 'center',
},
{
- name: 'client',
- label: t('Client'),
- field: (row) => row?.nickname,
+ name: 'city',
+ label: t('City'),
+ field: (row) => row?.city,
sortable: false,
align: 'left',
},
@@ -199,12 +199,22 @@ const confirmRemove = (ticket) => {
const openSmsDialog = async () => {
const clientsId = [];
const clientsPhone = [];
-
+ const clientWithoutPhone = [];
for (let ticket of selectedRows.value) {
clientsId.push(ticket?.clientFk);
const { data: client } = await axios.get(`Clients/${ticket?.clientFk}`);
+ if (!client.phone) {
+ clientWithoutPhone.push(ticket?.clientFk);
+ continue;
+ }
clientsPhone.push(client.phone);
}
+ if (clientWithoutPhone.length) {
+ quasar.notify({
+ type: 'warning',
+ message: t('components.VnNotes.clientWithoutPhone', { clientWithoutPhone }),
+ });
+ }
quasar.dialog({
component: SendSmsDialog,
@@ -319,7 +329,7 @@ const openSmsDialog = async () => {
selection="multiple"
>
-
+
{
-
+
{{ value }}
{{ t('Open buscaman') }}
@@ -349,7 +359,7 @@ const openSmsDialog = async () => {
-
+
{{ value }}
diff --git a/src/pages/Route/Vehicle/Card/VehicleCard.vue b/src/pages/Route/Vehicle/Card/VehicleCard.vue
index f59420aa2..b6038c24c 100644
--- a/src/pages/Route/Vehicle/Card/VehicleCard.vue
+++ b/src/pages/Route/Vehicle/Card/VehicleCard.vue
@@ -1,10 +1,10 @@
-
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
import VnLv from 'src/components/ui/VnLv.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
const { notify } = useNotify();
+
+const props = defineProps({
+ id: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+});
+
+const route = useRoute();
+const entityId = computed(() => props.id || route.params.id);
+import VehicleDescriptor from 'pages/Route/Vehicle/Card/VehicleDescriptor.vue';
+import VehicleSummary from './VehicleSummary.vue';
+
+const $props = defineProps({
+ id: {
+ type: Number,
+ required: true,
+ },
+ summary: {
+ type: Object,
+ default: null,
+ },
+});
+
+
+
+
+
+
diff --git a/src/pages/Route/Vehicle/Card/VehicleSummary.vue b/src/pages/Route/Vehicle/Card/VehicleSummary.vue
index 981870cb2..13d4bbc9d 100644
--- a/src/pages/Route/Vehicle/Card/VehicleSummary.vue
+++ b/src/pages/Route/Vehicle/Card/VehicleSummary.vue
@@ -13,16 +13,22 @@ const props = defineProps({ id: { type: [Number, String], default: null } });
const route = useRoute();
const entityId = computed(() => props.id || +route.params.id);
+const baseLink = `#/${route.meta.moduleName.toLowerCase()}/vehicle/${entityId.value}`;
const links = {
- 'basic-data': `#/vehicle/${entityId.value}/basic-data`,
- notes: `#/vehicle/${entityId.value}/notes`,
- dms: `#/vehicle/${entityId.value}/dms`,
- 'invoice-in': `#/vehicle/${entityId.value}/invoice-in`,
- events: `#/vehicle/${entityId.value}/events`,
+ 'basic-data': `${baseLink}/basic-data`,
+ notes: `${baseLink}/notes`,
+ dms: `${baseLink}/dms`,
+ 'invoice-in': `${baseLink}/invoice-in`,
+ events: `${baseLink}/events`,
};
-
+
{{ entity.id }} - {{ entity.numberPlate }}
@@ -49,7 +55,10 @@ const links = {
{{ entity.supplier?.name }}
-
+
@@ -58,6 +67,7 @@ const links = {
{{ entity.supplierCooler?.name }}
diff --git a/src/pages/Route/Vehicle/VehicleList.vue b/src/pages/Route/Vehicle/VehicleList.vue
index e5b945010..a79cc2e35 100644
--- a/src/pages/Route/Vehicle/VehicleList.vue
+++ b/src/pages/Route/Vehicle/VehicleList.vue
@@ -116,6 +116,7 @@ const columns = computed(() => [
title: t('components.smartCard.openSummary'),
icon: 'preview',
action: (row) => viewSummary(row.id, VehicleSummary),
+ isPrimary: true,
},
],
},
diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml
index cc445f412..283b61855 100644
--- a/src/pages/Route/locale/en.yml
+++ b/src/pages/Route/locale/en.yml
@@ -1,48 +1,79 @@
route:
+ filter:
+ Served: Served
+ extendedList:
+ selectStartingDate: Select the starting date
+ startingDate: Starting date
+ cloneSelectedRoutes: Clone selected routes
+ downloadSelectedRoutes: Download selected routes as PDF
+ markServed: Mark as served
roadmap:
+ roadmap: Roadmap
+ carrier: Carrier
+ vehicle: Vehicle
+ price: Price
+ observations: Observations
+ etd: ETD
+ dateCantEmpty: The date can't be empty
+ createRoadmap: Create roadmap
+ deleteRoadmap: Delete roadmap(s)
+ cloneSelected: Clone selected routes
+ selectedRoadmapsRemoved: Selected roadmaps will be removed
+ areYouSure: Are you sure you want to continue?
+ selectEtd: Select the estimated date of departure (ETD)
search: Search roadmap
searchInfo: You can search by roadmap reference
params:
+ warehouseFk: Warehouse
+ description: Description
+ m3: m³
+ scopeDays: Days Onward
+ vehicleFk: Vehicle
+ agencyModeFk: Agency
+ workerFk: Worker
+ from: From
+ to: To
+ isOk: Served
etd: ETD
tractorPlate: Plate
price: Price
observations: Observations
- id: ID
+ id: Id
name: Name
cmrFk: CMR id
hasCmrDms: Attached in gestdoc
ticketFk: Ticketd id
routeFk: Route id
+ clientFk: Client id
+ countryFk: Country
shipped: Shipped
agencyAgreement: Agency agreement
agencyModeName: Agency route
+ isOwn: Own
+ isAnyVolumeallowed: Any volume allowed
Worker: Worker
Agency: Agency
Vehicle: Vehicle
Description: Description
hourStarted: H.Start
hourFinished: H.End
- dated: Dated
- From: From
- To: To
+ createRoute: Create route
Date: Date
KmStart: Km start
KmEnd: Km end
Served: Served
- Clone Selected Routes: Clone selected routes
- Select the starting date: Select the starting date
- Stating date: Starting date
- Cancel: Cancel
- Mark as served: Mark as served
- Download selected routes as PDF: Download selected routes as PDF
- Add ticket: Add ticket
- Summary: Summary
+ addTicket: Add ticket
+ routeSummary: Go to summary
Route is closed: Route is closed
Route is not served: Route is not served
search: Search route
searchInfo: You can search by route reference
+ dated: Dated
+ preview: Preview
cmr:
- list:
+ search: Search Cmr
+ searchInfo: You can search Cmr by Id
+ params:
results: results
cmrFk: CMR id
hasCmrDms: Attached in gestdoc
@@ -50,8 +81,10 @@ route:
'false': 'No'
ticketFk: Ticketd id
routeFk: Route id
- country: Country
+ countryFk: Country
clientFk: Client id
+ warehouseFk: Warehouse
shipped: Preparation date
viewCmr: View CMR
- downloadCmrs: Download CMRs
\ No newline at end of file
+ downloadCmrs: Download CMRs
+ search: General search
diff --git a/src/pages/Route/locale/es.yml b/src/pages/Route/locale/es.yml
index 51d43774a..2785ded31 100644
--- a/src/pages/Route/locale/es.yml
+++ b/src/pages/Route/locale/es.yml
@@ -1,21 +1,57 @@
route:
+ filter:
+ Served: Servida
+ extendedList:
+ selectStartingDate: Seleccione la fecha de inicio
+ statingDate: Fecha de inicio
+ cloneSelectedRoutes: Clonar rutas seleccionadas
+ downloadSelectedRoutes: Descargar rutas seleccionadas como PDF
+ markServed: Marcar como servidas
roadmap:
+ roadmap: Troncal
+ carrier: Transportista
+ vehicle: Vehículo
+ price: Precio
+ observations: Observaciones
+ etd: ETD
+ dateCantEmpty: La fecha no puede estar vacía
+ createRoadmap: Crear troncal
+ deleteRoadmap: Eliminar troncal(es)
+ cloneSelected: Clonar rutas seleccionadas
+ selectedRoadmapsRemoved: Los troncales seleccionadas serán eliminados
+ areYouSure: ¿Seguro que quieres continuar?
+ selectEtd: Selecciona la fecha estimada de salida
search: Buscar troncales
searchInfo: Puedes buscar por referencia del troncal
params:
- agencyModeName: Agencia Ruta
- agencyAgreement: Agencia Acuerdo
- id: Id
- name: Troncal
+ warehouseFk: Almacén
+ description: Descripción
+ m3: m³
+ scopeDays: Días adelante
+ vehicleFk: Vehículo
+ agencyModeFk: Agencia
+ workerFk: Trabajador
+ from: Desde
+ to: Hasta
+ isOk: Servida
etd: ETD
tractorPlate: Matrícula
price: Precio
observations: Observaciones
+ id: Id
+ name: Troncal
cmrFk: Id CMR
hasCmrDms: Gestdoc
+ search: Búsqueda general
ticketFk: Id ticket
- routeFK: Id ruta
+ routeFk: Id ruta
+ clientFk: Id cliente
+ countryFk: Pais
shipped: Fecha preparación
+ agencyModeName: Agencia Ruta
+ agencyAgreement: Agencia Acuerdo
+ isOwn: Propio
+ isAnyVolumeAllowed: Cualquier volumen
Worker: Trabajador
Agency: Agencia
Vehicle: Vehículo
@@ -23,25 +59,18 @@ route:
hourStarted: H.Inicio
hourFinished: H.Fin
createRoute: Crear ruta
- From: Desde
- To: Hasta
Date: Fecha
KmStart: Km inicio
KmEnd: Km fin
Served: Servida
- Clone Selected Routes: Clonar rutas seleccionadas
- Select the starting date: Seleccione la fecha de inicio
- Stating date: Fecha de inicio
- Cancel: Cancelar
- Mark as served: Marcar como servidas
- Download selected routes as PDF: Descargar rutas seleccionadas como PDF
- Add ticket: Añadir tickets
- preview: Vista previa
- Summary: Resumen
+ addTicket: Añadir tickets
+ routeSummary: Ir a vista previa
Route is closed: La ruta está cerrada
Route is not served: La ruta no está servida
search: Buscar rutas
searchInfo: Puedes buscar por referencia de la ruta
+ dated: Fecha
+ preview: Vista previa
cmr:
list:
results: resultados
@@ -55,4 +84,4 @@ route:
clientFk: Id cliente
shipped: Fecha preparación
viewCmr: Ver CMR
- downloadCmrs: Descargar CMRs
\ No newline at end of file
+ downloadCmrs: Descargar CMRs
diff --git a/src/pages/Shelving/Card/ShelvingCard.vue b/src/pages/Shelving/Card/ShelvingCard.vue
index 9e0ac8ad2..e2fb79fb0 100644
--- a/src/pages/Shelving/Card/ShelvingCard.vue
+++ b/src/pages/Shelving/Card/ShelvingCard.vue
@@ -1,11 +1,11 @@
-
-
+
diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue
index f89ff4d78..4a6669624 100644
--- a/src/pages/Shelving/Card/ShelvingSummary.vue
+++ b/src/pages/Shelving/Card/ShelvingSummary.vue
@@ -6,6 +6,7 @@ import VnLv from 'components/ui/VnLv.vue';
import VnUserLink from 'components/ui/VnUserLink.vue';
import filter from './ShelvingFilter.js';
import ShelvingDescriptorMenu from './ShelvingDescriptorMenu.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
const $props = defineProps({
id: {
@@ -38,13 +39,10 @@ const entityId = computed(() => $props.id || route.params.id);
-
+
-import VnCardBeta from 'components/common/VnCardBeta.vue';
+import VnCard from 'components/common/VnCard.vue';
import ParkingDescriptor from 'pages/Shelving/Parking/Card/ParkingDescriptor.vue';
import filter from './ParkingFilter.js';
- props.id || route.params.id);
:url="`Parkings/${entityId}`"
title="code"
:filter="filter"
- :to-module="{ name: 'ParkingList' }"
+ :to-module="{ name: 'ParkingMain' }"
>
diff --git a/src/pages/Shelving/Parking/Card/ParkingSummary.vue b/src/pages/Shelving/Parking/Card/ParkingSummary.vue
index 7188ebeb6..1365c71ca 100644
--- a/src/pages/Shelving/Parking/Card/ParkingSummary.vue
+++ b/src/pages/Shelving/Parking/Card/ParkingSummary.vue
@@ -4,6 +4,7 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'components/ui/VnLv.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
const $props = defineProps({
id: {
@@ -28,13 +29,10 @@ const filter = {
-
+
-import VnPaginate from 'components/ui/VnPaginate.vue';
-import CardList from 'components/ui/CardList.vue';
-import VnLv from 'components/ui/VnLv.vue';
+import { computed } from 'vue';
import { useRouter } from 'vue-router';
-import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
-import ShelvingSummary from 'pages/Shelving/Card/ShelvingSummary.vue';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import { useI18n } from 'vue-i18n';
+import VnTable from 'components/VnTable/VnTable.vue';
import VnSection from 'src/components/common/VnSection.vue';
+import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
+import ShelvingSummary from './Card/ShelvingSummary.vue';
+import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import exprBuilder from './ShelvingExprBuilder.js';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
+const { t } = useI18n();
const router = useRouter();
const { viewSummary } = useSummaryDialog();
const dataKey = 'ShelvingList';
@@ -17,9 +20,56 @@ const filter = {
include: [{ relation: 'parking' }],
};
-function navigate(id) {
- router.push({ path: `/shelving/${id}` });
-}
+const columns = computed(() => [
+ {
+ align: 'left',
+ name: 'code',
+ label: t('globals.code'),
+ isId: true,
+ isTitle: true,
+ columnFilter: false,
+ create: true,
+ },
+ {
+ align: 'left',
+ name: 'parking',
+ label: t('shelving.list.parking'),
+ sortable: true,
+ format: (val) => val?.code ?? '',
+ cardVisible: true,
+ },
+ {
+ align: 'left',
+ name: 'priority',
+ label: t('shelving.list.priority'),
+ sortable: true,
+ cardVisible: true,
+ create: true,
+ },
+ {
+ align: 'left',
+ name: 'isRecyclable',
+ label: t('shelving.summary.recyclable'),
+ sortable: true,
+ },
+ {
+ align: 'right',
+ label: '',
+ name: 'tableActions',
+ actions: [
+ {
+ title: t('components.smartCard.viewSummary'),
+ icon: 'preview',
+ action: (row) => viewSummary(row.id, ShelvingSummary),
+ isPrimary: true,
+ },
+ ],
+ },
+]);
+
+const onDataSaved = ({ id }) => {
+ router.push({ name: 'ShelvingBasicData', params: { id } });
+};
@@ -37,48 +87,75 @@ function navigate(id) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('shelving.list.newShelving') }}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ es:
+ shelving:
+ list:
+ parking: Estacionamiento
+ priority: Prioridad
+
+ summary:
+ recyclable: Reciclable
+ en:
+ shelving:
+ list:
+ parking: Parking
+ priority: Priority
+
+ summary:
+ recyclable: Recyclable
+
diff --git a/src/pages/Supplier/Card/SupplierCard.vue b/src/pages/Supplier/Card/SupplierCard.vue
index e30f79f96..74b3520bf 100644
--- a/src/pages/Supplier/Card/SupplierCard.vue
+++ b/src/pages/Supplier/Card/SupplierCard.vue
@@ -1,10 +1,10 @@
- {
- {{ buy.itemName }}
+ {{ buy.itemName }}
diff --git a/src/pages/Supplier/Card/SupplierFilter.js b/src/pages/Supplier/Card/SupplierFilter.js
index 3ce5c3de2..3aabe2c6d 100644
--- a/src/pages/Supplier/Card/SupplierFilter.js
+++ b/src/pages/Supplier/Card/SupplierFilter.js
@@ -11,6 +11,11 @@ export default {
'isSerious',
'isTrucker',
'account',
+ 'workerFk',
+ 'note',
+ 'isReal',
+ 'isPayMethodChecked',
+ 'companySize',
],
include: [
{
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index ecee5b76b..4293bd41a 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -108,7 +108,6 @@ function handleLocation(data, location) {
diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue
index c9625518f..ec89d77e0 100644
--- a/src/pages/Supplier/SupplierList.vue
+++ b/src/pages/Supplier/SupplierList.vue
@@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
import VnTable from 'components/VnTable/VnTable.vue';
import VnSection from 'src/components/common/VnSection.vue';
import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'src/components/FetchData.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import SupplierSummary from './Card/SupplierSummary.vue';
@@ -53,7 +52,7 @@ const columns = computed(() => [
label: t('globals.alias'),
name: 'alias',
columnFilter: {
- name: 'search',
+ name: 'nickname',
},
cardVisible: true,
},
@@ -120,6 +119,21 @@ const columns = computed(() => [
],
},
]);
+
+const filterColumns = computed(() => {
+ const copy = [...columns.value];
+ copy.splice(copy.length - 1, 0, {
+ align: 'left',
+ label: t('globals.params.provinceFk'),
+ name: 'provinceFk',
+ options: provincesOptions.value,
+ columnFilter: {
+ component: 'select',
+ },
+ });
+
+ return copy;
+});
[
/>
[
-
-
-
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
index ef2eb75d6..3c2fe95e5 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
@@ -44,8 +44,8 @@ const getPriceDifference = async () => {
shipped: ticket.value.shipped,
};
const { data } = await axios.post(
- `tickets/${ticket.value.id}/priceDifference`,
- params
+ `tickets/${formData.value.id}/priceDifference`,
+ params,
);
ticket.value.sale = data;
};
@@ -71,8 +71,8 @@ const submit = async () => {
};
const { data } = await axios.post(
- `tickets/${ticket.value.id}/componentUpdate`,
- params
+ `tickets/${formData.value.id}/componentUpdate`,
+ params,
);
if (!data) return;
@@ -99,7 +99,7 @@ const onNextStep = async () => {
openConfirmationModal(
t('basicData.negativesConfirmTitle'),
t('basicData.negativesConfirmMessage'),
- submitWithNegatives
+ submitWithNegatives,
);
else submit();
}
diff --git a/src/pages/Ticket/Card/TicketCard.vue b/src/pages/Ticket/Card/TicketCard.vue
index e22d5799a..19dbd608c 100644
--- a/src/pages/Ticket/Card/TicketCard.vue
+++ b/src/pages/Ticket/Card/TicketCard.vue
@@ -1,10 +1,10 @@
- {
return $props.id || route.params.id;
});
const problems = ref({});
+const originalTicket = ref();
function ticketFilter(ticket) {
return JSON.stringify({ clientFk: ticket.clientFk });
}
+async function getClaims() {
+ const userFilter = { where: { refundTicketFk: entityId.value } };
+ const { data } = await axios.get(`TicketRefunds`, {
+ params: { filter: JSON.stringify(userFilter) },
+ });
+ if (!data) return;
+ originalTicket.value = data[0]?.originalTicketFk;
+}
+async function getProblems() {
+ const { data } = await axios.get(`Tickets/${entityId.value}/getTicketProblems`);
+ if (!data) return;
+ problems.value = data[0];
+}
+function getInfo() {
+ getClaims();
+ getProblems();
+}
- ([problems] = data)"
- />
@@ -73,12 +88,12 @@ function ticketFilter(ticket) {
-
+
-
+
+ {{ entity?.client?.department?.name || '-' }}
+
+
-
+
-
+
@@ -129,6 +144,15 @@ function ticketFilter(ticket) {
>
{{ t('ticket.card.newOrder') }}
+
+ {{ t('ticket.card.ticketClaimed') }}
+
diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
index 63e45c8ab..f7389b592 100644
--- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
@@ -32,7 +32,7 @@ onMounted(() => {
watch(
() => props.ticket,
- () => restoreTicket
+ () => restoreTicket,
);
const { push, currentRoute } = useRouter();
@@ -58,7 +58,7 @@ const hasDocuwareFile = ref();
const quasar = useQuasar();
const canRestoreTicket = ref(false);
-const onClientSelected = async(clientId) =>{
+const onClientSelected = async (clientId) => {
client.value = clientId;
await fetchClient();
await fetchAddresses();
@@ -66,10 +66,10 @@ const onClientSelected = async(clientId) =>{
const onAddressSelected = (addressId) => {
address.value = addressId;
-}
+};
const fetchClient = async () => {
- const response = await getClient(client.value)
+ const response = await getClient(client.value);
if (!response) return;
const [retrievedClient] = response.data;
selectedClient.value = retrievedClient;
@@ -151,7 +151,7 @@ function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
recipientId: ticket.value.clientFk,
type: type,
},
- '_blank'
+ '_blank',
);
}
@@ -297,8 +297,8 @@ async function transferClient() {
clientFk: client.value,
addressFk: address.value,
};
-
- await axios.patch( `Tickets/${ticketId.value}/transferClient`, params );
+
+ await axios.patch(`Tickets/${ticketId.value}/transferClient`, params);
window.location.reload();
}
@@ -339,7 +339,7 @@ async function changeShippedHour(time) {
const { data } = await axios.post(
`Tickets/${ticketId.value}/updateEditableTicket`,
- params
+ params,
);
if (data) window.location.reload();
@@ -405,8 +405,7 @@ async function uploadDocuware(force) {
uploadDocuware(true);
});
- const { data } = await axios.post(`Docuwares/upload`, {
- fileCabinet: 'deliveryNote',
+ const { data } = await axios.post(`Docuwares/upload-delivery-note`, {
ticketIds: [parseInt(ticketId.value)],
});
@@ -500,7 +499,7 @@ async function ticketToRestore() {
- {
};
const getMana = async () => {
- const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
+ const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
mana.value = data;
await getUsesMana();
};
diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue
index f8084ff2f..e9e153b70 100644
--- a/src/pages/Ticket/Card/TicketExpedition.vue
+++ b/src/pages/Ticket/Card/TicketExpedition.vue
@@ -37,7 +37,6 @@ const expeditionStateTypes = ref([]);
const expeditionsFilter = computed(() => ({
where: { ticketFk: route.params.id },
- order: ['created DESC'],
}));
const ticketArrayData = useArrayData('Ticket');
@@ -105,6 +104,9 @@ const columns = computed(() => [
name: 'created',
align: 'left',
cardVisible: true,
+ columnFilter: {
+ component: 'date',
+ },
format: (row) => toDateTimeFormat(row.created),
},
{
@@ -201,7 +203,7 @@ const getExpeditionState = async (expedition) => {
const openGrafana = (expeditionFk) => {
useOpenURL(
- `https://grafana.verdnatura.es/d/de1njb6p5answd/control-de-expediciones?orgId=1&var-expeditionFk=${expeditionFk}`
+ `https://grafana.verdnatura.es/d/de1njb6p5answd/control-de-expediciones?orgId=1&var-expeditionFk=${expeditionFk}`,
);
};
@@ -287,7 +289,7 @@ onMounted(async () => {
openConfirmationModal(
'',
t('expedition.removeExpeditionSubtitle'),
- deleteExpedition
+ deleteExpedition,
)
"
>
@@ -302,7 +304,6 @@ onMounted(async () => {
url="Expeditions/filter"
search-url="expeditions"
:columns="columns"
- :filter="expeditionsFilter"
v-model:selected="selectedRows"
:table="{
'row-key': 'id',
@@ -316,11 +317,14 @@ onMounted(async () => {
return { id: value };
case 'packageItemName':
return { packagingItemFk: value };
+ case 'created':
+ return { 'e.created': { gte: value } };
}
}
"
:redirect="false"
order="created DESC"
+ :filter="expeditionsFilter"
>
diff --git a/src/pages/Ticket/Card/TicketFilter.js b/src/pages/Ticket/Card/TicketFilter.js
index 7846f1658..daa204a7a 100644
--- a/src/pages/Ticket/Card/TicketFilter.js
+++ b/src/pages/Ticket/Card/TicketFilter.js
@@ -12,7 +12,7 @@ export default {
fields: [
'id',
'name',
- 'salesPersonFk',
+ 'departmentFk',
'phone',
'mobile',
'email',
@@ -29,7 +29,7 @@ export default {
fields: ['id', 'lang'],
},
},
- { relation: 'salesPersonUser' },
+ { relation: 'department' },
],
},
},
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 456a151a3..2fb305cc3 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -174,22 +174,26 @@ const getSaleTotal = (sale) => {
return price - discount;
};
-const getRowUpdateInputEvents = (sale) => ({
- 'keyup.enter': () => {
- changeQuantity(sale);
- },
- blur: () => {
- changeQuantity(sale);
- },
-});
+const getRowUpdateInputEvents = (sale) => {
+ return {
+ 'keyup.enter': () => {
+ changeQuantity(sale);
+ },
+ blur: () => {
+ changeQuantity(sale);
+ },
+ };
+};
const resetChanges = async () => {
arrayData.fetch({ append: false });
tableRef.value.reload();
+ selectedRows.value = [];
};
const changeQuantity = async (sale) => {
if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity)
return;
+ else sale.originalQuantity = sale.quantity;
if (!sale.id) return addSale(sale);
if (await isSalePrepared(sale)) {
@@ -235,7 +239,7 @@ const addSale = async (sale) => {
notify('globals.dataSaved', 'positive');
sale.isNew = false;
- arrayData.fetch({});
+ resetChanges();
};
const changeConcept = async (sale) => {
if (await isSalePrepared(sale)) {
@@ -258,6 +262,18 @@ const DEFAULT_EDIT = {
oldQuantity: null,
};
const edit = ref({ ...DEFAULT_EDIT });
+const usesMana = ref(null);
+
+const getUsesMana = async () => {
+ const { data } = await axios.get('Sales/usesMana');
+ usesMana.value = data;
+};
+
+const getMana = async () => {
+ const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
+ mana.value = data;
+ await getUsesMana();
+};
const selectedValidSales = computed(() => {
if (!sales.value) return;
@@ -310,7 +326,7 @@ const changeDiscount = async (sale) => {
}
};
-const updateDiscounts = async (sales, newDiscount = null) => {
+const updateDiscounts = async (sales, newDiscount) => {
const salesTracking = await fetchSalesTracking();
const someSaleIsPrepared = salesTracking.some((sale) =>
@@ -320,12 +336,11 @@ const updateDiscounts = async (sales, newDiscount = null) => {
else updateDiscount(sales, newDiscount);
};
-const updateDiscount = async (sales, newDiscount = null) => {
- const saleIds = sales.map((sale) => sale.id);
- const _newDiscount = newDiscount || edit.value.discount;
+const updateDiscount = async (sales, newDiscount = 0) => {
+ const salesIds = sales.map(({ id }) => id);
const params = {
- salesIds: saleIds,
- newDiscount: _newDiscount,
+ salesIds,
+ newDiscount,
manaCode: manaCode.value,
};
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
@@ -474,7 +489,7 @@ const endNewRow = (row) => {
};
async function confirmUpdate(cb) {
- await quasar
+ quasar
.dialog({
component: VnConfirm,
componentProps: {
@@ -664,6 +679,7 @@ watch(
selection: 'multiple',
}"
:right-search="false"
+ :search-url="false"
:column-search="false"
:disable-option="{ card: true }"
auto-load
@@ -681,6 +697,17 @@ watch(
:disabled-attr="isTicketEditable"
>
+
+
+ {{ `saleGroup: ${row.saleGroupFk}` }}
+
+
@@ -692,7 +719,7 @@ watch(
-
+
@@ -740,7 +767,7 @@ watch(
{{ row?.item?.subName.toUpperCase() }}
-
+
{
}
return false;
});
-const hasReserves = computed(() => props.sales.some((sale) => sale.reserved == true));
-
const sendSms = async (params) => {
await axios.post(`Tickets/${ticket.value.id}/sendSms`, params);
notify(t('SMS sent'), 'positive');
@@ -144,14 +142,6 @@ const onCreateClaimAccepted = async () => {
push({ name: 'ClaimBasicData', params: { id: data.id } });
};
-const setReserved = async (reserved) => {
- const params = { ticketId: ticket.value.id, sales: props.sales, reserved: reserved };
- await axios.post(`Sales/reserve`, params);
- props.sales.forEach((sale) => {
- sale.reserved = reserved;
- });
-};
-
const createRefund = async (withWarehouse) => {
if (!props.ticket) return;
@@ -252,18 +242,6 @@ const createRefund = async (withWarehouse) => {
{{ t('Mark as reserved') }}
-
-
- {{ t('Unmark as reserved') }}
-
-
{{ t('Refund') }}
diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue
index 6ce69a6aa..a44dce5c4 100644
--- a/src/pages/Ticket/Card/TicketService.vue
+++ b/src/pages/Ticket/Card/TicketService.vue
@@ -121,6 +121,50 @@ async function handleSave() {
isSaving.value = false;
}
}
+function validateFields(item) {
+ // Only validate fields that are being updated
+ const shouldExist = (field) => field in item;
+
+ if (!shouldExist('ticketServiceTypeFk') && !item.ticketServiceTypeFk) {
+ notify('Description is required', 'negative');
+ return false;
+ }
+
+ if (!shouldExist('quantity') && (!item.quantity || item.quantity <= 0)) {
+ notify('Quantity must be greater than 0', 'negative');
+ return false;
+ }
+
+ if (!shouldExist('price') && (!item.price || item.price < 0)) {
+ notify('Price must be valid', 'negative');
+ return false;
+ }
+
+ return true;
+}
+
+function beforeSave(data) {
+ const { creates = [], updates = [] } = data;
+ const validData = { creates: [], updates: [] };
+
+ // Validate creates
+ if (creates.length) {
+ for (const create of creates) {
+ create.ticketFk = route.params.id;
+ if (validateFields(create)) {
+ validData.creates.push(create);
+ }
+ }
+ }
+
+ // Validate updates
+ if (updates.length) {
+ for (const update of updates) {
+ validData.updates.push(update);
+ }
+ }
+ return validData;
+}
@@ -141,6 +185,7 @@ async function handleSave() {
v-model:selected="selected"
:order="['description ASC']"
:default-remove="false"
+ :beforeSaveFn="beforeSave"
>
@@ -196,6 +243,7 @@ async function handleSave() {
:label="col.label"
v-model.number="row.price"
type="number"
+ :required="true"
min="0"
@keyup.enter="handleSave"
/>
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 5838efa88..a19ab3779 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -13,9 +13,9 @@ import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import { getUrl } from 'src/composables/getUrl';
import useNotify from 'src/composables/useNotify.js';
import { useArrayData } from 'composables/useArrayData';
-import VnUserLink from 'src/components/ui/VnUserLink.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
@@ -152,12 +152,14 @@ onMounted(async () => {
-
+
-
+
+ {{ entity?.client?.department?.name || '-' }}
+
+
diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue
index acf464fb1..00610de44 100644
--- a/src/pages/Ticket/Card/TicketTracking.vue
+++ b/src/pages/Ticket/Card/TicketTracking.vue
@@ -81,6 +81,7 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
ref="paginateRef"
data-key="TicketTracking"
:user-filter="paginateFilter"
+ search-url="table"
url="TicketTrackings"
auto-load
order="created DESC"
diff --git a/src/pages/Ticket/Card/TicketTransferProxy.vue b/src/pages/Ticket/Card/TicketTransferProxy.vue
index 3f3f018df..7d5d82f85 100644
--- a/src/pages/Ticket/Card/TicketTransferProxy.vue
+++ b/src/pages/Ticket/Card/TicketTransferProxy.vue
@@ -42,7 +42,7 @@ const transferRef = ref(null);
/>