Code refactofing, PDF export bug fix, remove unused view function

This commit is contained in:
Gregory Trullemans 2022-04-29 09:09:17 +02:00
parent 049651709f
commit af1b5826b6
14 changed files with 85 additions and 236 deletions

View File

@ -38,15 +38,7 @@ class ClientForm(forms.ModelForm):
class ContractForm(forms.ModelForm):
class Meta:
model = Contract
fields = (
"title",
"client",
"advance",
"reference",
"is_finished",
"is_paid",
"description"
)
fields = ("title", "client", "advance", "reference", "is_finished", "is_paid", "description")
widgets = {
"title": forms.TextInput(
attrs={"class": "form-control", "placeholder": "Titre de la facture"}
@ -79,7 +71,11 @@ class PrestationForm(forms.ModelForm):
model = Prestation
fields = ("contract", "date", "label", "unit", "unit_price")
widgets = {
"contract": forms.HiddenInput(),
"contract": ModelSelect2Widget(
search_fields=["contract__icontains",],
max_results=10,
attrs={"data-minimum-input-length": 0, "class": "form-control"},
),
"date": forms.DateInput(
attrs={
"class": "form-control datepicker",
@ -95,14 +91,4 @@ class PrestationForm(forms.ModelForm):
"unit_price": forms.TextInput(
attrs={"class": "form-control", }
)
}
contract_related = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"placeholder": "Recherche contract",
"data-ref": "#id_client",
}
)
)
}

View File

@ -23,7 +23,7 @@ class Contract(models.Model):
verbose_name = "Contrat"
verbose_name_plural = "Contrats"
title = models.CharField(max_length=255, verbose_name="Nom")
title = models.CharField(max_length=255, verbose_name="Titre")
client = models.ForeignKey(
Client, related_name="contracts", on_delete=models.CASCADE
)
@ -39,7 +39,7 @@ class Contract(models.Model):
description = models.TextField(verbose_name="Description", blank=True, null=True)
def __str__(self):
return "%s" % self.name
return "%s" % self.title
def __generate_reference(self):
""" Génère automatiquement la référence du contract """

View File

@ -10,7 +10,6 @@ from .views import (
contract_detail,
contract_create_or_update,
contract_export,
prestation_listing,
prestation_create_or_update,
)
@ -34,7 +33,6 @@ contract_urlpatterns = [
]
prestation_urlpatterns = [
path(r"", prestation_listing, name="prestation_listing"),
path(r"create/", prestation_create_or_update, name="prestation_create"),
path(r"update/<int:prestation_id>/", prestation_create_or_update, name="prestation_update"),
]

View File

@ -42,6 +42,7 @@ def client_lookup(request):
return HttpResponse(json, content_type="application/json")
@require_http_methods(["GET"])
def client_listing(request):
""" Récupère la liste de tous les clients. """
client_list = Client.objects.all()
@ -49,6 +50,7 @@ def client_listing(request):
return render(request, "billing/clients/listing.html", context)
@require_http_methods(["GET"])
def client_details(request, client_id=None):
""" Récupère les informations d'un client.
@ -88,6 +90,7 @@ def client_create_or_update(request, client_id=None):
return render(request, "billing/clients/create.html", context)
@require_http_methods(["GET"])
def contract_listing(request):
""" Récupère la liste de tous les contrats. """
contract_list = Contract.objects.all()
@ -95,6 +98,7 @@ def contract_listing(request):
return render(request, "billing/contracts/listing.html", context)
@require_http_methods(["GET"])
def contract_detail(request, contract_id):
"""
Récupère toutes les informations relatives à un contrat et les prestations relatives à
@ -147,6 +151,7 @@ def contract_create_or_update(request, contract_id=None):
return render(request, "billing/contracts/create.html", context)
@require_http_methods(["GET"])
def contract_export(request, contract_id):
""" Génere un fichier PDF pour fournir au client.
@ -168,13 +173,6 @@ def contract_export(request, contract_id):
return response
def prestation_listing(request):
""" Récupère la liste de toutes les prestations. """
prestation_list = Prestation.objects.all()
context = {"prestation_list": prestation_list}
return render(request, "prestation_listing.html", context)
@require_http_methods(["GET", "POST"])
def prestation_create_or_update(request, prestation_id=None):
""" Création d'un contract.
@ -193,13 +191,15 @@ def prestation_create_or_update(request, prestation_id=None):
if form.is_valid():
prestation = form.save()
return HttpResponseRedirect(reverse("prestation/details", args=(prestation.pk, )))
return HttpResponseRedirect(reverse("contract_detail", args=(prestation.contract.id, )))
else:
print(form.errors)
else:
form = PrestationForm(instance=prestation)
context = {"form": form, "prestation_id": prestation_id}
return render(request, "billing/prestation/create.html", context)
return render(request, "billing/prestations/create.html", context)
@require_http_methods(["GET"])

