From 66304359c0f6fe6206f009f25ba6b96bc25acdd6 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Sun, 11 Dec 2016 16:22:55 -0200 Subject: [PATCH] unite cancel_ope and cancel_transfer --- kfet/views.py | 97 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/kfet/views.py b/kfet/views.py index 5fbcea3e..32889cff 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -1097,7 +1097,7 @@ def kpsul_perform_operations(request): @teamkfet_required def kpsul_cancel_operations(request): # Pour la réponse - data = { 'canceled': [], 'warnings': {}, 'errors': {}} + data = {'canceled': {}, 'warnings': {}, 'errors': {}} # Checking if BAD REQUEST (opes_pk not int or not existing) try: @@ -1105,20 +1105,39 @@ def kpsul_cancel_operations(request): opes_post = set(map(lambda s: int(s.split()[1]), filter(lambda s: s.split()[0] == 'ope', request.POST.getlist('operations[]', [])))) + transfers_post = \ + set(map(lambda s: int(s.split()[1]), + filter(lambda s: s.split()[0] == 'transfer', + request.POST.getlist('operations[]', [])))) except ValueError: return JsonResponse(data, status=400) + opes_all = ( Operation.objects .select_related('group', 'group__on_acc', 'group__on_acc__negative') .filter(pk__in=opes_post)) opes_pk = [ ope.pk for ope in opes_all ] opes_notexisting = [ ope for ope in opes_post if ope not in opes_pk ] - if opes_notexisting: - data['errors']['opes_notexisting'] = opes_notexisting + + transfers_all = ( + Transfer.objects + .select_related('group', 'from_acc', 'from_acc__negative', + 'to_acc', 'to_acc__negative') + .filter(pk__in=transfers_post)) + transfers_pk = [transfer.pk for transfer in transfers_all] + transfers_notexisting = [transfer for transfer in transfers_post + if transfer not in transfers_pk] + + if transfers_notexisting or opes_notexisting: + if transfers_notexisting: + data['errors']['transfers_notexisting'] = transfers_notexisting + if opes_notexisting: + data['errors']['opes_notexisting'] = opes_notexisting return JsonResponse(data, status=400) - opes_already_canceled = [] # Déjà annulée - opes = [] # Pas déjà annulée + already_canceled = {} # Opération/Transfert déjà annulé + opes = [] # Pas déjà annulée + transfers = [] required_perms = set() stop_all = False cancel_duration = Settings.CANCEL_DURATION() @@ -1129,7 +1148,7 @@ def kpsul_cancel_operations(request): for ope in opes_all: if ope.canceled_at: # Opération déjà annulée, va pour un warning en Response - opes_already_canceled.append(ope.pk) + already_canceled['opes'].append(ope.pk) else: opes.append(ope.pk) # Si opé il y a plus de CANCEL_DURATION, permission requise @@ -1163,7 +1182,7 @@ def kpsul_cancel_operations(request): if not last_statement or last_statement.at < ope.group.at: if ope.type == Operation.PURCHASE: if ope.group.on_acc.is_cash: - to_checkouts_balances[ope.group.checkout] -= - ope.amount + to_checkouts_balances[ope.group.checkout] -= -ope.amount else: to_checkouts_balances[ope.group.checkout] -= ope.amount @@ -1176,22 +1195,38 @@ def kpsul_cancel_operations(request): # est recalculé automatiquement if ope.article and ope.article_nb: last_stock = (InventoryArticle.objects - .select_related('inventory') - .filter(article=ope.article) - .order_by('inventory__at') - .last()) + .select_related('inventory') + .filter(article=ope.article) + .order_by('inventory__at') + .last()) if not last_stock or last_stock.inventory.at < ope.group.at: to_articles_stocks[ope.article] += ope.article_nb - if not opes: - data['warnings']['already_canceled'] = opes_already_canceled + for transfer in transfers_all: + if transfer.canceled_at: + # Transfert déjà annulé, va pour un warning en Response + already_canceled['transfers'].append(transfer.pk) + else: + transfers.append(transfer.pk) + # Si transfer il y a plus de CANCEL_DURATION, permission requise + if transfer.group.at + cancel_duration < timezone.now(): + required_perms.add('kfet.cancel_old_operations') + + # Calcul de toutes modifs à faire en cas de validation + + # Pour les balances de comptes + to_accounts_balances[transfer.from_acc] += transfer.amount + to_accounts_balances[transfer.to_acc] += -transfer.amount + + if not opes and not transfers: + data['warnings']['already_canceled'] = already_canceled return JsonResponse(data) negative_accounts = [] # Checking permissions or stop for account in to_accounts_balances: (perms, stop) = account.perms_to_perform_operation( - amount = to_accounts_balances[account]) + amount=to_accounts_balances[account]) required_perms |= perms stop_all = stop_all or stop if stop: @@ -1211,25 +1246,31 @@ def kpsul_cancel_operations(request): with transaction.atomic(): (Operation.objects.filter(pk__in=opes) .update(canceled_by=canceled_by, canceled_at=canceled_at)) + + (Transfer.objects.filter(pk__in=transfers) + .update(canceled_by=canceled_by, canceled_at=canceled_at)) + for account in to_accounts_balances: Account.objects.filter(pk=account.pk).update( - balance = F('balance') + to_accounts_balances[account]) + balance=F('balance') + to_accounts_balances[account]) for checkout in to_checkouts_balances: Checkout.objects.filter(pk=checkout.pk).update( - balance = F('balance') + to_checkouts_balances[checkout]) + balance=F('balance') + to_checkouts_balances[checkout]) for group in to_groups_amounts: OperationGroup.objects.filter(pk=group.pk).update( - amount = F('amount') + to_groups_amounts[group]) + amount=F('amount') + to_groups_amounts[group]) for article in to_articles_stocks: Article.objects.filter(pk=article.pk).update( - stock = F('stock') + to_articles_stocks[article]) + stock=F('stock') + to_articles_stocks[article]) # Websocket data - websocket_data = { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] } + websocket_data = {'opegroups': [], 'opes': [], + 'checkouts': [], 'articles': []} # Need refresh from db cause we used update on querysets - opegroups_pk = [ opegroup.pk for opegroup in to_groups_amounts ] + opegroups_pk = [opegroup.pk for opegroup in to_groups_amounts] opegroups = (OperationGroup.objects - .values('id','amount','is_cof').filter(pk__in=opegroups_pk)) + .values('id', 'amount', 'is_cof') + .filter(pk__in=opegroups_pk)) for opegroup in opegroups: websocket_data['opegroups'].append({ 'cancellation': True, @@ -1246,15 +1287,16 @@ def kpsul_cancel_operations(request): 'canceled_at': canceled_at, }) # Need refresh from db cause we used update on querysets - checkouts_pk = [ checkout.pk for checkout in to_checkouts_balances] + checkouts_pk = [checkout.pk for checkout in to_checkouts_balances] checkouts = (Checkout.objects - .values('id', 'balance').filter(pk__in=checkouts_pk)) + .values('id', 'balance') + .filter(pk__in=checkouts_pk)) for checkout in checkouts: websocket_data['checkouts'].append({ 'id': checkout['id'], 'balance': checkout['balance']}) # Need refresh from db cause we used update on querysets - articles_pk = [ article.pk for articles in to_articles_stocks] + articles_pk = [article.pk for articles in to_articles_stocks] articles = Article.objects.values('id', 'stock').filter(pk__in=articles_pk) for article in articles: websocket_data['articles'].append({ @@ -1262,9 +1304,10 @@ def kpsul_cancel_operations(request): 'stock': article['stock']}) consumers.KPsul.group_send('kfet.kpsul', websocket_data) - data['canceled'] = opes - if opes_already_canceled: - data['warnings']['already_canceled'] = opes_already_canceled + data['canceled']['opes'] = opes + data['canceled']['transfers'] = transfers + if already_canceled: + data['warnings']['already_canceled'] = already_canceled return JsonResponse(data) @login_required