Esempio n. 1
0
 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)},
         )
Esempio n. 2
0
 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())
Esempio n. 3
0
 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},
         )
Esempio n. 4
0
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
Esempio n. 5
0
    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},
            )
Esempio n. 6
0
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
Esempio n. 7
0
    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)
Esempio n. 8
0
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} " \
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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
Esempio n. 14
0
 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())
Esempio n. 15
0
 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,
         )