""" Daily sync job for e-conomic chart of accounts (kontoplan) Scheduled to run every day at 06:00 Updates the economic_accounts cache table with latest data from e-conomic API """ import logging from datetime import datetime from app.core.database import execute_query, execute_update, execute_insert from app.services.economic_service import get_economic_service from app.core.config import settings logger = logging.getLogger(__name__) async def sync_economic_accounts(): """ Sync e-conomic chart of accounts to local cache This job: 1. Fetches all accounts from e-conomic API 2. Updates economic_accounts table 3. Logs sync statistics """ try: logger.info("🔄 Starting daily e-conomic accounts sync...") # Check if e-conomic is configured if not settings.ECONOMIC_APP_SECRET_TOKEN or not settings.ECONOMIC_AGREEMENT_GRANT_TOKEN: logger.warning("⚠️ e-conomic credentials not configured - skipping sync") return { "success": False, "reason": "e-conomic credentials not configured" } # Get economic service economic_service = get_economic_service() # Fetch accounts from e-conomic logger.info("📥 Fetching accounts from e-conomic API...") accounts = economic_service.get_accounts() if not accounts: logger.warning("⚠️ No accounts returned from e-conomic API") return { "success": False, "reason": "No accounts returned from API" } logger.info(f"📦 Fetched {len(accounts)} accounts from e-conomic") # Update database - upsert each account updated_count = 0 inserted_count = 0 for account in accounts: account_number = account.get('accountNumber') name = account.get('name') account_type = account.get('accountType') vat_code = account.get('vatCode', {}).get('vatCode') if account.get('vatCode') else None if not account_number: continue # Check if account exists existing = execute_query( "SELECT account_number FROM economic_accounts WHERE account_number = %s", (account_number,) ) if existing: # Update existing execute_update( """UPDATE economic_accounts SET name = %s, account_type = %s, vat_code = %s, updated_at = CURRENT_TIMESTAMP WHERE account_number = %s""", (name, account_type, vat_code, account_number) ) updated_count += 1 else: # Insert new execute_insert( """INSERT INTO economic_accounts (account_number, name, account_type, vat_code, updated_at) VALUES (%s, %s, %s, %s, CURRENT_TIMESTAMP)""", (account_number, name, account_type, vat_code) ) inserted_count += 1 logger.info(f"✅ e-conomic accounts sync complete: {inserted_count} inserted, {updated_count} updated") return { "success": True, "fetched": len(accounts), "inserted": inserted_count, "updated": updated_count, "timestamp": datetime.now().isoformat() } except Exception as e: logger.error(f"❌ e-conomic accounts sync failed: {e}", exc_info=True) return { "success": False, "error": str(e), "timestamp": datetime.now().isoformat() } if __name__ == "__main__": # Allow running this job manually for testing import asyncio result = asyncio.run(sync_economic_accounts()) print(f"Sync result: {result}")