From 0356ec34ae3b4f81f71185c158faa0919bd80cc8 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Sun, 19 Mar 2017 16:03:19 -0300 Subject: [PATCH 1/4] Add createopes command --- kfet/management/commands/createopes.py | 173 +++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 kfet/management/commands/createopes.py diff --git a/kfet/management/commands/createopes.py b/kfet/management/commands/createopes.py new file mode 100644 index 00000000..aaca84c7 --- /dev/null +++ b/kfet/management/commands/createopes.py @@ -0,0 +1,173 @@ + +""" +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( + on_acc=account, + checkout=checkout, + is_cof=account.cofprofile.is_cof + ) + opegroup.save() + + # Generating operations + 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 + + opes_created += 1 + ope.save() + amount += ope.amount + + opegroup.amount = amount + opegroup.at = at + 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( + at=at, + comment=comment, + valid_by=random.choice(accounts) + ) + transfergroup.save() + + # Randomly generate transfer + for i in range(random.randint(1, 4)): + transfer = Transfer( + group=transfergroup, + from_acc=random.choice(accounts), + to_acc=random.choice(accounts), + amount=Decimal(random.randint(1, 99)/10) + ) + transfer.save() + transfers += 1 + + 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)) From 36dc6439a80d5673e518715ff0bbe8a4cc8d2b16 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Sun, 19 Mar 2017 16:03:39 -0300 Subject: [PATCH 2/4] Plug createopes into loadkfetdevdata --- kfet/management/commands/loadkfetdevdata.py | 64 +-------------------- 1 file changed, 3 insertions(+), 61 deletions(-) diff --git a/kfet/management/commands/loadkfetdevdata.py b/kfet/management/commands/loadkfetdevdata.py index 705f6f27..8eee85a9 100644 --- a/kfet/management/commands/loadkfetdevdata.py +++ b/kfet/management/commands/loadkfetdevdata.py @@ -5,15 +5,14 @@ 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) # Où sont stockés les fichiers json DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), @@ -130,61 +129,4 @@ class Command(MyBaseCommand): # 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') From 6d36d50e9ab5146bfeb3451aa9625156d8273744 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Mon, 20 Mar 2017 01:56:59 -0300 Subject: [PATCH 3/4] Fix 'at' property for transfergroups --- kfet/management/commands/createopes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kfet/management/commands/createopes.py b/kfet/management/commands/createopes.py index aaca84c7..75bb23ae 100644 --- a/kfet/management/commands/createopes.py +++ b/kfet/management/commands/createopes.py @@ -147,7 +147,6 @@ class Command(BaseCommand): comment = "" transfergroup = TransferGroup( - at=at, comment=comment, valid_by=random.choice(accounts) ) @@ -164,6 +163,9 @@ class Command(BaseCommand): transfer.save() transfers += 1 + transfergroup.at = at + transfergroup.save() + self.stdout.write( "- {:d} opérations créées dont {:d} commandes d'articles" .format(opes_created, purchases)) From dd4d1f3061f08680a120ab7a00775e0804e4238c Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Mon, 20 Mar 2017 20:19:04 -0300 Subject: [PATCH 4/4] Improves creation efficiency --- kfet/management/commands/createopes.py | 26 +++++++++++++------------- kfet/models.py | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/kfet/management/commands/createopes.py b/kfet/management/commands/createopes.py index 75bb23ae..77663b2b 100644 --- a/kfet/management/commands/createopes.py +++ b/kfet/management/commands/createopes.py @@ -78,14 +78,15 @@ class Command(BaseCommand): # Initialize opegroup amount amount = Decimal('0') - opegroup = OperationGroup( + opegroup = OperationGroup.objects.create( on_acc=account, checkout=checkout, + at=at, is_cof=account.cofprofile.is_cof ) - opegroup.save() # Generating operations + ope_list = [] for j in range(random.randint(1, 4)): # Operation type typevar = random.random() @@ -125,12 +126,12 @@ class Command(BaseCommand): ope.addcost_amount = addcost_amount * nb ope.amount -= ope.addcost_amount - opes_created += 1 - ope.save() + ope_list.append(ope) amount += ope.amount + Operation.objects.bulk_create(ope_list) + opes_created += len(ope_list) opegroup.amount = amount - opegroup.at = at opegroup.save() # Transfer generation @@ -146,25 +147,24 @@ class Command(BaseCommand): else: comment = "" - transfergroup = TransferGroup( + transfergroup = TransferGroup.objects.create( + at=at, comment=comment, valid_by=random.choice(accounts) ) - transfergroup.save() # Randomly generate transfer + transfer_list = [] for i in range(random.randint(1, 4)): - transfer = Transfer( + transfer_list.append(Transfer( group=transfergroup, from_acc=random.choice(accounts), to_acc=random.choice(accounts), amount=Decimal(random.randint(1, 99)/10) - ) - transfer.save() - transfers += 1 + )) - transfergroup.at = at - transfergroup.save() + Transfer.objects.bulk_create(transfer_list) + transfers += len(transfer_list) self.stdout.write( "- {:d} opérations créées dont {:d} commandes d'articles" diff --git a/kfet/models.py b/kfet/models.py index 419cd0a0..4e98c3c8 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -455,7 +455,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, @@ -491,7 +491,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)