diff --git a/app_new/equipments/main.py b/app_new/equipments/main.py index e8c5539..3ce9ccd 100644 --- a/app_new/equipments/main.py +++ b/app_new/equipments/main.py @@ -51,7 +51,41 @@ def index(): status = request.args.get('status', '') category_id = request.args.get('category', type=int) building_id = request.args.get('building', type=int) - + view = request.args.get('view', 'families') + + if view == 'zones': + # Vue inventaire : une ligne par type et par salle, avec quantités + # agrégées. Les groupes parents sans salle sont ignorés afin de ne + # pas compter deux fois leurs groupes localisés. + grouped = {} + rows = Equipment.query.filter_by(is_deleted=False).all() + for eq in rows: + room = eq.room + if not room or (eq.is_group and eq.children.count()): + continue + if search and search.lower() not in (eq.name or '').lower(): + continue + if category_id and eq.effective_category_id != category_id: + continue + if building_id and room.building_id != building_id: + continue + if status and eq.status != status: + continue + building = room.building + zone = room.zone + b = grouped.setdefault(building.id, {'name': building.name, 'zones': {}}) + z = b['zones'].setdefault(zone.id if zone else 0, {'name': zone.name if zone else 'Sans zone', 'rooms': {}}) + r = z['rooms'].setdefault(room.id, {'name': room.name, 'types': {}}) + key = eq.effective_category_id or f'name:{eq.name.lower().split(" #")[0]}' + display_name = eq.category.name if eq.category else eq.name.split(' #')[0] + item = r['types'].setdefault(key, {'name': display_name, 'category': eq.category.name if eq.category else '—', 'quantity': 0, 'ids': []}) + item['quantity'] += eq.quantity or 1 + item['ids'].append(eq.id) + zone_tree = [{'id': bid, 'name': b['name'], 'zones': [{'id': zid, 'name': z['name'], 'rooms': [{'id': rid, 'name': r['name'], 'types': list(r['types'].values())} for rid, r in z['rooms'].items()]} for zid, z in b['zones'].items()]} for bid, b in grouped.items()] + categories = EquipmentCategory.query.order_by(EquipmentCategory.name).all() + buildings = Building.query.order_by(Building.name).all() + return render_template('equipments/index.html', zone_tree=zone_tree, view=view, categories=categories, buildings=buildings, statuses=EQUIPMENT_STATUSES, filters={'search': search, 'status': status, 'category': category_id, 'building': building_id}) + # Pagination (page courante, 20 parents par page) page = request.args.get('page', 1, type=int) per_page = 20 @@ -95,7 +129,7 @@ def index(): categories=categories, buildings=buildings, statuses=EQUIPMENT_STATUSES, - filters={'search': search, 'status': status, 'category': category_id, 'building': building_id}) + filters={'search': search, 'status': status, 'category': category_id, 'building': building_id}, view=view) @main_bp.route('//hierarchy') diff --git a/app_new/equipments/templates/index.html b/app_new/equipments/templates/index.html index cdcf4b3..316889f 100644 --- a/app_new/equipments/templates/index.html +++ b/app_new/equipments/templates/index.html @@ -7,8 +7,22 @@ Nouvel+ +
+ Par familles + Par zones et salles +
+{% if view == 'zones' %} +
Les quantités sont regroupées par zone, salle et type d’équipement. Les groupes parents sont exclus pour éviter les doublons.
+{% for building in zone_tree %} +
{{ building.name }}
+{% for zone in building.zones %}
{{ zone.name }}
+{% for room in zone.rooms %}
{{ room.name }}
{% for item in room.types %}{% endfor %}
{{ item.name }}{{ item.category }}{{ item.quantity }}
{% endfor %} +
{% endfor %}
+{% else %}
Aucun équipement localisé ne correspond aux filtres.
{% endfor %} +{% else %} +
@@ -135,4 +149,5 @@

Aucun équipement

{% endif %} -{% endblock %} \ No newline at end of file +{% endif %} +{% endblock %}