unite cancel_ope and cancel_transfer

This commit is contained in:
Ludovic Stephan 2016-12-11 16:22:55 -02:00
parent 49bef61e53
commit 66304359c0

View file

@ -1097,7 +1097,7 @@ def kpsul_perform_operations(request):
@teamkfet_required @teamkfet_required
def kpsul_cancel_operations(request): def kpsul_cancel_operations(request):
# Pour la réponse # Pour la réponse
data = { 'canceled': [], 'warnings': {}, 'errors': {}} data = {'canceled': {}, 'warnings': {}, 'errors': {}}
# Checking if BAD REQUEST (opes_pk not int or not existing) # Checking if BAD REQUEST (opes_pk not int or not existing)
try: try:
@ -1105,20 +1105,39 @@ def kpsul_cancel_operations(request):
opes_post = set(map(lambda s: int(s.split()[1]), opes_post = set(map(lambda s: int(s.split()[1]),
filter(lambda s: s.split()[0] == 'ope', filter(lambda s: s.split()[0] == 'ope',
request.POST.getlist('operations[]', [])))) 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: except ValueError:
return JsonResponse(data, status=400) return JsonResponse(data, status=400)
opes_all = ( opes_all = (
Operation.objects Operation.objects
.select_related('group', 'group__on_acc', 'group__on_acc__negative') .select_related('group', 'group__on_acc', 'group__on_acc__negative')
.filter(pk__in=opes_post)) .filter(pk__in=opes_post))
opes_pk = [ ope.pk for ope in opes_all ] opes_pk = [ ope.pk for ope in opes_all ]
opes_notexisting = [ ope for ope in opes_post if ope not in opes_pk ] 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) return JsonResponse(data, status=400)
opes_already_canceled = [] # Déjà annulée already_canceled = {} # Opération/Transfert déjà annulé
opes = [] # Pas déjà annulée opes = [] # Pas déjà annulée
transfers = []
required_perms = set() required_perms = set()
stop_all = False stop_all = False
cancel_duration = Settings.CANCEL_DURATION() cancel_duration = Settings.CANCEL_DURATION()
@ -1129,7 +1148,7 @@ def kpsul_cancel_operations(request):
for ope in opes_all: for ope in opes_all:
if ope.canceled_at: if ope.canceled_at:
# Opération déjà annulée, va pour un warning en Response # 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: else:
opes.append(ope.pk) opes.append(ope.pk)
# Si opé il y a plus de CANCEL_DURATION, permission requise # 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 not last_statement or last_statement.at < ope.group.at:
if ope.type == Operation.PURCHASE: if ope.type == Operation.PURCHASE:
if ope.group.on_acc.is_cash: if ope.group.on_acc.is_cash:
to_checkouts_balances[ope.group.checkout] -= - ope.amount to_checkouts_balances[ope.group.checkout] -= -ope.amount
else: else:
to_checkouts_balances[ope.group.checkout] -= ope.amount to_checkouts_balances[ope.group.checkout] -= ope.amount
@ -1176,22 +1195,38 @@ def kpsul_cancel_operations(request):
# est recalculé automatiquement # est recalculé automatiquement
if ope.article and ope.article_nb: if ope.article and ope.article_nb:
last_stock = (InventoryArticle.objects last_stock = (InventoryArticle.objects
.select_related('inventory') .select_related('inventory')
.filter(article=ope.article) .filter(article=ope.article)
.order_by('inventory__at') .order_by('inventory__at')
.last()) .last())
if not last_stock or last_stock.inventory.at < ope.group.at: if not last_stock or last_stock.inventory.at < ope.group.at:
to_articles_stocks[ope.article] += ope.article_nb to_articles_stocks[ope.article] += ope.article_nb
if not opes: for transfer in transfers_all:
data['warnings']['already_canceled'] = opes_already_canceled 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) return JsonResponse(data)
negative_accounts = [] negative_accounts = []
# Checking permissions or stop # Checking permissions or stop
for account in to_accounts_balances: for account in to_accounts_balances:
(perms, stop) = account.perms_to_perform_operation( (perms, stop) = account.perms_to_perform_operation(
amount = to_accounts_balances[account]) amount=to_accounts_balances[account])
required_perms |= perms required_perms |= perms
stop_all = stop_all or stop stop_all = stop_all or stop
if stop: if stop:
@ -1211,25 +1246,31 @@ def kpsul_cancel_operations(request):
with transaction.atomic(): with transaction.atomic():
(Operation.objects.filter(pk__in=opes) (Operation.objects.filter(pk__in=opes)
.update(canceled_by=canceled_by, canceled_at=canceled_at)) .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: for account in to_accounts_balances:
Account.objects.filter(pk=account.pk).update( 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: for checkout in to_checkouts_balances:
Checkout.objects.filter(pk=checkout.pk).update( 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: for group in to_groups_amounts:
OperationGroup.objects.filter(pk=group.pk).update( 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: for article in to_articles_stocks:
Article.objects.filter(pk=article.pk).update( 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
websocket_data = { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] } websocket_data = {'opegroups': [], 'opes': [],
'checkouts': [], 'articles': []}
# Need refresh from db cause we used update on querysets # 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 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: for opegroup in opegroups:
websocket_data['opegroups'].append({ websocket_data['opegroups'].append({
'cancellation': True, 'cancellation': True,
@ -1246,15 +1287,16 @@ def kpsul_cancel_operations(request):
'canceled_at': canceled_at, 'canceled_at': canceled_at,
}) })
# Need refresh from db cause we used update on querysets # 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 checkouts = (Checkout.objects
.values('id', 'balance').filter(pk__in=checkouts_pk)) .values('id', 'balance')
.filter(pk__in=checkouts_pk))
for checkout in checkouts: for checkout in checkouts:
websocket_data['checkouts'].append({ websocket_data['checkouts'].append({
'id': checkout['id'], 'id': checkout['id'],
'balance': checkout['balance']}) 'balance': checkout['balance']})
# Need refresh from db cause we used update on querysets # 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) articles = Article.objects.values('id', 'stock').filter(pk__in=articles_pk)
for article in articles: for article in articles:
websocket_data['articles'].append({ websocket_data['articles'].append({
@ -1262,9 +1304,10 @@ def kpsul_cancel_operations(request):
'stock': article['stock']}) 'stock': article['stock']})
consumers.KPsul.group_send('kfet.kpsul', websocket_data) consumers.KPsul.group_send('kfet.kpsul', websocket_data)
data['canceled'] = opes data['canceled']['opes'] = opes
if opes_already_canceled: data['canceled']['transfers'] = transfers
data['warnings']['already_canceled'] = opes_already_canceled if already_canceled:
data['warnings']['already_canceled'] = already_canceled
return JsonResponse(data) return JsonResponse(data)
@login_required @login_required