100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
"""
|
|
Job quotidien: détecte les tâches 'du jour' liées aux prospects
|
|
et génère des brouillons d'emails basés sur un template.
|
|
À exécuter via crontab, par exemple:
|
|
0 8 * * * /usr/bin/python3 /chemin/vers/le/projet/jobs/daily_reminder_job.py >> /var/log/reminder_job.log 2>&1
|
|
"""
|
|
|
|
from datetime import date
|
|
import sys
|
|
import os
|
|
|
|
# S'assurer que le projet est dans le PYTHONPATH quand lancé via cron
|
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
if BASE_DIR not in sys.path:
|
|
sys.path.insert(0, BASE_DIR)
|
|
|
|
from modules.tasks.task_handler import TaskHandler
|
|
from modules.crm.prospect_handler import ProspectHandler
|
|
from modules.email.email_manager import EmailTemplate
|
|
from modules.email.draft import EmailDraft
|
|
from modules.email.draft_handler import DraftHandler
|
|
|
|
|
|
DEFAULT_TEMPLATE_ID = "prospect_followup"
|
|
|
|
|
|
def _render_with_fallback(template_mgr: EmailTemplate, template_id: str, context: dict) -> dict:
|
|
"""
|
|
Rend un template via EmailTemplate. Si introuvable, fabrique un contenu par défaut.
|
|
Retourne dict {subject, content}
|
|
"""
|
|
rendered = template_mgr.render_template(template_id, context=context)
|
|
if rendered:
|
|
return rendered
|
|
# Fallback basique
|
|
subject = f"Relance {context.get('name') or ''}".strip()
|
|
content = (
|
|
f"<p>Bonjour {context.get('name','')},</p>"
|
|
f"<p>Je me permets de revenir vers vous au sujet de {context.get('company','votre société')}."
|
|
f"</p><p>Restant à votre disposition,</p>"
|
|
)
|
|
return {"subject": subject, "content": content}
|
|
|
|
|
|
def main():
|
|
today = date.today().isoformat()
|
|
tasks = TaskHandler().list_today_tasks(status="todo")
|
|
# Filtrer uniquement les tâches liées aux prospects (interprétées comme 'rappel')
|
|
prospect_tasks = [t for t in tasks if t.entity_type == "prospect"]
|
|
|
|
if not prospect_tasks:
|
|
return 0
|
|
|
|
prospect_handler = ProspectHandler()
|
|
template_mgr = EmailTemplate()
|
|
draft_handler = DraftHandler()
|
|
|
|
created = 0
|
|
for t in prospect_tasks:
|
|
# Évite doublons: un draft existe déjà pour cette tâche ?
|
|
if draft_handler.find_existing_for_task(t.id):
|
|
continue
|
|
|
|
# Récupère prospect pour variables
|
|
prospect = prospect_handler.get_prospect_by_id(t.entity_id) if t.entity_id else None
|
|
if not prospect:
|
|
continue
|
|
|
|
to_email = prospect.email or ""
|
|
if not to_email:
|
|
# pas de destinataire, aucun draft créé
|
|
continue
|
|
|
|
context = {
|
|
"name": prospect.name,
|
|
"company": prospect.company or "",
|
|
}
|
|
rendered = _render_with_fallback(template_mgr, DEFAULT_TEMPLATE_ID, context)
|
|
|
|
draft = EmailDraft(
|
|
prospect_id=prospect.id,
|
|
to_email=to_email,
|
|
subject=rendered["subject"],
|
|
content=rendered["content"],
|
|
status="draft",
|
|
template_id=DEFAULT_TEMPLATE_ID,
|
|
task_id=t.id,
|
|
metadata={
|
|
"generated_for_date": today,
|
|
"task_title": t.title,
|
|
},
|
|
)
|
|
draft_handler.add_draft(draft)
|
|
created += 1
|
|
|
|
return created
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|