Exemple #1
0
def reverse_crypto_withdraw(_, request, queryset):
    with transaction.atomic():
        for withdraw in queryset.select_related('account__user',
                                                'account__currency'):
            with transaction.atomic():
                if withdraw.status == CryptoWithdraw.STATUS.reversed:
                    continue

                if Statement.objects.filter(
                        fk=withdraw.pk,
                        type=Statement.TYPES.reversed).exists():
                    continue

                account = withdraw.account
                account.deposit += abs(withdraw.amount)
                account.save()

                statement = Statement()
                statement.account = account
                statement.type = Statement.TYPES.reversed
                statement.description = "Reverse"
                statement.amount = abs(withdraw.amount)
                statement.fk = withdraw.pk
                statement.save()

                withdraw.status = CryptoWithdraw.STATUS.reversed
                withdraw.save()

                messages.success(request, _("Withdraw successfully reversed"))
Exemple #2
0
    def post(self, request):
        # Valor a ser emprestado
        amount = round(Decimal(request.POST.get('amount').replace(',', '.')),
                       8)
        # Numero de parcelas do empréstimo segundo a tabela
        times = int(request.POST.get('times'))

        investment = Investments.get_active_by_user(request.user)
        installments = generate_fixed_loan_table(investment,
                                                 amount,
                                                 times=times,
                                                 raw_date=True)
        checking_account = Accounts.objects.filter(
            user=request.user,
            currency__code=investment.account.currency.code,
            currency__type=Currencies.TYPES.checking).first()
        credit = Investments.get_credit_by_user(request.user)

        if times <= len(installments['data']) and credit['loan'][
                'available'] >= amount and amount >= Decimal('0.001'):
            # Faz tudo via transação no banco
            with transaction.atomic():
                checking_account.to_deposit(amount)

                # Cria um novo empréstimo associando o saldo negativo a ele
                loan = Loans()
                loan.account = investment.account
                loan.borrowed_amount = amount
                loan.total_amount = installments['data'][0]['total_amount']
                loan.times = times
                loan.save()

                # Cria o saldo negativo do empréstimo
                statement = Statement()
                statement.account = checking_account
                statement.description = 'New loan'
                statement.type = 'loan'
                statement.amount = amount
                statement.fk = loan.pk
                statement.save()

                for installment in installments['data']:
                    # Cria as parcelas
                    inst = Installments()
                    inst.loan = loan
                    inst.order = installment['times']
                    inst.due_date = installment['payment_date']
                    inst.interest_percent = installment['interest_percent']
                    inst.amount = Decimal(installment['amount'])
                    inst.save()

            return {
                'message_text':
                _("Your loan application was created with success!"),
                'message_type':
                'success'
            }
Exemple #3
0
def withdraw_investments():
    for item in Investments.objects.order_by('paid_date'):
        with transaction.atomic():
            reinvestments_qs = Reinvestments.objects.filter(investment=item, status=Reinvestments.STATUS.paid).order_by('created')
            reinvestment = reinvestments_qs.first()
            main_investment_was_paid = Statement.objects.filter(fk=item.pk, type=STATEMENT_TYPE).exists()
            remaining_days = item.remaining_days

            foreign_key = item.pk
            message_amount = item.amount

            if not reinvestment and item.status == Investments.STATUS.consumed:
                continue

            if reinvestment and main_investment_was_paid:
                remaining_days = reinvestment.remaining_days
                foreign_key = reinvestment.pk

            if Statement.objects.filter(type=foreign_key).exists():
                continue

            # Skip if investment grace period not ends yet
            if not remaining_days <= 0:
                continue

            account = item.account
            withdraw_fee = item.account.currency.withdraw_fee
            withdraw_fixed_fee = item.account.currency.withdraw_fixed_fee

            total_amount = account.deposit + account.reserved
            reserved = 0

            if reinvestment:
                if main_investment_was_paid:
                    message_amount = reinvestment.amount
                    reserved = account.reserved - reinvestment.amount
                    total_amount = total_amount - reserved

                    reinvestment.status = Reinvestments.STATUS.consumed
                    reinvestment.save()
                else:
                    message_amount = reinvestment.amount_before
                    reserved = account.reserved - reinvestment.amount_before
                    total_amount = total_amount - reserved

            discount = (total_amount * (withdraw_fee / 100)) + withdraw_fixed_fee
            pay_amount = total_amount - discount

            account.deposit = 0
            account.reserved = reserved
            account.save()

            checking_account = Accounts.objects.filter(user=account.user, currency__type=Currencies.TYPES.checking).first()
            checking_account.to_deposit(pay_amount)

            statement = Statement()
            statement.amount = Decimal('0') - total_amount
            statement.description = 'Termination of investment plan'
            statement.type = STATEMENT_TYPE
            statement.account = account
            statement.fk = foreign_key
            statement.save()

            statement = Statement()
            statement.amount = pay_amount
            statement.description = 'Return of invested amount'
            statement.type = STATEMENT_TYPE_RETURN
            statement.account = checking_account
            statement.fk = foreign_key
            statement.save()

            still_has_reinvestments = reinvestments_qs.exists()

            item.amount = reserved
            item.save()

            if not still_has_reinvestments:
                item.status = Investments.STATUS.consumed
                item.save()
            else:
                # Downgrade plan
                plan = Plans.get_by_amount(reserved)

                if plan.pk != item.plan_grace_period.plan.pk:
                    plan_grace_period = PlanGracePeriods.objects.get(plan=plan, grace_period=item.plan_grace_period.grace_period)
                    item.plan_grace_period = plan_grace_period
                    item.save()

                    # Remove all incomes and recalc them
                    start_date = timezone.now() + timedelta(days=1)
                    last_reinvestment = Reinvestments.objects.filter(investment=item).order_by('-created').first()
                    end_date = last_reinvestment.end_date

                    Incomes.objects.filter(investment=item, date__gte=start_date.date(), date__lte=end_date.date()).delete()

                    if last_reinvestment.remaining_months <= 0:
                        continue

                    range_dates = list(rrule(DAILY, dtstart=start_date, until=end_date))
                    income_amount = (item.amount * (plan_grace_period.income_percent / 100)) * last_reinvestment.remaining_months
                    income_table = decimal_split(income_amount, len(range_dates), 98, 100)

                    date_index = 0
                    bulk_incomes = []

                    for dt in range_dates:
                        income = Incomes()
                        income.date = dt
                        income.amount = income_table[date_index]
                        income.investment = item
                        bulk_incomes.append(income)

                        date_index += 1

                    Incomes.objects.bulk_create(bulk_incomes)

            print('Auto withdraw (re)investment of {} from {} user'.format(message_amount, item.account.user.username))
