Update login system to support the multiple threads of UWSGI

This commit is contained in:
Skia 2016-08-26 20:56:16 +02:00
parent b33c3b20bb
commit 9927310f6e
6 changed files with 134 additions and 44 deletions

View File

@ -291,6 +291,12 @@ label {
#user_edit img {
width: 100px;
}
#cash_summary_form label {
display: inline;
}
.inline {
display: inline;
}
.form_button {
width: 150px;
height: 120px;

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
import accounting.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('counter', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CashRegisterSummary',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('date', models.DateTimeField(verbose_name='date')),
('comment', models.TextField(null=True, verbose_name='comment', blank=True)),
('emptied', models.BooleanField(default=False, verbose_name='emptied')),
('counter', models.ForeignKey(to='counter.Counter', related_name='cash_summaries', verbose_name='counter')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='cash_summaries', verbose_name='user')),
],
options={
'verbose_name': 'cash register summary',
},
),
migrations.CreateModel(
name='CashRegisterSummaryItem',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('value', accounting.models.CurrencyField(max_digits=12, verbose_name='value', decimal_places=2)),
('quantity', models.IntegerField(default=0, verbose_name='quantity')),
('check', models.BooleanField(default=False, verbose_name='check')),
('cash_summary', models.ForeignKey(to='counter.CashRegisterSummary', related_name='items', verbose_name='cash summary')),
],
options={
'verbose_name': 'cash register summary item',
},
),
migrations.AlterField(
model_name='permanency',
name='counter',
field=models.ForeignKey(to='counter.Counter', related_name='permanencies', verbose_name='counter'),
),
migrations.AlterField(
model_name='permanency',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='permanencies', verbose_name='user'),
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import datetime
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('counter', '0002_auto_20160826_1342'),
]
operations = [
migrations.AddField(
model_name='permanency',
name='activity',
field=models.DateTimeField(verbose_name='activity time', auto_now=True, default=datetime.datetime(2016, 8, 26, 17, 5, 31, 202824, tzinfo=utc)),
preserve_default=False,
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0003_permanency_activity'),
]
operations = [
migrations.AlterField(
model_name='permanency',
name='end',
field=models.DateTimeField(verbose_name='end date', null=True),
),
]

View File

@ -109,15 +109,14 @@ class Product(models.Model):
class Counter(models.Model):
name = models.CharField(_('name'), max_length=30)
club = models.ForeignKey(Club, related_name="counters")
products = models.ManyToManyField(Product, related_name="counters", blank=True)
club = models.ForeignKey(Club, related_name="counters", verbose_name=_("club"))
products = models.ManyToManyField(Product, related_name="counters", verbose_name=_("products"), blank=True)
type = models.CharField(_('counter type'),
max_length=255,
choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))])
sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='counters', blank=True)
edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True)
barmen_session = {}
class Meta:
verbose_name = _('counter')
@ -144,31 +143,21 @@ class Counter(models.Model):
sub = get_subscriber(request.user)
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or sub in self.sellers
def add_barman(counter_id, user_id):
def add_barman(self, user):
"""
Logs a barman in to the given counter
A user is stored as a tuple with its login time
"""
counter_id = int(counter_id)
user_id = int(user_id)
if counter_id not in Counter.barmen_session.keys():
Counter.barmen_session[counter_id] = {'users': {(user_id, timezone.now())}, 'time': timezone.now()}
else:
Counter.barmen_session[counter_id]['users'].add((user_id, timezone.now()))
Permanency(user=user, counter=self, start=timezone.now(), end=None).save()
def del_barman(counter_id, user_id):
def del_barman(self, user):
"""
Logs a barman out and store its permanency
"""
counter_id = int(counter_id)
user_id = int(user_id)
user_tuple = None
for t in Counter.barmen_session[counter_id]['users']:
if t[0] == user_id: user_tuple = t
Counter.barmen_session[counter_id]['users'].remove(user_tuple)
u = User.objects.filter(id=user_id).first()
c = Counter.objects.filter(id=counter_id).first()
Permanency(user=u, counter=c, start=user_tuple[1], end=Counter.barmen_session[counter_id]['time']).save()
perm = Permanency.objects.filter(counter=self, user=user, end=None).all()
for p in perm:
p.end = p.activity
p.save()
def get_barmen_list(self):
"""
@ -176,19 +165,15 @@ class Counter(models.Model):
Also handle the timeout of the barmen
"""
pl = Permanency.objects.filter(counter=self, end=None).all()
bl = []
counter_id = self.id
if counter_id in list(Counter.barmen_session.keys()):
for b in Counter.barmen_session[counter_id]['users']:
# Reminder: user is stored as a tuple with its login time
bl.append(User.objects.filter(id=b[0]).first())
if (timezone.now() - Counter.barmen_session[counter_id]['time']) < timedelta(minutes=settings.SITH_BARMAN_TIMEOUT):
Counter.barmen_session[counter_id]['time'] = timezone.now()
for p in pl:
if timezone.now() - p.activity < timedelta(minutes=settings.SITH_BARMAN_TIMEOUT):
p.save() # Update activity
bl.append(p.user)
else:
for b in bl:
Counter.del_barman(counter_id, b.id)
bl = []
Counter.barmen_session[counter_id]['users'] = set()
p.end = p.activity
p.save()
return bl
def get_random_barman(self):
@ -292,10 +277,11 @@ class Permanency(models.Model):
"""
This class aims at storing a traceability of who was barman where and when
"""
user = models.ForeignKey(User, related_name="permanencies")
counter = models.ForeignKey(Counter, related_name="permanencies")
user = models.ForeignKey(User, related_name="permanencies", verbose_name=_("user"))
counter = models.ForeignKey(Counter, related_name="permanencies", verbose_name=_("counter"))
start = models.DateTimeField(_('start date'))
end = models.DateTimeField(_('end date'))
end = models.DateTimeField(_('end date'), null=True)
activity = models.DateTimeField(_('last activity date'), auto_now=True)
class Meta:
verbose_name = _("permanency")

