diff --git a/bda/models.py b/bda/models.py
index a405a665..df73a209 100644
--- a/bda/models.py
+++ b/bda/models.py
@@ -315,10 +315,11 @@ class SpectacleRevente(models.Model):
# Envoie un mail aux perdants
for inscrit in inscrits:
if inscrit != winner:
- context['acheteur'] = inscrit.user
+ new_context = dict(context)
+ new_context['acheteur'] = inscrit.user
datatuple.append((
'bda-revente-loser',
- context,
+ new_context,
settings.MAIL_DATA['revente']['FROM'],
[inscrit.user.email]
))
diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py
index 95fdf3b7..332e156c 100644
--- a/gestioncof/petits_cours_views.py
+++ b/gestioncof/petits_cours_views.py
@@ -215,7 +215,7 @@ def _traitement_other(request, demande, redo):
proposals = proposals.items()
proposed_for = proposed_for.items()
return render(request,
- "gestiocof/traitement_demande_petit_cours_autre_niveau.html",
+ "gestioncof/traitement_demande_petit_cours_autre_niveau.html",
{"demande": demande,
"unsatisfied": unsatisfied,
"proposals": proposals,
diff --git a/kfet/management/commands/createopes.py b/kfet/management/commands/createopes.py
new file mode 100644
index 00000000..77663b2b
--- /dev/null
+++ b/kfet/management/commands/createopes.py
@@ -0,0 +1,175 @@
+
+"""
+Crée des opérations aléatoires réparties sur une période de temps spécifiée
+"""
+
+import random
+from datetime import timedelta
+from decimal import Decimal
+from django.utils import timezone
+from django.core.management.base import BaseCommand
+
+from kfet.models import (Account, Article, OperationGroup, Operation,
+ Checkout, Transfer, TransferGroup)
+
+
+class Command(BaseCommand):
+ help = "Crée des opérations réparties uniformément sur une période de temps"
+
+ def add_arguments(self, parser):
+ # Nombre d'opérations à créer
+ parser.add_argument('opes', type=int,
+ help='Number of opegroups to create')
+
+ # Période sur laquelle créer (depuis num_days avant maintenant)
+ parser.add_argument('days', type=int,
+ help='Period in which to create opegroups')
+
+ # Optionnel : nombre de transfert à créer (défaut 0)
+ parser.add_argument('--transfers', type=int, default=0,
+ help='Number of transfers to create (default 0)')
+
+
+ def handle(self, *args, **options):
+
+ self.stdout.write("Génération d'opérations")
+
+ # Output log vars
+ opes_created = 0
+ purchases = 0
+ transfers = 0
+
+ num_ops = options['opes']
+ num_transfers = options['transfers']
+ # Convert to seconds
+ time = options['days'] * 24 * 3600
+
+ checkout = Checkout.objects.first()
+ articles = Article.objects.all()
+ accounts = Account.objects.exclude(trigramme='LIQ')
+ liq_account = Account.objects.get(trigramme='LIQ')
+ try:
+ con_account = Account.objects.get(
+ cofprofile__user__first_name='Assurancetourix'
+ )
+ except Account.DoesNotExist:
+ con_account = random.choice(accounts)
+
+ for i in range(num_ops):
+
+ # Randomly pick account
+ if random.random() > 0.25:
+ account = random.choice(accounts)
+ else:
+ account = liq_account
+
+ # Randomly pick time
+ at = timezone.now() - timedelta(
+ seconds=random.randint(0, time))
+
+ # Majoration sur compte 'concert'
+ if random.random() < 0.2:
+ addcost = True
+ addcost_for = con_account
+ addcost_amount = Decimal('0.5')
+ else:
+ addcost = False
+
+ # Initialize opegroup amount
+ amount = Decimal('0')
+
+ opegroup = OperationGroup.objects.create(
+ on_acc=account,
+ checkout=checkout,
+ at=at,
+ is_cof=account.cofprofile.is_cof
+ )
+
+ # Generating operations
+ ope_list = []
+ for j in range(random.randint(1, 4)):
+ # Operation type
+ typevar = random.random()
+
+ # 0.1 probability to have a charge
+ if typevar > 0.9 and account != liq_account:
+ ope = Operation(
+ group=opegroup,
+ type=Operation.DEPOSIT,
+ is_checkout=(random.random() > 0.2),
+ amount=Decimal(random.randint(1, 99)/10)
+ )
+ # 0.1 probability to have a withdrawal
+ elif typevar > 0.8 and account != liq_account:
+ ope = Operation(
+ group=opegroup,
+ type=Operation.WITHDRAW,
+ is_checkout=(random.random() > 0.2),
+ amount=-Decimal(random.randint(1, 99)/10)
+ )
+ else:
+ article = random.choice(articles)
+ nb = random.randint(1, 5)
+
+ ope = Operation(
+ group=opegroup,
+ type=Operation.PURCHASE,
+ amount=-article.price*nb,
+ article=article,
+ article_nb=nb
+ )
+
+ purchases += 1
+
+ if addcost:
+ ope.addcost_for = addcost_for
+ ope.addcost_amount = addcost_amount * nb
+ ope.amount -= ope.addcost_amount
+
+ ope_list.append(ope)
+ amount += ope.amount
+
+ Operation.objects.bulk_create(ope_list)
+ opes_created += len(ope_list)
+ opegroup.amount = amount
+ opegroup.save()
+
+ # Transfer generation
+ for i in range(num_transfers):
+
+ # Randomly pick time
+ at = timezone.now() - timedelta(
+ seconds=random.randint(0, time))
+
+ # Choose whether to have a comment
+ if random.random() > 0.5:
+ comment = "placeholder comment"
+ else:
+ comment = ""
+
+ transfergroup = TransferGroup.objects.create(
+ at=at,
+ comment=comment,
+ valid_by=random.choice(accounts)
+ )
+
+ # Randomly generate transfer
+ transfer_list = []
+ for i in range(random.randint(1, 4)):
+ transfer_list.append(Transfer(
+ group=transfergroup,
+ from_acc=random.choice(accounts),
+ to_acc=random.choice(accounts),
+ amount=Decimal(random.randint(1, 99)/10)
+ ))
+
+ Transfer.objects.bulk_create(transfer_list)
+ transfers += len(transfer_list)
+
+ self.stdout.write(
+ "- {:d} opérations créées dont {:d} commandes d'articles"
+ .format(opes_created, purchases))
+
+ if transfers:
+ self.stdout.write("- {:d} transferts créés"
+ .format(transfers))
diff --git a/kfet/management/commands/loadkfetdevdata.py b/kfet/management/commands/loadkfetdevdata.py
index 705f6f27..7f2ec9a3 100644
--- a/kfet/management/commands/loadkfetdevdata.py
+++ b/kfet/management/commands/loadkfetdevdata.py
@@ -5,15 +5,15 @@ Crée des utilisateurs, des articles et des opérations aléatoires
import os
import random
from datetime import timedelta
-from decimal import Decimal
from django.utils import timezone
from django.contrib.auth.models import User, Group, Permission, ContentType
+from django.core.management import call_command
from gestioncof.management.base import MyBaseCommand
from gestioncof.models import CofProfile
-from kfet.models import (Account, Article, OperationGroup, Operation,
- Checkout, CheckoutStatement)
+from kfet.models import (Account, Checkout, CheckoutStatement, Supplier,
+ SupplierArticle, Article)
# Où sont stockés les fichiers json
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
@@ -126,65 +126,24 @@ class Command(MyBaseCommand):
amount_error=0
)
+ # ---
+ # Fournisseur
+ # ---
+
+ supplier, created = Supplier.objects.get_or_create(name="Panoramix")
+ if created:
+ articles = random.sample(list(Article.objects.all()), 40)
+ to_create = []
+ for article in articles:
+ to_create.append(SupplierArticle(
+ supplier=supplier,
+ article=article
+ ))
+
+ SupplierArticle.objects.bulk_create(to_create)
+
# ---
# Opérations
# ---
- self.stdout.write("Génération d'opérations")
-
- articles = Article.objects.all()
- accounts = Account.objects.exclude(trigramme='LIQ')
-
- num_op = 100
- # Operations are put uniformly over the span of a week
- past_date = 3600*24*7
-
- for i in range(num_op):
- if random.random() > 0.25:
- account = random.choice(accounts)
- else:
- account = liq_account
-
- amount = Decimal('0')
- at = timezone.now() - timedelta(
- seconds=random.randint(0, past_date))
-
- opegroup = OperationGroup(
- on_acc=account,
- checkout=checkout,
- at=at,
- is_cof=account.cofprofile.is_cof)
-
- opegroup.save()
-
- for j in range(random.randint(1, 4)):
- typevar = random.random()
- if typevar > 0.9 and account != liq_account:
- ope = Operation(
- group=opegroup,
- type=Operation.DEPOSIT,
- amount=Decimal(random.randint(1, 99)/10,)
- )
- elif typevar > 0.8 and account != liq_account:
- ope = Operation(
- group=opegroup,
- type=Operation.WITHDRAW,
- amount=-Decimal(random.randint(1, 99)/10,)
- )
- else:
- article = random.choice(articles)
- nb = random.randint(1, 5)
-
- ope = Operation(
- group=opegroup,
- type=Operation.PURCHASE,
- amount=-article.price*nb,
- article=article,
- article_nb=nb
- )
-
- ope.save()
- amount += ope.amount
-
- opegroup.amount = amount
- opegroup.save()
+ call_command('createopes', '100', '7', '--transfers=20')
diff --git a/kfet/migrations/0048_default_datetime.py b/kfet/migrations/0048_default_datetime.py
new file mode 100644
index 00000000..c9bacf1e
--- /dev/null
+++ b/kfet/migrations/0048_default_datetime.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('kfet', '0047_auto_20170104_1528'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='operationgroup',
+ name='at',
+ field=models.DateTimeField(default=django.utils.timezone.now),
+ ),
+ migrations.AlterField(
+ model_name='transfergroup',
+ name='at',
+ field=models.DateTimeField(default=django.utils.timezone.now),
+ ),
+ ]
diff --git a/kfet/models.py b/kfet/models.py
index 9d4a9536..9bb4f4f1 100644
--- a/kfet/models.py
+++ b/kfet/models.py
@@ -466,7 +466,7 @@ class OrderArticle(models.Model):
quantity_received = models.IntegerField(default = 0)
class TransferGroup(models.Model):
- at = models.DateTimeField(auto_now_add = True)
+ at = models.DateTimeField(default=timezone.now)
# Optional
comment = models.CharField(
max_length = 255,
@@ -502,7 +502,7 @@ class OperationGroup(models.Model):
checkout = models.ForeignKey(
Checkout, on_delete = models.PROTECT,
related_name = "opesgroup")
- at = models.DateTimeField(auto_now_add = True)
+ at = models.DateTimeField(default=timezone.now)
amount = models.DecimalField(
max_digits = 6, decimal_places = 2,
default = 0)
diff --git a/kfet/static/kfet/js/kfet.js b/kfet/static/kfet/js/kfet.js
index 8236b3e9..cc369e32 100644
--- a/kfet/static/kfet/js/kfet.js
+++ b/kfet/static/kfet/js/kfet.js
@@ -27,6 +27,53 @@ $(document).ready(function() {
}
});
+/*
+ * Generic Websocket class and k-psul ws instanciation
+ */
+
+class KfetWebsocket {
+
+ static get defaults() {
+ return {"relative_url": "", "default_msg": {}, "handlers": []};
+ }
+
+ constructor(data) {
+ $.extend(this, this.constructor.defaults, data);
+ }
+
+ get url() {
+ var websocket_protocol = window.location.protocol == 'https:' ? 'wss' : 'ws';
+ var location_host = window.location.host;
+ var location_url = window.location.pathname.startsWith('/gestion/') ? location_host + '/gestion' : location_host;
+
+ return websocket_protocol+"://" + location_url + this.relative_url ;
+ }
+
+ add_handler(handler) {
+ if (!this.socket)
+ this.listen();
+
+ this.handlers.push(handler);
+ }
+
+ listen() {
+ var that = this;
+ this.socket = new ReconnectingWebSocket(this.url);
+
+ this.socket.onmessage = function(e) {
+ var data = $.extend({}, that.default_msg, JSON.parse(e.data));
+ for (let handler of that.handlers) {
+ handler(data);
+ }
+ }
+ }
+}
+
+var OperationWebSocket = new KfetWebsocket({
+ 'relative_url': '/ws/k-fet/k-psul/',
+ 'default_msg': {'opegroups':[],'opes':[],'checkouts':[],'articles':[]},
+});
+
function dateUTCToParis(date) {
return moment.tz(date, 'UTC').tz('Europe/Paris');
}
diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html
index 5e5ce87d..1360a4be 100644
--- a/kfet/templates/kfet/kpsul.html
+++ b/kfet/templates/kfet/kpsul.html
@@ -12,7 +12,6 @@
-
{% endblock %}
@@ -1362,15 +1361,7 @@ $(document).ready(function() {
// Synchronization
// -----
- websocket_msg_default = {'opegroups':[],'opes':[],'checkouts':[],'articles':[]}
-
- var websocket_protocol = window.location.protocol == 'https:' ? 'wss' : 'ws';
- var location_host = window.location.host;
- var location_url = window.location.pathname.startsWith('/gestion/') ? location_host + '/gestion' : location_host;
- socket = new ReconnectingWebSocket(websocket_protocol+"://" + location_url + "/ws/k-fet/k-psul/");
- socket.onmessage = function(e) {
- data = $.extend({}, websocket_msg_default, JSON.parse(e.data));
-
+ OperationWebSocket.add_handler(function(data) {
for (var i=0; i