Exemple #4
0
    def post(self, request):
        if Investments.get_active_by_user(self.request.user):
            return {'message': _("ERROR! You already have a investment")}

        grace_period_pk = request.POST['grace_period']
        grace_period = PlanGracePeriods.objects.get(pk=grace_period_pk)
        checking_account = Accounts.objects.get(
            user=request.user,
            currency__code=grace_period.currency.code,
            currency__type=Currencies.TYPES.checking)
        investment_account = Accounts.objects.get(
            user=request.user, currency=grace_period.currency)

        amount = request.POST.get('amount', '0.00').replace(',', '.')
        amount = ''.join(c for c in amount if c.isdigit() or c == '.')

        if not amount:
            amount = '0.00'

        amount = Decimal(amount)
        amount_with_fee = amount + grace_period.plan.membership_fee
        min_invest = grace_period.plan.min_down
        max_invest = grace_period.plan.max_down

        if min_invest > amount or max_invest < amount:
            return {
                'message':
                _("ERROR! The investment amount it is out of the plan limit")
            }
        elif amount_with_fee > checking_account.deposit:
            return {
                'message':
                _("ERROR! Your {} account does not have enought deposit amount"
                  .format(checking_account.currency.name))
            }
        else:
            with transaction.atomic():
                investment = Investments()
                investment.plan_grace_period = grace_period
                investment.account = investment_account
                investment.amount = amount
                investment.status = Investments.STATUS.paid
                investment.membership_fee = grace_period.plan.membership_fee
                investment.paid_date = timezone.now()
                investment.save()

                if grace_period.grace_period.months > 0:
                    start_date = datetime.now() + timedelta(days=1)
                    end_date = start_date + relativedelta(
                        months=grace_period.grace_period.months)
                    range_dates = list(
                        rrule(DAILY, dtstart=start_date, until=end_date))
                    income_amount = (amount *
                                     (grace_period.income_percent /
                                      100)) * grace_period.grace_period.months
                    income_table = decimal_split(income_amount,
                                                 len(range_dates), 98, 100)

                    date_index = 0
                    bulk_incomes = []

                    for dt in range_dates:
                        income = Incomes()
                        income.date = dt
                        income.amount = income_table[date_index]
                        income.investment = investment
                        bulk_incomes.append(income)

                        date_index += 1

                    Incomes.objects.bulk_create(bulk_incomes)

                checking_account.deposit -= amount_with_fee
                checking_account.save()

                investment_account.reserved += amount
                investment_account.save()

                statement = Statement()
                statement.account = checking_account
                statement.amount = Decimal('0.00') - amount_with_fee
                statement.type = Statement.TYPES.investment
                statement.description = 'New investment'
                statement.fk = investment.pk
                statement.save()

                statement = Statement()
                statement.account = investment_account
                statement.amount = amount
                statement.type = Statement.TYPES.investment
                statement.description = 'New investment'
                statement.fk = investment.pk
                statement.save()

            return {
                'message':
                _("Congratulations! Your investing plan was created."),
                'redirect': True
            }
        return {
            'message':
            _("Someting in your new investment plan didn't work as expected.")
        }