View File

@ -19,9 +19,10 @@ from ajax_select import make_ajax_form, make_ajax_field
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from core.views.forms import SelectUser
from core.models import User
from subscription.models import Subscriber
from subscription.views import get_subscriber
from counter.models import Counter, Customer, Product, Selling, Refilling, ProductType
from counter.models import Counter, Customer, Product, Selling, Refilling, ProductType, CashRegisterSummary, CashRegisterSummaryItem
class GetUserForm(forms.Form):
"""
@ -212,7 +213,7 @@ class CounterClick(DetailView):
product = self.get_product(pid)
can_buy = False
for g in product.buying_groups.all():
if request.user.is_in_group(g.name):
if self.customer.user.is_in_group(g.name):
can_buy = True
if not can_buy:
request.session['not_allowed'] = True
@ -343,12 +344,13 @@ class CounterLogin(RedirectView):
Register the logged user as barman for this counter
"""
self.counter_id = kwargs['counter_id']
self.counter = Counter.objects.filter(id=kwargs['counter_id']).first()
form = AuthenticationForm(request, data=request.POST)
self.errors = []
if form.is_valid():
user = Subscriber.objects.filter(username=form.cleaned_data['username']).first()
if user.is_subscribed():
Counter.add_barman(self.counter_id, user.id)
user = User.objects.filter(username=form.cleaned_data['username']).first()
if user.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP) and not user in self.counter.get_barmen_list():
self.counter.add_barman(user)
else:
self.errors += ["subscription"]
else:
@ -364,8 +366,9 @@ class CounterLogout(RedirectView):
"""
Unregister the user from the barman
"""
self.counter_id = kwargs['counter_id']
Counter.del_barman(self.counter_id, request.POST['user_id'])
self.counter = Counter.objects.filter(id=kwargs['counter_id']).first()
user = User.objects.filter(id=request.POST['user_id']).first()
self.counter.del_barman(user)
return super(CounterLogout, self).post(request, *args, **kwargs)
def get_redirect_url(self, *args, **kwargs):
@ -384,8 +387,8 @@ class CounterEditForm(forms.ModelForm):
class Meta:
model = Counter
fields = ['sellers', 'products']
sellers = make_ajax_field(Counter, 'sellers', 'users', show_help_text=False)
products = make_ajax_field(Counter, 'products', 'products')
sellers = make_ajax_field(Counter, 'sellers', 'users', help_text="")
products = make_ajax_field(Counter, 'products', 'products', help_text="")
class CounterEditView(CanEditMixin, UpdateView):
"""
@ -394,7 +397,7 @@ class CounterEditView(CanEditMixin, UpdateView):
model = Counter
form_class = CounterEditForm
pk_url_kwarg = "counter_id"
template_name = 'counter/counter_edit.jinja'
template_name = 'core/edit.jinja'
def get_success_url(self):
return reverse_lazy('counter:admin', kwargs={'counter_id': self.object.id})