diff --git a/cotisations/forms.py b/cotisations/forms.py index 696f1f5c..524e878f 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -145,25 +145,11 @@ class NewFactureFormPdf(Form): """ Form used to create a custom PDF invoice. """ - article = forms.ModelMultipleChoiceField( - queryset=Article.objects.all(), - label=_l("Article") - ) - number = forms.IntegerField( - label=_l("Quantity"), - validators=[MinValueValidator(1)] - ) paid = forms.BooleanField(label=_l("Paid"), required=False) # TODO : change dest field to recipient dest = forms.CharField(required=True, max_length=255, label=_l("Recipient")) # TODO : change chambre field to address chambre = forms.CharField(required=False, max_length=10, label=_l("Address")) - # TODO : change fid field to invoice_id - fid = forms.CharField( - required=True, - max_length=10, - label=_l("Invoice number") - ) # TODO : change Facture to Invoice class EditFactureForm(FieldPermissionFormMixin, NewFactureForm): diff --git a/cotisations/templates/cotisations/control.html b/cotisations/templates/cotisations/control.html index cdd212e3..bb3a06b6 100644 --- a/cotisations/templates/cotisations/control.html +++ b/cotisations/templates/cotisations/control.html @@ -65,12 +65,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Date" as tr_date %} - {% include 'buttons/sort.html' with prefix='control' col='date' text=tr_date %}< - /th> + {% include 'buttons/sort.html' with prefix='control' col='date' text=tr_date %}i + {% trans "Validated" as tr_validated %} - {% include 'buttons/sort.html' with prefix='control' col='valid' text=tr_validated %}< - /th> + {% include 'buttons/sort.html' with prefix='control' col='valid' text=tr_validated %} + {% trans "Controlled" as tr_controlled %} {% include 'buttons/sort.html' with prefix='control' col='control' text=tr_controlled %} diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index 2b0cd456..d708b407 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -34,8 +34,105 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% csrf_token %} +

{% trans "Invoice's articles" %}

+
+ {{ articlesformset.management_form }} + {% for articlesform in articlesformset.forms %} +
+ {% trans "Article" %} :   + {% bootstrap_form articlesform label_class='sr-only' %} +   + +
+ {% endfor %} +
+ +

+ {% blocktrans %} + Total price : 0,00 € + {% endblocktrans %} +

