bmc_hub/app/jobs/sync_economic_accounts.py
Christian 3dcd04396e feat(webshop): Initial implementation of webshop module with views, migrations, and templates
- Added views for webshop admin interface using FastAPI and Jinja2 templates.
- Created initial SQL migration for webshop configurations, products, orders, and order items.
- Defined module metadata in module.json for webshop.
- Implemented HTML template for the webshop index page.
- Documented frontend requirements and API contracts in WEBSHOP_FRONTEND_PROMPT.md.
- Introduced scripts for generating conversation summaries and testing Whisper capabilities.
2026-01-25 03:29:28 +01:00

116 lines
4.0 KiB
Python

"""
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}")