Phase 1 - Analytics y Reportes: - PostMetrics and AnalyticsReport models for tracking engagement - Analytics service with dashboard stats, top posts, optimal times - 8 API endpoints at /api/analytics/* - Interactive dashboard with Chart.js charts - Celery tasks for metrics fetch (15min) and weekly reports Phase 2 - Integración Odoo: - Lead and OdooSyncLog models for CRM integration - Odoo fields added to Product and Service models - XML-RPC service for bidirectional sync - Lead management API at /api/leads/* - Leads dashboard template - Celery tasks for product/service sync and lead export Phase 3 - A/B Testing y Recycling: - ABTest, ABTestVariant, RecycledPost models - Statistical winner analysis using chi-square test - Content recycling with engagement-based scoring - APIs at /api/ab-tests/* and /api/recycling/* - Automated test evaluation and content recycling tasks Phase 4 - Thread Series y Templates: - ThreadSeries and ThreadPost models for multi-post threads - AI-powered thread generation - Enhanced ImageTemplate with HTML template support - APIs at /api/threads/* and /api/templates/* - Thread scheduling with reply chain support Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
"""
|
|
Odoo Sync Log Model - Track synchronization history with Odoo.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from sqlalchemy import Column, Integer, String, Text, DateTime, JSON
|
|
|
|
from app.core.database import Base
|
|
|
|
|
|
class OdooSyncLog(Base):
|
|
"""
|
|
Log of synchronization operations with Odoo ERP.
|
|
"""
|
|
__tablename__ = "odoo_sync_logs"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
|
|
# Sync operation details
|
|
sync_type = Column(String(50), nullable=False, index=True)
|
|
# Types: products, services, leads, sales
|
|
|
|
direction = Column(String(20), nullable=False)
|
|
# Direction: import (from Odoo), export (to Odoo)
|
|
|
|
status = Column(String(20), nullable=False, index=True)
|
|
# Status: started, completed, failed, partial
|
|
|
|
# Statistics
|
|
records_processed = Column(Integer, default=0)
|
|
records_created = Column(Integer, default=0)
|
|
records_updated = Column(Integer, default=0)
|
|
records_failed = Column(Integer, default=0)
|
|
|
|
# Error details
|
|
error_message = Column(Text, nullable=True)
|
|
error_details = Column(JSON, nullable=True)
|
|
# Contains list of failed records with error details
|
|
|
|
# Sync details
|
|
sync_filter = Column(JSON, nullable=True)
|
|
# Filters applied during sync (e.g., date range, categories)
|
|
|
|
# Timestamps
|
|
started_at = Column(DateTime, default=datetime.utcnow)
|
|
completed_at = Column(DateTime, nullable=True)
|
|
|
|
def __repr__(self):
|
|
return f"<OdooSyncLog {self.id} - {self.sync_type} {self.status}>"
|
|
|
|
def to_dict(self):
|
|
"""Convert to dictionary."""
|
|
return {
|
|
"id": self.id,
|
|
"sync_type": self.sync_type,
|
|
"direction": self.direction,
|
|
"status": self.status,
|
|
"records_processed": self.records_processed,
|
|
"records_created": self.records_created,
|
|
"records_updated": self.records_updated,
|
|
"records_failed": self.records_failed,
|
|
"error_message": self.error_message,
|
|
"error_details": self.error_details,
|
|
"started_at": self.started_at.isoformat() if self.started_at else None,
|
|
"completed_at": self.completed_at.isoformat() if self.completed_at else None,
|
|
"duration_seconds": (self.completed_at - self.started_at).total_seconds() if self.completed_at and self.started_at else None
|
|
}
|
|
|
|
def mark_completed(self):
|
|
"""Mark sync as completed."""
|
|
self.status = "completed"
|
|
self.completed_at = datetime.utcnow()
|
|
|
|
def mark_failed(self, error_message: str, details: dict = None):
|
|
"""Mark sync as failed with error details."""
|
|
self.status = "failed"
|
|
self.error_message = error_message
|
|
self.error_details = details
|
|
self.completed_at = datetime.utcnow()
|