Files
social-media-automation/app/models/odoo_sync_log.py
Consultoría AS ecc2ca73ea feat: Add Analytics, Odoo Integration, A/B Testing, and Content features
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>
2026-01-28 03:10:42 +00:00

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()