mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-26 02:54:20 +00:00
Merge branch 'consignes' into 'master'
Add limit for ecocup recording See merge request !90
This commit is contained in:
commit
0ffd7485e3
@ -39,7 +39,7 @@ from accounting.models import GeneralJournal, BankAccount, ClubAccount, Operatio
|
|||||||
from core.utils import resize_image
|
from core.utils import resize_image
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from subscription.models import Subscription
|
from subscription.models import Subscription
|
||||||
from counter.models import Customer, ProductType, Product, Counter
|
from counter.models import Customer, ProductType, Product, Counter, Selling
|
||||||
from com.models import Sith, Weekmail
|
from com.models import Sith, Weekmail
|
||||||
from election.models import Election, Role, Candidature, ElectionList
|
from election.models import Election, Role, Candidature, ElectionList
|
||||||
from forum.models import Forum, ForumTopic
|
from forum.models import Forum, ForumTopic
|
||||||
@ -340,6 +340,8 @@ Welcome to the wiki page!
|
|||||||
c.save()
|
c.save()
|
||||||
r = ProductType(name="Rechargements")
|
r = ProductType(name="Rechargements")
|
||||||
r.save()
|
r.save()
|
||||||
|
verre = ProductType(name="Verre")
|
||||||
|
verre.save()
|
||||||
cotis = Product(name="Cotis 1 semestre", code="1SCOTIZ", product_type=c, purchase_price="15", selling_price="15",
|
cotis = Product(name="Cotis 1 semestre", code="1SCOTIZ", product_type=c, purchase_price="15", selling_price="15",
|
||||||
special_selling_price="15", club=main_club)
|
special_selling_price="15", club=main_club)
|
||||||
cotis.save()
|
cotis.save()
|
||||||
@ -355,6 +357,14 @@ Welcome to the wiki page!
|
|||||||
cble = Product(name="Chimay Bleue", code="CBLE", product_type=p, purchase_price="1.50", selling_price="1.7",
|
cble = Product(name="Chimay Bleue", code="CBLE", product_type=p, purchase_price="1.50", selling_price="1.7",
|
||||||
special_selling_price="1.6", club=main_club)
|
special_selling_price="1.6", club=main_club)
|
||||||
cble.save()
|
cble.save()
|
||||||
|
cons = Product(name="Consigne Eco-cup", code="CONS", product_type=verre, purchase_price="1", selling_price="1",
|
||||||
|
special_selling_price="1", club=main_club)
|
||||||
|
cons.id = 1152
|
||||||
|
cons.save()
|
||||||
|
dcons = Product(name="Déconsigne Eco-cup", code="DECO", product_type=verre, purchase_price="-1", selling_price="-1",
|
||||||
|
special_selling_price="-1", club=main_club)
|
||||||
|
dcons.id = 1151
|
||||||
|
dcons.save()
|
||||||
Product(name="Corsendonk", code="CORS", product_type=p, purchase_price="1.50", selling_price="1.7",
|
Product(name="Corsendonk", code="CORS", product_type=p, purchase_price="1.50", selling_price="1.7",
|
||||||
special_selling_price="1.6", club=main_club).save()
|
special_selling_price="1.6", club=main_club).save()
|
||||||
Product(name="Carolus", code="CARO", product_type=p, purchase_price="1.50", selling_price="1.7",
|
Product(name="Carolus", code="CARO", product_type=p, purchase_price="1.50", selling_price="1.7",
|
||||||
@ -362,6 +372,8 @@ Welcome to the wiki page!
|
|||||||
mde = Counter.objects.filter(name="MDE").first()
|
mde = Counter.objects.filter(name="MDE").first()
|
||||||
mde.products.add(barb)
|
mde.products.add(barb)
|
||||||
mde.products.add(cble)
|
mde.products.add(cble)
|
||||||
|
mde.products.add(cons)
|
||||||
|
mde.products.add(dcons)
|
||||||
mde.sellers.add(skia)
|
mde.sellers.add(skia)
|
||||||
mde.save()
|
mde.save()
|
||||||
|
|
||||||
@ -473,6 +485,9 @@ Welcome to the wiki page!
|
|||||||
start=s.subscription_start)
|
start=s.subscription_start)
|
||||||
s.save()
|
s.save()
|
||||||
|
|
||||||
|
Selling(label=dcons.name, product=dcons, counter=mde, unit_price=dcons.selling_price, club=main_club,
|
||||||
|
quantity=settings.SITH_ECOCUP_LIMIT + 3, seller=skia, customer=krophil.customer).save()
|
||||||
|
|
||||||
# Add barman to counter
|
# Add barman to counter
|
||||||
c = Counter.objects.get(id=2)
|
c = Counter.objects.get(id=2)
|
||||||
c.sellers.add(User.objects.get(pk=krophil.pk))
|
c.sellers.add(User.objects.get(pk=krophil.pk))
|
||||||
|
@ -37,14 +37,18 @@
|
|||||||
<h3>{% trans %}User account{% endtrans %}</h3>
|
<h3>{% trans %}User account{% endtrans %}</h3>
|
||||||
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
|
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
|
||||||
<div id="drop">
|
<div id="drop">
|
||||||
{% if customer.refillings.exists() %}
|
{% set bought = customer.buyings.exists() %}
|
||||||
{% if customer.buyings.exists() %}
|
{% set refilled = customer.refillings.exists() %}
|
||||||
|
{% if bought or refilled %}
|
||||||
|
{% if bought %}
|
||||||
<h5>{% trans %}Account buyings{% endtrans %}</h5>
|
<h5>{% trans %}Account buyings{% endtrans %}</h5>
|
||||||
{{ monthly(buyings_month) }}
|
{{ monthly(buyings_month) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if refilled %}
|
||||||
<h5>{% trans %}Refillings{% endtrans %}</h5>
|
<h5>{% trans %}Refillings{% endtrans %}</h5>
|
||||||
{{ monthly(refilling_month) }}
|
{{ monthly(refilling_month) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if customer.user.invoices.exists() %}
|
{% if customer.user.invoices.exists() %}
|
||||||
<h5>{% trans %}Eboutic invoices{% endtrans %}</h5>
|
<h5>{% trans %}Eboutic invoices{% endtrans %}</h5>
|
||||||
{{ monthly(invoices_month) }}
|
{{ monthly(invoices_month) }}
|
||||||
|
43
counter/migrations/0013_customer_recorded_products.py
Normal file
43
counter/migrations/0013_customer_recorded_products.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.db import migrations, models
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from core.models import User
|
||||||
|
from counter.models import Customer, Product, Selling, Counter
|
||||||
|
|
||||||
|
|
||||||
|
def balance_ecocups(apps, schema_editor):
|
||||||
|
for customer in Customer.objects.all():
|
||||||
|
customer.recorded_products = 0
|
||||||
|
for selling in customer.buyings.filter(product__id__in=[settings.SITH_ECOCUP_CONS, settings.SITH_ECOCUP_DECO]).all():
|
||||||
|
if selling.product.is_record_product:
|
||||||
|
customer.recorded_products += selling.quantity
|
||||||
|
elif selling.product.is_unrecord_product:
|
||||||
|
customer.recorded_products -= selling.quantity
|
||||||
|
if customer.recorded_products < -settings.SITH_ECOCUP_LIMIT:
|
||||||
|
qt = -(customer.recorded_products + settings.SITH_ECOCUP_LIMIT)
|
||||||
|
cons = Product.objects.get(id=settings.SITH_ECOCUP_CONS)
|
||||||
|
Selling(label=_("Ecocup regularization"), product=cons, unit_price=cons.selling_price,
|
||||||
|
club=cons.club, counter=Counter.objects.filter(name='Foyer').first(),
|
||||||
|
quantity=qt, seller=User.objects.get(id=0), customer=customer).save(allow_negative=True)
|
||||||
|
customer.recorded_products += qt
|
||||||
|
customer.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('counter', '0012_auto_20170515_2202'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customer',
|
||||||
|
name='recorded_products',
|
||||||
|
field=models.IntegerField(verbose_name='recorded items', default=0),
|
||||||
|
),
|
||||||
|
migrations.RunPython(balance_ecocups),
|
||||||
|
]
|
@ -51,6 +51,7 @@ class Customer(models.Model):
|
|||||||
user = models.OneToOneField(User, primary_key=True)
|
user = models.OneToOneField(User, primary_key=True)
|
||||||
account_id = models.CharField(_('account id'), max_length=10, unique=True)
|
account_id = models.CharField(_('account id'), max_length=10, unique=True)
|
||||||
amount = CurrencyField(_('amount'))
|
amount = CurrencyField(_('amount'))
|
||||||
|
recorded_products = models.IntegerField(_('recorded product'), default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('customer')
|
verbose_name = _('customer')
|
||||||
@ -60,6 +61,13 @@ class Customer(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s" % (self.user.username, self.account_id)
|
return "%s - %s" % (self.user.username, self.account_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_record(self):
|
||||||
|
return self.recorded_products > -settings.SITH_ECOCUP_LIMIT
|
||||||
|
|
||||||
|
def can_record_more(self, number):
|
||||||
|
return self.recorded_products - number >= -settings.SITH_ECOCUP_LIMIT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_buy(self):
|
def can_buy(self):
|
||||||
return (self.user.subscriptions.last() and
|
return (self.user.subscriptions.last() and
|
||||||
@ -72,8 +80,13 @@ class Customer(models.Model):
|
|||||||
letter = random.choice(string.ascii_lowercase)
|
letter = random.choice(string.ascii_lowercase)
|
||||||
return number + letter
|
return number + letter
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, allow_negative=False, is_selling=False, *args, **kwargs):
|
||||||
if self.amount < 0:
|
"""
|
||||||
|
is_selling : tell if the current action is a selling
|
||||||
|
allow_negative : ignored if not a selling. Allow a selling to put the account in negative
|
||||||
|
Those two parameters avoid blocking the save method of a customer if his account is negative
|
||||||
|
"""
|
||||||
|
if self.amount < 0 and (is_selling and not allow_negative):
|
||||||
raise ValidationError(_("Not enough money"))
|
raise ValidationError(_("Not enough money"))
|
||||||
super(Customer, self).save(*args, **kwargs)
|
super(Customer, self).save(*args, **kwargs)
|
||||||
|
|
||||||
@ -143,6 +156,14 @@ class Product(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('product')
|
verbose_name = _('product')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_record_product(self):
|
||||||
|
return settings.SITH_ECOCUP_CONS == self.id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_unrecord_product(self):
|
||||||
|
return settings.SITH_ECOCUP_DECO == self.id
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
@ -376,13 +397,16 @@ class Selling(models.Model):
|
|||||||
html_message=message_html
|
html_message=message_html
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, allow_negative=False, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
allow_negative : Allow this selling to use more money than available for this user
|
||||||
|
"""
|
||||||
if not self.date:
|
if not self.date:
|
||||||
self.date = timezone.now()
|
self.date = timezone.now()
|
||||||
self.full_clean()
|
self.full_clean()
|
||||||
if not self.is_validated:
|
if not self.is_validated:
|
||||||
self.customer.amount -= self.quantity * self.unit_price
|
self.customer.amount -= self.quantity * self.unit_price
|
||||||
self.customer.save()
|
self.customer.save(allow_negative=allow_negative, is_selling=True)
|
||||||
self.is_validated = True
|
self.is_validated = True
|
||||||
u = User.objects.filter(id=self.customer.user.id).first()
|
u = User.objects.filter(id=self.customer.user.id).first()
|
||||||
if u.was_subscribed:
|
if u.was_subscribed:
|
||||||
|
@ -330,6 +330,28 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
except:
|
except:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def compute_record_product(self, request, product=None):
|
||||||
|
recorded = 0
|
||||||
|
basket = request.session['basket']
|
||||||
|
|
||||||
|
if product:
|
||||||
|
if product.is_record_product:
|
||||||
|
recorded -= 1
|
||||||
|
elif product.is_unrecord_product:
|
||||||
|
recorded += 1
|
||||||
|
|
||||||
|
for p in basket:
|
||||||
|
bproduct = self.get_product(str(p))
|
||||||
|
if bproduct.is_record_product:
|
||||||
|
recorded -= basket[p]['qty']
|
||||||
|
elif bproduct.is_unrecord_product:
|
||||||
|
recorded += basket[p]['qty']
|
||||||
|
return recorded
|
||||||
|
|
||||||
|
def is_record_product_ok(self, request, product):
|
||||||
|
return self.customer.can_record_more(
|
||||||
|
self.compute_record_product(request, product))
|
||||||
|
|
||||||
def add_product(self, request, q=1, p=None):
|
def add_product(self, request, q=1, p=None):
|
||||||
"""
|
"""
|
||||||
Add a product to the basket
|
Add a product to the basket
|
||||||
@ -359,6 +381,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
if self.customer.amount < (total + round(q * float(price), 2)): # Check for enough money
|
if self.customer.amount < (total + round(q * float(price), 2)): # Check for enough money
|
||||||
request.session['not_enough'] = True
|
request.session['not_enough'] = True
|
||||||
return False
|
return False
|
||||||
|
if product.is_unrecord_product and not self.is_record_product_ok(request, product):
|
||||||
|
request.session['not_allowed'] = True
|
||||||
|
return False
|
||||||
if product.limit_age >= 18 and not self.customer.user.date_of_birth:
|
if product.limit_age >= 18 and not self.customer.user.date_of_birth:
|
||||||
request.session['no_age'] = True
|
request.session['no_age'] = True
|
||||||
return False
|
return False
|
||||||
@ -421,6 +446,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
""" Finish the click session, and validate the basket """
|
""" Finish the click session, and validate the basket """
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
request.session['last_basket'] = []
|
request.session['last_basket'] = []
|
||||||
|
if self.sum_basket(request) > self.customer.amount:
|
||||||
|
raise DataError(_("You have not enough money to buy all the basket"))
|
||||||
|
|
||||||
for pid, infos in request.session['basket'].items():
|
for pid, infos in request.session['basket'].items():
|
||||||
# This duplicates code for DB optimization (prevent to load many times the same object)
|
# This duplicates code for DB optimization (prevent to load many times the same object)
|
||||||
p = Product.objects.filter(pk=pid).first()
|
p = Product.objects.filter(pk=pid).first()
|
||||||
@ -428,8 +456,6 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
uprice = p.special_selling_price
|
uprice = p.special_selling_price
|
||||||
else:
|
else:
|
||||||
uprice = p.selling_price
|
uprice = p.selling_price
|
||||||
if uprice * infos['qty'] > self.customer.amount:
|
|
||||||
raise DataError(_("You have not enough money to buy all the basket"))
|
|
||||||
request.session['last_basket'].append("%d x %s" % (infos['qty'] + infos['bonus_qty'], p.name))
|
request.session['last_basket'].append("%d x %s" % (infos['qty'] + infos['bonus_qty'], p.name))
|
||||||
s = Selling(label=p.name, product=p, club=p.club, counter=self.object, unit_price=uprice,
|
s = Selling(label=p.name, product=p, club=p.club, counter=self.object, unit_price=uprice,
|
||||||
quantity=infos['qty'], seller=self.operator, customer=self.customer)
|
quantity=infos['qty'], seller=self.operator, customer=self.customer)
|
||||||
@ -438,6 +464,8 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
s = Selling(label=p.name + " (Plateau)", product=p, club=p.club, counter=self.object, unit_price=0,
|
s = Selling(label=p.name + " (Plateau)", product=p, club=p.club, counter=self.object, unit_price=0,
|
||||||
quantity=infos['bonus_qty'], seller=self.operator, customer=self.customer)
|
quantity=infos['bonus_qty'], seller=self.operator, customer=self.customer)
|
||||||
s.save()
|
s.save()
|
||||||
|
self.customer.recorded_products -= self.compute_record_product(request)
|
||||||
|
self.customer.save()
|
||||||
request.session['last_customer'] = self.customer.user.get_display_name()
|
request.session['last_customer'] = self.customer.user.get_display_name()
|
||||||
request.session['last_total'] = "%0.2f" % self.sum_basket(request)
|
request.session['last_total'] = "%0.2f" % self.sum_basket(request)
|
||||||
request.session['new_customer_amount'] = str(self.customer.amount)
|
request.session['new_customer_amount'] = str(self.customer.amount)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -397,6 +397,13 @@ SITH_COUNTER_BANK = [
|
|||||||
('LA-POSTE', 'La Poste'),
|
('LA-POSTE', 'La Poste'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SITH_ECOCUP_CONS = 1152
|
||||||
|
|
||||||
|
SITH_ECOCUP_DECO = 1151
|
||||||
|
|
||||||
|
# The limit is the maximum difference between cons and deco possible for a customer
|
||||||
|
SITH_ECOCUP_LIMIT = 3
|
||||||
|
|
||||||
# Defines pagination for cash summary
|
# Defines pagination for cash summary
|
||||||
SITH_COUNTER_CASH_SUMMARY_LENGTH = 50
|
SITH_COUNTER_CASH_SUMMARY_LENGTH = 50
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user