Files
3d-pricing/GUIDE.md
T

249 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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_impression``running` / `finish` / `unknown`
- `binary_sensor.{prefix}_erreur_d_impression``on` / `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 |