first commit
This commit is contained in:
commit
e6c52820cd
227 changed files with 16156 additions and 0 deletions
100
jobs/daily_reminder_job.py
Normal file
100
jobs/daily_reminder_job.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"""
|
||||
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())
|
||||
Loading…
Add table
Add a link
Reference in a new issue