{% bootstrap_form factureform %} {% bootstrap_button action_name button_type='submit' icon='star' %}
+ + + + {% endblock %} diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex index 1619ea5e..3f2ebedc 100644 --- a/cotisations/templates/cotisations/factures.tex +++ b/cotisations/templates/cotisations/factures.tex @@ -32,76 +32,97 @@ \usepackage{graphicx} \usepackage{tabularx} \usepackage{eurosym} +\usepackage{multicol} \pagestyle{empty} % No page numbers \linespread{1.5} % Line spacing -\setlength{\doublerulesep}{\arrayrulewidth} % Double rules look like one thick one -\def \tab {\hspace*{3ex}} % Define \tab to create some horizontal white space +\newcommand{\doublehline}{\noalign{\hrule height 1pt}} \setlength{\parindent}{0cm} \begin{document} -%\newcommand{\product}[5][0][0][0][0][0]{ -%\setlength{ptotal}{#3*\real{#4}} -%\addtolength{total}{#3*\real{#4}} + + %---------------------------------------------------------------------------------------- + % HEADING SECTION + %---------------------------------------------------------------------------------------- + \begin{center} + {\Huge\bf {{asso_name|safe}} } % Company providing the invoice + \end{center} -%---------------------------------------------------------------------------------------- -% HEADING SECTION -%---------------------------------------------------------------------------------------- -%\includegraphics[width=3.5cm]{% templatetag openbrace %}{{ tpl_path }}} -\tab \tab \tab \tab \tab {\Huge\bf {{asso_name|safe}} }\hfil % Company providing the invoice -\bigskip\break % Whitespace -\hrule % Horizontal line \\ -\vspace{0.5cm} -{\bf Adresse :} \tab \parbox [t] {0.5\textwidth}{ {{line1|safe}} \\ {{line2|safe}} } \hfill \parbox [t] {0.3\textwidth}{ {\bf Téléphone :} {{phone}} \\ {\bf Mail :} {{email|safe}} } \\ % Your address and contact information -\\ -{\bf Siret :} \tab{{siret}} -\\ \\ \\ -\\ -\parbox [t] {0.5\textwidth}{ {\bf Pour :} {{dest.name|safe}} {{dest.surname|safe}} \\ {\bf Adresse :} \tab {% if dest.room == None %} Aucune adresse renseignée {% else %}{{dest.room}}{% endif %} } \hfill \parbox [t] {0.3\textwidth}{ {\bf Date :} {{DATE}} } -\\ \\ + \bigskip + \hrule + \smallskip -{\bf Facture \no :} \tab {{ fid }} \\\\ -%---------------------------------------------------------------------------------------- -% TABLE OF EXPENSES -%---------------------------------------------------------------------------------------- + {\setlength{\tabcolsep}{0pt} % Make table columns tighter, usefull for postionning + \begin{tabular}{l l} + {\bf Adresse :}~ & {{line1|safe}} \\ + & {{line2|safe}} \\ + \end{tabular} + \hfill + \begin{tabular}{r} + {\bf Téléphone :} {{phone}} \\ + {\bf Mail :} {{email|safe}} \\ + \end{tabular} + } + \\ + {\bf Siret :} {{siret|safe}} -\begin{tabularx}{\textwidth}{|X|r|r|r|} -\hline - \textbf{Désignation} & \textbf{Prix Unit.} \euro & \textbf{Quantité} & \textbf{Prix total} \euro\\ -\hline + \vspace{2cm} + + \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} l r} + {\bf Pour :} {{recipient_name|safe}} & {\bf Date :} {{DATE}} \\ + {\bf Adresse :} {% if address is None %}Aucune adresse renseignée{% else %}{{address}}{% endif %} & \\ + {% if fid is not None %} + {\bf Facture n\textsuperscript{o} :} {{ fid }} & \\ + {% endif %} + \end{tabular*} + \\ -{% for a in article %} -\hline - {{a.0.name}} & {{a.0.prix}} \euro & {{a.1}} & {{a.2}} \euro\\ -\hline -{% endfor %} + %---------------------------------------------------------------------------------------- + % TABLE OF EXPENSES + %---------------------------------------------------------------------------------------- + + \begin{tabularx}{\textwidth}{|X|r|r|r|} - \hline -\end{tabularx} + \hline + \textbf{Désignation} & \textbf{Prix Unit.} \euro & \textbf{Quantité} & \textbf{Prix total} \euro\\ + \doublehline + + {% for a in article %} + {{a.name}} & {{a.price}} \euro & {{a.quantity}} & {{a.total_price}} \euro\\ + \hline + {% endfor %} + + \end{tabularx} + + \vspace{1cm} -\vspace{1cm} -\hfill -\begin{tabular}{|l|r|} -\hline -\textbf{Total} & {{total|floatformat:2}} \euro \\ -\textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro \\ -\hline -\textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\ -\hline -\hline + \hfill + \begin{tabular}{|l|r|} + \hline + \textbf{Total} & {{total|floatformat:2}} \euro \\ + \textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro \\ + \doublehline + \textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\ + \hline + \end{tabular} + + \vfill -\end{tabular} -\vspace{1.5cm} % Whitespace -\hrule % Horizontal line -\vspace{0.25cm} -\footnotesize{TVA non applicable, art. 293 B du CGI} - -{% endlanguage %} -%---------------------------------------------------------------------------------------- + %---------------------------------------------------------------------------------------- + % FOOTNOTE + %---------------------------------------------------------------------------------------- + + \hrule + \smallskip + \footnotesize{TVA non applicable, art. 293 B du CGI} + + %---------------------------------------------------------------------------------------- \end{document} + +{% endlanguage %} diff --git a/cotisations/tex.py b/cotisations/tex.py index e3bf62f5..fb50d05b 100644 --- a/cotisations/tex.py +++ b/cotisations/tex.py @@ -48,7 +48,7 @@ def render_invoice(request, ctx={}): filename = '_'.join([ 'invoice', slugify(ctx['asso_name']), - slugify(ctx['dest'].pseudo), + slugify(ctx['recipient_name']), str(ctx['DATE'].year), str(ctx['DATE'].month), str(ctx['DATE'].day), diff --git a/cotisations/views.py b/cotisations/views.py index f99ff93e..b946c3d6 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -198,24 +198,40 @@ def new_facture_pdf(request): get invoices that are not taken into account, for the administrative point of view. """ + # The template needs the list of articles (for the JS part) + articles = Article.objects.filter( + Q(type_user='All') | Q(type_user=request.user.class_name) + ) + # Building the invocie form and the article formset invoice_form = NewFactureFormPdf(request.POST or None) - if invoice_form.is_valid(): - tbl = [] - article = facture_form.cleaned_data['article'] - quantity = facture_form.cleaned_data['number'] - paid = facture_form.cleaned_data['paid'] - recipient = facture_form.cleaned_data['dest'] - room = facture_form.cleaned_data['chambre'] - invoice_id = facture_form.cleaned_data['fid'] - for art in article: - tbl.append([art, quantity, art.prix * quantity]) - total_price = sum(a[2] for a in tbl) - user = {'name': recipient, 'room': room} + if request.user.is_class_club: + articles_formset = formset_factory(SelectClubArticleForm)(request.POST or None) + else: + articles_formset = formset_factory(SelectUserArticleForm)(request.POST or None) + if invoice_form.is_valid() and articles_formset.is_valid(): + # Get the article list and build an list out of it + # contiaining (article_name, article_price, quantity, total_price) + articles_info = [] + for articles_form in articles_formset: + if articles_form.cleaned_data: + article = articles_form.cleaned_data['article'] + quantity = articles_form.cleaned_data['quantity'] + articles_info.append({ + 'name': article.name, + 'price': article.prix, + 'quantity': quantity, + 'total_price': article.prix * quantity + }) + paid = invoice_form.cleaned_data['paid'] + recipient = invoice_form.cleaned_data['dest'] + address = invoice_form.cleaned_data['chambre'] + total_price = sum(a['total_price'] for a in articles_info) + return render_invoice(request, { 'DATE': timezone.now(), - 'dest': user, - 'fid': invoice_id, - 'article': tbl, + 'recipient_name': recipient, + 'address': address, + 'article': articles_info, 'total': total_price, 'paid': paid, 'asso_name': AssoOption.get_cached_value('name'), @@ -228,7 +244,9 @@ def new_facture_pdf(request): }) return form({ 'factureform': invoice_form, - 'action_name': _("Edit") + 'action_name': _("Create"), + 'articlesformset': articles_formset, + 'articles': articles }, 'cotisations/facture.html', request) @@ -244,15 +262,26 @@ def facture_pdf(request, facture, factureid): """ # TODO : change vente to purchase purchases_objects = Vente.objects.all().filter(facture=facture) - purchases = [] + # Get the article list and build an list out of it + # contiaining (article_name, article_price, quantity, total_price) + purchases_info = [] for purchase in purchases_objects: - purchases.append([purchase, purchase.number, purchase.prix_total]) + purchases_info.append({ + 'name': purchase.name, + 'price': purchase.prix, + 'quantity': purchase.number, + 'total_price': purchase.prix_total + }) return render_invoice(request, { 'paid': True, 'fid': facture.id, 'DATE': facture.date, - 'dest': facture.user, - 'article': purchases, + 'recipient_name': "{} {}".format( + facture.user.name, + facture.user.surname + ), + 'address': facture.user.room, + 'article': purchases_info, 'total': facture.prix_total(), 'asso_name': AssoOption.get_cached_value('name'), 'line1': AssoOption.get_cached_value('adresse1'),