From 0f0717f3827e0efcd9d0e755af5b3d9bdea12359 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Thu, 6 Feb 2025 13:50:49 -0300
Subject: [PATCH 01/25] refactor: use Salix for the pending orders

---
 .dockerignore                        |  5 +-
 quasar.config.js                     | 35 ++-----------
 src/pages/Ecomerce/PendingOrders.vue | 75 ++++++++++++++++++++++------
 3 files changed, 67 insertions(+), 48 deletions(-)

diff --git a/.dockerignore b/.dockerignore
index ebf83b0b..aee456a4 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,2 +1,5 @@
 debian
-node_modules
\ No newline at end of file
+node_modules
+.quasar
+build
+.vscode
diff --git a/quasar.config.js b/quasar.config.js
index e7bbb5e0..84e934d1 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -8,7 +8,6 @@
 // Configuration for your app
 // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
 
-const ESLintPlugin = require('eslint-webpack-plugin');
 const path = require('path');
 
 const { configure } = require('quasar/wrappers');
@@ -68,11 +67,7 @@ module.exports = configure(function (ctx) {
             // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
 
             chainWebpack(chain) {
-                chain
-                    .plugin('eslint-webpack-plugin')
-                    .use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
-                chain.resolve.alias
-                    .set('@', path.resolve(__dirname, 'src'));
+                chain.resolve.alias.set('@', path.resolve(__dirname, 'src'));
                 chain.module
                     .rule('i18n-resource')
                     .test(/\.(json5?|ya?ml)$/)
@@ -96,7 +91,7 @@ module.exports = configure(function (ctx) {
                 type: 'http'
             },
             port: 8080,
-            open: false,
+            open: true,
             // static: __dirname,
             headers: { 'Access-Control-Allow-Origin': '*' },
             // stats: { chunks: false },
@@ -144,12 +139,6 @@ module.exports = configure(function (ctx) {
             maxAge: 1000 * 60 * 60 * 24 * 30,
             // Tell browser when a file from the server should expire from cache (in ms)
 
-            chainWebpackWebserver(chain) {
-                chain
-                    .plugin('eslint-webpack-plugin')
-                    .use(ESLintPlugin, [{ extensions: ['js'] }]);
-            },
-
             middlewares: [
                 ctx.prod ? 'compression' : '',
                 'render' // keep this as last one
@@ -164,11 +153,7 @@ module.exports = configure(function (ctx) {
             // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
             // if using workbox in InjectManifest mode
 
-            chainWebpackCustomSW(chain) {
-                chain
-                    .plugin('eslint-webpack-plugin')
-                    .use(ESLintPlugin, [{ extensions: ['js'] }]);
-            },
+            chainWebpackCustomSW(chain) {},
 
             manifest: {
                 name: 'Hedera',
@@ -237,21 +222,9 @@ module.exports = configure(function (ctx) {
                 // https://www.electron.build/configuration/configuration
 
                 appId: 'hedera-web'
-            },
+            }
 
             // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
-
-            chainWebpackMain(chain) {
-                chain
-                    .plugin('eslint-webpack-plugin')
-                    .use(ESLintPlugin, [{ extensions: ['js'] }]);
-            },
-
-            chainWebpackPreload(chain) {
-                chain
-                    .plugin('eslint-webpack-plugin')
-                    .use(ESLintPlugin, [{ extensions: ['js'] }]);
-            }
         }
     };
 });
diff --git a/src/pages/Ecomerce/PendingOrders.vue b/src/pages/Ecomerce/PendingOrders.vue
index c9257cb2..ebca0b2d 100644
--- a/src/pages/Ecomerce/PendingOrders.vue
+++ b/src/pages/Ecomerce/PendingOrders.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, inject, onMounted } from 'vue';
+import { ref, inject, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 
@@ -10,13 +10,16 @@ import { currency, formatDateTitle } from 'src/lib/filters.js';
 import { useVnConfirm } from 'src/composables/useVnConfirm.js';
 import useNotify from 'src/composables/useNotify.js';
 import { useAppStore } from 'stores/app';
+import { useUserStore } from 'stores/user';
 import { storeToRefs } from 'pinia';
 
 const jApi = inject('jApi');
+const api = inject('api');
 const { t } = useI18n();
 const { openConfirmationModal } = useVnConfirm();
 const { notify } = useNotify();
 const appStore = useAppStore();
+const userStore = useUserStore();
 const { isHeaderMounted } = storeToRefs(appStore);
 const router = useRouter();
 
@@ -26,15 +29,48 @@ const orders = ref([]);
 const getOrders = async () => {
     try {
         loading.value = true;
-        orders.value = await jApi.query(
-            `SELECT o.id, o.sent, o.deliveryMethodFk, o.taxableBase,
-        a.nickname, am.description agency
-        FROM myOrder o
-        JOIN myAddress a ON a.id = o.addressFk
-        JOIN vn.agencyMode am ON am.id = o.agencyModeFk
-        WHERE NOT o.isConfirmed
-        ORDER BY o.sent DESC`
-        );
+
+        const clientFk = userStore?.user?.id;
+
+        const filter = {
+          where: {
+            clientFk,
+            'address.clientFk': clientFk,
+            isConfirmed: 0,
+            source_app: 'WEB',
+          },
+          include: [
+            {
+              relation: 'address',
+              scope: {
+                fields: ['nickname', 'city'],
+              }
+            },
+            {
+              relation: 'agencyMode',
+              scope: {
+                fields: ['description'],
+              }
+            },
+          ],
+          fields: [
+            'id',
+            'landed',
+            'delivery_method_id',
+            'taxableBase',
+            'addressFk',
+            'agencyModeFk'
+          ]
+        };
+
+        const { data: salixOrders } = await api.get('Orders', {
+          params: {
+            filter: JSON.stringify(filter)
+          }
+        });
+
+        orders.value = salixOrders;
+
         loading.value = false;
     } catch (error) {
         console.error('Error getting orders:', error);
@@ -63,9 +99,16 @@ const loadOrder = orderId => {
     router.push({ name: 'catalog' });
 };
 
-onMounted(async () => {
-    getOrders();
-});
+watch(
+  () => userStore?.user?.id,
+  async userId => {
+    if (userId) {
+      getOrders();
+    }
+  },
+  { immediate: true }
+);
+
 </script>
 
 <template>
@@ -93,11 +136,11 @@ onMounted(async () => {
             >
                 <template #content>
                     <QItemLabel class="text-bold q-mb-sm">
-                        {{ formatDateTitle(order.sent) }}
+                        {{ formatDateTitle(order.landed) }}
                     </QItemLabel>
                     <QItemLabel> #{{ order.id }} </QItemLabel>
-                    <QItemLabel>{{ order.nickname }}</QItemLabel>
-                    <QItemLabel>{{ order.agency }}</QItemLabel>
+                    <QItemLabel>{{ order.address.nickname }}</QItemLabel>
+                    <QItemLabel>{{ order.agencyMode.description }}</QItemLabel>
                     <QItemLabel>{{ currency(order.taxableBase) }}</QItemLabel>
                 </template>
                 <template #actions>

From cba6b000fc1cdc439a723d8869f2b7cc3bdc17c1 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Tue, 11 Mar 2025 23:48:48 -0300
Subject: [PATCH 02/25] orders.value = await
 api.post('applications/myTicket_list/execute-proc', params);

---
 src/pages/Ecomerce/OrdersView.vue | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index 67daeb1c..35370cc8 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -17,6 +17,7 @@ import { storeToRefs } from 'pinia';
 const { t } = useI18n();
 const route = useRoute();
 const jApi = inject('jApi');
+const api = inject('api');
 const { notify } = useNotify();
 const appStore = useAppStore();
 const { isHeaderMounted } = storeToRefs(appStore);
@@ -30,7 +31,13 @@ const tpv = tpvStore();
 onMounted(async () => {
     await tpv.check(route);
 
-    orders.value = await jApi.query('CALL myTicket_list(NULL, NULL)');
+    const myTickets = await api.post('applications/myTicket_list/execute-proc', new URLSearchParams({
+      schema: 'hedera',
+      params: '[null, null]',
+    }));
+
+    orders.value = myTickets.data;
+
     debt.value = await jApi.getValue('SELECT -myClient_getDebt(NULL)');
 });
 

From 1698a8505524d845853587cee6fe100d7a6bafa7 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Thu, 13 Mar 2025 02:48:54 -0300
Subject: [PATCH 03/25] debt.value = await api.get(`clients/${userId}/getDebt`)

---
 src/pages/Ecomerce/OrdersView.vue | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index 35370cc8..a5b85a52 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onMounted, inject } from 'vue';
+import {ref, onMounted, inject, watch} from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -12,6 +12,7 @@ import useNotify from 'src/composables/useNotify.js';
 import { currency, formatDateTitle } from 'src/lib/filters.js';
 import { tpvStore } from 'stores/tpv';
 import { useAppStore } from 'stores/app';
+import { useUserStore } from 'stores/user';
 import { storeToRefs } from 'pinia';
 
 const { t } = useI18n();
@@ -20,6 +21,7 @@ const jApi = inject('jApi');
 const api = inject('api');
 const { notify } = useNotify();
 const appStore = useAppStore();
+const userStore = useUserStore();
 const { isHeaderMounted } = storeToRefs(appStore);
 
 const showAmountToPayDialog = ref(null);
@@ -35,12 +37,14 @@ onMounted(async () => {
       schema: 'hedera',
       params: '[null, null]',
     }));
-
     orders.value = myTickets.data;
-
-    debt.value = await jApi.getValue('SELECT -myClient_getDebt(NULL)');
 });
 
+const getDebt = async (userId) => {
+  const myClientDebt = await api.get(`clients/${userId}/getDebt`);
+  debt.value = -myClientDebt.data;
+}
+
 const onPayClick = async () => {
     showAmountToPayDialog.value = true;
 
@@ -59,6 +63,17 @@ const onConfirmPay = async () => {
     amountToPay.value = parseFloat(amount);
     await tpv.pay(amountToPay.value);
 };
+
+watch(
+  () => userStore?.user?.id,
+  async userId => {
+    if (userId) {
+      await getDebt(userId);
+    }
+  },
+  { immediate: true }
+);
+
 </script>
 
 <template>

From d08c1ac86ff4250190331f88964cf48abb9487e9 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Thu, 13 Mar 2025 03:09:24 -0300
Subject: [PATCH 04/25] fix style

---
 src/pages/Ecomerce/OrdersView.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index a5b85a52..34d00318 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -1,5 +1,5 @@
 <script setup>
-import {ref, onMounted, inject, watch} from 'vue';
+import { ref, onMounted, inject, watch } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 

From ce4fdf06f5b6baf4fb56dcee78d9bce3ffdcb748 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Sun, 16 Mar 2025 17:31:24 -0300
Subject: [PATCH 05/25] Control panel migration

---
 src/pages/Admin/LinksView.vue | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/pages/Admin/LinksView.vue b/src/pages/Admin/LinksView.vue
index 60cb0bc5..1b1e480d 100644
--- a/src/pages/Admin/LinksView.vue
+++ b/src/pages/Admin/LinksView.vue
@@ -1,16 +1,15 @@
 <script setup>
 import { ref, onMounted, inject } from 'vue';
 
-const jApi = inject('jApi');
+const api = inject('api');
 
 const links = ref([]);
 
 const getLinks = async () => {
     try {
-        links.value = await jApi.query(
-            `SELECT image, name, description, link FROM link
-            ORDER BY name`
-        );
+        const filter = { order: 'name ASC' };
+        const { data } = await api.get('/Links', { params: { filter } });
+        links.value = data;
     } catch (error) {
         console.error('Error getting links:', error);
     }

From 259387681344ae875f225f5b1118a3f01cf3a35b Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Mon, 17 Mar 2025 16:02:04 -0300
Subject: [PATCH 06/25] refactor: onUserId

---
 src/pages/Ecomerce/OrdersView.vue | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index 34d00318..5285c56f 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -64,16 +64,22 @@ const onConfirmPay = async () => {
     await tpv.pay(amountToPay.value);
 };
 
-watch(
+const onUserId = (cb) => watch(
   () => userStore?.user?.id,
   async userId => {
     if (userId) {
-      await getDebt(userId);
+      try {
+        await cb(userId);
+      } catch (error) {
+        console.error(error);
+      }
     }
   },
   { immediate: true }
 );
 
+onUserId(getDebt);
+
 </script>
 
 <template>

From 49d816539510557ee0760279e9bb6e9247b65747 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Tue, 18 Mar 2025 22:07:58 -0300
Subject: [PATCH 07/25] refactor: onUserId.js

---
 src/pages/Ecomerce/OrdersView.vue | 19 ++-----------------
 src/utils/onUserId.js             | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 17 deletions(-)
 create mode 100644 src/utils/onUserId.js

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index 5285c56f..0c1ff6a5 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onMounted, inject, watch } from 'vue';
+import { ref, onMounted, inject } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -8,11 +8,11 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import VnList from 'src/components/ui/VnList.vue';
 
+import { onUserId } from 'src/utils/onUserId';
 import useNotify from 'src/composables/useNotify.js';
 import { currency, formatDateTitle } from 'src/lib/filters.js';
 import { tpvStore } from 'stores/tpv';
 import { useAppStore } from 'stores/app';
-import { useUserStore } from 'stores/user';
 import { storeToRefs } from 'pinia';
 
 const { t } = useI18n();
@@ -21,7 +21,6 @@ const jApi = inject('jApi');
 const api = inject('api');
 const { notify } = useNotify();
 const appStore = useAppStore();
-const userStore = useUserStore();
 const { isHeaderMounted } = storeToRefs(appStore);
 
 const showAmountToPayDialog = ref(null);
@@ -64,20 +63,6 @@ const onConfirmPay = async () => {
     await tpv.pay(amountToPay.value);
 };
 
-const onUserId = (cb) => watch(
-  () => userStore?.user?.id,
-  async userId => {
-    if (userId) {
-      try {
-        await cb(userId);
-      } catch (error) {
-        console.error(error);
-      }
-    }
-  },
-  { immediate: true }
-);
-
 onUserId(getDebt);
 
 </script>
diff --git a/src/utils/onUserId.js b/src/utils/onUserId.js
new file mode 100644
index 00000000..28c1fcae
--- /dev/null
+++ b/src/utils/onUserId.js
@@ -0,0 +1,19 @@
+import { watch } from 'vue';
+
+import { useUserStore } from 'stores/user';
+
+const userStore = useUserStore();
+
+export const onUserId = (cb) => watch(
+  () => userStore?.user?.id,
+  async userId => {
+    if (userId) {
+      try {
+        await cb(userId);
+      } catch (error) {
+        console.error(error);
+      }
+    }
+  },
+  { immediate: true }
+);

From d012ca74fea7273ff2fc337b100cf666182ec5b3 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Tue, 18 Mar 2025 22:11:01 -0300
Subject: [PATCH 08/25] refactor: minor code cleanup

---
 src/pages/Ecomerce/OrdersView.vue | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/pages/Ecomerce/OrdersView.vue b/src/pages/Ecomerce/OrdersView.vue
index 0c1ff6a5..a5d6d9d9 100644
--- a/src/pages/Ecomerce/OrdersView.vue
+++ b/src/pages/Ecomerce/OrdersView.vue
@@ -17,7 +17,6 @@ import { storeToRefs } from 'pinia';
 
 const { t } = useI18n();
 const route = useRoute();
-const jApi = inject('jApi');
 const api = inject('api');
 const { notify } = useNotify();
 const appStore = useAppStore();
@@ -32,17 +31,17 @@ const tpv = tpvStore();
 onMounted(async () => {
     await tpv.check(route);
 
-    const myTickets = await api.post('applications/myTicket_list/execute-proc', new URLSearchParams({
+    const myTickets = await api.post('applications/myTicket_list/execute-proc', {
       schema: 'hedera',
-      params: '[null, null]',
-    }));
+      params: [null, null],
+    });
     orders.value = myTickets.data;
 });
 
-const getDebt = async (userId) => {
+onUserId(async (userId) => {
   const myClientDebt = await api.get(`clients/${userId}/getDebt`);
   debt.value = -myClientDebt.data;
-}
+});
 
 const onPayClick = async () => {
     showAmountToPayDialog.value = true;
@@ -62,9 +61,6 @@ const onConfirmPay = async () => {
     amountToPay.value = parseFloat(amount);
     await tpv.pay(amountToPay.value);
 };
-
-onUserId(getDebt);
-
 </script>
 
 <template>

From afbbbace4b7f1d13af261dd28ed71bf141f6dac9 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Thu, 20 Mar 2025 23:55:53 -0300
Subject: [PATCH 09/25] refactor: onUserId

---
 src/pages/Ecomerce/PendingOrders.vue | 17 +++--------------
 src/utils/onUserId.js                | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+), 14 deletions(-)
 create mode 100644 src/utils/onUserId.js

diff --git a/src/pages/Ecomerce/PendingOrders.vue b/src/pages/Ecomerce/PendingOrders.vue
index ebca0b2d..619f47d4 100644
--- a/src/pages/Ecomerce/PendingOrders.vue
+++ b/src/pages/Ecomerce/PendingOrders.vue
@@ -10,8 +10,8 @@ import { currency, formatDateTitle } from 'src/lib/filters.js';
 import { useVnConfirm } from 'src/composables/useVnConfirm.js';
 import useNotify from 'src/composables/useNotify.js';
 import { useAppStore } from 'stores/app';
-import { useUserStore } from 'stores/user';
 import { storeToRefs } from 'pinia';
+import { onUserId } from 'src/utils/onUserId';
 
 const jApi = inject('jApi');
 const api = inject('api');
@@ -19,19 +19,16 @@ const { t } = useI18n();
 const { openConfirmationModal } = useVnConfirm();
 const { notify } = useNotify();
 const appStore = useAppStore();
-const userStore = useUserStore();
 const { isHeaderMounted } = storeToRefs(appStore);
 const router = useRouter();
 
 const loading = ref(false);
 const orders = ref([]);
 
-const getOrders = async () => {
+const getOrders = async (clientFk) => {
     try {
         loading.value = true;
 
-        const clientFk = userStore?.user?.id;
-
         const filter = {
           where: {
             clientFk,
@@ -99,15 +96,7 @@ const loadOrder = orderId => {
     router.push({ name: 'catalog' });
 };
 
-watch(
-  () => userStore?.user?.id,
-  async userId => {
-    if (userId) {
-      getOrders();
-    }
-  },
-  { immediate: true }
-);
+onUserId(getOrders);
 
 </script>
 
diff --git a/src/utils/onUserId.js b/src/utils/onUserId.js
new file mode 100644
index 00000000..28c1fcae
--- /dev/null
+++ b/src/utils/onUserId.js
@@ -0,0 +1,19 @@
+import { watch } from 'vue';
+
+import { useUserStore } from 'stores/user';
+
+const userStore = useUserStore();
+
+export const onUserId = (cb) => watch(
+  () => userStore?.user?.id,
+  async userId => {
+    if (userId) {
+      try {
+        await cb(userId);
+      } catch (error) {
+        console.error(error);
+      }
+    }
+  },
+  { immediate: true }
+);

From 89de158514ef4b7d487c7900199aa3c1213798a1 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Sat, 22 Mar 2025 12:08:46 -0300
Subject: [PATCH 10/25] refactor: remove redundant `where` filter clause

---
 src/pages/Ecomerce/PendingOrders.vue | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/pages/Ecomerce/PendingOrders.vue b/src/pages/Ecomerce/PendingOrders.vue
index 619f47d4..6b2da717 100644
--- a/src/pages/Ecomerce/PendingOrders.vue
+++ b/src/pages/Ecomerce/PendingOrders.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, inject, watch } from 'vue';
+import { ref, inject } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 
@@ -32,7 +32,6 @@ const getOrders = async (clientFk) => {
         const filter = {
           where: {
             clientFk,
-            'address.clientFk': clientFk,
             isConfirmed: 0,
             source_app: 'WEB',
           },

From b691bf2cf45fd3318773d821999234a0e9bf7d10 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Mon, 24 Mar 2025 13:02:19 +0100
Subject: [PATCH 11/25] Connections view

---
 src/pages/Admin/ConnectionsView.vue | 98 ++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 21 deletions(-)

diff --git a/src/pages/Admin/ConnectionsView.vue b/src/pages/Admin/ConnectionsView.vue
index 175f32c7..c5171edd 100644
--- a/src/pages/Admin/ConnectionsView.vue
+++ b/src/pages/Admin/ConnectionsView.vue
@@ -12,12 +12,49 @@ import { useAppStore } from 'stores/app';
 import { storeToRefs } from 'pinia';
 
 const { t } = useI18n();
-const jApi = inject('jApi');
+const api = inject('api');
 const router = useRouter();
 const userStore = useUserStore();
 const appStore = useAppStore();
 const { isHeaderMounted } = storeToRefs(appStore);
 
+const filter = {
+    include: [
+        {
+            relation: 'visitUser',
+            scope: {
+                include: [
+                    {
+                        relation: 'visitAccess',
+                        scope: {
+                            fields: ['id', 'agentFk'],
+                            include: [
+                                {
+                                    relation: 'visitAgent',
+                                    scope: {
+                                        fields: [
+                                            'platform',
+                                            'browser',
+                                            'version'
+                                        ]
+                                    }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        relation: 'user',
+                        scope: {
+                            fields: ['id', 'nickname', 'name']
+                        }
+                    }
+                ],
+                fields: ['userFk', 'stamp', 'accessFk']
+            }
+        }
+    ],
+    order: 'lastUpdate DESC'
+};
 const connections = ref([]);
 const loading = ref(false);
 const intervalId = ref(null);
@@ -25,20 +62,36 @@ const intervalId = ref(null);
 const getConnections = async () => {
     try {
         loading.value = true;
-        connections.value = await jApi.query(
-            `SELECT vu.userFk userId, vu.stamp, u.nickname, s.lastUpdate,
-            a.platform, a.browser, a.version, u.name user
-            FROM userSession s
-            JOIN visitUser vu ON vu.id = s.userVisitFk
-            JOIN visitAccess ac ON ac.id = vu.accessFk
-            JOIN visitAgent a ON a.id = ac.agentFk
-            JOIN visit v ON v.id = a.visitFk
-            JOIN account.user u ON u.id = vu.userFk
-            ORDER BY lastUpdate DESC`
-        );
-        loading.value = false;
+
+        const { data } = await api.get('/userSessions', {
+            params: { filter: JSON.stringify(filter) }
+        });
+
+        if (!data) {
+            connections.value = [];
+            return;
+        }
+
+        const formattedConnections = data
+            .map(connection => {
+                const { visitUser = {}, ...rest } = connection;
+
+                const { visitAccess, user, stamp } = visitUser;
+                const { visitAgent } = visitAccess || {};
+
+                return {
+                    ...rest,
+                    user,
+                    stamp,
+                    visitAgent
+                };
+            })
+            .filter(connection => connection.user);
+        connections.value = formattedConnections;
     } catch (error) {
         console.error('Error getting connections:', error);
+    } finally {
+        loading.value = false;
     }
 };
 
@@ -89,11 +142,11 @@ onBeforeUnmount(() => clearInterval(intervalId.value));
             <CardList
                 v-for="(connection, index) in connections"
                 :key="index"
-                :to="{ name: 'accessLog', params: { id: connection.userId } }"
+                :to="{ name: 'accessLog', params: { id: connection.user?.id } }"
             >
                 <template #content>
                     <span class="text-bold q-mb-sm">
-                        {{ connection.nickname }}
+                        {{ connection.user?.nickname }}
                     </span>
                     <span>
                         {{
@@ -109,13 +162,14 @@ onBeforeUnmount(() => clearInterval(intervalId.value));
                     >
                     <span
                         v-if="
-                            connection.platform &&
-                            connection.browser &&
-                            connection.version
+                            connection.visitAgent?.platform &&
+                            connection.visitAgent?.browser &&
+                            connection.visitAgent?.version
                         "
                     >
-                        {{ connection.platform }} - {{ connection.browser }} -
-                        {{ connection.version }}
+                        {{ connection.visitAgent?.platform }} -
+                        {{ connection.visitAgent?.browser }} -
+                        {{ connection.visitAgent?.version }}
                     </span>
                 </template>
                 <template #actions>
@@ -123,7 +177,9 @@ onBeforeUnmount(() => clearInterval(intervalId.value));
                         icon="people"
                         flat
                         rounded
-                        @click.stop.prevent="supplantUser(connection.user)"
+                        @click.stop.prevent="
+                            supplantUser(connection.user?.name)
+                        "
                     >
                         <QTooltip>
                             {{ t('supplantUser') }}

From 859ffbd1fd465807944dc06a63673f37e1630307 Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Tue, 25 Mar 2025 04:08:43 -0300
Subject: [PATCH 12/25] fix(PendingOrders): migrate removeOrder, too

---
 src/pages/Ecomerce/PendingOrders.vue | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/pages/Ecomerce/PendingOrders.vue b/src/pages/Ecomerce/PendingOrders.vue
index 6b2da717..32ed1ccb 100644
--- a/src/pages/Ecomerce/PendingOrders.vue
+++ b/src/pages/Ecomerce/PendingOrders.vue
@@ -75,14 +75,7 @@ const getOrders = async (clientFk) => {
 
 const removeOrder = async (id, index) => {
     try {
-        await jApi.execQuery(
-            `START TRANSACTION;
-            DELETE FROM hedera.myOrder WHERE ((id = #id));
-            COMMIT`,
-            {
-                id
-            }
-        );
+        await api.delete(`Orders/${id}`);
         orders.value.splice(index, 1);
         notify(t('dataSaved'), 'positive');
     } catch (error) {

From 512b0b5e9ce35209dcc9cfdbd2234c0358c5173b Mon Sep 17 00:00:00 2001
From: taro <taro@taro.codes>
Date: Tue, 25 Mar 2025 05:50:08 -0300
Subject: [PATCH 13/25] refactor(PendingOrders): address PR comments

---
 src/pages/Ecomerce/PendingOrders.vue |  2 +-
 src/utils/onUserId.js                | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/pages/Ecomerce/PendingOrders.vue b/src/pages/Ecomerce/PendingOrders.vue
index 32ed1ccb..a8657174 100644
--- a/src/pages/Ecomerce/PendingOrders.vue
+++ b/src/pages/Ecomerce/PendingOrders.vue
@@ -32,7 +32,7 @@ const getOrders = async (clientFk) => {
         const filter = {
           where: {
             clientFk,
-            isConfirmed: 0,
+            isConfirmed: false,
             source_app: 'WEB',
           },
           include: [
diff --git a/src/utils/onUserId.js b/src/utils/onUserId.js
index 28c1fcae..2ea4189f 100644
--- a/src/utils/onUserId.js
+++ b/src/utils/onUserId.js
@@ -7,12 +7,11 @@ const userStore = useUserStore();
 export const onUserId = (cb) => watch(
   () => userStore?.user?.id,
   async userId => {
-    if (userId) {
-      try {
-        await cb(userId);
-      } catch (error) {
-        console.error(error);
-      }
+    if (!userId) return;
+    try {
+      await cb(userId);
+    } catch (error) {
+      console.error(error);
     }
   },
   { immediate: true }

From a7264fe1fc9e306a3b3a8dbcd5a97ba84a394b3b Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Tue, 25 Mar 2025 11:42:53 +0100
Subject: [PATCH 14/25] Migrate image collections

---
 src/pages/Admin/PhotosView.vue | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/pages/Admin/PhotosView.vue b/src/pages/Admin/PhotosView.vue
index b1e32f94..2802e1ce 100644
--- a/src/pages/Admin/PhotosView.vue
+++ b/src/pages/Admin/PhotosView.vue
@@ -7,7 +7,6 @@ import VnForm from 'src/components/common/VnForm.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import useNotify from 'src/composables/useNotify.js';
 
-const jApi = inject('jApi');
 const api = inject('api');
 const { t } = useI18n();
 const { notify } = useNotify();
@@ -45,9 +44,8 @@ const isSubmitable = computed(() =>
 
 const getImageCollections = async () => {
     try {
-        imageCollections.value = await jApi.query(
-            'SELECT name, `desc` FROM imageCollection ORDER BY `desc`'
-        );
+        const { data } = await api.get('imageCollections');
+        imageCollections.value = data;
     } catch (error) {
         console.error('Error getting image collections:', error);
     }

From f7030d1213e736a161f375250f7da5ec11ee3b36 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Tue, 25 Mar 2025 15:11:42 +0100
Subject: [PATCH 15/25] WIP

---
 src/pages/Admin/PhotosView.vue | 46 +++++++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/pages/Admin/PhotosView.vue b/src/pages/Admin/PhotosView.vue
index 2802e1ce..d80c61ee 100644
--- a/src/pages/Admin/PhotosView.vue
+++ b/src/pages/Admin/PhotosView.vue
@@ -32,7 +32,7 @@ const statusIcons = {
     }
 };
 const formInitialData = reactive({
-    schema: 'catalog',
+    collectionFk: 'catalog',
     updateMatching: true
 });
 const imageCollections = ref([]);
@@ -51,6 +51,10 @@ const getImageCollections = async () => {
     }
 };
 
+const buildUploadUrl = (id, collection) => {
+    return `images/upload?id=${encodeURIComponent(id)}&collection=${encodeURIComponent(collection)}`;
+};
+
 const onSubmit = async data => {
     if (!addedFiles.value.length) {
         notify(t('noFilesToUpload'), 'warning');
@@ -59,20 +63,37 @@ const onSubmit = async data => {
     const filteredFiles = addedFiles.value.filter(
         file => file.uploadStatus === 'pending'
     );
-    const promises = filteredFiles.map((file, index) => {
+    const promises = filteredFiles.map(async (file, index) => {
         const fileIndex = filteredFiles[index].index;
         addedFiles.value[fileIndex].uploadStatus = 'uploading';
 
+        // const formData = new FormData();
+        // formData.append('file', file.file);
+
+        // const entityId = imageCollections.value.find(
+        //     collection => collection.name === data.collectionFk
+        // ).model;
+
+        // const url = buildUploadUrl(entityId, data.collectionFk);
+        // console.log('url', url);
+        // return api({
+        //     method: 'post',
+        //     url: url,
+        //     data: formData,
+        //     headers: {
+        //         'Content-Type': 'multipart/form-data'
+        //     }
+        // });
+
         const formData = new FormData();
-        formData.append('updateMatching', data.updateMatching);
-        formData.append('image', file.file);
-        formData.append('name', file.name);
-        formData.append('schema', data.schema);
-        formData.append('srv', 'json:image/upload');
-        return api({
-            method: 'post',
-            url: location.origin,
-            data: formData,
+        const now = Date.vnNew();
+        const timestamp = now.getTime();
+        console.log('file', file);
+        const fileName = `${file.file?.name}_${timestamp}`;
+        formData.append('blob', file.file, fileName);
+
+        await axios.post('Images/upload', formData, {
+            params: newPhoto,
             headers: {
                 'Content-Type': 'multipart/form-data'
             }
@@ -102,6 +123,7 @@ const onSubmit = async data => {
 };
 
 const onFilesAdded = files => {
+    console.log('files', files);
     const initialFilesLength = addedFiles.value.length;
     files.forEach((file, index) => {
         const [name] = file.name.split('.');
@@ -146,7 +168,7 @@ onMounted(async () => getImageCollections());
         >
             <template #form="{ data }">
                 <VnSelect
-                    v-model="data.schema"
+                    v-model="data.collectionFk"
                     :label="t('collection')"
                     option-label="desc"
                     option-value="name"

From d9445f72e3353d6b7d072c9a8add59a9447311b1 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Wed, 26 Mar 2025 09:31:47 +0100
Subject: [PATCH 16/25] Acortar codigo

---
 src/pages/Admin/ConnectionsView.vue | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/src/pages/Admin/ConnectionsView.vue b/src/pages/Admin/ConnectionsView.vue
index c5171edd..1dcf4cee 100644
--- a/src/pages/Admin/ConnectionsView.vue
+++ b/src/pages/Admin/ConnectionsView.vue
@@ -72,22 +72,14 @@ const getConnections = async () => {
             return;
         }
 
-        const formattedConnections = data
-            .map(connection => {
-                const { visitUser = {}, ...rest } = connection;
-
-                const { visitAccess, user, stamp } = visitUser;
-                const { visitAgent } = visitAccess || {};
-
-                return {
-                    ...rest,
-                    user,
-                    stamp,
-                    visitAgent
-                };
-            })
-            .filter(connection => connection.user);
-        connections.value = formattedConnections;
+        connections.value = data
+            .map(({ visitUser = {}, ...rest }) => ({
+                ...rest,
+                user: visitUser.user,
+                stamp: visitUser.stamp,
+                visitAgent: visitUser.visitAccess?.visitAgent
+            }))
+            .filter(({ user }) => user);
     } catch (error) {
         console.error('Error getting connections:', error);
     } finally {

From 365d4d31e105d5ccb748c046ce01b3db53eddc45 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Wed, 26 Mar 2025 09:37:24 +0100
Subject: [PATCH 17/25] Code improvement

---
 src/pages/Admin/ConnectionsView.vue | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/pages/Admin/ConnectionsView.vue b/src/pages/Admin/ConnectionsView.vue
index 1dcf4cee..6b8f63d6 100644
--- a/src/pages/Admin/ConnectionsView.vue
+++ b/src/pages/Admin/ConnectionsView.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onMounted, inject, onBeforeUnmount } from 'vue';
+import { ref, onMounted, inject, onBeforeUnmount, h } from 'vue';
 import { useRouter } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -103,6 +103,13 @@ onMounted(async () => {
 });
 
 onBeforeUnmount(() => clearInterval(intervalId.value));
+
+const renderAgentDetails = connection => {
+    const agent = connection.visitAgent;
+    return agent?.platform && agent?.browser && agent?.version
+        ? h('span', `${agent.platform} - ${agent.browser} - ${agent.version}`)
+        : null;
+};
 </script>
 
 <template>
@@ -152,17 +159,7 @@ onBeforeUnmount(() => clearInterval(intervalId.value));
                             )
                         }}</span
                     >
-                    <span
-                        v-if="
-                            connection.visitAgent?.platform &&
-                            connection.visitAgent?.browser &&
-                            connection.visitAgent?.version
-                        "
-                    >
-                        {{ connection.visitAgent?.platform }} -
-                        {{ connection.visitAgent?.browser }} -
-                        {{ connection.visitAgent?.version }}
-                    </span>
+                    <component :is="renderAgentDetails(connection)" />
                 </template>
                 <template #actions>
                     <QBtn

From a6b6599977b33a86ae0322fdc8e7cb6e9088d3c8 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Thu, 27 Mar 2025 09:37:04 +0100
Subject: [PATCH 18/25] Photos view migration

---
 src/pages/Admin/PhotosView.vue | 48 +++++++++-------------------------
 1 file changed, 13 insertions(+), 35 deletions(-)

diff --git a/src/pages/Admin/PhotosView.vue b/src/pages/Admin/PhotosView.vue
index d80c61ee..a66e3fc8 100644
--- a/src/pages/Admin/PhotosView.vue
+++ b/src/pages/Admin/PhotosView.vue
@@ -3,9 +3,9 @@ import { useI18n } from 'vue-i18n';
 import { ref, onMounted, inject, reactive, computed } from 'vue';
 
 import VnSelect from 'src/components/common/VnSelect.vue';
-import VnForm from 'src/components/common/VnForm.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import useNotify from 'src/composables/useNotify.js';
+import FormModel from 'src/components/common/FormModel.vue';
 
 const api = inject('api');
 const { t } = useI18n();
@@ -51,10 +51,6 @@ const getImageCollections = async () => {
     }
 };
 
-const buildUploadUrl = (id, collection) => {
-    return `images/upload?id=${encodeURIComponent(id)}&collection=${encodeURIComponent(collection)}`;
-};
-
 const onSubmit = async data => {
     if (!addedFiles.value.length) {
         notify(t('noFilesToUpload'), 'warning');
@@ -66,52 +62,33 @@ const onSubmit = async data => {
     const promises = filteredFiles.map(async (file, index) => {
         const fileIndex = filteredFiles[index].index;
         addedFiles.value[fileIndex].uploadStatus = 'uploading';
-
-        // const formData = new FormData();
-        // formData.append('file', file.file);
-
-        // const entityId = imageCollections.value.find(
-        //     collection => collection.name === data.collectionFk
-        // ).model;
-
-        // const url = buildUploadUrl(entityId, data.collectionFk);
-        // console.log('url', url);
-        // return api({
-        //     method: 'post',
-        //     url: url,
-        //     data: formData,
-        //     headers: {
-        //         'Content-Type': 'multipart/form-data'
-        //     }
-        // });
-
         const formData = new FormData();
-        const now = Date.vnNew();
+        const now = new Date();
         const timestamp = now.getTime();
-        console.log('file', file);
-        const fileName = `${file.file?.name}_${timestamp}`;
-        formData.append('blob', file.file, fileName);
+        const fileName = `${file.name}_${timestamp}`;
+        formData.append('image', file.file, fileName);
 
-        await axios.post('Images/upload', formData, {
-            params: newPhoto,
+        await api.post('photos/upload', formData, {
+            params: {
+                name: fileName,
+                collection: data.collectionFk,
+                updateMatching: data.updateMatching
+            },
             headers: {
                 'Content-Type': 'multipart/form-data'
             }
         });
     });
-
     const results = await Promise.allSettled(promises);
     results.forEach((result, index) => {
         const fileIndex = filteredFiles[index].index;
         addedFiles.value[fileIndex].uploadStatus = result.status;
-
         if (result.status === 'rejected') {
             addedFiles.value[fileIndex].errorMessage = t(
                 result.reason?.response?.data?.data?.message
             );
         }
     });
-
     const allSuccessful = results.every(
         result => result.status === 'fulfilled'
     );
@@ -159,12 +136,13 @@ onMounted(async () => getImageCollections());
 
 <template>
     <QPage class="vn-w-sm">
-        <VnForm
+        <FormModel
             ref="vnFormRef"
             :default-actions="false"
             :form-initial-data="formInitialData"
             separation-between-inputs="md"
             show-bottom-actions
+            :save-fn="onSubmit"
         >
             <template #form="{ data }">
                 <VnSelect
@@ -289,7 +267,7 @@ onMounted(async () => getImageCollections());
                     data-cy="photoUploadSubmitBtn"
                 />
             </template>
-        </VnForm>
+        </FormModel>
     </QPage>
 </template>
 

From 59efebd022fc39d707f1ecfe36649ae46d36c559 Mon Sep 17 00:00:00 2001
From: Guido <guidoolguin@hotmail.com>
Date: Thu, 27 Mar 2025 10:56:23 -0300
Subject: [PATCH 19/25] feat: migrate query agency volume procedure

---
 src/pages/Agencies/PackagesView.vue | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/pages/Agencies/PackagesView.vue b/src/pages/Agencies/PackagesView.vue
index 922db3e6..fd2d1ab4 100644
--- a/src/pages/Agencies/PackagesView.vue
+++ b/src/pages/Agencies/PackagesView.vue
@@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
 
 import VnTable from 'src/components/ui/VnTable.vue';
 
-const jApi = inject('jApi');
+const api = inject('api');
 const { t } = useI18n();
 
 const packages = ref([]);
@@ -43,7 +43,12 @@ const columns = computed(() => [
 
 const getPackages = async () => {
     try {
-        const data = await jApi.query('CALL vn.agencyVolume()');
+        const { data } = await api.post(
+            'applications/agencyVolume/execute-proc',
+            {
+                schema: 'vn'
+            }
+        );
         packages.value = data;
     } catch (error) {
         console.error(error);

From bf22196e44984610b7f09c90383aca85ac8a68db Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Fri, 28 Mar 2025 15:09:31 +0100
Subject: [PATCH 20/25] Remove dash

---
 src/pages/Admin/LinksView.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Admin/LinksView.vue b/src/pages/Admin/LinksView.vue
index 1b1e480d..4368b66c 100644
--- a/src/pages/Admin/LinksView.vue
+++ b/src/pages/Admin/LinksView.vue
@@ -8,7 +8,7 @@ const links = ref([]);
 const getLinks = async () => {
     try {
         const filter = { order: 'name ASC' };
-        const { data } = await api.get('/Links', { params: { filter } });
+        const { data } = await api.get('Links', { params: { filter } });
         links.value = data;
     } catch (error) {
         console.error('Error getting links:', error);

From 1e0ae8f976eb7993446c9b60d920c0de8e6bbe10 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Mon, 31 Mar 2025 11:20:10 +0200
Subject: [PATCH 21/25] Migrate visits view

---
 src/pages/Admin/VisitsView.vue | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/src/pages/Admin/VisitsView.vue b/src/pages/Admin/VisitsView.vue
index c2bf260d..f8157ee6 100644
--- a/src/pages/Admin/VisitsView.vue
+++ b/src/pages/Admin/VisitsView.vue
@@ -10,7 +10,7 @@ import { useAppStore } from 'stores/app';
 import { storeToRefs } from 'pinia';
 
 const { t } = useI18n();
-const jApi = inject('jApi');
+const api = inject('api');
 const route = useRoute();
 const router = useRouter();
 const appStore = useAppStore();
@@ -24,28 +24,21 @@ const visitsData = ref(null);
 const getVisits = async () => {
     try {
         loading.value = true;
-        const [visitsResponse] = await jApi.query(
-            `SELECT browser,
-            MIN(CAST(version AS DECIMAL(4,1))) minVersion,
-            MAX(CAST(version AS DECIMAL(4,1))) maxVersion,
-            MAX(c.stamp) lastVisit,
-            COUNT(DISTINCT c.id) visits,
-            SUM(a.firstAccessFk = c.id AND v.firstAgentFk = a.id) newVisits
-            FROM visitUser e
-            JOIN visitAccess c ON c.id = e.accessFk
-            JOIN visitAgent a ON a.id = c.agentFk
-            JOIN visit v ON v.id = a.visitFk
-            WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
-            GROUP BY browser ORDER BY visits DESC`,
-            {
+
+        const { data } = await api.get('visitUsers/getVisits', {
+            params: {
                 from: date(from.value),
                 to: date(to.value)
             }
-        );
-        visitsData.value = visitsResponse;
-        loading.value = false;
+        });
+
+        if (!data || !data.length) return;
+
+        visitsData.value = data[0];
     } catch (error) {
         console.error('Error getting visits:', error);
+    } finally {
+        loading.value = false;
     }
 };
 

From 5881f12306c28526ae5eb820617041df07110be8 Mon Sep 17 00:00:00 2001
From: Guido <guidoolguin@hotmail.com>
Date: Mon, 31 Mar 2025 16:03:57 -0300
Subject: [PATCH 22/25] feat(invoices):  migrar de jApi a endpoint REST API

- Reemplazar consulta SQL directa por llamada a endpoint
---
 src/pages/Ecomerce/InvoicesView.vue | 35 ++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/src/pages/Ecomerce/InvoicesView.vue b/src/pages/Ecomerce/InvoicesView.vue
index 76599998..70f84a09 100644
--- a/src/pages/Ecomerce/InvoicesView.vue
+++ b/src/pages/Ecomerce/InvoicesView.vue
@@ -8,9 +8,10 @@ import { currency, formatDate } from 'src/lib/filters.js';
 import { usePrintService } from 'src/composables/usePrintService';
 import { useAppStore } from 'stores/app';
 import { storeToRefs } from 'pinia';
+import { onUserId } from 'src/utils/onUserId';
 
 const { t } = useI18n();
-const jApi = inject('jApi');
+const api = inject('api');
 const { openReport } = usePrintService();
 const appStore = useAppStore();
 const { isHeaderMounted } = storeToRefs(appStore);
@@ -50,27 +51,39 @@ const columns = computed(() => [
     }
 ]);
 
-const fetchInvoices = async () => {
+const fetchInvoices = async clientFk => {
     const params = {
         from: new Date(currentYear.value, 0),
         to: new Date(currentYear.value, 11, 31, 23, 59, 59)
     };
-    invoices.value = await jApi.query(
-        `SELECT id, ref, issued, amount, hasPdf
-          FROM myInvoice
-          WHERE issued BETWEEN #from AND #to
-          ORDER BY issued DESC
-          LIMIT 100`,
-        params
-    );
+    const filter = {
+        where: {
+            clientFk,
+            issued: {
+                between: [params.from, params.to]
+            }
+        },
+        order: ['issued DESC'],
+        fields: ['id', 'ref', 'issued', 'amount', 'hasPdf'],
+        limit: 100
+    };
+
+    const { data } = await api.get('InvoiceOuts', {
+        params: {
+            filter: JSON.stringify(filter)
+        }
+    });
+
+    invoices.value = data;
 };
 
 onMounted(async () => {
-    await fetchInvoices();
     for (let year = currentYear.value - 5; year <= currentYear.value; year++) {
         years.value.push(year);
     }
 });
+
+onUserId(fetchInvoices);
 </script>
 
 <template>

From 3f356f4143e854a98776df837359c0eeacb1c610 Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Tue, 1 Apr 2025 09:49:31 +0200
Subject: [PATCH 23/25] Remove console.log

---
 src/pages/Admin/PhotosView.vue | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/pages/Admin/PhotosView.vue b/src/pages/Admin/PhotosView.vue
index a66e3fc8..5d437551 100644
--- a/src/pages/Admin/PhotosView.vue
+++ b/src/pages/Admin/PhotosView.vue
@@ -100,7 +100,6 @@ const onSubmit = async data => {
 };
 
 const onFilesAdded = files => {
-    console.log('files', files);
     const initialFilesLength = addedFiles.value.length;
     files.forEach((file, index) => {
         const [name] = file.name.split('.');

From 17ce649a11e068d65cf6c66de3f26fcfa0a5594e Mon Sep 17 00:00:00 2001
From: wbuezas <wbuezas@verdnatura.es>
Date: Tue, 1 Apr 2025 11:31:56 +0200
Subject: [PATCH 24/25] Change route

---
 src/pages/Admin/PhotosView.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Admin/PhotosView.vue b/src/pages/Admin/PhotosView.vue
index 5d437551..257adef7 100644
--- a/src/pages/Admin/PhotosView.vue
+++ b/src/pages/Admin/PhotosView.vue
@@ -68,7 +68,7 @@ const onSubmit = async data => {
         const fileName = `${file.name}_${timestamp}`;
         formData.append('image', file.file, fileName);
 
-        await api.post('photos/upload', formData, {
+        await api.post('images/uploadPhotoAdmin', formData, {
             params: {
                 name: fileName,
                 collection: data.collectionFk,

From 4ef5e8f97b228d935a0e3ac1db5314ae41ba65e9 Mon Sep 17 00:00:00 2001
From: Guido <guidoolguin@hotmail.com>
Date: Tue, 1 Apr 2025 11:39:31 -0300
Subject: [PATCH 25/25] =?UTF-8?q?fix(invoices):=20Refactorizaci=C3=B3n=20d?=
 =?UTF-8?q?el=20manejo=20de=20fechas=20en=20la=20funci=C3=B3n=20fetchInvoi?=
 =?UTF-8?q?ces?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Se actualizó la función fetchInvoices para desestructurar los parámetros de fecha de un objeto y mejorar la legibilidad.
---
 src/pages/Ecomerce/InvoicesView.vue | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/pages/Ecomerce/InvoicesView.vue b/src/pages/Ecomerce/InvoicesView.vue
index 70f84a09..b89e28fa 100644
--- a/src/pages/Ecomerce/InvoicesView.vue
+++ b/src/pages/Ecomerce/InvoicesView.vue
@@ -52,7 +52,7 @@ const columns = computed(() => [
 ]);
 
 const fetchInvoices = async clientFk => {
-    const params = {
+    const { from, to } = {
         from: new Date(currentYear.value, 0),
         to: new Date(currentYear.value, 11, 31, 23, 59, 59)
     };
@@ -60,7 +60,7 @@ const fetchInvoices = async clientFk => {
         where: {
             clientFk,
             issued: {
-                between: [params.from, params.to]
+                between: [from, to]
             }
         },
         order: ['issued DESC'],
@@ -73,7 +73,6 @@ const fetchInvoices = async clientFk => {
             filter: JSON.stringify(filter)
         }
     });
-
     invoices.value = data;
 };