Binary file not shown.

View File

@ -46,7 +46,7 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Facturation <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/billing/client/">Liste clients</a></li>
<li><a href="/billing/contract/">Liste factures</a></li>
<li><a href="/billing/contract/">Liste contracts</a></li>
</ul>
</li>
<li><a href="/admin/" target="_blank">Administration</a></li>

View File

@ -7,46 +7,48 @@
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>{% if client_id %}Modification{% else %}Ajout{% endif %} Client</h1>
<h1>{% if client_id %}Modification{% else %}Ajout{% endif %} d'un client</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-lg-6 col-xl-6 col-md-offset-3 col-lg-offset-3 col-xl-offset-3">
<form action="{% if client_id %}{% url 'client_update' client_id %}{% else %}{% url 'client_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Nom</label>
<div class="col-8 col-sm-6 col-md-4 col-lg-4 col-xl-4 {% if form.name.errors %}has-danger{% endif %}">
{{ form.name }}
{% if form.name.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.name.errors %}{{error}}{% endfor %}</span>{% endif %}
<div class="well well-small text-right">
<form action="{% if client_id %}{% url 'client_update' client_id %}{% else %}{% url 'client_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 control-label">Nom</label>
<div class="col-12 col-sm-10 col-md-8 col-lg-8 col-xl-8 {% if form.name.errors %}has-danger{% endif %}">
{{ form.name }}
{% if form.name.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.name.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
</div>
<div class="form-group row ">
<label for="id_gymnast" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Adresse</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.address.errors %}has-danger{% endif %}">
{{ form.address }}<br>
{{ form.postal_code }} {{ form.city }}
{% if form.address.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.address.errors %}{{error}}{% endfor %}</span>{% endif %}
<div class="form-group row ">
<label for="id_gymnast" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 control-label">Adresse</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.address.errors %}has-danger{% endif %}">
{{ form.address }}<br>
{{ form.postal_code }} {{ form.city }}
{% if form.address.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.address.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
</div>
<div class="form-group row ">
<label for="id_skill" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">contact</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.contact.errors %}has-danger{% endif %}">
{{ form.contact }}
{% if form.contact.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.contact.errors %}{{error}}{% endfor %}</span>{% endif %}
<div class="form-group row ">
<label for="id_skill" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 control-label">contact</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.contact.errors %}has-danger{% endif %}">
{{ form.contact }}
{% if form.contact.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.contact.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">N° BCE</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.company_number.errors %}has-danger{% endif %}">
{{ form.company_number }}
{% if form.company_number.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.company_number.errors %}{{error}}{% endfor %}</span>{% endif %}
<div class="form-group row ">
<label for="id_information" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 control-label">N° BCE</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.company_number.errors %}has-danger{% endif %}">
{{ form.company_number }}
{% if form.company_number.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.company_number.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Ajouter{% endif %}" class="btn btn-primary" />
</div>
</form>
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Ajouter{% endif %}" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -12,28 +12,30 @@
<div id="content">
<div class="row">
<div class="col-md-12 col-lg-12">
<h1>{% if contract_id %}Modification{% else %}Nouvelle{% endif %} facture</h1>
<h1>{% if contract_id %}Modification{% else %}Nouveau{% endif %} contract</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-l-6 col-xl-6 col-md-offset-3 col-l-offset-3 col-xl-offset-3">
<form action="{% if contract_id %}{% url 'contract_update' contract_id %}{% else %}{% url 'contract_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="well well-small text-right">
<form action="{% if contract_id %}{% url 'contract_update' contract_id %}{% else %}{% url 'contract_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id }}" class="col-lg-2 control-label">{{ field.label_tag }}</label>
<div class="col-lg-8">
{{ field }}
{% if field.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in field.errors %}{{error}}{% endfor %}</span>{% endif %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id }}" class="col-lg-2 control-label">{{ field.label_tag }}</label>
<div class="col-lg-8">
{{ field }}
{% if field.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in field.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Modifier{% endif %}" class="btn btn-warning" />
</div>
</form>
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Modifier{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -9,7 +9,7 @@
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>{{ contract.name }} <small>({{ prestation_count }} prestations{% if not contract.is_paid%} <b><u>non payées</u></b>{% endif %})</small></h1>
<h1>{{ contract.title }} <small>({{ prestation_count }} prestations{% if not contract.is_paid%} <b><u>non payées</u></b>{% endif %})</small></h1>
</div>
</div>
<div class="row">
@ -25,7 +25,7 @@
{% for prestation in prestation_list %}
<tr>
<td>{{ prestation.date|date:"d-m-Y" }}</td>
<td>{{ prestation.label }}</td>
<td><a href="{% url 'prestation_update' prestation.id %}">{{ prestation.label }}</a></td>
<td class="push-right">{{ prestation.unit }}</td>
<td class="push-right">{{ prestation.unit_price }}</td>
<td class="push-right">{{ prestation.total_amount }}</td>

View File

@ -8,7 +8,7 @@
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>Liste des factures</h1>
<h1>Liste des contracts</h1>
</div>
</div>
<div class="row">
@ -34,7 +34,7 @@
{% endfor %}
</table>
<p class="text-right">
<a class="btn btn-primary" href="{% url 'contract_create' %}">Nouvelle facture</a>
<a class="btn btn-primary" href="{% url 'contract_create' %}">Nouveau contract</a>
</p>
</div>
</div>

View File

@ -1,98 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div id="page" class=" sidebar_right">
<div class="container">
<div id="frame2">
<div id="content">
<div class="row">
<div class="col-md-12 col-lg-12">
<h1>{% if prestation_id %}Modification{% else %}Nouvelle{% endif %} Prestation</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-l-6 col-xl-6 col-md-offset-3 col-l-offset-3 col-xl-offset-3">
<form action="{% if prestation_id %}{% url 'prestation_update' prestation_id %}{% else %}{% url 'prestation_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_contract" class="col-sm-4 col-md-4 col-lg-3 col-xl-2 col-form-label">{{ form.contract.label }}</label>
<div class="col-sm-6 col-md-6 col-lg-6 col-xl-6 {% if form.gymnast.errors %}has-danger{% endif %}">
{{ form.contract }}
{{ form.contract_related }}
{% if form.contract.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.contract.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-sm-4 col-md-4 col-lg-3 col-xl-2 col-form-label">{{ form.date.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_label" class="col-sm-4 col-md-4 col-lg-3 col-xl-2 col-form-label">{{ form.label.label }}</label>
<div class="col-sm-6 col-md-6 col-lg-6 col-xl-6 {% if form.label.errors %}has-danger{% endif %}">
{{ form.label }}
{% if form.label.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.label.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_unit" class="col-sm-4 col-md-4 col-lg-3 col-xl-2 col-form-label">{{ form.unit.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.unit.errors %}has-danger{% endif %}">
{{ form.unit }}
{% if form.unit.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.unit.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_unit_price" class="col-sm-4 col-md-4 col-lg-3 col-xl-2 col-form-label">{{ form.unit_price.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.unit_price.errors %}has-danger{% endif %}">
{{ form.unit_price }}
{% if form.unit_price.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.unit_price.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Ajouter{% endif %}" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" >
$(function(){
$('#id_contract_related').autocomplete({
source: function(request, response){
$.ajax({
url: '/billing/contract/lookup/?pattern=' + $('#id_contract_related').val(),
dataType: "json",
success: function(data){
if(data.length != 0){
response($.map(data, function(item){
return {
label: item.Name,
value: item.Name,
contractid: item.ID
}
}))
} else {
response([{ label: 'No result found.', value: '' }]);
};
},
error: function(exception){
console.log(exception);
}
});
},
minLength: 3,
select: function(event, ui){
$($(this).data('ref')).val(ui.item.contractid);
}
});
});
</script>
{% endblock %}

View File

@ -1,44 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div id="page" class=" sidebar_right">
<div class="container">
<div id="frame2">
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>Prestations</h1>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<table class="table table-striped table-bordered table-condensed">
<thead>
<th>Date</th>
<th>Prestation</th>
<th>Contrat</th>
<th class="centered">Unité</th>
<th class="centered">Prix</th>
<th class="centered">Total</th>
</thead>
{% for prestation in prestation_list %}
<tr>
<td>{{ prestation.date|date:"d-m-Y" }}</td>
<td>{{ prestation.label }}</td>
<td><a href="/billing/contract/{{ prestation.contract.id }}">{{ prestation.contract }}</a></td>
<td class="push-right">{{ prestation.unit }}</td>
<td class="push-right">{{ prestation.unit_price }}</td>
<td class="push-right">{{ prestation.total_amount }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -13,8 +13,8 @@
<h1>{{ transaction.description }}</h1>
</div>
<br />
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="well well-small">
<div class="col-xs-12 col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">
<div class="well well-small text-right">
<table class="table-condensed">
<tr>
<td class="col-xs-6 col-sm-4 col-md-4 col-lg-4"><p class="text-muted">Date</p></td>
@ -48,10 +48,12 @@
<td><p class="text-muted">Effectuée ?</p></td>
<td><p class="text-{% if transaction.is_done %}primary{% else %}danger{% endif %}">{% if transaction.is_done %}Oui{% else %}Non{% endif %}</p></td>
</tr>
{% if transaction.is_simulated %}
<tr>
<td><p class="text-muted">Simulée ?</p></td>
<td><p class="text-{% if transaction.is_simulated %}danger{% else %}primary{% endif %}">{% if transaction.is_simulated %}Oui{% else %}Non{% endif %}</p></td>
<td><p class="text-{% if transaction.is_simulated %}danger{% else %}primary{% endif %}">Oui</p></td>
</tr>
{% endif %}
{% if transaction.event %}
<tr class="alert alert-danger">
<td><p class="text-muted">Evènement</p></td>
@ -65,6 +67,7 @@
</tr>
{% endif %}
</table>
<a href="{% url 'transaction_update' transaction.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>&nbsp;Modifier</a>
</div>
</div>
</div>

View File

@ -186,7 +186,7 @@ class SpfDocument(PDFDocument):
def add_recette_expenses(self, accounting_year):
""" Ajoute l'état des recettes et dépense pour une année comptable passée en paramètre.
Args:
accounting_year (int): année comptable.
@ -536,7 +536,7 @@ class BillPaper(PDFDocument):
)
self.add_vspace()
self.add_new_line(TITLED_X, "Concernant la/le")
self.add_string(200, contract.name, font_decoration="Bold")
self.add_string(200, contract.title, font_decoration="Bold")
self.add_vspace()
def add_payement_informations(self, contract):
@ -620,7 +620,7 @@ class BillPaper(PDFDocument):
Args:
total (int): somme totale des prestations.
Returns:
ne retourne rien.
"""
@ -657,7 +657,7 @@ class BillPaper(PDFDocument):
Args:
prestations_list (list): liste des prestations d'un contrat.
Returns:
ne retourne rien.
"""
@ -673,7 +673,7 @@ class BillPaper(PDFDocument):
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien.
"""