feat: agregar sincronización de ventas de catálogo a Tryton
- Agregar método sendCatalogSalesToTryton() en django-api.js y api.js - Crear página sincronizar_catalog_sales_tryton.vue para exportar catalog_sales - Agregar botón 'Sincronizar a Tryton' en CatalogSalesManagement header - Reorganizar menú admin en NavBar con sección 'Sincronización Tryton' - Separar opciones de importación (download) y exportación (upload) a Tryton - Endpoint: /don_confiao/api/enviar_catalog_sales_a_tryton - Mostrar resultados exitosos/fallidos similar a sincronización de ventas normales
This commit is contained in:
@@ -6,6 +6,14 @@
|
|||||||
<h1 class="text-h4">Ventas por Catálogo</h1>
|
<h1 class="text-h4">Ventas por Catálogo</h1>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" md="6" class="text-md-right">
|
<v-col cols="12" md="6" class="text-md-right">
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
prepend-icon="mdi-sync"
|
||||||
|
@click="$router.push('/sincronizar_catalog_sales_tryton')"
|
||||||
|
class="mr-2"
|
||||||
|
>
|
||||||
|
Sincronizar a Tryton
|
||||||
|
</v-btn>
|
||||||
<v-chip color="primary" variant="flat">
|
<v-chip color="primary" variant="flat">
|
||||||
{{ catalogSales.length }} venta(s)
|
{{ catalogSales.length }} venta(s)
|
||||||
</v-chip>
|
</v-chip>
|
||||||
|
|||||||
@@ -63,13 +63,16 @@
|
|||||||
<v-list-item prepend-icon="mdi-cog" title="Administracion" @click="toggleAdminMenu()" v-if="isAuthenticated && isAdmin"></v-list-item>
|
<v-list-item prepend-icon="mdi-cog" title="Administracion" @click="toggleAdminMenu()" v-if="isAuthenticated && isAdmin"></v-list-item>
|
||||||
<v-list-item v-if="isAuthenticated && isAdmin && showAdminMenu">
|
<v-list-item v-if="isAuthenticated && isAdmin && showAdminMenu">
|
||||||
<v-list>
|
<v-list>
|
||||||
|
<template v-for="(item, index) in menuAdminItems" :key="index">
|
||||||
|
<v-divider v-if="item.divider"></v-divider>
|
||||||
|
<v-list-subheader v-else-if="item.header">{{ item.header }}</v-list-subheader>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-for="item in menuAdminItems"
|
v-else
|
||||||
:key="item.title"
|
|
||||||
:title="item.title"
|
:title="item.title"
|
||||||
:prepend-icon="item.icon"
|
:prepend-icon="item.icon"
|
||||||
@click="navigateAdmin(item.route)"
|
@click="navigateAdmin(item.route)"
|
||||||
></v-list-item>
|
></v-list-item>
|
||||||
|
</template>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
@@ -105,9 +108,12 @@
|
|||||||
{ title: 'Compra adm', route: '/compra_admin', icon: 'mdi-cart'},
|
{ title: 'Compra adm', route: '/compra_admin', icon: 'mdi-cart'},
|
||||||
{ title: 'Gestión de Productos', route: '/admin/products', icon: 'mdi-package-variant'},
|
{ title: 'Gestión de Productos', route: '/admin/products', icon: 'mdi-package-variant'},
|
||||||
{ title: 'Ver Ventas por Catálogo', route: '/admin/catalog-sales', icon: 'mdi-cart-arrow-down'},
|
{ title: 'Ver Ventas por Catálogo', route: '/admin/catalog-sales', icon: 'mdi-cart-arrow-down'},
|
||||||
{ title: 'Actualizar Productos De Tryton', route: '/sincronizar_productos_tryton', icon: 'mdi-sync'},
|
{ divider: true },
|
||||||
{ title: 'Actualizar Clientes De Tryton', route: '/sincronizar_clientes_tryton', icon: 'mdi-sync'},
|
{ header: 'Sincronización Tryton' },
|
||||||
{ title: 'Actualizar Ventas Tryton', route: '/sincronizar_ventas_tryton', icon: 'mdi-sync'}
|
{ title: 'Importar Productos', route: '/sincronizar_productos_tryton', icon: 'mdi-download'},
|
||||||
|
{ title: 'Importar Clientes', route: '/sincronizar_clientes_tryton', icon: 'mdi-download'},
|
||||||
|
{ title: 'Exportar Ventas', route: '/sincronizar_ventas_tryton', icon: 'mdi-upload'},
|
||||||
|
{ title: 'Exportar Ventas Catálogo', route: '/sincronizar_catalog_sales_tryton', icon: 'mdi-upload'}
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
120
src/pages/sincronizar_catalog_sales_tryton.vue
Normal file
120
src/pages/sincronizar_catalog_sales_tryton.vue
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<v-container v-if="authStore.isAdmin" class="fill-height">
|
||||||
|
<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">
|
||||||
|
🔄 Sincronización de Ventas de Catálogo
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<p>
|
||||||
|
Esta acción sincronizará las <strong>ventas de catálogo</strong> desde el sistema
|
||||||
|
<strong>Tryton</strong> hacia la plataforma.
|
||||||
|
</p>
|
||||||
|
<v-alert type="warning" dense border="start" border-color="warning" class="mt-4">
|
||||||
|
<strong>Advertencia:</strong> Este proceso podría tardar varios minutos
|
||||||
|
y reemplazar datos existentes en la plataforma.
|
||||||
|
Asegúrese de que la información en Tryton esté actualizada antes de
|
||||||
|
continuar.
|
||||||
|
</v-alert>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions class="justify-center">
|
||||||
|
<v-btn color="primary" @click="startSync">
|
||||||
|
Iniciar Sincronización
|
||||||
|
</v-btn>
|
||||||
|
<v-btn text @click="$router.push('/')">
|
||||||
|
Cancelar
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</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 ventas de catálogo...</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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useAuthStore } from '@/stores/auth';
|
||||||
|
import { inject } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CatalogSalesToTryton',
|
||||||
|
setup() {
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
return { authStore };
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
api: inject('api'),
|
||||||
|
loading: false,
|
||||||
|
result: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatItems(ids) {
|
||||||
|
if (!ids || ids.length === 0) return [];
|
||||||
|
return ids.map(id => ({ id }));
|
||||||
|
},
|
||||||
|
startSync() {
|
||||||
|
this.loading = true;
|
||||||
|
this.api.sendCatalogSalesToTryton()
|
||||||
|
.then(response => {
|
||||||
|
this.result = response;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error al sincronizar ventas de catálogo:', error);
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -71,6 +71,10 @@ class Api {
|
|||||||
return this.apiImplementation.sendSalesToTryton();
|
return this.apiImplementation.sendSalesToTryton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendCatalogSalesToTryton() {
|
||||||
|
return this.apiImplementation.sendCatalogSalesToTryton();
|
||||||
|
}
|
||||||
|
|
||||||
getCatalogSales() {
|
getCatalogSales() {
|
||||||
return this.apiImplementation.getCatalogSales();
|
return this.apiImplementation.getCatalogSales();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ class DjangoApi {
|
|||||||
return this.postRequest(url, {});
|
return this.postRequest(url, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendCatalogSalesToTryton() {
|
||||||
|
const url = this.base + "/don_confiao/api/enviar_catalog_sales_a_tryton";
|
||||||
|
return this.postRequest(url, {});
|
||||||
|
}
|
||||||
|
|
||||||
getCatalogSales() {
|
getCatalogSales() {
|
||||||
const url = this.base + "/don_confiao/api/catalog_sales/";
|
const url = this.base + "/don_confiao/api/catalog_sales/";
|
||||||
return this.getRequest(url);
|
return this.getRequest(url);
|
||||||
|
|||||||
Reference in New Issue
Block a user