Merge pull request 'Arreglando vistas de importación de clientes, productos y envio de ventas a tryton #24' (#33) from fix_tryton_products_custom_views_#24 into main

Reviewed-on: #33
This commit is contained in:
2026-03-14 23:25:32 -05:00
3 changed files with 337 additions and 105 deletions

View File

@@ -1,6 +1,8 @@
<template> <template>
<v-container v-if="authStore.isAdmin" class="fill-height d-flex align-center justify-center"> <v-container v-if="authStore.isAdmin" class="fill-height">
<v-card class="pa-6" max-width="600" elevation="4"> <v-row v-if="!result && !loading" justify="center">
<v-col cols="12" md="8">
<v-card class="pa-6" elevation="4">
<v-card-title class="text-h5 font-weight-bold text-center"> <v-card-title class="text-h5 font-weight-bold text-center">
🔄 Sincronización de Clientes 🔄 Sincronización de Clientes
</v-card-title> </v-card-title>
@@ -10,14 +12,14 @@
Esta acción sincronizará los <strong>clientes</strong> desde el sistema Esta acción sincronizará los <strong>clientes</strong> desde el sistema
<strong>Tryton</strong> hacia la plataforma. <strong>Tryton</strong> hacia la plataforma.
</p> </p>
<v-alert type="warning" dense border="start" border-color="warning"> <v-alert type="warning" dense border="start" border-color="warning" class="mt-4">
<strong>Advertencia:</strong> Este proceso podría tardar varios minutos <strong>Advertencia:</strong> Este proceso podría tardar varios minutos
y reemplazar datos existentes en la plataforma. y reemplazar datos existentes en la plataforma.
Asegúrese de que la información en Tryton esté actualizada antes de Asegúrese de que la información en Tryton esté actualizada antes de
continuar. continuar.
</v-alert> </v-alert>
<p class="mt-4"> <p class="mt-4">
Durante la sincronización, no se podrán modificar productos en la Durante la sincronización, no se podrán modificar clientes en la
plataforma para evitar conflictos. plataforma para evitar conflictos.
</p> </p>
</v-card-text> </v-card-text>
@@ -31,12 +33,94 @@
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-col>
</v-row>
<v-row v-else-if="loading" justify="center" align="center">
<v-col cols="12" class="text-center">
<v-progress-circular indeterminate color="primary" size="64"></v-progress-circular>
<p class="mt-4 text-h6">Sincronizando clientes...</p>
</v-col>
</v-row>
<v-data-table :items="checked_tryton_parties"></v-data-table> <v-row v-else>
<v-data-table :items="created_customers"></v-data-table> <v-col cols="12">
<v-data-table :items="failed_parties"></v-data-table> <v-alert type="success" variant="tonal" class="mb-4">
<v-data-table :items="untouched_customers"></v-data-table> <strong>Sincronización completada</strong>
</v-alert>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-error text-white"> Fallidos ({{ result.failed_parties?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.failed_parties)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-success text-white"> Creados ({{ result.created_customers?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.created_customers)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-warning">🔄 Actualizados ({{ result.updated_customers?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.updated_customers)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-grey-lighten-1"> Sin cambios ({{ result.untouched_customers?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.untouched_customers)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-info text-white">🔍 Verificados ({{ result.checked_tryton_parties?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.checked_tryton_parties)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" class="text-center mt-4">
<v-btn color="primary" @click="$router.push('/')">
Volver al inicio
</v-btn>
</v-col>
</v-row>
</v-container> </v-container>
</template> </template>
@@ -53,11 +137,8 @@
data() { data() {
return { return {
api: inject('api'), api: inject('api'),
checked_tryton_parties: [], loading: false,
created_customers: [], result: null,
failed_parties: [],
untouched_customers: [],
updated_customers: [],
} }
}, },
mounted() { mounted() {
@@ -66,16 +147,20 @@
} }
}, },
methods: { methods: {
formatItems(ids) {
if (!ids || ids.length === 0) return [];
return ids.map(id => ({ id }));
},
startSync() { startSync() {
this.loading = true;
this.api.getCustomersFromTryton() this.api.getCustomersFromTryton()
.then(response => { .then(response => {
this.checked_tryton_parties = response.checked_tryton_parties.map(id => ({ id })); this.result = response;
this.created_customers = response.created_customers.map(id => ({ id })); this.loading = false;
this.failed_parties = response.failed_parties.map(id => ({ id }));
this.untouched_customers = response.untouched_customers.map(id => ({ id }));
}) })
.catch(error => { .catch(error => {
console.error("Error al sincronizar clientes:", error); console.error('Error al sincronizar clientes:', error);
this.loading = false;
}); });
} }
} }

View File

@@ -1,6 +1,8 @@
<template> <template>
<v-container v-if="authStore.isAdmin" class="fill-height d-flex align-center justify-center"> <v-container v-if="authStore.isAdmin" class="fill-height">
<v-card class="pa-6" max-width="600" elevation="4"> <v-row v-if="!result && !loading" justify="center">
<v-col cols="12" md="8">
<v-card class="pa-6" elevation="4">
<v-card-title class="text-h5 font-weight-bold text-center"> <v-card-title class="text-h5 font-weight-bold text-center">
🔄 Sincronización de Productos 🔄 Sincronización de Productos
</v-card-title> </v-card-title>
@@ -10,7 +12,7 @@
Esta acción sincronizará los <strong>productos</strong> desde el sistema Esta acción sincronizará los <strong>productos</strong> desde el sistema
<strong>Tryton</strong> hacia la plataforma. <strong>Tryton</strong> hacia la plataforma.
</p> </p>
<v-alert type="warning" dense border="start" border-color="warning"> <v-alert type="warning" dense border="start" border-color="warning" class="mt-4">
<strong>Advertencia:</strong> Este proceso podría tardar varios minutos <strong>Advertencia:</strong> Este proceso podría tardar varios minutos
y reemplazar datos existentes en la plataforma. y reemplazar datos existentes en la plataforma.
Asegúrese de que la información en Tryton esté actualizada antes de Asegúrese de que la información en Tryton esté actualizada antes de
@@ -31,7 +33,81 @@
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-data-table :items="productos_tryton"></v-data-table> </v-col>
</v-row>
<v-row v-else-if="loading" justify="center" align="center">
<v-col cols="12" class="text-center">
<v-progress-circular indeterminate color="primary" size="64"></v-progress-circular>
<p class="mt-4 text-h6">Sincronizando productos...</p>
</v-col>
</v-row>
<v-row v-else>
<v-col cols="12">
<v-alert type="success" variant="tonal" class="mb-4">
<strong>Sincronización completada</strong>
</v-alert>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-error text-white"> Fallidos ({{ result.failed_products?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.failed_products)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-success text-white"> Creados ({{ result.created_products?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.created_products)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-info text-white">🔄 Actualizados ({{ result.updated_products?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.updated_products)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-grey-lighten-1"> Sin cambios ({{ result.untouched_products?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.untouched_products)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" class="text-center mt-4">
<v-btn color="primary" @click="$router.push('/')">
Volver al inicio
</v-btn>
</v-col>
</v-row>
</v-container> </v-container>
</template> </template>
@@ -48,7 +124,8 @@
data() { data() {
return { return {
api: inject('api'), api: inject('api'),
productos_tryton: [{}], loading: false,
result: null,
} }
}, },
mounted() { mounted() {
@@ -57,8 +134,21 @@
} }
}, },
methods: { methods: {
formatItems(ids) {
if (!ids || ids.length === 0) return [];
return ids.map(id => ({ id }));
},
startSync() { startSync() {
this.productos_tryton = this.api.getProductsFromTryton() this.loading = true;
this.api.getProductsFromTryton()
.then(response => {
this.result = response;
this.loading = false;
})
.catch(error => {
console.error('Error al sincronizar productos:', error);
this.loading = false;
});
} }
} }
} }

View File

@@ -1,6 +1,8 @@
<template> <template>
<v-container v-if="authStore.isAdmin" class="fill-height d-flex align-center justify-center"> <v-container v-if="authStore.isAdmin" class="fill-height">
<v-card class="pa-6" max-width="600" elevation="4"> <v-row v-if="!result && !loading" justify="center">
<v-col cols="12" md="8">
<v-card class="pa-6" elevation="4">
<v-card-title class="text-h5 font-weight-bold text-center"> <v-card-title class="text-h5 font-weight-bold text-center">
🔄 Sincronización de Ventas 🔄 Sincronización de Ventas
</v-card-title> </v-card-title>
@@ -10,7 +12,7 @@
Esta acción sincronizará las <strong>ventas</strong> desde el sistema Esta acción sincronizará las <strong>ventas</strong> desde el sistema
<strong>Tryton</strong> hacia la plataforma. <strong>Tryton</strong> hacia la plataforma.
</p> </p>
<v-alert type="warning" dense border="start" border-color="warning"> <v-alert type="warning" dense border="start" border-color="warning" class="mt-4">
<strong>Advertencia:</strong> Este proceso podría tardar varios minutos <strong>Advertencia:</strong> Este proceso podría tardar varios minutos
y reemplazar datos existentes en la plataforma. y reemplazar datos existentes en la plataforma.
Asegúrese de que la información en Tryton esté actualizada antes de Asegúrese de que la información en Tryton esté actualizada antes de
@@ -27,10 +29,58 @@
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-data-table :items="ventas_tryton_failed"></v-data-table> </v-col>
<v-data-table :items="ventas_tryton_successful"></v-data-table> </v-row>
<v-row v-else-if="loading" justify="center" align="center">
<v-col cols="12" class="text-center">
<v-progress-circular indeterminate color="primary" size="64"></v-progress-circular>
<p class="mt-4 text-h6">Sincronizando ventas...</p>
</v-col>
</v-row>
<v-row v-else>
<v-col cols="12">
<v-alert type="success" variant="tonal" class="mb-4">
<strong>Sincronización completada</strong>
</v-alert>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-error text-white"> Fallidos ({{ result.failed?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.failed)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="2">
<v-card-title class="bg-success text-white"> Exitosos ({{ result.successful?.length || 0 }})</v-card-title>
<v-card-text>
<v-data-table
:items="formatItems(result.successful)"
density="compact"
:headers="[{ title: 'ID', key: 'id' }]"
></v-data-table>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" class="text-center mt-4">
<v-btn color="primary" @click="$router.push('/')">
Volver al inicio
</v-btn>
</v-col>
</v-row>
</v-container> </v-container>
</template> </template>
<script> <script>
import { useAuthStore } from '@/stores/auth'; import { useAuthStore } from '@/stores/auth';
import { inject } from 'vue'; import { inject } from 'vue';
@@ -44,7 +94,8 @@
data() { data() {
return { return {
api: inject('api'), api: inject('api'),
ventas_tryton: [], loading: false,
result: null,
} }
}, },
mounted() { mounted() {
@@ -53,14 +104,20 @@
} }
}, },
methods: { methods: {
formatItems(ids) {
if (!ids || ids.length === 0) return [];
return ids.map(id => ({ id }));
},
startSync() { startSync() {
this.loading = true;
this.api.sendSalesToTryton() this.api.sendSalesToTryton()
.then(response => { .then(response => {
this.ventas_tryton_failed = response.failed.map(id => ({ id })); this.result = response;
this.ventas_tryton_successful = response.successful.map(id => ({ id })); this.loading = false;
}) })
.catch(error => { .catch(error => {
console.error("Error al sincronizar las ventas", error); console.error('Error al sincronizar ventas:', error);
this.loading = false;
}); });
} }
} }