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:
Aurélien Delobelle 2016-08-23 00:15:17 +02:00
parent e89f8fd6a5
commit f73b25e65f
7 changed files with 234 additions and 4 deletions

View file

@ -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

View 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),
),
]

View file

@ -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):

View file

@ -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">

View 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 %}

View file

@ -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

View file

@ -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
# ----- # -----