Files
3d-pricing/GUIDE.md
T

9.4 KiB
Raw Blame History

Guide — 3D Pricing App

Application web Flask/SQLite de gestion du pricing et de la planification pour un atelier d'impression 3D.


Architecture technique

Flask (Python)  ──►  SQLite (WAL mode)
     │
     ├── Templates Jinja2 (Bootstrap 5 + vis.js)
     ├── Thread arrière-plan : sync Home Assistant
     └── Docker : /data/pricing.db (persistant)

Stack :

  • Python 3.12 + Flask
  • SQLite avec WAL (pas de blocage lecture/écriture simultanée)
  • Bootstrap 5 + Bootstrap Icons
  • vis.js Timeline (Gantt planning)
  • Authelia OIDC (optionnel, activé via variables d'env)
  • Home Assistant REST API (optionnel)
  • Nextcloud WebDAV (optionnel)

Schéma de base de données

Table Rôle
settings Clés/valeurs de configuration globale
clients Clients avec profils par défaut
projects Projets regroupant plusieurs commandes
jobs Commandes / calculs de prix (1 plateau = 1 job)
materials Filaments avec stock et historique de prix
material_price_history Historique des changements de prix filament
machine_profiles Profils machine (usure, électricité)
handling_profiles Profils manutention (taux horaire, minutes/plateau)
material_profiles Profils marge matière
pricing_profiles Profils multiplicateur design + marge brute
printers Imprimantes physiques avec préfixe HA
print_slots Créneaux d'impression planifiés
working_schedule Planning hebdomadaire (TT / sur site / off)
calendar_blocks Indisponibilités ponctuelles (plage de dates)

Moteur de calcul (calc())

Tout se calcule par pièce à partir des données du plateau Bambu.

Coût fixe = matière + marge_matière + usure_machine + électricité
                                         (divisé par pièces/plateau)

Sous-total = coût_fixe + manutention + design

Marge brute = sous-total × gross_margin_pct / 100

Total marge = manutention + design + marge_brute

Prix HT = coût_fixe + total_marge

Prix HT net = prix_ht / (1 - cotisations - VFL - autres_taxes)
  └─ les charges fiscales sont "self-contained" dans le prix

Prix TTC = prix_ht_net × (1 + TVA)

Prix final = prix_ttc × (1 - remise)

Multiplicateur design : coefficient appliqué au coût matière pour valoriser le temps de modélisation. ×0.8 = design simple, ×1.8 = design complexe.


Pages et fonctionnalités

Dashboard (/)

Vue d'ensemble : 10 dernières commandes, CA total, CA du mois, alertes stock bas.

Commandes (/jobs)

Liste de toutes les commandes avec réf. plateau, poids, durée, marge, remise, prix final.

  • Nouveau job : saisie manuelle ou import .gcode.3mf depuis Nextcloud
  • Import Bambu : parse slice_info.config → détecte les plateaux, poids, durée, filaments
  • Duplication (?clone_from=ID) : copie les paramètres + re-parse automatiquement le fichier Nextcloud si source_nc_path est renseigné
  • Export CSV : toutes les commandes en CSV

Détail commande (/jobs/<id>)

  • Décomposition du prix (coût fixe, variable, fiscal)
  • Section Plateaux d'impression : liste des slots avec statut, pièces, avancement HA
  • Portail client : génération d'un lien de partage tokenisé

Projets (/projects)

Regroupe plusieurs commandes sous un même projet client. Affiche total pièces et CA.

Clients (/clients)

Clients avec profils par défaut (machine, manutention, matière, tarif). Ces profils se chargent automatiquement à la création d'un job pour ce client.

Matières (/materials)

  • Stock en grammes avec alerte seuil bas
  • Historique des prix
  • Déduction automatique du stock à la création d'un job
  • Suivi du gaspillage (impressions ratées)

Profils (/profiles)

4 types de profils réutilisables :

  • Machine : prix imprimante, durée de vie, nozzle, plateau, puissance, électricité
  • Manutention : taux horaire, minutes par plateau
  • Matière : marge matière en %
  • Tarif : multiplicateur design + marge brute

Planning (/planning)

Gantt vis.js sur 14 jours (démarre 12h avant maintenant pour voir les impressions en cours).

  • Gantt : slots par imprimante, codes couleur par statut, bandes rouges si capacité saturée
  • À planifier : jobs dont tous les plateaux ne sont pas encore planifiés
  • Overlay HA live : rafraîchissement automatique (intervalle configurable) des statuts depuis Home Assistant
  • Badges compensation : si HA signale des pièces ignorées sur un plateau, les autres plateaux du même job proposent d'augmenter leur quantité

Planifier un slot :

  1. Cliquer sur un job "À planifier"
  2. Choisir imprimante + date/heure de lancement
  3. Option "Déjà imprimé" pour enregistrer rétroactivement sans vérification de capacité

Statuts des slots :

Statut Couleur Signification
planned bleu Planifié, pas encore lancé
running orange En cours (mis à jour par HA sync)
done vert Terminé
failed rouge Raté (gaspillage logué)
cancelled gris Annulé

Imprimantes (/printers)

  • Activer/désactiver des imprimantes
  • Configurer le préfixe HA (a1_1 → surveille sensor.a1_1_etat_de_l_impression)
  • Modifier nom, préfixe HA, notes

Planning horaire (/working-schedule)

Configuré par jour de la semaine :

  • TT (télétravail) : fenêtre horaire avec nb de lancements calculé automatiquement
  • Onsite : 2 créneaux fixes (ex: 07h00 + 18h30)
  • Off : aucun lancement possible

Indisponibilités (/calendar-blocks)

Bloquer une période (date début → date fin optionnelle) pour une ou toutes les imprimantes. Types : Off / Télétravail / Sur site / Maintenance machine.

Page mobile (/mobile)

Interface simplifiée pour saisie rapide sur smartphone :

  • Ajouter une indisponibilité
  • Décaler un créneau
  • Marquer une impression comme ratée ou terminée

Statistiques (/stats)

CA par période, matières les plus utilisées, gaspillage, top clients.

Paramètres (/settings)

  • Taux fiscaux (cotisations, VFL, TVA, autres taxes)
  • Paramètres machine par défaut
  • Configuration Nextcloud (URL, user, mot de passe d'app, dossier racine)
  • Configuration Home Assistant (URL, token, intervalle de sync)
  • Nombre max d'imprimantes simultanées
  • Cooldown entre impressions (minutes)

Home Assistant Sync

Le thread HA tourne en arrière-plan et poll toutes les N secondes (configurable, défaut 60s).

Entités surveillées (par imprimante avec préfixe {prefix}) :

  • sensor.{prefix}_etat_de_l_impressionrunning / finish / unknown
  • binary_sensor.{prefix}_erreur_d_impressionon / off
  • sensor.{prefix}_objets_ignores → nombre de pièces ignorées (compensation multi-plateau)
  • sensor.{prefix}_avancement_de_l_impression → % d'avancement

Logique de sync :

  1. Cherche un slot planned ou running qui chevauche la fenêtre actuelle (±30 min)
  2. running → passe le slot à running
  3. finish → passe le slot à done
  4. binary_sensor erreur = on → passe le slot à failed
  5. objets_ignores > 0 → met à jour pieces_ignored sur le slot

Important : le sync utilise des connexions courtes par imprimante (autocommit) pour ne pas bloquer les requêtes Flask.


Nextcloud

Utilisé comme bibliothèque de fichiers .gcode.3mf.

  • Navigation WebDAV via le picker modal dans "Nouveau job"
  • Téléchargement + parsing du .3mf côté serveur (/api/nextcloud/parse)
  • Chemin stocké dans source_nc_path pour permettre la duplication sans re-sélection

Portail client

Chaque commande peut générer un lien tokenisé (/portal/<token>) donnant accès à :

  • Décomposition du prix en lecture seule
  • Sans authentification requise

Variables d'environnement (Docker)

Variable Défaut Rôle
SECRET_KEY généré aléatoirement Clé session Flask
DATABASE_PATH /data/pricing.db Chemin SQLite
OIDC_CLIENT_ID Active l'auth OIDC si défini
OIDC_CLIENT_SECRET Secret OIDC
OIDC_DISCOVERY_URL URL metadata OIDC (Authelia)
OIDC_END_SESSION_URL URL déconnexion OIDC

Calendrier iCal (/calendar.ics)

Export iCal des créneaux planifiés. Protégé par token (ical_token dans settings). URL : http://host/calendar.ics?token=<ical_token>


API JSON principales

Endpoint Méthode Rôle
/api/calculate POST Calcul de prix live (formulaire new_job)
/api/slots GET Liste des slots pour le Gantt (7 derniers jours → +)
/api/slots/new POST Créer un slot planifié
/api/slots/<id>/move POST Déplacer un slot
/api/slots/<id>/fail POST Marquer comme raté
/api/slots/<id>/done POST Marquer comme terminé
/api/slots/<id>/status POST Changer le statut
/api/slots/<id>/pieces_override POST Override nb pièces (compensation)
/api/suggest-slot POST Suggérer le prochain créneau libre
/api/capacity POST Calculer la capacité de production
/api/ha/status GET Statuts HA de toutes les imprimantes
/api/parse-3mf POST Parser un fichier .3mf uploadé
/api/nextcloud/browse GET Lister un dossier Nextcloud
/api/nextcloud/parse GET Fetch + parser un .3mf Nextcloud
/api/nextcloud/file GET Proxy téléchargement fichier Nextcloud
/api/client/<id>/defaults GET Profils par défaut d'un client