import csv from datetime import date from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.shortcuts import render, get_object_or_404 from .models import Entreprise from . import services MOIS = services.MOIS_FR def _entreprise(request): """Entreprise courante, restreinte à celles accessibles par l'utilisateur.""" accessibles = Entreprise.accessibles(request.user) eid = request.GET.get("entreprise") if eid: return get_object_or_404(accessibles, pk=eid) return accessibles.first() def _annee(request): return int(request.GET.get("annee", date.today().year)) TRIMESTRES = [(1, "T1 (janv.–mars)", [1, 2, 3]), (2, "T2 (avr.–juin)", [4, 5, 6]), (3, "T3 (juil.–sept.)", [7, 8, 9]), (4, "T4 (oct.–déc.)", [10, 11, 12])] def _periode(request, entreprise, champ): """Retourne (mois_filtre, periode_sel, label, options, type) selon la périodicité (mensuelle/trimestrielle) configurée sur l'entreprise.""" if getattr(entreprise, champ, "mensuelle") == "trimestrielle": defaut = (date.today().month - 1) // 3 + 1 sel = min(max(int(request.GET.get("periode", defaut)), 1), 4) _, label, mois = TRIMESTRES[sel - 1] return mois, sel, label, [(i, lab) for i, lab, _ in TRIMESTRES], "trimestre" defaut = date.today().month sel = min(max(int(request.GET.get("periode", request.GET.get("mois", defaut))), 1), 12) return sel, sel, MOIS[sel - 1], [(i, MOIS[i - 1]) for i in range(1, 13)], "mois" def _base_ctx(request, entreprise, annee, vue): return { "entreprise": entreprise, "entreprises": Entreprise.accessibles(request.user), "annee": annee, "annees": services.annees_disponibles(entreprise) or [annee], "vue": vue, "mois_liste": list(enumerate(MOIS, start=1)), } @login_required def dashboard(request): entreprise = _entreprise(request) if entreprise is None: return render(request, "compta/dashboard.html", {"entreprise": None}) annee = _annee(request) ctx = services.synthese(entreprise, annee) ctx.update(_base_ctx(request, entreprise, annee, "global")) ctx.update({ "mois_labels": ["Jan", "Fév", "Mar", "Avr", "Mai", "Juin", "Juil", "Août", "Sep", "Oct", "Nov", "Déc"], "ca_mensuel_json": [float(v) for v in ctx["ca_mensuel"]], }) return render(request, "compta/dashboard.html", ctx) @login_required def vue_mensuelle(request): entreprise = _entreprise(request) if entreprise is None: return render(request, "compta/mensuel.html", {"entreprise": None}) annee = _annee(request) ctx = _base_ctx(request, entreprise, annee, "mensuel") ctx["rows"] = services.tableau_mensuel(entreprise, annee) return render(request, "compta/mensuel.html", ctx) @login_required def declaration_urssaf(request): entreprise = _entreprise(request) if entreprise is None: return render(request, "compta/decl_urssaf.html", {"entreprise": None}) annee = _annee(request) mois, periode_sel, label, options, ptype = _periode(request, entreprise, "periodicite_urssaf") ctx = _base_ctx(request, entreprise, annee, "urssaf") ctx.update({"periode_sel": periode_sel, "periode_options": options, "periode_type": ptype}) ctx["decl"] = services.declaration_urssaf(entreprise, annee, mois, label) return render(request, "compta/decl_urssaf.html", ctx) @login_required def declaration_tva(request): entreprise = _entreprise(request) if entreprise is None: return render(request, "compta/decl_tva.html", {"entreprise": None}) annee = _annee(request) mois, periode_sel, label, options, ptype = _periode(request, entreprise, "periodicite_tva") mode = request.GET.get("mode") or entreprise.vue_tva ctx = _base_ctx(request, entreprise, annee, "tva") ctx.update({"periode_sel": periode_sel, "periode_options": options, "periode_type": ptype, "mode": mode}) ctx["decl"] = services.declaration_tva(entreprise, annee, mois, label) return render(request, "compta/decl_tva.html", ctx) # ---- Exports CSV -------------------------------------------------------- def _csv(filename): resp = HttpResponse(content_type="text/csv; charset=utf-8") resp["Content-Disposition"] = f'attachment; filename="{filename}"' resp.write("") return resp @login_required def export_ventes(request): entreprise = _entreprise(request) annee = _annee(request) resp = _csv(f"ventes_{annee}.csv") w = csv.writer(resp, delimiter=";") w.writerow(["Numero", "Client", "Activite", "Date emission", "Date encaissement", "Statut", "HT", "TVA", "TTC"]) for f in services.factures_encaissees(entreprise, annee).select_related("client"): w.writerow([f.numero, f.client.nom, f.get_activite_display(), f.date_emission, f.date_encaissement, f.get_statut_display(), f.montant_ht, f.montant_tva, f.montant_ttc]) return resp @login_required def export_tva(request): entreprise = _entreprise(request) annee = _annee(request) s = services.synthese(entreprise, annee) resp = _csv(f"tva_{annee}.csv") w = csv.writer(resp, delimiter=";") w.writerow(["Annee", "TVA sur ventes", "TVA autoliquidee", "TVA collectee", "TVA deductible", "TVA a reverser"]) w.writerow([annee, s["tva_sur_ventes"], s["tva_autoliquidee"], s["tva_collectee"], s["tva_deductible"], s["tva_a_reverser"]]) return resp @login_required def export_urssaf(request): entreprise = _entreprise(request) annee = _annee(request) s = services.synthese(entreprise, annee) resp = _csv(f"urssaf_{annee}.csv") w = csv.writer(resp, delimiter=";") w.writerow(["Annee", "Activite", "CA HT", "Taux URSSAF", "Cotisations", "Taux VL", "Versement liberatoire", "Abattement", "Revenu imposable"]) for l in s["lignes_activite"]: w.writerow([annee, l["label"], l["ca_ht"], l["taux_urssaf"], l["cotisations"], l["taux_vl"], l["versement_liberatoire"], l["abattement_fiscal"], l["revenu_imposable"]]) w.writerow([annee, "TOTAL", s["ca_ht"], "", s["cotisations_urssaf"], "", s["versement_liberatoire"], "", s["revenu_imposable"]]) return resp