|
|
|
@ -1047,85 +1047,89 @@ class InterestViewSet(Base, Retrieve, Create): |
|
|
|
|
class ProtocoinViewSet(Base): |
|
|
|
|
@action(detail=False, methods=['post'], permission_classes=[AllowMetadata | IsAuthenticated]) |
|
|
|
|
def send_to_member(self, request): |
|
|
|
|
source_user = self.request.user |
|
|
|
|
source_member = source_user.member |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
member_id = int(request.data['member_id']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='Invalid number.')) |
|
|
|
|
with transaction.atomic(): |
|
|
|
|
source_user = self.request.user |
|
|
|
|
source_member = source_user.member |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
balance = float(request.data['balance']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Invalid number.')) |
|
|
|
|
try: |
|
|
|
|
member_id = int(request.data['member_id']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='Invalid number.')) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
amount = float(request.data['amount']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Invalid number.')) |
|
|
|
|
try: |
|
|
|
|
balance = float(request.data['balance']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Invalid number.')) |
|
|
|
|
|
|
|
|
|
if amount < 1.00: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Amount too small.')) |
|
|
|
|
try: |
|
|
|
|
amount = float(request.data['amount']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Invalid number.')) |
|
|
|
|
|
|
|
|
|
if amount < 1.00: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Amount too small.')) |
|
|
|
|
|
|
|
|
|
if member_id == source_member.id: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='Unable to send to self.')) |
|
|
|
|
|
|
|
|
|
destination_member = get_object_or_404(models.Member, id=member_id) |
|
|
|
|
destination_user = destination_member.user |
|
|
|
|
if member_id == source_member.id: |
|
|
|
|
raise exceptions.ValidationError(dict(member_id='Unable to send to self.')) |
|
|
|
|
|
|
|
|
|
source_user_balance = source_user.transactions.aggregate(Sum('protocoin'))['protocoin__sum'] |
|
|
|
|
source_user_balance = float(source_user_balance) |
|
|
|
|
destination_member = get_object_or_404(models.Member, id=member_id) |
|
|
|
|
destination_user = destination_member.user |
|
|
|
|
|
|
|
|
|
if source_user_balance != balance: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Incorrect current balance.')) |
|
|
|
|
source_user_balance = source_user.transactions.aggregate(Sum('protocoin'))['protocoin__sum'] |
|
|
|
|
source_user_balance = float(source_user_balance) |
|
|
|
|
|
|
|
|
|
if source_user_balance < amount: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Insufficient funds.')) |
|
|
|
|
if source_user_balance != balance: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Incorrect current balance.')) |
|
|
|
|
|
|
|
|
|
source_delta = -amount |
|
|
|
|
destination_delta = amount |
|
|
|
|
if source_user_balance < amount: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Insufficient funds.')) |
|
|
|
|
|
|
|
|
|
memo = 'Protocoin - Transaction {} ({}) sent ₱ {} to {} ({})'.format( |
|
|
|
|
source_member.first_name + ' ' + source_member.last_name, |
|
|
|
|
source_member.id, |
|
|
|
|
amount, |
|
|
|
|
destination_member.first_name + ' ' + destination_member.last_name, |
|
|
|
|
destination_member.id, |
|
|
|
|
) |
|
|
|
|
source_delta = -amount |
|
|
|
|
destination_delta = amount |
|
|
|
|
|
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=source_user, |
|
|
|
|
protocoin=source_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Other', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
memo = 'Protocoin - Transaction {} ({}) sent ₱ {} to {} ({})'.format( |
|
|
|
|
source_member.first_name + ' ' + source_member.last_name, |
|
|
|
|
source_member.id, |
|
|
|
|
amount, |
|
|
|
|
destination_member.first_name + ' ' + destination_member.last_name, |
|
|
|
|
destination_member.id, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=destination_user, |
|
|
|
|
protocoin=destination_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Other', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=source_user, |
|
|
|
|
protocoin=source_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Other', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
|
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=destination_user, |
|
|
|
|
protocoin=destination_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Other', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
|
|
|
|
|
return Response(200) |
|
|
|
|
return Response(200) |
|
|
|
|
except OperationalError: |
|
|
|
|
self.send_to_member(request) |
|
|
|
|
|
|
|
|
|
@action(detail=True, methods=['get']) |
|
|
|
|
def card_vend_balance(self, request, pk=None): |
|
|
|
@ -1147,65 +1151,69 @@ class ProtocoinViewSet(Base): |
|
|
|
|
|
|
|
|
|
@action(detail=True, methods=['post']) |
|
|
|
|
def card_vend_request(self, request, pk=None): |
|
|
|
|
auth_token = request.META.get('HTTP_AUTHORIZATION', '') |
|
|
|
|
if secrets.VEND_API_TOKEN and auth_token != 'Bearer ' + secrets.VEND_API_TOKEN: |
|
|
|
|
raise exceptions.PermissionDenied() |
|
|
|
|
try: |
|
|
|
|
with transaction.atomic(): |
|
|
|
|
auth_token = request.META.get('HTTP_AUTHORIZATION', '') |
|
|
|
|
if secrets.VEND_API_TOKEN and auth_token != 'Bearer ' + secrets.VEND_API_TOKEN: |
|
|
|
|
raise exceptions.PermissionDenied() |
|
|
|
|
|
|
|
|
|
source_card = get_object_or_404(models.Card, card_number=pk) |
|
|
|
|
source_user = source_card.user |
|
|
|
|
source_card = get_object_or_404(models.Card, card_number=pk) |
|
|
|
|
source_user = source_card.user |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
number = request.data['number'] |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(number='This field is required.')) |
|
|
|
|
try: |
|
|
|
|
number = request.data['number'] |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(number='This field is required.')) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
balance = float(request.data['balance']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Invalid number.')) |
|
|
|
|
try: |
|
|
|
|
balance = float(request.data['balance']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Invalid number.')) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
amount = float(request.data['amount']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Invalid number.')) |
|
|
|
|
try: |
|
|
|
|
amount = float(request.data['amount']) |
|
|
|
|
except KeyError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='This field is required.')) |
|
|
|
|
except ValueError: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Invalid number.')) |
|
|
|
|
|
|
|
|
|
if amount < 1.00: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Amount too small.')) |
|
|
|
|
if amount < 1.00: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Amount too small.')) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source_user_balance = source_user.transactions.aggregate(Sum('protocoin'))['protocoin__sum'] |
|
|
|
|
source_user_balance = float(source_user_balance) |
|
|
|
|
source_user_balance = source_user.transactions.aggregate(Sum('protocoin'))['protocoin__sum'] |
|
|
|
|
source_user_balance = float(source_user_balance) |
|
|
|
|
|
|
|
|
|
if source_user_balance != balance: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Incorrect current balance.')) |
|
|
|
|
if source_user_balance != balance: |
|
|
|
|
raise exceptions.ValidationError(dict(balance='Incorrect current balance.')) |
|
|
|
|
|
|
|
|
|
if source_user_balance < amount: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Insufficient funds.')) |
|
|
|
|
if source_user_balance < amount: |
|
|
|
|
raise exceptions.ValidationError(dict(amount='Insufficient funds.')) |
|
|
|
|
|
|
|
|
|
source_delta = -amount |
|
|
|
|
source_delta = -amount |
|
|
|
|
|
|
|
|
|
memo = 'Protocoin - Purchase spent ₱ {} on vending machine item #{}'.format( |
|
|
|
|
amount, |
|
|
|
|
number, |
|
|
|
|
) |
|
|
|
|
memo = 'Protocoin - Purchase spent ₱ {} on vending machine item #{}'.format( |
|
|
|
|
amount, |
|
|
|
|
number, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=source_user, |
|
|
|
|
protocoin=source_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Snacks', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
tx = models.Transaction.objects.create( |
|
|
|
|
user=source_user, |
|
|
|
|
protocoin=source_delta, |
|
|
|
|
amount=0, |
|
|
|
|
number_of_membership_months=0, |
|
|
|
|
account_type='Protocoin', |
|
|
|
|
category='Snacks', |
|
|
|
|
info_source='System', |
|
|
|
|
memo=memo, |
|
|
|
|
) |
|
|
|
|
utils.log_transaction(tx) |
|
|
|
|
|
|
|
|
|
return Response(200) |
|
|
|
|
return Response(200) |
|
|
|
|
except OperationalError: |
|
|
|
|
self.card_vend_request(request, pk) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RegistrationView(RegisterView): |
|
|
|
|