forked from seb_vallee/BillManager
187 lines
5.8 KiB
Python
187 lines
5.8 KiB
Python
import json
|
|
from datetime import date, timedelta
|
|
from fastapi import APIRouter, Depends, Request, Form, HTTPException
|
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlalchemy.orm import Session
|
|
|
|
from database import get_db
|
|
from models import Devis, LigneDevis, Client, StatutDevis
|
|
from numerotation import generer_numero_devis
|
|
from auth import get_current_user
|
|
from template_helper import render
|
|
|
|
router = APIRouter(prefix="/devis", tags=["devis"], dependencies=[Depends(get_current_user)])
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
@router.get("/", response_class=HTMLResponse)
|
|
def liste_devis(request: Request, db: Session = Depends(get_db)):
|
|
devis = db.query(Devis).order_by(Devis.date_emission.desc()).all()
|
|
return render(templates, "devis/liste.html", request, {
|
|
"devis": devis
|
|
})
|
|
|
|
|
|
@router.get("/nouveau", response_class=HTMLResponse)
|
|
def nouveau_devis_form(request: Request, db: Session = Depends(get_db)):
|
|
clients = db.query(Client).filter(Client.actif == True).order_by(Client.nom).all()
|
|
return render(templates, "devis/form.html", request, {
|
|
"devis": None,
|
|
"clients": clients,
|
|
"titre": "Nouveau devis",
|
|
"date_aujourd_hui": date.today().isoformat(),
|
|
"date_validite_defaut": (date.today() + timedelta(days=30)).isoformat(),
|
|
})
|
|
|
|
|
|
@router.post("/nouveau")
|
|
def creer_devis(
|
|
request: Request,
|
|
client_id: int = Form(...),
|
|
date_emission: str = Form(...),
|
|
date_validite: str = Form(...),
|
|
notes: str = Form(""),
|
|
conditions: str = Form(""),
|
|
lignes_json: str = Form(...),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
numero = generer_numero_devis(db)
|
|
devis = Devis(
|
|
numero=numero,
|
|
client_id=client_id,
|
|
date_emission=date.fromisoformat(date_emission),
|
|
date_validite=date.fromisoformat(date_validite),
|
|
notes=notes,
|
|
conditions=conditions,
|
|
)
|
|
db.add(devis)
|
|
db.flush()
|
|
|
|
lignes = json.loads(lignes_json)
|
|
for i, l in enumerate(lignes):
|
|
ligne = LigneDevis(
|
|
devis_id=devis.id,
|
|
description=l["description"],
|
|
quantite=float(l["quantite"]),
|
|
prix_unitaire_ht=float(l["prix_unitaire_ht"]),
|
|
ordre=i
|
|
)
|
|
db.add(ligne)
|
|
|
|
db.commit()
|
|
return RedirectResponse(f"/devis/{devis.id}", status_code=303)
|
|
|
|
|
|
@router.get("/{devis_id}", response_class=HTMLResponse)
|
|
def voir_devis(request: Request, devis_id: int, db: Session = Depends(get_db)):
|
|
devis = db.query(Devis).get(devis_id)
|
|
if not devis:
|
|
raise HTTPException(status_code=404)
|
|
return render(templates, "devis/detail.html", request, {
|
|
"devis": devis, "StatutDevis": StatutDevis
|
|
})
|
|
|
|
|
|
@router.get("/{devis_id}/modifier", response_class=HTMLResponse)
|
|
def modifier_devis_form(request: Request, devis_id: int, db: Session = Depends(get_db)):
|
|
devis = db.query(Devis).get(devis_id)
|
|
if not devis:
|
|
raise HTTPException(status_code=404)
|
|
clients = db.query(Client).filter(Client.actif == True).order_by(Client.nom).all()
|
|
return render(templates, "devis/form.html", request, {
|
|
"devis": devis,
|
|
"clients": clients,
|
|
"titre": "Modifier le devis",
|
|
"date_aujourd_hui": date.today().isoformat(),
|
|
"date_validite_defaut": devis.date_validite.isoformat(),
|
|
})
|
|
|
|
|
|
@router.post("/{devis_id}/modifier")
|
|
def modifier_devis(
|
|
devis_id: int,
|
|
client_id: int = Form(...),
|
|
date_emission: str = Form(...),
|
|
date_validite: str = Form(...),
|
|
notes: str = Form(""),
|
|
conditions: str = Form(""),
|
|
lignes_json: str = Form(...),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
devis = db.query(Devis).get(devis_id)
|
|
if not devis:
|
|
raise HTTPException(status_code=404)
|
|
devis.client_id = client_id
|
|
devis.date_emission = date.fromisoformat(date_emission)
|
|
devis.date_validite = date.fromisoformat(date_validite)
|
|
devis.notes = notes
|
|
devis.conditions = conditions
|
|
|
|
for ligne in devis.lignes:
|
|
db.delete(ligne)
|
|
db.flush()
|
|
|
|
lignes = json.loads(lignes_json)
|
|
for i, l in enumerate(lignes):
|
|
ligne = LigneDevis(
|
|
devis_id=devis.id,
|
|
description=l["description"],
|
|
quantite=float(l["quantite"]),
|
|
prix_unitaire_ht=float(l["prix_unitaire_ht"]),
|
|
ordre=i
|
|
)
|
|
db.add(ligne)
|
|
|
|
db.commit()
|
|
return RedirectResponse(f"/devis/{devis_id}", status_code=303)
|
|
|
|
|
|
@router.post("/{devis_id}/statut")
|
|
def changer_statut_devis(
|
|
devis_id: int,
|
|
statut: str = Form(...),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
devis = db.query(Devis).get(devis_id)
|
|
if not devis:
|
|
raise HTTPException(status_code=404)
|
|
devis.statut = StatutDevis(statut)
|
|
db.commit()
|
|
return RedirectResponse(f"/devis/{devis_id}", status_code=303)
|
|
|
|
|
|
@router.post("/{devis_id}/convertir")
|
|
def convertir_en_facture(devis_id: int, db: Session = Depends(get_db)):
|
|
from models import Facture, LigneFacture
|
|
from numerotation import generer_numero_facture
|
|
devis = db.query(Devis).get(devis_id)
|
|
if not devis:
|
|
raise HTTPException(status_code=404)
|
|
|
|
numero = generer_numero_facture(db)
|
|
facture = Facture(
|
|
numero=numero,
|
|
client_id=devis.client_id,
|
|
devis_id=devis.id,
|
|
date_emission=date.today(),
|
|
date_echeance=date.today() + timedelta(days=30),
|
|
notes=devis.notes,
|
|
)
|
|
db.add(facture)
|
|
db.flush()
|
|
|
|
for i, l in enumerate(devis.lignes):
|
|
ligne = LigneFacture(
|
|
facture_id=facture.id,
|
|
description=l.description,
|
|
quantite=l.quantite,
|
|
prix_unitaire_ht=l.prix_unitaire_ht,
|
|
ordre=i
|
|
)
|
|
db.add(ligne)
|
|
|
|
devis.statut = StatutDevis.accepte
|
|
db.commit()
|
|
return RedirectResponse(f"/factures/{facture.id}", status_code=303)
|