mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-25 18:44:23 +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 club.models import Club, Membership
|
||||
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 election.models import Election, Role, Candidature, ElectionList
|
||||
from forum.models import Forum, ForumTopic
|
||||
@ -340,6 +340,8 @@ Welcome to the wiki page!
|
||||
c.save()
|
||||
r = ProductType(name="Rechargements")
|
||||
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",
|
||||
special_selling_price="15", club=main_club)
|
||||
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",
|
||||
special_selling_price="1.6", club=main_club)
|
||||
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",
|
||||
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",
|
||||
@ -362,6 +372,8 @@ Welcome to the wiki page!
|
||||
mde = Counter.objects.filter(name="MDE").first()
|
||||
mde.products.add(barb)
|
||||
mde.products.add(cble)
|
||||
mde.products.add(cons)
|
||||
mde.products.add(dcons)
|
||||
mde.sellers.add(skia)
|
||||
mde.save()
|
||||
|
||||
@ -473,6 +485,9 @@ Welcome to the wiki page!
|
||||
start=s.subscription_start)
|
||||
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
|
||||
c = Counter.objects.get(id=2)
|
||||
c.sellers.add(User.objects.get(pk=krophil.pk))
|
||||
|
@ -37,14 +37,18 @@
|
||||
<h3>{% trans %}User account{% endtrans %}</h3>
|
||||
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
|
||||
<div id="drop">
|
||||
{% if customer.refillings.exists() %}
|
||||
{% if customer.buyings.exists() %}
|
||||
{% set bought = customer.buyings.exists() %}
|
||||
{% set refilled = customer.refillings.exists() %}
|
||||
{% if bought or refilled %}
|
||||
{% if bought %}
|
||||
<h5>{% trans %}Account buyings{% endtrans %}</h5>
|
||||
{{ monthly(buyings_month) }}
|
||||
{% endif %}
|
||||
{% if refilled %}
|
||||
<h5>{% trans %}Refillings{% endtrans %}</h5>
|
||||
{{ monthly(refilling_month) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if customer.user.invoices.exists() %}
|
||||
<h5>{% trans %}Eboutic invoices{% endtrans %}</h5>
|
||||
{{ 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)
|
||||
account_id = models.CharField(_('account id'), max_length=10, unique=True)
|
||||
amount = CurrencyField(_('amount'))
|
||||
recorded_products = models.IntegerField(_('recorded product'), default=0)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('customer')
|
||||
@ -60,6 +61,13 @@ class Customer(models.Model):
|
||||
def __str__(self):
|
||||
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
|
||||
def can_buy(self):
|
||||
return (self.user.subscriptions.last() and
|
||||
@ -72,8 +80,13 @@ class Customer(models.Model):
|
||||
letter = random.choice(string.ascii_lowercase)
|
||||
return number + letter
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.amount < 0:
|
||||
def save(self, allow_negative=False, is_selling=False, *args, **kwargs):
|
||||
"""
|
||||
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"))
|
||||
super(Customer, self).save(*args, **kwargs)
|
||||
|
||||
@ -143,6 +156,14 @@ class Product(models.Model):
|
||||
class Meta:
|
||||
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):
|
||||
"""
|
||||
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
|
||||
)
|
||||
|
||||
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:
|
||||
self.date = timezone.now()
|
||||
self.full_clean()
|
||||
if not self.is_validated:
|
||||
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
|
||||
u = User.objects.filter(id=self.customer.user.id).first()
|
||||
if u.was_subscribed:
|
||||
|
@ -330,6 +330,28 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
||||
except:
|
||||
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):
|
||||
"""
|
||||
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
|
||||
request.session['not_enough'] = True
|
||||
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:
|
||||
request.session['no_age'] = True
|
||||
return False
|
||||
@ -421,6 +446,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
||||
""" Finish the click session, and validate the basket """
|
||||
with transaction.atomic():
|
||||
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():
|
||||
# This duplicates code for DB optimization (prevent to load many times the same object)
|
||||
p = Product.objects.filter(pk=pid).first()
|
||||
@ -428,8 +456,6 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
||||
uprice = p.special_selling_price
|
||||
else:
|
||||
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))
|
||||
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)
|
||||
@ -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,
|
||||
quantity=infos['bonus_qty'], seller=self.operator, customer=self.customer)
|
||||
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_total'] = "%0.2f" % self.sum_basket(request)
|
||||
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'),
|
||||
]
|
||||
|
||||
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
|
||||
SITH_COUNTER_CASH_SUMMARY_LENGTH = 50
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user