[WIP] working for #3 and #4

This commit is contained in:
Trullemans Gregory 2020-03-16 19:19:19 +01:00
parent 8bba8247a4
commit 2f0793769e
12 changed files with 205 additions and 113 deletions

View File

@ -2,7 +2,9 @@ import csv
import math
import datetime
from django import forms
from datetime import date
from .models import Client, Contract, Prestation
from django_select2.forms import Select2MultipleWidget, ModelSelect2Widget
class ClientForm(forms.ModelForm):
@ -49,7 +51,11 @@ class ContractForm(forms.ModelForm):
"name": forms.TextInput(
attrs={"class": "form-control", "placeholder": "Nom du contract"}
),
"client": forms.HiddenInput(),
"client": ModelSelect2Widget(
search_fields=["client__name__icontains", "client__contact__icontains", "client__city__icontains"],
max_results=10,
attrs={"data-minimum-input-length": 0, "class": "form-control"},
),
"advance": forms.TextInput(
attrs={"class": "form-control", }
),
@ -67,26 +73,18 @@ class ContractForm(forms.ModelForm):
)
}
client_related = forms.CharField(
widget=forms.TextInput(
attrs={
"class": "form-control",
"placeholder": "Recherche client…",
"data-ref": "#id_client",
}
)
)
class PrestationForm(forms.ModelForm):
class Meta:
model = Prestation
fields = ("contract", "date", "label", "unit", "unit_price", "total_amount")
fields = ("contract", "date", "label", "unit", "unit_price")
widgets = {
"contract": forms.TextInput(
attrs={"class": "form-control", "placeholder": "Nom du contract"}
),
"date": forms.TextInput(
attrs={"class": "form-control", }
"contract": forms.HiddenInput(),
"date": forms.DateInput(
attrs={
"class": "form-control datepicker",
"value": date.today().strftime("%Y-%m-%d"),
}
),
"label": forms.TextInput(
attrs={"class": "form-control", }
@ -94,10 +92,17 @@ class PrestationForm(forms.ModelForm):
"unit": forms.TextInput(
attrs={"class": "form-control", }
),
"unit_price": forms.CheckboxInput(
attrs={"class": "form-control", }
),
"total_amount": forms.CheckboxInput(
"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

@ -5,11 +5,13 @@ from .views import (
client_listing,
client_details,
client_create_or_update,
contract_lookup,
contract_listing,
contract_detail,
contract_create_or_update,
contract_export,
prestation_listing,
prestation_create_or_update,
)
app_name = "billing"
@ -21,6 +23,7 @@ urlpatterns = [
url(r"^client/create/$", client_create_or_update, name="client_create"),
url(r"^client/update/(?P<client_id>[0-9]+)/$", client_create_or_update, name="client_update"),
url(r"^contract/lookup/$", contract_lookup, name="contract_lookup"),
url(r"^contract/$", contract_listing, name="contract_listing"),
url(
r"^contract/(?P<contract_id>[0-9]+)/$", contract_detail, name="contract_detail"
@ -34,4 +37,6 @@ urlpatterns = [
),
url(r"^prestation/$", prestation_listing, name="prestation_listing"),
url(r"^prestation/create/$", prestation_create_or_update, name="prestation_create"),
url(r"^prestation/update/(?P<prestation_id>[0-9]+)/$", prestation_create_or_update, name="prestation_update"),
]

View File

@ -20,7 +20,7 @@ from .models import (
from .forms import (
ClientForm,
ContractForm,
# PrestationForm,
PrestationForm,
)
from tools.pdf_generator import BillPaper
@ -34,7 +34,7 @@ def client_lookup(request):
if pattern is not None and len(pattern) >= 3:
results = Client.objects.filter(
Q(name__icontains=pattern) | Q(city__icontains=pattern)
Q(name__icontains=pattern) | Q(contact__icontains=pattern) | Q(city__icontains=pattern)
)
client_list = [{"ID": x.id, "name": str(x)} for x in results]
@ -138,7 +138,7 @@ def contract_create_or_update(request, contract_id=None):
if form.is_valid():
contract = form.save()
return HttpResponseRedirect(reverse("contract_details", args=(contract.pk, )))
return HttpResponseRedirect(reverse("billing:contract_details", args=(contract.pk, )))
else:
form = ContractForm(instance=contract)
@ -173,3 +173,44 @@ def prestation_listing(request):
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.
Args:
prestation_id (int): identifiant d'un prestation.
"""
if prestation_id:
prestation = get_object_or_404(Prestation, pk=prestation_id)
else:
prestation = None
if request.method == "POST":
form = PrestationForm(request.POST, instance=prestation)
if form.is_valid():
prestation = form.save()
return HttpResponseRedirect(reverse("prestation_details", args=(prestation.pk, )))
else:
form = PrestationForm(instance=prestation)
context = {"form": form, "prestation_id": prestation_id}
return render(request, "prestation_create_or_update.html", context)
@require_http_methods(["GET"])
def contract_lookup(request):
""" Récupère la liste des clients à la volée suivant des caractères de recherches entrés.
"""
pattern = request.GET.get("pattern", 0)
if pattern is not None and len(pattern) >= 3:
results = Contract.objects.filter(Q(name__icontains=pattern))
contract_list = [{"ID": x.id, "name": str(x)} for x in results]
json = simplejson.dumps(contract_list)
return HttpResponse(json, content_type="application/json")

View File

@ -29,6 +29,7 @@ INSTALLED_APPS = [
"eventCompta.apps.ManagementConfig",
"billing.apps.BillingConfig",
"django.contrib.humanize",
"django_select2",
]
MIDDLEWARE = [

View File

@ -19,6 +19,7 @@ from django.contrib import admin
from comptabilite.views import year_listing
urlpatterns = [
url(r'^select2/', include('django_select2.urls')),
url(r"^$", year_listing),
url(r"^admin/", admin.site.urls),
url(

View File

@ -12,7 +12,7 @@
</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="{% url 'billing:client_create' %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
<form action="{% if client_id %}{% url 'billing:client_update' client_id %}{% else %}{% url 'billing: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>

View File

@ -8,17 +8,15 @@
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>Détails client</h1>
<h1>Détails {{ client.name }}</h1>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
{{ client.name }}
{{ client.company_number }}
{{ client.contact }}
{{ client.address }}
{{ client.postal_code }}
{{ client.city }}
<p><b>Nom Client : </b>{{ client.name }}</p>
<p><b>N° BCE : </b>{{ client.company_number }}</p>
<p><b>Nom de contact : </b>{{ client.contact }}</p>
<p><b>Adresse : </b>{{ client.address }} - {{ client.postal_code }} {{ client.city }}</p>
</div>
</div>
</div>

View File

@ -25,7 +25,7 @@
{% for client in client_list %}
<tr>
<td><a href="{% url 'billing:client_details' client.id %}">{{ client.name }}</a></td>
<td>{{ client.company_number }}</td>
<td>{% if client.company_number %}{{ client.company_number }}{% endif %}</td>
<td>{{ client.contact }}</td>
<td>{{ client.address }}</td>
<td>{{ client.postal_code }}</td>

View File

@ -7,57 +7,22 @@
<div id="content">
<div class="row">
<div class="col-md-12 col-lg-12">
<h1>{% if client_id %}Modification{% else %}Nouveau{% endif %} Contrat</h1>
<h1>{% if contract_id %}Modification{% else %}Nouveau{% endif %} Contrat</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="{% url 'billing:client_create' %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
<form action="{% if contract_id %}{% url 'billing:contract_update' contract_id %}{% else %}{% url 'billing:contract_create' %}{% endif %}" method="post" class="form" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_name" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.name.label }}</label>
<div class="col-8 col-sm-6 col-md-4 col-lg-4 col-xl-4 {% if form.date.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 class="form-group row ">
<label for="id_client" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.client.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.gymnast.errors %}has-danger{% endif %}">
{{ form.client }}
{{ form.client_related }}
{% if form.client.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.client.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_advance" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.advance.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.educative.errors %}has-danger{% endif %}">
{{ form.advance }}
{% if form.advance.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.advance.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_is_finished" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.is_finished.label }} ?</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.educative.errors %}has-danger{% endif %}">
{{ form.is_finished }}
{% if form.is_finished.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.is_finished.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_is_finished" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.is_paid.label }} ?</label>
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.educative.errors %}has-danger{% endif %}">
{{ form.is_paid }}
{% if form.is_paid.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.is_paid.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_reference" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">{{ form.reference.label }}</label>
<div class="col-sm-3 col-md-3 col-lg-3 col-xl-3 {% if form.reference.errors %}has-danger{% endif %}">
{{ form.reference }}
{% if form.reference.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.reference.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
{% for field in form %}
<div class="form-group">
<label for="">{{ field.label_tag }}</label>
{{ field }}
{% if field.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in field.errors %}{{error}}{% endfor %}</span>{% endif %}
</div>
{% endfor %}
<div class="form-group text-center">
<input type="submit" value="{% if client_id %}Sauvegarder{% else %}Ajouter{% endif %}" class="btn btn-warning" />
</div>
@ -69,37 +34,4 @@
</div>
</div>
<script type="text/javascript" >
$(function(){
$('#id_client_related').autocomplete({
source: function(request, response){
$.ajax({
url: '/billing/client/lookup/?pattern=' + $('#id_client_related').val(),
dataType: "json",
success: function(data){
if(data.length != 0){
response($.map(data, function(item){
return {
label: item.Name,
value: item.Name,
clientid: 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.clientid);
}
});
});
</script>
{% endblock %}

View File

@ -13,7 +13,7 @@
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">
<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>
@ -36,8 +36,17 @@
<td class="push-right"><b>{{ total|floatformat:2|intdot }}</b></td>
</tr>
</table>
<p class="right"><a href="/billing/contract/pdf/{{ contract.id }}" class="btn btn-default btn-primary" role="button">Facture PDF</a></p>
</div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<a href="/billing/contract/pdf/{{ contract.id }}" class="btn btn-default btn-success" role="button">Facture PDF</a>
</div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<p class="text-right">
<a href="{% url 'billing:prestation_create' %}" class="btn btn-default btn-primary" role="button">Ajouter prestation</a>
</p>
</div>
</div>
</div>
</div>

View File

@ -33,7 +33,9 @@
</tr>
{% endfor %}
</table>
<a href="{% url 'billing:contract_create' %}">Nouveau contrat</a>
<p class="text-right">
<a class="btn btn-primary" href="{% url 'billing:contract_create' %}">Nouveau contrat</a>
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,98 @@
{% 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 'billing:prestation_update' prestation_id %}{% else %}{% url 'billing: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 %}