Exemple #5
0
    def post(self, request):
        investment = Investments.get_by_user(request.user)
        reinvestment_old_invest = investment.plan_grace_period
        reinvestment_amount_before = investment.account.reserved
        reinvestment_incomes = investment.account.deposit

        grace_period_pk = request.POST['grace_period']
        grace_period = PlanGracePeriods.objects.get(pk=grace_period_pk)
        use_checking = request.POST['use_checking'] in ['true', '1']

        if grace_period.grace_period.months < investment.plan_grace_period.grace_period.months:
            return {'message': _("ERROR! Selected grace period is not valid.")}

        checking_account = Accounts.objects.get(
            user=request.user,
            currency__code=grace_period.currency.code,
            currency__type=Currencies.TYPES.checking)
        investment_account = Accounts.objects.get(
            user=request.user, currency=grace_period.currency)

        amount = request.POST.get('amount', '0.00').replace(',', '.')
        amount = ''.join(c for c in amount if c.isdigit() or c == '.')

        if not amount:
            amount = '0.00'

        amount = Decimal(amount)
        reinvestment_amount = amount
        membership_fee = Decimal('0.00')
        amount_with_fee = amount + membership_fee
        amount_with_investment = amount + investment.amount
        reinvest_plan = Plans.objects.filter(
            min_down__lte=amount_with_investment,
            max_down__gte=amount_with_investment).order_by(
                '-max_down').first()
        min_reinvest = grace_period.plan.min_reinvest
        months = grace_period.grace_period.months
        grace_period = PlanGracePeriods.objects.get(
            plan=reinvest_plan, grace_period__months=months)
        reinvestment_new_invest = grace_period

        # Se for um upgrade, soma a diferenca do membership_fee
        if reinvest_plan and reinvest_plan.pk != investment.plan_grace_period.plan.pk:
            membership_fee = (reinvest_plan.membership_fee -
                              investment.plan_grace_period.plan.membership_fee)
            amount_with_fee = amount + membership_fee

        reinvestment_membership_fee = membership_fee
        # Saldo para validacao do reinvestimento
        balance = investment_account.deposit

        if use_checking:
            balance += checking_account.deposit

        # Valida se o valor minimo de reinvestimento e compativel com o reinvestimento desejado
        if min_reinvest > amount:
            return {
                'message':
                _("ERROR! The min reinvestment for this plan is {}").format(
                    min_reinvest)
            }
        if amount_with_fee > balance:
            return {'message': _("ERROR! You does not have enought balance")}

        with transaction.atomic():
            investment.plan_grace_period = grace_period
            investment.amount = amount_with_investment
            investment.status = Investments.STATUS.paid
            investment.membership_fee = membership_fee
            investment.paid_date = timezone.now()
            investment.save()

            if grace_period.grace_period.months > 0:
                start_date = datetime.now() + timedelta(days=1)
                end_date = start_date + relativedelta(
                    months=grace_period.grace_period.months)

                Incomes.objects.filter(investment=investment,
                                       date__gte=start_date.date(),
                                       date__lte=end_date.date()).delete()

                range_dates = list(
                    rrule(DAILY, dtstart=start_date, until=end_date))
                income_amount = (amount_with_investment *
                                 (grace_period.income_percent /
                                  100)) * grace_period.grace_period.months
                income_table = decimal_split(income_amount, len(range_dates),
                                             98, 100)

                date_index = 0
                bulk_incomes = []

                for dt in range_dates:
                    income = Incomes()
                    income.date = dt
                    income.amount = income_table[date_index]
                    income.investment = investment
                    bulk_incomes.append(income)

                    date_index += 1

                Incomes.objects.bulk_create(bulk_incomes)

            discount_amount = investment_account.deposit - amount_with_fee

            if discount_amount < Decimal('0.00'):
                statement = Statement()
                statement.account = investment_account
                statement.amount = Decimal('0.00') - investment_account.deposit
                statement.type = 'reinvestment'
                statement.description = 'New reinvestment'
                statement.fk = investment.pk
                statement.save()

                investment_account.deposit = Decimal('0.00')
                investment_account.save()
            else:
                statement = Statement()
                statement.account = investment_account
                statement.amount = Decimal('0.00') - amount_with_fee
                statement.type = 'reinvestment'
                statement.description = 'New reinvestment'
                statement.fk = investment.pk
                statement.save()

                investment_account.takeout(amount_with_fee)

            if use_checking and discount_amount < Decimal('0.00'):
                checking_account.takeout(abs(discount_amount))

                statement = Statement()
                statement.account = checking_account
                statement.amount = discount_amount
                statement.type = 'reinvestment'
                statement.description = 'New reinvestment'
                statement.fk = investment.pk
                statement.save()

            investment_account.reserved += amount
            investment_account.save()

            statement = Statement()
            statement.account = investment_account
            statement.amount = amount
            statement.type = 'reinvestment'
            statement.description = 'New reinvestment'
            statement.fk = investment.pk
            statement.save()

            reinvestment = Reinvestments()
            reinvestment.old_invest = reinvestment_old_invest
            reinvestment.new_invest = reinvestment_new_invest
            reinvestment.amount = reinvestment_amount
            reinvestment.amount_before = reinvestment_amount_before
            reinvestment.incomes = reinvestment_incomes
            reinvestment.membership_fee = reinvestment_membership_fee
            reinvestment.investment = investment
            reinvestment.save()

        return {
            'message':
            _("Congratulations! Your reinvesting plan was created."),
            'redirect': True
        }