Skip to content

Commit

Permalink
Merge pull request #215 from bcgov/develop
Browse files Browse the repository at this point in the history
Merge develop to master. The changes included belong to v0.1.0.
  • Loading branch information
kuanfandevops authored Apr 12, 2018
2 parents 112f497 + 8dc0bce commit fb03373
Show file tree
Hide file tree
Showing 17 changed files with 607 additions and 134 deletions.
18 changes: 18 additions & 0 deletions backend/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,24 @@ class Meta:
class CreditTradeUpdateSerializer(serializers.ModelSerializer):

def validate(self, data):
if (data.get('fair_market_value_per_credit') == 0 and
data.get('zero_reason') is None):
allowed_types = list(
CreditTradeType.objects
.filter(the_type__in=[
"Credit Validation", "Credit Retirement", "Part 3 Award"
])
.only('id')
)

credit_trade_type = data.get('type')

if credit_trade_type not in allowed_types:
raise serializers.ValidationError({
'zeroDollarReason': 'Zero Dollar Reason is required '
'for Credit Transfers with 0 Dollar per Credit'
})

return data

class Meta:
Expand Down
89 changes: 83 additions & 6 deletions backend/api/services/CreditTradeService.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from api.exceptions import PositiveIntegerException
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.db import transaction

import datetime

Expand Down Expand Up @@ -137,23 +138,26 @@ def approve(credit_trade):
return credit_trade

@staticmethod
@transaction.non_atomic_requests()
def transfer_credits(_from, _to, credit_trade_id, num_of_credits,
effective_date):
from_starting_bal = OrganizationBalance.objects.get(
from_starting_bal, created = OrganizationBalance.objects.get_or_create(
organization_id=_from.id,
expiration_date=None)
expiration_date=None,
defaults={'validated_credits': 0})

to_starting_bal = OrganizationBalance.objects.get(
to_starting_bal, created = OrganizationBalance.objects.get_or_create(
organization_id=_to.id,
expiration_date=None)
expiration_date=None,
defaults={'validated_credits': 0})

# Compute for end balance
from_credits = from_starting_bal.validated_credits - num_of_credits
to_credits = to_starting_bal.validated_credits + num_of_credits

if 0 > from_credits:
if from_credits < 0:
raise PositiveIntegerException("Can't complete transaction,"
"insufficient credits")
"`{}` has insufficient credits".format(_from.name))

# Update old balance effective date
from_starting_bal.expiration_date = effective_date
Expand All @@ -180,3 +184,76 @@ def transfer_credits(_from, _to, credit_trade_id, num_of_credits,

from_new_bal.save()
to_new_bal.save()

@staticmethod
def validate_credits(credit_trades):
errors = []
temp_storage = []

for credit_trade in credit_trades:
from_starting_index, from_starting_balance = CreditTradeService. \
get_temp_balance(temp_storage, credit_trade.credits_from.id)

to_starting_index, to_starting_balance = CreditTradeService. \
get_temp_balance(temp_storage, credit_trade.credits_to.id)

from_credits_remaining = from_starting_balance - \
credit_trade.number_of_credits

to_credits_remaining = to_starting_balance + \
credit_trade.number_of_credits

CreditTradeService.update_temp_balance(
temp_storage,
from_starting_index,
from_credits_remaining,
credit_trade.credits_from.id)

CreditTradeService.update_temp_balance(
temp_storage,
to_starting_index,
to_credits_remaining,
credit_trade.credits_to.id)

if from_credits_remaining < 0:
errors.append(
"[ID: {}] "
"Can't complete transaction,"
"`{}` has insufficient credits.".
format(credit_trade.id, credit_trade.credits_from.name))

if len(errors) > 0:
raise PositiveIntegerException(errors)

@staticmethod
def get_temp_balance(storage, id):
starting_balance = None
index = None

if len(storage) > 0:
for balance_index, balance in enumerate(storage):
if balance["id"] == id:
starting_balance = balance["credits"]
index = balance_index

if starting_balance is None:
try: # if balance hasn't been populated, get from the database
organization_balance = OrganizationBalance.objects.get(
organization_id=id,
expiration_date=None)

starting_balance = organization_balance.validated_credits
except OrganizationBalance.DoesNotExist:
starting_balance = 0

return index, starting_balance

@staticmethod
def update_temp_balance(storage, index, credits, id):
if index is None:
storage.append({
"id": id,
"credits": credits
})
else:
storage[index]["credits"] = credits
Loading

0 comments on commit fb03373

Please sign in to comment.