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

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

View file

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

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',
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

View file

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