def _validate_withdrawing_at_least_minimum(self): if self.action == Action.WITHDRAW \ and self.amount < ProjectMoney(amount=settings.MINIMUM_WITHDRAWAL_AMOUNT): raise ValidationError( _("Withdrawing less than %(mwa)s is not allowed."), code=BUSINESS_LOGIC_ERROR_CODE, params={'mwa': ProjectMoney(amount=settings.MINIMUM_WITHDRAWAL_AMOUNT)}, )
def balance(self, create: bool, extracted: Optional[ProjectMoney], **kwargs): if extracted is not None: self.balance = extracted else: self.balance = ProjectMoney( amount=settings.MINIMUM_TRANSFER_BALANCE + Faker().pyint())
def _validate_transferring_at_least_minimum(self): minimum_transfer_amount = ProjectMoney(amount=settings.MINIMUM_TRANSFER_AMOUNT) if self.action == Action.TRANSFER \ and self.amount < minimum_transfer_amount: raise ValidationError( _("Transferring less than %(mta)s is not allowed."), code=BUSINESS_LOGIC_ERROR_CODE, params={'mta': minimum_transfer_amount}, )
def test_raises_when_not_enough_balance_to_withdraw(): # TODO: (lazy) settings sender_balance = ProjectMoney(amount=settings.MINIMUM_WITHDRAWAL_BALANCE) sender = WithdrawalSenderWalletFactory(balance=sender_balance, user__referrals=[UserFactory()]) receiver = WithdrawalReceiverWalletFactory() receiver_balance = receiver.balance with pytest.raises(ValidationError): TransactionFactory( amount=ProjectMoney(amount=settings.MINIMUM_WITHDRAWAL_AMOUNT - 1), action=Action.WITHDRAW, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance receiver.refresh_from_db() assert receiver.balance == receiver_balance
def _validate_sender_balance_never_below_minimum(self): # Disable checking for DEPOSIT action from External wallet. # Let's assume that the External wallet is always # greater than the minimum sender's balance. if self.action == Action.WITHDRAW and self.sender.kind == WalletKind.REFERRAL: minimum_sender_balance = ProjectMoney( amount=settings.MINIMUM_REFER_SENDER_BALANCE) else: minimum_sender_balance = ProjectMoney( amount=settings.MINIMUM_SENDER_BALANCE) sender_balance_remainder = self.sender.balance - self.amount if sender_balance_remainder < minimum_sender_balance: raise ValidationError( _("No transaction leaving sender's wallet balance below %(msb)s is allowed." ), code=BUSINESS_LOGIC_ERROR_CODE, params={'msb': minimum_sender_balance}, )
def test_raises_when_not_enough_balance_to_transfer(): # TODO: (lazy) settings sender_balance = ProjectMoney(amount=config.MINIMUM_SENDER_BALANCE + config.MINIMUM_TRANSFER_AMOUNT) sender = TransferSenderWalletFactory(balance=sender_balance, user__referrals=[UserFactory()]) receiver = TransferReceiverWalletFactory() receiver_balance = receiver.balance with pytest.raises(ValidationError): TransactionFactory( amount=ProjectMoney(amount=config.MINIMUM_TRANSFER_AMOUNT - 1), action=Action.TRANSFER, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance receiver.refresh_from_db() assert receiver.balance == receiver_balance
def activate(self, request, *args, **kwargs): user = request.user if request.user.status==ActivatedDeactivatedStatus.ACTIVATED: return Response({'message': "It's already activated"}, status=status.HTTP_200_OK) activation_cost = ProjectMoney(amount=config.ACTIVATION_COST) referral_bonus = ProjectMoney(amount=config.REFERRAL_BONUS) main = Wallet.objects.filter(user=user, kind=WalletKind.MAIN).first() transfer = Wallet.objects.filter(user=user, kind=WalletKind.TRANSFER).first() refer = Wallet.objects.filter(user=user, kind=WalletKind.REFERRAL).first() super_main = Wallet.objects.filter(user__is_superuser=True, kind=WalletKind.MAIN).first() if main.balance > activation_cost: main.balance -= activation_cost main.save() elif transfer.balance > activation_cost: transfer.balance -= activation_cost transfer.save() elif refer.balance > activation_cost: refer.balance -= activation_cost refer.save() else: return Response({'message': "You haven't sufficient balance in any of your wallet"}, status=status.HTTP_400_BAD_REQUEST) super_main.balance += activation_cost if user.referrer is not None: referr_wallet = Wallet.objects.filter(user=user.referrer, kind=WalletKind.REFERRAL).first() super_refer = Wallet.objects.filter(user__is_superuser=True, kind=WalletKind.REFERRAL).first() Transaction.objects.create(action=Action.REFERRAL_BONUS, sender=super_refer, receiver=referr_wallet, amount=referral_bonus, status=ProcessStatus.COMPLETED) super_main.save() user.status=ActivatedDeactivatedStatus.ACTIVATED user.activation_date = datetime.now() user.expiration_date = datetime.now() + timedelta(days=90) user.save() return Response({'message': 'Congratulations! Your account has been activated'}, status=status.HTTP_200_OK)
class PaymentMethod(TimeStampedModel): class Meta: verbose_name = _("PaymentMethod") verbose_name_plural = _("PaymentMethods") name = CharField(max_length=30, null=True, verbose_name='Payment Method Name') option = PaymentMethodOptionField() min_deposit_amount = ProjectMoneyField(default=ProjectMoney(amount=0), verbose_name='Minimum Deposit Amount') def __str__(self): return f"{self.name} " \ f" for {PaymentMethodOption(self.option).label} " \
def test_raises_when_sender_balance_less_than_minimum(): sender_balance = ProjectMoney(amount=config.MINIMUM_SENDER_BALANCE - 1) sender = WalletFactory(balance=sender_balance) receiver = WalletFactory() receiver_balance = receiver.balance with pytest.raises(ValidationError): TransactionFactory( amount=sender_balance, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance receiver.refresh_from_db() assert receiver.balance == receiver_balance
def test_raises_when_zero_amount_transaction(): zero = ProjectMoney(amount=0) sender = WalletFactory(balance=zero) receiver = WalletFactory() receiver_balance = receiver.balance with pytest.raises(ValidationError): TransactionFactory( amount=zero, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == zero receiver.refresh_from_db() assert receiver.balance == receiver_balance
def test_wallets_balanced_after_transaction(): amount = ProjectMoney(amount=config.MINIMUM_TRANSFER_AMOUNT) sender = TransferSenderWalletFactory() sender_balance = sender.balance receiver = TransferReceiverWalletFactory() receiver_balance = receiver.balance TransferTransactionFactory( amount=amount, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance - amount receiver.refresh_from_db() assert receiver.balance == receiver_balance + amount
def test_raises_when_non_activated_user_withdrawing( non_activated_user_status: ActivatedDeactivatedStatus): user = UserFactory(status=non_activated_user_status) sender = WithdrawalSenderWalletFactory(user=user, user__referrals=[UserFactory()]) sender_balance = sender.balance receiver = WithdrawalReceiverWalletFactory() receiver_balance = receiver.balance with pytest.raises(ValidationError): WithdrawalTransactionFactory( amount=ProjectMoney(amount=config.MINIMUM_WITHDRAWAL_AMOUNT), sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance receiver.refresh_from_db() assert receiver.balance == receiver_balance
def test_raises_when_same_sender_and_receiver(): # TODO: parametrize user = UserFactory() sender = WalletFactory(user=user, kind=WalletKind.MAIN) sender_balance = sender.balance receiver = WalletFactory(user=user, kind=WalletKind.TRANSFER) receiver_balance = receiver.balance with pytest.raises(ValidationError): TransactionFactory( amount=ProjectMoney(100), action=Action.TRANSFER, sender=sender, receiver=receiver, ) sender.refresh_from_db() assert sender.balance == sender_balance receiver.refresh_from_db() assert receiver.balance == receiver_balance
def balance(self, create: bool, extracted: Optional[ProjectMoney], **kwargs): if extracted is not None: self.balance = extracted else: self.balance = ProjectMoney(amount=config.MINIMUM_SENDER_BALANCE + config.MINIMUM_WITHDRAWAL_AMOUNT + Faker().pyint())
def _validate_amount_greater_than_zero(self): if self.amount == ProjectMoney(amount=0): raise ValidationError( _("Zero-amount transaction does not make sense."), code=INVALID_ERROR_CODE, )