fix(cleaning): rendre les produits disponibles sur fiches papier

This commit is contained in:
root 2026-08-22 15:33:15 +00:00
parent 8d49bfe242
commit c2c050a13e
3 changed files with 33 additions and 2 deletions

View file

@ -57,7 +57,7 @@ def product_new():
elif ProductGeneric.query.filter_by(name=name).first(): elif ProductGeneric.query.filter_by(name=name).first():
flash("Ce produit générique existe déjà.", "warning") flash("Ce produit générique existe déjà.", "warning")
else: else:
product = ProductGeneric(name=name, description=request.form.get("description"), category_id=request.form.get("category_id") or None, product_type=request.form.get("product_type") or "consommable", reference_unit=request.form.get("reference_unit") or "unité", stock_minimum=minimum, stock_security=security, forecast_daily_quantity=daily) product = ProductGeneric(name=name, description=request.form.get("description"), category_id=request.form.get("category_id") or None, product_type=request.form.get("product_type") or "consommable", reference_unit=request.form.get("reference_unit") or "unité", stock_minimum=minimum, stock_security=security, forecast_daily_quantity=daily, request_enabled=request.form.get("request_enabled") == "on")
db.session.add(product); db.session.commit() db.session.add(product); db.session.commit()
flash("Produit générique créé.", "success") flash("Produit générique créé.", "success")
return redirect(url_for("cleaning.products")) return redirect(url_for("cleaning.products"))
@ -84,6 +84,7 @@ def product_edit(id):
product.stock_security = security product.stock_security = security
product.forecast_daily_quantity = daily product.forecast_daily_quantity = daily
product.is_active = request.form.get("is_active") == "on" product.is_active = request.form.get("is_active") == "on"
product.request_enabled = request.form.get("request_enabled") == "on"
db.session.commit() db.session.commit()
flash("Produit générique mis à jour.", "success") flash("Produit générique mis à jour.", "success")
return redirect(url_for("cleaning.products")) return redirect(url_for("cleaning.products"))

View file

@ -1 +1,25 @@
{% extends "base.html" %}{% block title %}Produit générique{% endblock %}{% block content %}<div class="container"><h1>{{ 'Modifier' if product else 'Nouveau' }} produit générique</h1><form method="post"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"><div class="mb-3"><label class="form-label">Nom générique</label><input class="form-control" required name="name" value="{{ product.name if product else '' }}"></div><div class="mb-3"><label class="form-label">Description</label><textarea class="form-control" name="description">{{ product.description if product else '' }}</textarea></div><div class="row"><div class="col-md-4"><label class="form-label">Catégorie</label><select class="form-select" name="category_id"><option value=""></option>{% for c in categories %}<option value="{{ c.id }}" {% if product and product.category_id==c.id %}selected{% endif %}>{{ c.name }}</option>{% endfor %}</select></div><div class="col-md-4"><label class="form-label">Unité de référence</label><input class="form-control" name="reference_unit" value="{{ product.reference_unit if product else 'unité' }}"></div><div class="col-md-4"><label class="form-label">Type</label><select class="form-select" name="product_type"><option>consommable</option><option>liquide</option><option>matériel</option></select></div></div><div class="row mt-3"><div class="col-md-4"><label>Stock minimum</label><input class="form-control" type="number" step="0.000001" name="stock_minimum" value="{{ product.stock_minimum if product else 0 }}"></div><div class="col-md-4"><label>Stock de sécurité</label><input class="form-control" type="number" step="0.000001" name="stock_security" value="{{ product.stock_security if product else 0 }}"></div><div class="col-md-4"><label>Consommation prévue/jour</label><input class="form-control" type="number" step="0.000001" name="forecast_daily_quantity" value="{{ product.forecast_daily_quantity if product else 0 }}"></div></div><button class="btn btn-primary mt-3">Enregistrer</button></form></div>{% endblock %} {% extends "base.html" %}
{% block title %}Produit générique{% endblock %}
{% block content %}
<div class="container">
<h1>{{ 'Modifier' if product else 'Nouveau' }} produit générique</h1>
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-3"><label class="form-label" for="name">Nom générique</label><input id="name" class="form-control" required name="name" value="{{ product.name if product else '' }}"></div>
<div class="mb-3"><label class="form-label" for="description">Description</label><textarea id="description" class="form-control" name="description">{{ product.description if product else '' }}</textarea></div>
<div class="row">
<div class="col-md-4"><label class="form-label" for="category_id">Catégorie</label><select id="category_id" class="form-select" name="category_id"><option value=""></option>{% for c in categories %}<option value="{{ c.id }}" {% if product and product.category_id==c.id %}selected{% endif %}>{{ c.name }}</option>{% endfor %}</select></div>
<div class="col-md-4"><label class="form-label" for="reference_unit">Unité de référence</label><input id="reference_unit" class="form-control" name="reference_unit" value="{{ product.reference_unit if product else 'unité' }}"></div>
<div class="col-md-4"><label class="form-label" for="product_type">Type</label><select id="product_type" class="form-select" name="product_type"><option>consommable</option><option>liquide</option><option>matériel</option></select></div>
</div>
<div class="row mt-3">
<div class="col-md-4"><label for="stock_minimum">Stock minimum</label><input id="stock_minimum" class="form-control" type="number" step="0.000001" name="stock_minimum" value="{{ product.stock_minimum if product else 0 }}"></div>
<div class="col-md-4"><label for="stock_security">Stock de sécurité</label><input id="stock_security" class="form-control" type="number" step="0.000001" name="stock_security" value="{{ product.stock_security if product else 0 }}"></div>
<div class="col-md-4"><label for="forecast_daily_quantity">Consommation prévue/jour</label><input id="forecast_daily_quantity" class="form-control" type="number" step="0.000001" name="forecast_daily_quantity" value="{{ product.forecast_daily_quantity if product else 0 }}"></div>
</div>
<div class="form-check mt-3"><input id="request_enabled" class="form-check-input" type="checkbox" name="request_enabled" {% if not product or product.request_enabled %}checked{% endif %}><label class="form-check-label" for="request_enabled">Proposer sur les fiches papier de demande</label></div>
{% if product %}<div class="form-check mt-2"><input id="is_active" class="form-check-input" type="checkbox" name="is_active" {% if product.is_active %}checked{% endif %}><label class="form-check-label" for="is_active">Produit actif</label></div>{% endif %}
<button class="btn btn-primary mt-3">Enregistrer</button>
</form>
</div>
{% endblock %}

View file

@ -163,6 +163,12 @@ def test_invalid_product_quantity_is_validation_error(authenticated_client, app)
assert "numériques" in response.get_data(as_text=True) assert "numériques" in response.get_data(as_text=True)
def test_product_request_enabled_is_editable(authenticated_client, app):
response = authenticated_client.get('/cleaning/products/new')
assert response.status_code == 200
assert 'request_enabled' in response.get_data(as_text=True)
def test_cleaning_pages_load_without_reference_data(authenticated_client, app): def test_cleaning_pages_load_without_reference_data(authenticated_client, app):
# Some legacy RBAC tests intentionally alter the admin role. Restore only # Some legacy RBAC tests intentionally alter the admin role. Restore only
# the permission required by this independent route smoke test. # the permission required by this independent route smoke test.