Lier les tâches préventives aux contrats
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
This commit is contained in:
parent
2d6e9fb0ca
commit
d18deec5d5
7 changed files with 29 additions and 3 deletions
|
|
@ -375,6 +375,8 @@ class LotTask(db.Model):
|
|||
tache = db.Column(db.Text, nullable=True)
|
||||
periodicite = db.Column(db.String(200), nullable=True)
|
||||
contrat = db.Column(db.Boolean, default=False)
|
||||
company_id = db.Column(db.Integer, db.ForeignKey("companies.id"), nullable=True)
|
||||
contract_id = db.Column(db.Integer, db.ForeignKey("contracts.id"), nullable=True)
|
||||
gestionnaire = db.Column(db.String(50), nullable=True)
|
||||
jours_entre_interventions = db.Column(db.Integer, nullable=True)
|
||||
type_maintenance = db.Column(db.String(50), nullable=True)
|
||||
|
|
@ -390,6 +392,8 @@ class LotTask(db.Model):
|
|||
unavailable_policy = db.Column(db.String(20), nullable=False, default="suspend")
|
||||
after_repair_policy = db.Column(db.String(20), nullable=False, default="preserve")
|
||||
is_safety_critical = db.Column(db.Boolean, nullable=False, default=False)
|
||||
company = db.relationship("Company")
|
||||
contract = db.relationship("Contract")
|
||||
|
||||
def effective_duration(self):
|
||||
"""Duree previsionnelle auto-adaptee pour cette tache de lot.
|
||||
|
|
|
|||
|
|
@ -426,6 +426,7 @@ class PreventiveTask(db.Model):
|
|||
has_contract = db.Column(db.Boolean, default=False)
|
||||
manager = db.Column(db.String(50))
|
||||
company_id = db.Column(db.Integer, db.ForeignKey("companies.id"))
|
||||
contract_id = db.Column(db.Integer, db.ForeignKey("contracts.id"), nullable=True)
|
||||
|
||||
trigger_type = db.Column(db.String(20), default="time")
|
||||
meter_type_required = db.Column(db.String(50))
|
||||
|
|
@ -441,6 +442,7 @@ class PreventiveTask(db.Model):
|
|||
lot = db.relationship("Lot", backref=db.backref("preventive_tasks", lazy="dynamic"))
|
||||
category = db.relationship("EquipmentCategory", backref=db.backref("preventive_tasks", lazy="dynamic"))
|
||||
company = db.relationship("Company")
|
||||
contract = db.relationship("Contract")
|
||||
consumables_needed = db.relationship("PreventiveTaskConsumable", back_populates="task", lazy="dynamic")
|
||||
|
||||
def __repr__(self):
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ def generate_due_tasks(task: LotTask, event=None, today=None, equipment_ids=None
|
|||
status = "suspended" if unavailable and not task.is_safety_critical and task.unavailable_policy == "suspend" else "planned"
|
||||
item = ScheduledTask(lot_task_id=task.id, equipment_id=equipment.id,
|
||||
room_id=room.id if room else None,
|
||||
company_id=task.company_id,
|
||||
contract_id=task.contract_id,
|
||||
scheduled_date=due, estimated_duration=task.effective_duration(), status=status,
|
||||
suspension_reason="Équipement indisponible" if status == "suspended" else None,
|
||||
room_name_snapshot=room.name if room else None,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from ..core.models.maintenance import Lot, LotTask
|
|||
from ..core.models.planning import ScheduledTask
|
||||
from ..core.services.maintenance_engine import generate_due_tasks
|
||||
from ..core.models.company import Company
|
||||
from ..contracts.models import Contract
|
||||
from ..core.models.equipment import Equipment
|
||||
|
||||
lots_bp = Blueprint('lots', __name__)
|
||||
|
|
@ -71,6 +72,8 @@ def _apply_task_form(task):
|
|||
task.after_repair_policy = request.form.get('after_repair_policy') or 'preserve'
|
||||
task.is_safety_critical = request.form.get('is_safety_critical') == 'on'
|
||||
task.is_active = request.form.get('is_active') == 'on'
|
||||
task.company_id = request.form.get('company_id', type=int) or None
|
||||
task.contract_id = request.form.get('contract_id', type=int) or None
|
||||
|
||||
|
||||
@lots_bp.route('/<int:lot_id>/tasks/new', methods=['GET', 'POST'])
|
||||
|
|
@ -87,7 +90,7 @@ def task_create(lot_id):
|
|||
db.session.commit()
|
||||
flash('Tâche préventive ajoutée au lot.', 'success')
|
||||
return redirect(url_for('lots.detail', id=lot.id))
|
||||
return render_template('lots/task_form.html', lot=lot, task=task, creating=True)
|
||||
return render_template('lots/task_form.html', lot=lot, task=task, creating=True, companies=Company.query.order_by(Company.name).all(), contracts=Contract.query.order_by(Contract.name).all())
|
||||
|
||||
|
||||
@lots_bp.route('/<int:lot_id>/tasks/<int:task_id>/edit', methods=['GET', 'POST'])
|
||||
|
|
@ -103,7 +106,7 @@ def task_edit(lot_id, task_id):
|
|||
db.session.commit()
|
||||
flash('Règle préventive mise à jour.', 'success')
|
||||
return redirect(url_for('lots.detail', id=lot.id))
|
||||
return render_template('lots/task_form.html', lot=lot, task=task, creating=False)
|
||||
return render_template('lots/task_form.html', lot=lot, task=task, creating=False, companies=Company.query.order_by(Company.name).all(), contracts=Contract.query.order_by(Contract.name).all())
|
||||
|
||||
|
||||
@lots_bp.route('/<int:lot_id>/generate', methods=['POST'])
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
<td>{{ task.scheduled_date.strftime('%d/%m/%Y') if task.scheduled_date else '-' }}</td>
|
||||
<td>{{ task.scheduled_start.strftime('%H:%M') if task.scheduled_start else '- - -' }}</td>
|
||||
<td><strong>{{ task.lot_task.tache if task.lot_task else '-' }}</strong></td>
|
||||
<td>{{ task.equipment.name if task.equipment else '-' }}</td>
|
||||
<td>{{ task.equipment.name if task.equipment else '-' }}{% if task.company %}<div class="small text-primary"><i class="bi bi-building"></i> {{ task.company.name }}{% if task.contract %} · {{ task.contract.name }}{% endif %}</div>{% endif %}</td>
|
||||
<td>{{ task.room.name if task.room else '-' }}</td>
|
||||
<td>{% if task.estimated_duration %}{{ task.estimated_duration }}{% elif task.lot_task and task.lot_task.duree_minutes %}{{ task.lot_task.duree_minutes }}{% else %}-{% endif %} min</td>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
<div class="col-md-6"><label class="form-label">Portée</label><select class="form-select" name="application_scope"><option value="auto" {% if task.application_scope == 'auto' %}selected{% endif %}>Automatique selon le type d’équipement</option><option value="group" {% if task.application_scope == 'group' %}selected{% endif %}>Une tâche par groupe/localisation</option><option value="unit" {% if task.application_scope == 'unit' %}selected{% endif %}>Une tâche par unité individualisée</option></select><div class="form-text">Pour 30 chaises, « groupe » crée une seule tâche dans la salle.</div></div>
|
||||
<div class="col-md-6"><label class="form-label">Si l’équipement est indisponible</label><select class="form-select" name="unavailable_policy"><option value="suspend" {% if task.unavailable_policy == 'suspend' %}selected{% endif %}>Suspendre et reprendre après réparation</option><option value="keep" {% if task.unavailable_policy == 'keep' %}selected{% endif %}>Maintenir la tâche</option><option value="postpone" {% if task.unavailable_policy == 'postpone' %}selected{% endif %}>Ne pas générer avant remise en service</option></select></div>
|
||||
<div class="col-md-6"><label class="form-label">Après réparation</label><select class="form-select" name="after_repair_policy"><option value="preserve" {% if task.after_repair_policy == 'preserve' %}selected{% endif %}>Conserver l’échéance d’origine</option><option value="reset" {% if task.after_repair_policy == 'reset' %}selected{% endif %}>Repartir de la date de réparation</option></select></div>
|
||||
<div class="col-md-6"><label class="form-label">Entreprise exécutante</label><select class="form-select" name="company_id"><option value="">Interne / non définie</option>{% for company in companies %}<option value="{{ company.id }}" {% if task.company_id == company.id %}selected{% endif %}>{{ company.name }}</option>{% endfor %}</select></div>
|
||||
<div class="col-md-6"><label class="form-label">Contrat associé</label><select class="form-select" name="contract_id"><option value="">Aucun contrat</option>{% for contract in contracts %}<option value="{{ contract.id }}" {% if task.contract_id == contract.id %}selected{% endif %}>{{ contract.name }}{% if contract.contract_number %} — {{ contract.contract_number }}{% endif %}</option>{% endfor %}</select></div>
|
||||
<div class="col-md-3 form-check ms-2 mt-5"><input class="form-check-input" type="checkbox" name="is_safety_critical" id="safety" {% if task.is_safety_critical %}checked{% endif %}><label class="form-check-label" for="safety">Tâche de sécurité</label></div>
|
||||
<div class="col-md-2 form-check ms-2 mt-5"><input class="form-check-input" type="checkbox" name="is_active" id="active" {% if task.is_active %}checked{% endif %}><label class="form-check-label" for="active">Active</label></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
"""Lie les tâches préventives aux entreprises et contrats."""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
revision = "fc3d4e5f6a7b"
|
||||
down_revision = "fb2c3d4e5f6a"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
def upgrade():
|
||||
op.add_column("lot_tasks", sa.Column("company_id", sa.Integer(), sa.ForeignKey("companies.id"), nullable=True))
|
||||
op.add_column("lot_tasks", sa.Column("contract_id", sa.Integer(), sa.ForeignKey("contracts.id"), nullable=True))
|
||||
op.add_column("scheduled_tasks", sa.Column("contract_id", sa.Integer(), sa.ForeignKey("contracts.id"), nullable=True))
|
||||
def downgrade():
|
||||
op.drop_column("scheduled_tasks", "contract_id"); op.drop_column("lot_tasks", "contract_id"); op.drop_column("lot_tasks", "company_id")
|
||||
Loading…
Reference in a new issue