146 lines
6.9 KiB
Python
146 lines
6.9 KiB
Python
|
|
"""
|
||
|
|
Contracts Routes - GMAO College
|
||
|
|
Suivi des contrats d'entreprise.
|
||
|
|
"""
|
||
|
|
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
|
||
|
|
from flask_login import login_required, current_user
|
||
|
|
from ..extensions import db
|
||
|
|
from ..contracts.models import Contract
|
||
|
|
from ..core.models.maintenance import Lot
|
||
|
|
from ..core.models.equipment import Equipment
|
||
|
|
from ..companies.routes import Company
|
||
|
|
from datetime import datetime, date
|
||
|
|
|
||
|
|
contracts_bp = Blueprint('contracts', __name__, url_prefix='/contracts', template_folder='templates')
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/')
|
||
|
|
@login_required
|
||
|
|
def index():
|
||
|
|
"""Liste de tous les contrats."""
|
||
|
|
contracts = Contract.query.order_by(
|
||
|
|
db.case((Contract.end_date.is_(None), 1), else_=0),
|
||
|
|
Contract.end_date.asc()
|
||
|
|
).all()
|
||
|
|
|
||
|
|
# Stats
|
||
|
|
active = sum(1 for c in contracts if c.is_active)
|
||
|
|
expiring = sum(1 for c in contracts if c.is_expiring_soon)
|
||
|
|
notice = sum(1 for c in contracts if c.must_send_notice_now)
|
||
|
|
expired = sum(1 for c in contracts if c.status == 'expire' or (c.end_date and c.end_date < date.today() and c.status == 'actif'))
|
||
|
|
|
||
|
|
return render_template('contracts/index.html',
|
||
|
|
contracts=contracts,
|
||
|
|
active_count=active,
|
||
|
|
expiring_count=expiring,
|
||
|
|
notice_count=notice,
|
||
|
|
expired_count=expired)
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/new', methods=['GET', 'POST'])
|
||
|
|
@login_required
|
||
|
|
def create():
|
||
|
|
"""Creer un contrat."""
|
||
|
|
lots = Lot.query.order_by(Lot.name).all()
|
||
|
|
equipments = Equipment.query.order_by(Equipment.name).all()
|
||
|
|
companies = Company.query.order_by(Company.name).all()
|
||
|
|
|
||
|
|
if request.method == 'POST':
|
||
|
|
contract = Contract(
|
||
|
|
name=request.form.get('name'),
|
||
|
|
contract_number=request.form.get('contract_number'),
|
||
|
|
lot_id=request.form.get('lot_id') or None,
|
||
|
|
equipment_id=request.form.get('equipment_id') or None,
|
||
|
|
company_id=request.form.get('company_id') or None,
|
||
|
|
signed_date=datetime.strptime(request.form.get('signed_date'), '%Y-%m-%d').date() if request.form.get('signed_date') else None,
|
||
|
|
start_date=datetime.strptime(request.form.get('start_date'), '%Y-%m-%d').date() if request.form.get('start_date') else date.today(),
|
||
|
|
end_date=datetime.strptime(request.form.get('end_date'), '%Y-%m-%d').date() if request.form.get('end_date') else None,
|
||
|
|
tacit_renewal=request.form.get('tacit_renewal') == '1',
|
||
|
|
renewal_period_days=int(request.form.get('renewal_period_days', 365)),
|
||
|
|
notice_period_days=int(request.form.get('notice_period_days')) if request.form.get('notice_period_days') else None,
|
||
|
|
notice_deadline=datetime.strptime(request.form.get('notice_deadline'), '%Y-%m-%d').date() if request.form.get('notice_deadline') else None,
|
||
|
|
annual_amount=float(request.form.get('annual_amount')) if request.form.get('annual_amount') else None,
|
||
|
|
status=request.form.get('status', 'actif'),
|
||
|
|
notes=request.form.get('notes', ''),
|
||
|
|
)
|
||
|
|
db.session.add(contract)
|
||
|
|
db.session.commit()
|
||
|
|
flash('Contrat cree avec succes.', 'success')
|
||
|
|
return redirect(url_for('contracts.detail', id=contract.id))
|
||
|
|
|
||
|
|
# Pre-remplir si lot_id ou equipment_id dans l'URL
|
||
|
|
pre_lot = request.args.get('lot_id', type=int)
|
||
|
|
pre_eq = request.args.get('equipment_id', type=int)
|
||
|
|
pre_company = request.args.get('company_id', type=int)
|
||
|
|
|
||
|
|
return render_template('contracts/form.html',
|
||
|
|
lots=lots, equipments=equipments, companies=companies,
|
||
|
|
pre_lot=pre_lot, pre_eq=pre_eq, pre_company=pre_company,
|
||
|
|
contract=None)
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/<int:id>')
|
||
|
|
@login_required
|
||
|
|
def detail(id):
|
||
|
|
"""Detail d'un contrat."""
|
||
|
|
contract = Contract.query.get_or_404(id)
|
||
|
|
return render_template('contracts/detail.html', contract=contract)
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/<int:id>/edit', methods=['GET', 'POST'])
|
||
|
|
@login_required
|
||
|
|
def edit(id):
|
||
|
|
"""Modifier un contrat."""
|
||
|
|
contract = Contract.query.get_or_404(id)
|
||
|
|
lots = Lot.query.order_by(Lot.name).all()
|
||
|
|
equipments = Equipment.query.order_by(Equipment.name).all()
|
||
|
|
companies = Company.query.order_by(Company.name).all()
|
||
|
|
|
||
|
|
if request.method == 'POST':
|
||
|
|
contract.name = request.form.get('name')
|
||
|
|
contract.contract_number = request.form.get('contract_number')
|
||
|
|
contract.lot_id = request.form.get('lot_id') or None
|
||
|
|
contract.equipment_id = request.form.get('equipment_id') or None
|
||
|
|
contract.company_id = request.form.get('company_id') or None
|
||
|
|
contract.signed_date = datetime.strptime(request.form.get('signed_date'), '%Y-%m-%d').date() if request.form.get('signed_date') else None
|
||
|
|
contract.start_date = datetime.strptime(request.form.get('start_date'), '%Y-%m-%d').date() if request.form.get('start_date') else date.today()
|
||
|
|
contract.end_date = datetime.strptime(request.form.get('end_date'), '%Y-%m-%d').date() if request.form.get('end_date') else None
|
||
|
|
contract.tacit_renewal = request.form.get('tacit_renewal') == '1'
|
||
|
|
contract.renewal_period_days = int(request.form.get('renewal_period_days', 365))
|
||
|
|
contract.notice_period_days = int(request.form.get('notice_period_days')) if request.form.get('notice_period_days') else None
|
||
|
|
contract.notice_deadline = datetime.strptime(request.form.get('notice_deadline'), '%Y-%m-%d').date() if request.form.get('notice_deadline') else None
|
||
|
|
contract.annual_amount = float(request.form.get('annual_amount')) if request.form.get('annual_amount') else None
|
||
|
|
contract.status = request.form.get('status', 'actif')
|
||
|
|
contract.notes = request.form.get('notes', '')
|
||
|
|
db.session.commit()
|
||
|
|
flash('Contrat modifie.', 'success')
|
||
|
|
return redirect(url_for('contracts.detail', id=contract.id))
|
||
|
|
|
||
|
|
return render_template('contracts/form.html',
|
||
|
|
contract=contract, lots=lots, equipments=equipments, companies=companies,
|
||
|
|
pre_lot=None, pre_eq=None, pre_company=None)
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/<int:id>/delete', methods=['POST'])
|
||
|
|
@login_required
|
||
|
|
def delete(id):
|
||
|
|
"""Supprimer un contrat."""
|
||
|
|
contract = Contract.query.get_or_404(id)
|
||
|
|
db.session.delete(contract)
|
||
|
|
db.session.commit()
|
||
|
|
flash('Contrat supprime.', 'success')
|
||
|
|
return redirect(url_for('contracts.index'))
|
||
|
|
|
||
|
|
|
||
|
|
@contracts_bp.route('/api/summary')
|
||
|
|
@login_required
|
||
|
|
def api_summary():
|
||
|
|
"""Resume des contrats pour le dashboard."""
|
||
|
|
contracts = Contract.query.filter_by(status='actif').all()
|
||
|
|
return jsonify({
|
||
|
|
'total': len(contracts),
|
||
|
|
'active': sum(1 for c in contracts if c.is_active),
|
||
|
|
'expiring_soon': sum(1 for c in contracts if c.is_expiring_soon),
|
||
|
|
'must_send_notice': sum(1 for c in contracts if c.must_send_notice_now),
|
||
|
|
'expired': sum(1 for c in contracts if c.end_date and c.end_date < date.today()),
|
||
|
|
})
|