- Detect missing invoice lines, open orders not invoiced, quantity drops, price changes - Import e-conomic invoices and Simply CRM sales orders - Dashboard and issues UI with sag/ordre-draft actions - Scheduled daily sync job at 05:00 - Add invoice_error_finder permissions
85 lines
3.1 KiB
Python
85 lines
3.1 KiB
Python
"""
|
|
Scheduled sync job for Invoice Error Finder.
|
|
Runs daily after subscription processing to import e-conomic and Simply data
|
|
and re-run anomaly detection.
|
|
"""
|
|
import logging
|
|
|
|
from app.modules.invoice_error_finder.services.economic_import_service import EconomicImportService
|
|
from app.modules.invoice_error_finder.services.simply_import_service import SimplyImportService
|
|
from app.modules.invoice_error_finder.services.detection_service import DetectionService
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def run_invoice_error_finder_sync() -> dict:
|
|
"""
|
|
Daily scheduled job:
|
|
1. Import e-conomic invoices (last 13 months).
|
|
2. Import open Simply CRM sales orders.
|
|
3. Re-import Simply subscription staging via existing endpoint.
|
|
4. Run anomaly detection for current month.
|
|
"""
|
|
logger.info("🔄 Starting scheduled Invoice Error Finder sync")
|
|
|
|
economic_result = {"records_imported": 0, "records_failed": 0}
|
|
simply_result = {"records_imported": 0, "records_failed": 0}
|
|
staging_result = {"records_imported": 0, "records_failed": 0}
|
|
detection_counts = {}
|
|
errors = []
|
|
|
|
try:
|
|
economic_service = EconomicImportService()
|
|
economic_result = await economic_service.import_invoices(
|
|
triggered_by_user_id=None,
|
|
is_scheduled=True,
|
|
)
|
|
except Exception as exc:
|
|
logger.error("❌ Scheduled e-conomic import failed: %s", exc, exc_info=True)
|
|
errors.append(f"economic: {exc}")
|
|
|
|
try:
|
|
simply_service = SimplyImportService()
|
|
simply_result = await simply_service.import_sales_orders(
|
|
triggered_by_user_id=None,
|
|
is_scheduled=True,
|
|
)
|
|
except Exception as exc:
|
|
logger.error("❌ Scheduled Simply sales order import failed: %s", exc, exc_info=True)
|
|
errors.append(f"simply: {exc}")
|
|
|
|
# Refresh Simply subscription staging by calling the existing import function directly
|
|
try:
|
|
from app.subscriptions.backend.router import import_simply_subscriptions_to_staging
|
|
|
|
staging_data = await import_simply_subscriptions_to_staging()
|
|
staging_result = {
|
|
"records_imported": staging_data.get("imported", 0),
|
|
"records_failed": staging_data.get("errors", 0),
|
|
}
|
|
except Exception as exc:
|
|
logger.error("❌ Scheduled Simply subscription staging import failed: %s", exc, exc_info=True)
|
|
errors.append(f"staging: {exc}")
|
|
|
|
try:
|
|
detection_service = DetectionService()
|
|
detection_counts = detection_service.analyze()
|
|
except Exception as exc:
|
|
logger.error("❌ Scheduled detection failed: %s", exc, exc_info=True)
|
|
errors.append(f"detection: {exc}")
|
|
|
|
result = {
|
|
"economic": economic_result,
|
|
"simply": simply_result,
|
|
"staging": staging_result,
|
|
"detection": detection_counts,
|
|
"errors": errors,
|
|
}
|
|
|
|
if errors:
|
|
logger.warning("⚠️ Invoice Error Finder sync completed with errors: %s", errors)
|
|
else:
|
|
logger.info("✅ Invoice Error Finder sync completed successfully: %s", result)
|
|
|
|
return result
|