gmao/app_new/core/services/maintenance_engine.py

59 lines
2.6 KiB
Python
Raw Normal View History

"""Moteur unique de génération des échéances depuis les tâches de lot."""
from datetime import date, timedelta
from app_new.extensions import db
from app_new.core.models.planning import Meter, ScheduledTask
from app_new.core.models.maintenance import LotTask
from app_new.core.services.planning_service import PlanningService
def _targets(lot):
result = []
for root in lot.equipments.filter_by(is_deleted=False):
if root.tracked_individually:
result.extend([x for x in root.all_children if not x.is_group and not x.is_deleted])
elif root.is_group and root.children.count():
result.extend([x for x in root.children if not x.is_deleted])
else:
result.append(root)
return list({item.id: item for item in result}.values())
def _working_day(candidate):
for _ in range(370):
if PlanningService.get_working_hours(candidate):
return candidate
candidate += timedelta(days=1)
raise ValueError("Aucune journée travaillée disponible dans les 12 prochains mois.")
def generate_due_tasks(task: LotTask, event=None, today=None):
"""Génère les échéances sans doublon et retourne les objets créés."""
today = today or date.today()
if not task.is_active:
return []
if task.trigger_type in ("event", "weather") and task.trigger_event != event:
return []
if task.trigger_type == "season":
start, end = task.season_start_month or 1, task.season_end_month or 12
inside = start <= today.month <= end if start <= end else today.month >= start or today.month <= end
if not inside:
return []
created = []
for equipment in _targets(task.lot):
if task.trigger_type == "meter":
meter = Meter.query.filter_by(equipment_id=equipment.id, is_active=True).order_by(Meter.current_value.desc()).first()
if not meter or task.meter_threshold is None or meter.current_value < task.meter_threshold:
continue
existing = ScheduledTask.query.filter_by(lot_task_id=task.id, equipment_id=equipment.id, status="planned").first()
if existing:
continue
due = _working_day(today + timedelta(days=max(task.advance_days or 0, 0)))
item = ScheduledTask(lot_task_id=task.id, equipment_id=equipment.id,
room_id=equipment.effective_room.id if equipment.effective_room else None,
scheduled_date=due, estimated_duration=task.effective_duration(), status="planned")
db.session.add(item)
created.append(item)
db.session.commit()
return created