""" 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.core.management.base import BaseCommand from django.utils import timezone from kfet.models import ( Account, Article, Checkout, Operation, OperationGroup, 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 now = timezone.now() 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) # use to fetch OperationGroup pk created by bulk_create at_list = [] # use to lazy set OperationGroup pk on Operation objects ope_by_grp = [] # OperationGroup objects to bulk_create opegroup_list = [] 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 = 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") # 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( type=Operation.DEPOSIT, amount=Decimal(random.randint(1, 99) / 10), ) # 0.05 probability to have a withdrawal elif typevar > 0.85 and account != liq_account: ope = Operation( type=Operation.WITHDRAW, amount=-Decimal(random.randint(1, 99) / 10), ) # 0.05 probability to have an edition elif typevar > 0.8 and account != liq_account: ope = Operation( type=Operation.EDIT, amount=Decimal(random.randint(1, 99) / 10) ) else: article = random.choice(articles) nb = random.randint(1, 5) ope = Operation( 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 opegroup_list.append( OperationGroup( on_acc=account, checkout=checkout, at=at, is_cof=account.cofprofile.is_cof, amount=amount, ) ) at_list.append(at) ope_by_grp.append((at, ope_list)) OperationGroup.objects.bulk_create(opegroup_list) # Fetch created OperationGroup objects pk by at opegroups = OperationGroup.objects.filter(at__in=at_list).values("id", "at") opegroups_by = {grp["at"]: grp["id"] for grp in opegroups} all_ope = [] for _ in range(num_ops): at, ope_list = ope_by_grp.pop() for ope in ope_list: ope.group_id = opegroups_by[at] all_ope.append(ope) Operation.objects.bulk_create(all_ope) opes_created = len(all_ope) # Transfer generation transfer_by_grp = [] transfergroup_list = [] at_list = [] for i in range(num_transfers): # Randomly pick time at = now - timedelta(seconds=random.randint(0, time)) # Choose whether to have a comment if random.random() > 0.5: comment = "placeholder comment" else: comment = "" transfergroup_list.append( TransferGroup(at=at, comment=comment, valid_by=random.choice(accounts)) ) at_list.append(at) # Randomly generate transfer transfer_list = [] for i in range(random.randint(1, 4)): transfer_list.append( Transfer( from_acc=random.choice(accounts), to_acc=random.choice(accounts), amount=Decimal(random.randint(1, 99) / 10), ) ) transfer_by_grp.append((at, transfer_list)) TransferGroup.objects.bulk_create(transfergroup_list) transfergroups = TransferGroup.objects.filter(at__in=at_list).values("id", "at") transfergroups_by = {grp["at"]: grp["id"] for grp in transfergroups} all_transfer = [] for _ in range(num_transfers): at, transfer_list = transfer_by_grp.pop() for transfer in transfer_list: transfer.group_id = transfergroups_by[at] all_transfer.append(transfer) Transfer.objects.bulk_create(all_transfer) transfers += len(all_transfer) 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))