mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Add discount for custom invoices.
This commit is contained in:
parent
81b7a7c4af
commit
e7a7e81a2c
4 changed files with 172 additions and 98 deletions
|
@ -46,7 +46,7 @@ from django.shortcuts import get_object_or_404
|
|||
|
||||
from re2o.field_permissions import FieldPermissionFormMixin
|
||||
from re2o.mixins import FormRevMixin
|
||||
from .models import Article, Paiement, Facture, Banque, CustomInvoice
|
||||
from .models import Article, Paiement, Facture, Banque, CustomInvoice, Vente
|
||||
from .payment_methods import balance
|
||||
|
||||
|
||||
|
@ -104,7 +104,44 @@ class SelectArticleForm(FormRevMixin, Form):
|
|||
user = kwargs.pop('user')
|
||||
target_user = kwargs.pop('target_user', None)
|
||||
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
||||
self.fields['article'].queryset = Article.find_allowed_articles(user, target_user)
|
||||
self.fields['article'].queryset = Article.find_allowed_articles(
|
||||
user, target_user)
|
||||
|
||||
|
||||
class DiscountForm(Form):
|
||||
"""
|
||||
Form used in oder to create a discount on an invoice.
|
||||
"""
|
||||
is_relative = forms.BooleanField(
|
||||
label=_("Discount is on percentage"),
|
||||
required=False,
|
||||
)
|
||||
discount = forms.DecimalField(
|
||||
label=_("Discount"),
|
||||
max_value=100,
|
||||
min_value=0,
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
required=False,
|
||||
)
|
||||
|
||||
def apply_to_invoice(self, invoice):
|
||||
invoice_price = invoice.prix_total()
|
||||
discount = self.cleaned_data['discount']
|
||||
is_relative = self.cleaned_data['is_relative']
|
||||
if is_relative:
|
||||
amount = discount/100 * invoice_price
|
||||
else:
|
||||
amount = discount
|
||||
if amount > 0:
|
||||
name = _("{}% discount") if is_relative else _("{}€ discount")
|
||||
name = name.format(discount)
|
||||
Vente.objects.create(
|
||||
facture=invoice,
|
||||
name=name,
|
||||
prix=-amount,
|
||||
number=1
|
||||
)
|
||||
|
||||
|
||||
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
||||
|
@ -248,7 +285,8 @@ class RechargeForm(FormRevMixin, Form):
|
|||
super(RechargeForm, self).__init__(*args, **kwargs)
|
||||
self.fields['payment'].empty_label = \
|
||||
_("Select a payment method")
|
||||
self.fields['payment'].queryset = Paiement.find_allowed_payments(user_source).exclude(is_balance=True)
|
||||
self.fields['payment'].queryset = Paiement.find_allowed_payments(
|
||||
user_source).exclude(is_balance=True)
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
|
@ -266,4 +304,3 @@ class RechargeForm(FormRevMixin, Form):
|
|||
}
|
||||
)
|
||||
return self.cleaned_data
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
{% blocktrans %}Current balance: {{ balance }} €{% endblocktrans %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% bootstrap_form_errors factureform %}
|
||||
{% bootstrap_form_errors discount_form %}
|
||||
|
||||
<form class="form" method="post">
|
||||
{% csrf_token %}
|
||||
|
@ -68,6 +70,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
{% endfor %}
|
||||
</div>
|
||||
<input class="btn btn-primary btn-block" role="button" value="{% trans "Add an extra article"%}" id="add_one">
|
||||
<h3>{% trans "Discount" %}</h3>
|
||||
{% if discount_form %}
|
||||
{% bootstrap_form discount_form %}
|
||||
{% endif %}
|
||||
<p>
|
||||
{% blocktrans %}Total price: <span id="total_price">0,00</span> €{% endblocktrans %}
|
||||
</p>
|
||||
|
@ -119,6 +125,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
'id_form-' + i.toString() + '-quantity').value;
|
||||
price += article_price * quantity;
|
||||
}
|
||||
{% if discount_form %}
|
||||
var relative_discount = document.getElementById('id_is_relative').checked;
|
||||
var discount = document.getElementById('id_discount').value;
|
||||
if(relative_discount) {
|
||||
discount = discount/100 * price;
|
||||
}
|
||||
price -= discount;
|
||||
{% endif %}
|
||||
document.getElementById('total_price').innerHTML =
|
||||
price.toFixed(2).toString().replace('.', ',');
|
||||
}
|
||||
|
@ -148,6 +162,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
for (i = 0; i < product_count; ++i){
|
||||
add_listenner_for_id(i);
|
||||
}
|
||||
document.getElementById('id_discount')
|
||||
.addEventListener('change', update_price, true);
|
||||
document.getElementById('id_is_relative')
|
||||
.addEventListener('click', update_price, true);
|
||||
update_price();
|
||||
});
|
||||
{% endif %}
|
||||
|
|
|
@ -36,6 +36,7 @@ from django.template import Context
|
|||
from django.http import HttpResponse
|
||||
from django.conf import settings
|
||||
from django.utils.text import slugify
|
||||
import logging
|
||||
|
||||
|
||||
TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-')
|
||||
|
@ -93,6 +94,20 @@ def create_pdf(template, ctx={}):
|
|||
return pdf
|
||||
|
||||
|
||||
def escape_chars(string):
|
||||
"""Escape the '%' and the '€' signs to avoid messing with LaTeX"""
|
||||
if not isinstance(string, str):
|
||||
return string
|
||||
mapping = (
|
||||
('€', r'\euro'),
|
||||
('%', r'\%'),
|
||||
)
|
||||
r = str(string)
|
||||
for k, v in mapping:
|
||||
r = r.replace(k, v)
|
||||
return r
|
||||
|
||||
|
||||
def render_tex(_request, template, ctx={}):
|
||||
"""Creates a PDF from a LaTex templates using pdflatex.
|
||||
|
||||
|
|
|
@ -80,9 +80,10 @@ from .forms import (
|
|||
DelBanqueForm,
|
||||
SelectArticleForm,
|
||||
RechargeForm,
|
||||
CustomInvoiceForm
|
||||
CustomInvoiceForm,
|
||||
DiscountForm
|
||||
)
|
||||
from .tex import render_invoice
|
||||
from .tex import render_invoice, escape_chars
|
||||
from .payment_methods.forms import payment_method_factory
|
||||
from .utils import find_payment_method
|
||||
|
||||
|
@ -198,8 +199,9 @@ def new_custom_invoice(request):
|
|||
request.POST or None,
|
||||
form_kwargs={'user': request.user}
|
||||
)
|
||||
discount_form = DiscountForm(request.POST or None)
|
||||
|
||||
if invoice_form.is_valid() and articles_formset.is_valid():
|
||||
if invoice_form.is_valid() and articles_formset.is_valid() and discount_form.is_valid():
|
||||
new_invoice_instance = invoice_form.save()
|
||||
for art_item in articles_formset:
|
||||
if art_item.cleaned_data:
|
||||
|
@ -213,6 +215,7 @@ def new_custom_invoice(request):
|
|||
duration=article.duration,
|
||||
number=quantity
|
||||
)
|
||||
discount_form.apply_to_invoice(new_invoice_instance)
|
||||
messages.success(
|
||||
request,
|
||||
_("The custom invoice was created.")
|
||||
|
@ -223,7 +226,8 @@ def new_custom_invoice(request):
|
|||
'factureform': invoice_form,
|
||||
'action_name': _("Confirm"),
|
||||
'articlesformset': articles_formset,
|
||||
'articlelist': articles
|
||||
'articlelist': articles,
|
||||
'discount_form': discount_form
|
||||
}, 'cotisations/facture.html', request)
|
||||
|
||||
|
||||
|
@ -382,7 +386,7 @@ def custom_invoice_pdf(request, invoice, **_kwargs):
|
|||
purchases_info = []
|
||||
for purchase in purchases_objects:
|
||||
purchases_info.append({
|
||||
'name': purchase.name,
|
||||
'name': escape_chars(purchase.name),
|
||||
'price': purchase.prix,
|
||||
'quantity': purchase.number,
|
||||
'total_price': purchase.prix_total
|
||||
|
|
Loading…
Reference in a new issue