Correction de l'usage de transaction dans K-Psul
This commit is contained in:
parent
726f42c469
commit
4c8b23e999
1 changed files with 40 additions and 36 deletions
|
@ -418,6 +418,7 @@ def kpsul_perform_operations(request):
|
||||||
cof_grant_divisor = 1 + cof_grant / 100
|
cof_grant_divisor = 1 + cof_grant / 100
|
||||||
is_addcost = (addcost_for and addcost_amount
|
is_addcost = (addcost_for and addcost_amount
|
||||||
and addcost_for != operationgroup.on_acc)
|
and addcost_for != operationgroup.on_acc)
|
||||||
|
addcost_total = 0
|
||||||
|
|
||||||
# 1. Calculating amount of each PURCHASE operations
|
# 1. Calculating amount of each PURCHASE operations
|
||||||
# 1.1 Standard price for n articles
|
# 1.1 Standard price for n articles
|
||||||
|
@ -437,7 +438,7 @@ def kpsul_perform_operations(request):
|
||||||
operation.addcost_amount = addcost_amount * operation.article_nb
|
operation.addcost_amount = addcost_amount * operation.article_nb
|
||||||
operation.amount -= operation.addcost_amount
|
operation.amount -= operation.addcost_amount
|
||||||
# 5
|
# 5
|
||||||
addcost_for.balance += operation.addcost_amount
|
addcost_total += operation.addcost_amount
|
||||||
operation.addcost_for = addcost_for
|
operation.addcost_for = addcost_for
|
||||||
# 1.3
|
# 1.3
|
||||||
if operationgroup.on_acc.is_cof:
|
if operationgroup.on_acc.is_cof:
|
||||||
|
@ -450,47 +451,40 @@ def kpsul_perform_operations(request):
|
||||||
if operation.type == Operation.DEPOSIT:
|
if operation.type == Operation.DEPOSIT:
|
||||||
required_perms.append('kfet.can_perform_deposit')
|
required_perms.append('kfet.can_perform_deposit')
|
||||||
|
|
||||||
|
# Starting transaction to ensure data consistency
|
||||||
|
# Using select_for_update where it is critical
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
on_acc = operationgroup.on_acc
|
||||||
|
on_acc = Account.objects.select_for_update().get(pk=on_acc.pk)
|
||||||
# Adding required permissions to perform operation group
|
# Adding required permissions to perform operation group
|
||||||
opegroup_perms = operationgroup.on_acc.perms_to_perform_operation(
|
opegroup_perms = on_acc.perms_to_perform_operation(
|
||||||
amount = operationgroup.amount)
|
amount = operationgroup.amount)
|
||||||
required_perms += opegroup_perms
|
required_perms += opegroup_perms
|
||||||
|
|
||||||
# Checking authenticated user has all perms
|
# Checking authenticated user has all perms
|
||||||
if not request.user.has_perms(required_perms):
|
if not request.user.has_perms(required_perms):
|
||||||
# Sending BAD_REQUEST with missing perms
|
raise PermissionDenied
|
||||||
missing_perms = \
|
|
||||||
[ Permission.objects.get(codename=codename).name for codename in (
|
|
||||||
(perm.split('.'))[1] for perm in
|
|
||||||
required_perms if not request.user.has_perm(perm)
|
|
||||||
)]
|
|
||||||
data['errors'].append({'missing_perms': missing_perms })
|
|
||||||
return JsonResponse(data, status=403)
|
|
||||||
|
|
||||||
# If 1 perm is required, saving who perform the operations
|
# If 1 perm is required, saving who perform the operations
|
||||||
if len(required_perms) > 0:
|
if len(required_perms) > 0:
|
||||||
operationgroup.valid_by = request.user.profile.account_kfet
|
operationgroup.valid_by = request.user.profile.account_kfet
|
||||||
|
|
||||||
# Filling cof status for statistics
|
# Filling cof status for statistics
|
||||||
operationgroup.is_cof = operationgroup.on_acc.is_cof
|
operationgroup.is_cof = on_acc.is_cof
|
||||||
|
|
||||||
# Updating (no commit) account's balance
|
# Saving account's balance
|
||||||
operationgroup.on_acc.balance += operationgroup.amount
|
on_acc.balance += operationgroup.amount
|
||||||
|
on_acc.save()
|
||||||
|
# Saving addcost_for with new balance if there is one
|
||||||
|
if is_addcost:
|
||||||
|
addcost_for += addcost_total
|
||||||
|
addcost_for.save()
|
||||||
|
|
||||||
# Saving in a transaction to ensure database integrity
|
|
||||||
try:
|
|
||||||
with transaction.atomic():
|
|
||||||
# Saving operation group
|
# Saving operation group
|
||||||
operationgroup.save()
|
operationgroup.save()
|
||||||
data['operationgroup'] = operationgroup.pk
|
data['operationgroup'] = operationgroup.pk
|
||||||
|
|
||||||
# Saving account with new balance
|
|
||||||
operationgroup.on_acc.save()
|
|
||||||
|
|
||||||
# Saving addcost_for with new balance if there is one
|
|
||||||
if is_addcost:
|
|
||||||
addcost_for.save()
|
|
||||||
|
|
||||||
# Filling operationgroup id for each operations and saving
|
# Filling operationgroup id for each operations and saving
|
||||||
# Saving articles with new stock
|
# Saving articles with new stock
|
||||||
for operation in operations:
|
for operation in operations:
|
||||||
|
@ -499,7 +493,17 @@ def kpsul_perform_operations(request):
|
||||||
if operation.type == Operation.PURCHASE:
|
if operation.type == Operation.PURCHASE:
|
||||||
operation.article.save()
|
operation.article.save()
|
||||||
data['operations'].append(operation.pk)
|
data['operations'].append(operation.pk)
|
||||||
|
except PermissionDenied:
|
||||||
|
# Sending BAD_REQUEST with missing perms
|
||||||
|
missing_perms = \
|
||||||
|
[ Permission.objects.get(codename=codename).name for codename in (
|
||||||
|
(perm.split('.'))[1] for perm in
|
||||||
|
required_perms if not request.user.has_perm(perm)
|
||||||
|
)]
|
||||||
|
data['errors'].append({'missing_perms': missing_perms })
|
||||||
|
return JsonResponse(data, status=403)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
data['errors'].append('DB error')
|
data['errors'].append('DB error')
|
||||||
|
return JsonResponse(data, status=500)
|
||||||
|
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
Loading…
Reference in a new issue