def post(self, request, gateway, account_pk): # Importa dinamicamente o modulo do gateway configurado para a moeda gateway_module = importlib.import_module( 'exchange_payments.gateways.{}'.format(gateway)) gateway = gateway_module.Gateway() account = Accounts.objects.get(pk=account_pk) # Validates if transaction already exists in our system if Statement.objects.filter(tx_id=request.POST['txn_id']).exists(): raise Exception('Transaction already exists!') # Checa se o deposito pode ser feito if gateway.can_deposit(account, request.POST): # Adiciona o saldo na conta do usuario, e cria a entrada no extrato with transaction.atomic(): account.deposit += gateway.deposit_amount account.save() statement = Statement() statement.account = account statement.description = 'Deposit' statement.amount = gateway.deposit_amount statement.type = Statement.TYPES.deposit statement.tx_id = gateway.tx_id statement.save() return {'amount': statement.amount} return {'error': _("Deposit can't be done.")}
def check_transaction(output): with transaction.atomic(): accounts = Accounts.objects.filter(address=output['address']) if not accounts.exists(): return account = accounts.first() print('Processando conta do usuario {}'.format(account.user.username)) if Statement.objects.filter(account=account, tx_id=output['id']).exists(): return satoshis = Decimal(output['value']) if satoshis < 0: return amount = satoshis / Decimal('100000000') account.deposit += amount account.save() statement = Statement() statement.account = account statement.tx_id = output['id'] statement.amount = amount statement.description = 'Deposit' statement.type = Statement.TYPES.deposit statement.save() print("Transfering {} to {} account".format(amount, account.pk))
def post(self, request): account = Accounts.objects.filter(user=request.user, currency__code='BTC', currency__type='checking').first() br_account = Accounts.objects.filter(user=request.user, currency__code='BRL').first() form = RechargeForm(request.POST, user=request.user) if not form.is_valid(): return {'errors': form.errors} usd = CurrencyPrice('coinbase') br = CurrencyPrice('mercadobitcoin') address = request.user.addresses.first() if address and address.country.name.lower() == 'brazil': quote = br.to_br(1) else: quote = usd.to_usd(1) quote = quote * Decimal('0.93') recharge = form.save(commit=False) recharge.quote = quote btc_amount = round(recharge.amount / quote, 8) if btc_amount > account.deposit: form.add_error('amount', _("You does not have enought balance")) return {'errors': form.errors} with transaction.atomic(): recharge.amount = btc_amount recharge.deposit = account.deposit recharge.reserved = account.reserved recharge.quote = quote recharge.card = Cards.objects.filter( account__user=request.user).first() recharge.save() account.takeout(btc_amount) amount = Decimal('0') - btc_amount statement = Statement(account=account, amount=amount, fk=recharge.pk) statement.description = 'Card Recharge' statement.type = 'card_recharge' statement.save() card = recharge.card card.deposit += recharge.quote_amount card.save() br_account.to_deposit(recharge.quote_amount) return { 'message_type': 'success', 'message_text': _("Your recharge has been processed by our team and will be available in your card within 24 hours" ) }
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"))
def post(self, request): if not Investments.get_active_by_user(request.user): return {'title': _("Error!"), 'message': _("You are not a investor yet, please make a Xfactor investment plan first and go back here to get your card."), 'type': 'error'} if not Graduations.objects.filter(type=Graduations._advisor, user=request.user).exists(): return {'title': _("Error!"), 'message': _("You need be a investment advisor first, to request your card."), 'type': 'error'} course_subscription_form = CourseSubscriptionForm(request.POST, user=request.user) if Statement.objects.filter(account__user=request.user, type='advisor_card_request').exists(): return {'title': _("Warning!"), 'message': _("Your already have requested your card."), 'type': 'warning'} if not course_subscription_form.is_valid(): return {'errors': course_subscription_form.errors} amount = Decimal('0.01') checking_account = request.user.accounts.filter(currency__type=Currencies.TYPES.checking).first() if amount > checking_account.deposit: return {'title': _("Error!"), 'message': _("You not have enought balance for request your card."), 'type': 'error'} with transaction.atomic(): statement = Statement() statement.description = 'Advisor card request' statement.account = checking_account statement.type = 'advisor_card_request' statement.amount = Decimal('0') - amount statement.save() checking_account.takeout(amount) return {'title': _("Congratulations!"), 'message': _("Your card request has been successfully made."), 'type': 'success'}
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' }
def handle(self, *args, **options): while True: with transaction.atomic(): advisors = Graduations.objects.select_related('user').filter(type=Graduations._advisor).order_by('user__created') savings = Plans.objects.get(name__iexact='savings') for advisor in advisors: referral_advisors = Statement.objects.filter(type__in=['course_subscription', 'advisor_card_request'], account__user__referral__promoter=advisor.user).count() investment = Investments.get_active_by_user(advisor.user) if referral_advisors < 5: continue if not investment: continue _1 = get_descents([advisor.user], LINE_1_LIMIT) _2 = get_descents(_1, LINE_2_LIMIT) _3 = get_descents(_2, LINE_3_LIMIT) comission_amount = len(_1 + _2 + _3) * savings.membership_fee investment_account = Accounts.objects.get(user=advisor.user, currency__type='investment') items = Statement.objects.filter(account=investment_account, type='profit_sharing_bonus', **date_kwargs) discount = Decimal('0') for item in items: discount += item.amount comission_amount -= discount if comission_amount <= Decimal('0'): continue investment_account.to_deposit(comission_amount) s = Statement() s.account = investment_account s.amount = comission_amount s.description = 'Profit sharing bonus' s.type = 'profit_sharing_bonus' s.save() comission = Comissions() comission.amount = comission_amount comission.investment = investment comission.fk = s.pk comission.save() print('Paying {} of profit sharing to {}'.format(comission_amount, advisor.user.username)) raise Exception('iasjdaisjdiasd')
def new_income(self, account, amount, tx_id, fk, date): # Transfere o rendimento para a conta do investidor account.deposit += amount account.save() # Cria o extrato do rendimento para o investidor statement = Statement(account_id=self.pk, amount=amount, tx_id=tx_id, fk=fk) statement.account = account statement.description = 'Income' statement.type = Statement.TYPES.income statement.created = date statement.modified = date statement.save() return statement
def handle(self, *args, **options): while True: txs = rpc_proxy._call('listtransactions') for tx in txs: with transaction.atomic(): # Valida se o tipo e o valor da transacao atendedem os requisitos para deposito if tx['category'] != 'receive' or tx['amount'] <= 0: continue # Pega a conta TCOIN do usuario usando a carteira dele currency = Currencies.objects.get( code=settings.BITCOINZ_CURRENCY_CODE) accounts = Accounts.objects.filter(currency=currency, address=tx['address']) # Se a conta para a carteira nao existir, vai para a proxima transacao if not accounts.exists(): continue account = accounts.first() # Valida se a transacao ja foi processada statements = Statement.objects.filter(account=account, tx_id=tx['txid']) if statements.exists(): continue # Deposita o valor para o usuario statement = Statement() statement.account = account statement.amount = Decimal(tx['amount']) statement.description = 'Deposit' statement.type = Statement.TYPES.deposit statement.tx_id = tx['txid'] statement.save() account.deposit += Decimal(tx['amount']) account.save() print('Pagando {} para a conta Bitcoin Z do usuario {}'. format(tx['amount'], account.user.username)) time.sleep(settings.BITCOINZ_CONFIRM_PAYMENTS_WAIT_SECONDS)
def post(self, request): coin = request.POST['coin'] # O POST e imutavel por default, sendo assim, # precisamos alterar essa caracteristica do object para alterar seus valores request.POST._mutable = True # Fazemos isto, pois esse campo precisa passar pela validacao do formulario request.POST['address'] = 'whatever' # Define um valor padrao para code do two factor, caso o usuario nao tenha configurado ele ainda # Fazemos isto, pois esse campo precisa passar pela validacao do formulario if not user_has_device(request.user): request.POST['code'] = '123' account = Accounts.objects.get(user=request.user, currency__code='BTC', currency__type=Currencies.TYPES.investment) withdraw_form = NewWithdrawForm(request.POST, user=request.user, account=account) if not withdraw_form.is_valid(): return {'status': 'error', 'errors': withdraw_form.errors} fee = (withdraw_form.cleaned_data['amount'] * (account.currency.withdraw_fee / 100)) + account.currency.withdraw_fixed_fee checking_account = Accounts.objects.get(user=request.user, currency__code='BTC', currency__type=Currencies.TYPES.checking) with transaction.atomic(): amount = abs(withdraw_form.cleaned_data['amount']) statement = Statement() statement.account = account statement.amount = Decimal('0.00') - amount statement.description = 'Income Withdrawal' statement.type = 'income_withdraw' statement.save() account.takeout(amount) statement = Statement() statement.account = checking_account statement.amount = (amount - abs(fee)) statement.description = 'Income Deposit' statement.type = 'income_deposit' statement.save() checking_account.to_deposit((amount - abs(fee)) ) return {'status': 'success', 'amount': amount}
def post(self, request): account = Accounts.objects.filter(user=request.user, currency__code='BRL', currency__type='checking').first() form = BankSlipForm(request.POST, user=request.user) if not form.is_valid(): return {'errors': form.errors} amount = form.cleaned_data['amount'] if amount > account.deposit: form.add_error('amount', _("You does not have enought balance")) return {'errors': form.errors} with transaction.atomic(): boleto = form.save(commit=False) boleto.card = Cards.objects.filter( account__user=request.user).first() boleto.payer_name = request.user.name boleto.payer_document = request.user.document_1 boleto.save() account.takeout(amount) amount = Decimal('0') - amount statement = Statement(account=account, amount=amount, fk=boleto.pk) statement.description = 'Bank slip payment' statement.type = 'bank_slip_payment' statement.save() card = boleto.card card.deposit -= abs(boleto.amount) card.save() account.takeout(abs(boleto.amount)) return { 'message_type': 'success', 'message_text': _("Your bank slip has been processed by our team and will be paid within 24 hours" ) }
def post(self, request): # Valor a ser emprestado amount = round(Decimal(request.POST.get('amount').replace(',', '.')), 8) investment = Investments.get_active_by_user(request.user) 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 credit['overdraft']['available'] >= amount and amount >= Decimal( '0.001'): with transaction.atomic(): checking_account.to_deposit(amount) statement = Statement() statement.account = checking_account statement.description = 'New overdraft' statement.amount = amount statement.type = 'overdraft' statement.save() # Cria o novo credito overdraft = Overdrafts() overdraft.account = investment.account overdraft.statement = statement overdraft.borrowed_amount = amount overdraft.total_amount = amount overdraft.due_date = timezone.now() + timedelta( days=investment.plan_grace_period.plan.overdraft_free_days) overdraft.save() return { 'message_text': _("Your credit application was created with success!"), 'message_type': 'success' }
def post(self, request): coin = request.POST['coin'] # O POST e imutavel por default, sendo assim, # precisamos alterar essa caracteristica do object para alterar seus valores request.POST._mutable = True # Define um valor padrao para o address caso o deposito seja em reais # Fazemos isto, pois esse campo precisa passar pela validacao do formulario if coin == settings.BRL_CURRENCY_CODE: request.POST['address'] = 'whatever' # Define um valor padrao para code do two factor, caso o usuario nao tenha configurado ele ainda # Fazemos isto, pois esse campo precisa passar pela validacao do formulario if not user_has_device(request.user): request.POST['code'] = '123' account = Accounts.objects.get(user=request.user, currency__code=coin, currency__type=CHECKING_TYPE) withdraw_form = NewWithdrawForm(request.POST, user=request.user, account=account) if not withdraw_form.is_valid(): return {'status': 'error', 'errors': withdraw_form.errors} fee = (withdraw_form.cleaned_data['amount'] * (account.currency.withdraw_fee / 100)) + account.currency.withdraw_fixed_fee system_accounts = Accounts.objects.filter( address=withdraw_form.cleaned_data['address']) is_tbsa = False if coin != settings.BRL_CURRENCY_CODE and system_accounts.exists(): fee = (withdraw_form.cleaned_data['amount'] * (account.currency.tbsa_fee / 100)) + account.currency.tbsa_fixed_fee amount_with_fee = abs(withdraw_form.cleaned_data['amount']) - fee if amount_with_fee < 0: amount_with_fee = 0 system_account = system_accounts.first() system_account.deposit += amount_with_fee system_account.save() tbsa_statement = Statement() tbsa_statement.account = system_account tbsa_statement.description = 'TBSA' tbsa_statement.type = Statement.TYPES.tbsa tbsa_statement.amount = abs(withdraw_form.cleaned_data['amount']) tbsa_statement.save() is_tbsa = True with transaction.atomic(): if coin == settings.BRL_CURRENCY_CODE: withdraw = BankWithdraw() else: withdraw = CryptoWithdraw() withdraw.account = account withdraw.deposit = account.deposit withdraw.reserved = account.reserved withdraw.amount = Decimal( '0.00') - withdraw_form.cleaned_data['amount'] withdraw.fee = fee if coin == settings.BRL_CURRENCY_CODE: br_bank_account = request.user.br_bank_account withdraw.bank = br_bank_account.bank withdraw.agency = br_bank_account.agency withdraw.agency_digit = br_bank_account.agency_digit withdraw.account_type = br_bank_account.account_type withdraw.account_number = br_bank_account.account_number withdraw.account_number_digit = br_bank_account.account_number_digit else: withdraw.address = withdraw_form.cleaned_data['address'] withdraw.save() if coin != settings.BRL_CURRENCY_CODE and not is_tbsa: withdraw_hash = encrypt(settings.SECRET_KEY, str(withdraw.pk)).hex() approve_link = settings.DOMAIN + reverse( 'payments>approve-withdraw', kwargs={'withdraw_hash': withdraw_hash}) # Sends withdraw confirmation e-mail to admin send_templated_mail( template_name='approve-withdraw', from_email=settings.DEFAULT_FROM_EMAIL, context={ 'withdraw': withdraw, 'approve_link': approve_link }, recipient_list=settings.WITHDRAW_APPROVE_EMAILS) if settings.WITHDRAW_USER_SEND_CONFIRMATION: # Sends withdraw confirmation e-mail to user send_templated_mail(template_name='approve-withdraw', from_email=settings.DEFAULT_FROM_EMAIL, context={ 'withdraw': withdraw, 'approve_link': approve_link }, recipient_list=[request.user.email]) account.deposit -= abs(withdraw.amount) account.save() statement = Statement() statement.account = account statement.description = 'Withdraw' statement.type = Statement.TYPES.withdraw statement.amount = Decimal('0.00') - abs(withdraw.amount) statement.save() return {'status': 'success', 'amount': withdraw.amount}
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))
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.") }
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 }