forked from DGNum/gestioCOF
Amélioration gestion des relevés
Nouveau relevé: Il faut donner le détail du nombre de chaque pièces/billets pris et laissé en caisse pour calculer les valeurs `balance_new` et `amount_taken` d'un relevé (`CheckoutStatement`). L'erreur est directement calculée par rapport à la balance actuelle de la caisse et ces 2 valeurs. Une erreur positive correspond à un surplus d'argent et inversement. Modification d'un relevé: Il est possible de modifier les infos d'un ancien relevé. L'erreur est ensuite recalculée à partir de ces infos. Important: Dans le cas où `balance_new` est modifiée et qu'il s'agit du relevé le plus récent sur cette caisse. Alors la balance de la caisse est mise à jour en prenant en compte cette correction (et en conservant les modifications s'il y a eu des mouvements sur la caisse)
This commit is contained in:
parent
e89f8fd6a5
commit
f73b25e65f
7 changed files with 234 additions and 4 deletions
|
@ -130,10 +130,33 @@ class CheckoutRestrictForm(CheckoutForm):
|
|||
class Meta(CheckoutForm.Meta):
|
||||
fields = ['name', 'valid_from', 'valid_to']
|
||||
|
||||
class CheckoutStatementForm(forms.ModelForm):
|
||||
|
||||
class CheckoutStatementCreateForm(forms.ModelForm):
|
||||
balance_001 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_002 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_005 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_01 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_02 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_05 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_1 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_2 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_5 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_10 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_20 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_50 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_100 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_200 = forms.IntegerField(min_value=0, initial=0)
|
||||
balance_500 = forms.IntegerField(min_value=0, initial=0)
|
||||
|
||||
class Meta:
|
||||
model = CheckoutStatement
|
||||
fields = ['balance_new', 'amount_taken']
|
||||
exclude = ['by', 'at', 'checkout', 'amount_error', 'amount_taken',
|
||||
'balance_old', 'balance_new']
|
||||
|
||||
class CheckoutStatementUpdateForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = CheckoutStatement
|
||||
exclude = ['by', 'at', 'checkout', 'amount_error', 'amount_taken']
|
||||
|
||||
# -----
|
||||
# Article forms
|
||||
|
|
94
kfet/migrations/0032_auto_20160822_2350.py
Normal file
94
kfet/migrations/0032_auto_20160822_2350.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('kfet', '0031_auto_20160822_0523'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_001',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_002',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_005',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_01',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_02',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_05',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_1',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_10',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_100',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_2',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_20',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_200',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_5',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_50',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_500',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='checkoutstatement',
|
||||
name='taken_cheque',
|
||||
field=models.PositiveSmallIntegerField(default=0),
|
||||
),
|
||||
]
|
|
@ -7,6 +7,7 @@ from gestioncof.models import CofProfile
|
|||
from django.utils.six.moves import reduce
|
||||
from django.utils import timezone
|
||||
from django.db import transaction
|
||||
from django.db.models import F
|
||||
from django.core.cache import cache
|
||||
from datetime import date, timedelta
|
||||
import re
|
||||
|
@ -259,6 +260,23 @@ class CheckoutStatement(models.Model):
|
|||
amount_error = models.DecimalField(max_digits = 6, decimal_places = 2)
|
||||
at = models.DateTimeField(auto_now_add = True)
|
||||
|
||||
taken_001 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_002 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_005 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_01 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_02 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_05 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_1 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_2 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_5 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_10 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_20 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_50 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_100 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_200 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_500 = models.PositiveSmallIntegerField(default=0)
|
||||
taken_cheque = models.PositiveSmallIntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s' % (self.checkout, self.at)
|
||||
|
||||
|
@ -273,6 +291,18 @@ class CheckoutStatement(models.Model):
|
|||
Checkout.objects.filter(pk=checkout_id).update(balance=self.balance_new)
|
||||
super(CheckoutStatement, self).save(*args, **kwargs)
|
||||
else:
|
||||
self.amount_error = (
|
||||
self.balance_new + self.amount_taken - self.balance_old)
|
||||
# Si on modifie le dernier relevé d'une caisse et que la nouvelle
|
||||
# balance est modifiée alors on modifie la balance actuelle de la caisse
|
||||
last_statement = (CheckoutStatement.objects
|
||||
.filter(checkout=self.checkout)
|
||||
.order_by('at')
|
||||
.last())
|
||||
if (last_statement.pk == self.pk
|
||||
and last_statement.balance_new != self.balance_new):
|
||||
Checkout.objects.filter(pk=self.checkout_id).update(
|
||||
balance=F('balance') - last_statement.balance_new + self.balance_new)
|
||||
super(CheckoutStatement, self).save(*args, **kwargs)
|
||||
|
||||
class ArticleCategory(models.Model):
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
{% if not perms.ket.add_checkoutstatement %}
|
||||
{% if not perms.kfet.add_checkoutstatement %}
|
||||
<input type="password" name="KFETPASSWORD">
|
||||
{% endif %}
|
||||
<input type="submit" value="Enregistrer">
|
||||
|
|
33
kfet/templates/kfet/checkoutstatement_update.html
Normal file
33
kfet/templates/kfet/checkoutstatement_update.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
{% extends 'kfet/base.html' %}
|
||||
|
||||
{% block title %}Modification d'un relevé{% endblock %}
|
||||
{% block content-header-title %}
|
||||
Caisse {{ checkout.name }} - Modification relevé {{ checkoutstatement.at }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 col-md-3 col-content-left">
|
||||
<div class="content-left">
|
||||
{% include 'kfet/left_checkout.html' %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 col-md-9 col-content-right">
|
||||
{% include 'kfet/base_messages.html' %}
|
||||
<div class="content-right">
|
||||
<div class="content-right-block">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
{% if not perms.kfet.change_checkoutstatement %}
|
||||
<input type="password" name="KFETPASSWORD">
|
||||
{% endif %}
|
||||
<input type="submit" value="Enregistrer">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -80,6 +80,10 @@ urlpatterns = [
|
|||
url('^checkouts/(?P<pk_checkout>\d+)/statements/add',
|
||||
permission_required('kfet.is_team')(views.CheckoutStatementCreate.as_view()),
|
||||
name = 'kfet.checkoutstatement.create'),
|
||||
# Checkout Statement - Update
|
||||
url('^checkouts/(?P<pk_checkout>\d+)/statements/(?P<pk>\d+)/edit',
|
||||
permission_required('kfet.is_team')(views.CheckoutStatementUpdate.as_view()),
|
||||
name = 'kfet.checkoutstatement.update'),
|
||||
|
||||
# -----
|
||||
# Article urls
|
||||
|
|
|
@ -410,10 +410,30 @@ class CheckoutStatementList(ListView):
|
|||
|
||||
# Checkout Statement - Create
|
||||
|
||||
def getAmountTaken(data):
|
||||
return Decimal(data.taken_001 * 0.01 + data.taken_002 * 0.02
|
||||
+ data.taken_005 * 0.05 + data.taken_01 * 0.1
|
||||
+ data.taken_02 * 0.2 + data.taken_05 * 0.5
|
||||
+ data.taken_1 * 1 + data.taken_2 * 2
|
||||
+ data.taken_5 * 5 + data.taken_10 * 10
|
||||
+ data.taken_20 * 20 + data.taken_50 * 50
|
||||
+ data.taken_100 * 100 + data.taken_200 * 200
|
||||
+ data.taken_500 * 500 + data.taken_cheque)
|
||||
|
||||
def getAmountBalance(data):
|
||||
return Decimal(data['balance_001'] * 0.01 + data['balance_002'] * 0.02
|
||||
+ data['balance_005'] * 0.05 + data['balance_01'] * 0.1
|
||||
+ data['balance_02'] * 0.2 + data['balance_05'] * 0.5
|
||||
+ data['balance_1'] * 1 + data['balance_2'] * 2
|
||||
+ data['balance_5'] * 5 + data['balance_10'] * 10
|
||||
+ data['balance_20'] * 20 + data['balance_50'] * 50
|
||||
+ data['balance_100'] * 100 + data['balance_200'] * 200
|
||||
+ data['balance_500'] * 500)
|
||||
|
||||
class CheckoutStatementCreate(SuccessMessageMixin, CreateView):
|
||||
model = CheckoutStatement
|
||||
template_name = 'kfet/checkoutstatement_create.html'
|
||||
form_class = CheckoutStatementForm
|
||||
form_class = CheckoutStatementCreateForm
|
||||
success_message = 'Nouveau relevé : %(checkout)s - %(at)s'
|
||||
|
||||
def get_success_url(self):
|
||||
|
@ -437,10 +457,36 @@ class CheckoutStatementCreate(SuccessMessageMixin, CreateView):
|
|||
form.add_error(None, 'Permission refusée')
|
||||
return self.form_invalid(form)
|
||||
# Creating
|
||||
form.instance.amount_taken = getAmountTaken(form.instance)
|
||||
form.instance.balance_new = getAmountBalance(form.cleaned_data)
|
||||
form.instance.checkout_id = self.kwargs['pk_checkout']
|
||||
form.instance.by = self.request.user.profile.account_kfet
|
||||
return super(CheckoutStatementCreate, self).form_valid(form)
|
||||
|
||||
class CheckoutStatementUpdate(SuccessMessageMixin, UpdateView):
|
||||
model = CheckoutStatement
|
||||
template_name = 'kfet/checkoutstatement_update.html'
|
||||
form_class = CheckoutStatementUpdateForm
|
||||
success_message = 'Relevé modifié'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('kfet.checkout.read', kwargs={'pk':self.kwargs['pk_checkout']})
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CheckoutStatementUpdate, self).get_context_data(**kwargs)
|
||||
checkout = Checkout.objects.get(pk=self.kwargs['pk_checkout'])
|
||||
context['checkout'] = checkout
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
# Checking permission
|
||||
if not self.request.user.has_perm('kfet.change_checkoutstatement'):
|
||||
form.add_error(None, 'Permission refusée')
|
||||
return self.form_invalid(form)
|
||||
# Updating
|
||||
form.instance.amount_taken = getAmountTaken(form.instance)
|
||||
return super(CheckoutStatementUpdate, self).form_valid(form)
|
||||
|
||||
# -----
|
||||
# Article views
|
||||
# -----
|
||||
|
|
Loading…
Reference in a new issue