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):
|
class Meta(CheckoutForm.Meta):
|
||||||
fields = ['name', 'valid_from', 'valid_to']
|
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:
|
class Meta:
|
||||||
model = CheckoutStatement
|
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
|
# 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.six.moves import reduce
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models import F
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
import re
|
import re
|
||||||
|
@ -259,6 +260,23 @@ class CheckoutStatement(models.Model):
|
||||||
amount_error = models.DecimalField(max_digits = 6, decimal_places = 2)
|
amount_error = models.DecimalField(max_digits = 6, decimal_places = 2)
|
||||||
at = models.DateTimeField(auto_now_add = True)
|
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):
|
def __str__(self):
|
||||||
return '%s %s' % (self.checkout, self.at)
|
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)
|
Checkout.objects.filter(pk=checkout_id).update(balance=self.balance_new)
|
||||||
super(CheckoutStatement, self).save(*args, **kwargs)
|
super(CheckoutStatement, self).save(*args, **kwargs)
|
||||||
else:
|
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)
|
super(CheckoutStatement, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class ArticleCategory(models.Model):
|
class ArticleCategory(models.Model):
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
{% if not perms.ket.add_checkoutstatement %}
|
{% if not perms.kfet.add_checkoutstatement %}
|
||||||
<input type="password" name="KFETPASSWORD">
|
<input type="password" name="KFETPASSWORD">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<input type="submit" value="Enregistrer">
|
<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',
|
url('^checkouts/(?P<pk_checkout>\d+)/statements/add',
|
||||||
permission_required('kfet.is_team')(views.CheckoutStatementCreate.as_view()),
|
permission_required('kfet.is_team')(views.CheckoutStatementCreate.as_view()),
|
||||||
name = 'kfet.checkoutstatement.create'),
|
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
|
# Article urls
|
||||||
|
|
|
@ -410,10 +410,30 @@ class CheckoutStatementList(ListView):
|
||||||
|
|
||||||
# Checkout Statement - Create
|
# 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):
|
class CheckoutStatementCreate(SuccessMessageMixin, CreateView):
|
||||||
model = CheckoutStatement
|
model = CheckoutStatement
|
||||||
template_name = 'kfet/checkoutstatement_create.html'
|
template_name = 'kfet/checkoutstatement_create.html'
|
||||||
form_class = CheckoutStatementForm
|
form_class = CheckoutStatementCreateForm
|
||||||
success_message = 'Nouveau relevé : %(checkout)s - %(at)s'
|
success_message = 'Nouveau relevé : %(checkout)s - %(at)s'
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
@ -437,10 +457,36 @@ class CheckoutStatementCreate(SuccessMessageMixin, CreateView):
|
||||||
form.add_error(None, 'Permission refusée')
|
form.add_error(None, 'Permission refusée')
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
# Creating
|
# 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.checkout_id = self.kwargs['pk_checkout']
|
||||||
form.instance.by = self.request.user.profile.account_kfet
|
form.instance.by = self.request.user.profile.account_kfet
|
||||||
return super(CheckoutStatementCreate, self).form_valid(form)
|
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
|
# Article views
|
||||||
# -----
|
# -----
|
||||||
|
|
Loading…
Reference in a new issue