from datetime import datetime, timedelta from apscheduler.schedulers.background import BackgroundScheduler from flask import current_app scheduler = BackgroundScheduler(job_defaults={'coalesce': True, 'max_instances': 1}) def init_scheduler(app): if scheduler.running: return def sync_job(): with app.app_context(): from app.models.company import Company from app.models.sync_log import SyncLog from app.services.sync_service import SyncService current_app.logger.info('Scheduled sync checker started') companies = Company.query.filter_by(is_active=True, sync_enabled=True).all() for company in companies: last_log = SyncLog.query.filter_by(company_id=company.id, status='finished').order_by(SyncLog.finished_at.desc()).first() due = not last_log or not last_log.finished_at or (datetime.utcnow() - last_log.finished_at) >= timedelta(minutes=company.sync_interval_minutes) if due: SyncService(company).run_scheduled_sync() def refresh_dashboard_cache_job(): with app.app_context(): from app.models.company import Company from app.models.invoice import Invoice from app.services.health_service import HealthService from app.services.redis_service import RedisService from sqlalchemy import extract from datetime import date from decimal import Decimal today = date.today() for company in Company.query.filter_by(is_active=True).all(): base = Invoice.query.filter_by(company_id=company.id) month_invoices = base.filter( extract('month', Invoice.issue_date) == today.month, extract('year', Invoice.issue_date) == today.year, ).order_by(Invoice.issue_date.desc(), Invoice.id.desc()).all() recent_ids = [invoice.id for invoice in base.order_by(Invoice.created_at.desc(), Invoice.id.desc()).limit(200).all()] totals = { 'net': str(sum(Decimal(invoice.net_amount) for invoice in month_invoices)), 'vat': str(sum(Decimal(invoice.vat_amount) for invoice in month_invoices)), 'gross': str(sum(Decimal(invoice.gross_amount) for invoice in month_invoices)), } RedisService.set_json( f'dashboard.summary.company.{company.id}', { 'month_invoice_ids': [invoice.id for invoice in month_invoices], 'unread': base.filter_by(is_unread=True).count(), 'totals': totals, 'recent_invoice_ids': recent_ids, }, ttl=300, ) HealthService().warm_cache(company.id) scheduler.add_job(sync_job, 'interval', minutes=1, id='ksef_sync', replace_existing=True) scheduler.add_job(refresh_dashboard_cache_job, 'interval', minutes=5, id='dashboard_cache_refresh', replace_existing=True) scheduler.start()