def except_protected_error(self): if self.request.POST.get('delete_anyway'): self.object = self.get_object() success_url = self.get_success_url() # This query will "convert" transfer transactions to non-transfer (income-expense). Transactions, linked to # this wallet, will be not "converted" because anyway they will be deleted after this query. Transfer # transactions, only linked to another wallets, will be "converted". query = 'UPDATE "transaction" SET "transfer" = false, "transfer_related_id" = NULL where "id" IN' \ ' (SELECT "id" FROM "transaction" WHERE "transfer_related_id" IN (SELECT "id" FROM "transaction"' \ ' WHERE "wallet_id" = ' + str(self.object.id) + ' AND "transfer" = true AND "owner_id" = ' + \ str(self.request.user.id) + ' AND "value" > 0) UNION ALL SELECT "transfer_related_id" as "id"' \ ' FROM "transaction" WHERE "wallet_id" = ' + str(self.object.id) + ' AND "transfer" = true AND' \ ' "owner_id" = ' + str(self.request.user.id) + ' AND "value" < 0) RETURNING "transfer";' with db_transaction_atomic(): sql.sql(query) ta_m.Transaction.objects.filter(owner=self.request.user, wallet=self.object).delete() self.object.delete() messages.success(self.request, self.success_message) return HttpResponseRedirect(success_url) messages.info( self.request, _('Use checkbox below for delete this wallet and all transactions, linked to' ' this wallet.')) return super().except_protected_error()
def update_account(request): if request.method == 'POST': user_form = f.UserForm(data=request.POST, instance=request.user) account_form = f.AccountForm(data=request.POST, instance=request.user.account) if user_form.is_valid() and account_form.is_valid(): with db_transaction_atomic(): user_form.save() account_form.save() messages.success(request, _('Your Account Was Updated')) activate(request.user.account.language) return redirect('account:update_account') else: user_form = f.UserForm(instance=request.user) try: account_form = f.AccountForm(instance=request.user.account) except m.Account.DoesNotExist: m.Account.objects.create(user=request.user) account_form = f.AccountForm(instance=request.user.account) return render( request, 'common/form.html', { 'title': _('Update Account'), 'submit_btn': _('Update Account'), 'form': user_form, 'form2': account_form, })
def copy_transaction(request, pk): transaction = get_object_or_404(m.Transaction, pk=pk, owner=request.user, transfer=False) if request.method == 'POST': tags_for_transaction = [tag for tag in transaction.tag.all()] transaction.pk = None with db_transaction_atomic(): transaction.save() transaction.tag.add(*tags_for_transaction) messages.success(request, _('The transaction was copied.')) return redirect(reverse_lazy('transaction:list')) model_labels_and_fields = vie_List.model_labels_and_fields return render(request=request, template_name='common/confirm_delete_copy.html', context={ 'title': _('Make copy of existing transaction'), 'description': _('Are you sure you want to make a copy of the following transaction?'), 'submit_btn': _('Make copy'), 'links': ( m.Transaction.links['list'], m.Transaction.links['new_income_expense'], m.Transaction.links['new_pair_transfer'], m.Transaction.links['new_income_expense_set'], m.Transaction.links['list_filter'], m.Transaction.links['list_the_edit_mode'], ), 'transaction': True, 'labels': [m.Transaction._meta.get_field(label).verbose_name for label in model_labels_and_fields], 'fields': model_labels_and_fields, 'objects': (transaction,), })
def form_valid(self, form): with db_transaction_atomic(): ab_m.ReasonToDeleteAccount.objects.create( reason=form.cleaned_data.get('reason')) ta_m.Transaction.objects.filter(owner=self.request.user).delete() self.request.user.delete() messages.success(self.request, _('Your account was deleted')) return super().form_valid(form)
def delete_pair_transfer(request, pk): ta = get_object_or_404(m.Transaction.objects.select_related( 'transfer_related', 'wallet').prefetch_related('tag'), owner=request.user, transfer=True, pk=pk) if ta.transfer_related: ta1 = ta.transfer_related ta2 = ta else: ta1 = ta ta2 = get_object_or_404(m.Transaction.objects.select_related( 'transfer_related', 'wallet'), owner=request.user, transfer=True, transfer_related=ta) if request.method == 'POST': with db_transaction_atomic(): # TODO: Why Django/PostgreSQL want to remove one of transactions twice? ta1.delete() ta2.delete() messages.success( request, _('Transactions (Pair of Money Transfer) was deleted.')) return redirect(reverse_lazy('transaction:list')) model_labels_and_fields = vie_List.model_labels_and_fields return render( request=request, template_name='common/confirm_delete_copy.html', context={ 'title': _('Delete Transactions (Pair of Money Transfer)'), 'description': _('Are you sure you want to delete the transactions shown below?'), 'submit_btn': _('Yes, I am sure. Delete it!'), 'links': ( m.Transaction.links['list'], m.Transaction.links['new_income_expense'], m.Transaction.links['new_pair_transfer'], m.Transaction.links['new_income_expense_set'], m.Transaction.links['list_filter'], m.Transaction.links['list_the_edit_mode'], ), 'transaction': True, 'labels': [ m.Transaction._meta.get_field(label).verbose_name for label in model_labels_and_fields ], 'fields': model_labels_and_fields, 'objects': (ta1, ta2), })
def form_valid(self, form): fcd = form.cleaned_data ta1 = m.Transaction( owner=self.request.user, transfer=True, date=fcd.get('date'), value=fcd.get('value1'), wallet=fcd.get('wallet1'), category=fcd.get('category'), description=fcd.get('description1'), # tag below currency=fcd.get('currency'), value_in_curr=fcd.get('value_in_curr'), contact=fcd.get('contact'), bank_date=fcd.get('bank_date1'), bank_ta_id=fcd.get('bank_ta_id1'), ) ta2 = m.Transaction( owner=self.request.user, transfer=True, date=ta1.date, value=fcd.get('value2'), wallet=fcd.get('wallet2'), category=ta1.category, description=fcd.get('description2'), # tag below currency=ta1.currency, value_in_curr=ta1.value_in_curr * -1, contact=ta1.contact, bank_date=fcd.get('bank_date2'), bank_ta_id=fcd.get('bank_ta_id2'), ) tags_for_ta1 = [tag1 for tag1 in fcd.get('tag1')] tags_for_ta2 = [tag2 for tag2 in fcd.get('tag2')] with db_transaction_atomic(): ta1.save() ta2.transfer_related = ta1 ta2.save() ta1.tag.add(*tags_for_ta1) ta2.tag.add(*tags_for_ta2) messages.success( self.request, _('Transactions (Pair of Money Transfer) have been created.')) return super().form_valid(form)
def create_set(request): def get_formset(request, extra): formset = formset_factory(form=f.CreateEditIncomeExpenseForm, max_num=15, extra=extra) form_kwargs = {'user': request.user} if request.POST: return formset(request.POST, form_kwargs=form_kwargs) return formset(form_kwargs=form_kwargs) extra = 2 if request.GET.get('extra'): try: extra = int(request.GET.get('extra')) except ValueError: pass formset = get_formset(request, extra) if request.method == 'POST': if formset.is_valid(): with db_transaction_atomic(): for form in formset: form.instance.owner = request.user form.save() messages.success(request, _('Transactions have been created.')) return redirect(reverse_lazy('transaction:list')) return render(request=request, template_name='transaction/new_set.html', context={ 'form': f.CreateEditIncomeExpenseForm, 'formset': formset, 'title': _('New Set (Income or Expense)'), 'extra': extra, 'datetimepicker': True, 'links': ( m.Transaction.links['new_income_expense'], m.Transaction.links['new_pair_transfer'], m.Transaction.links['list'], m.Transaction.links['list_filter'], m.Transaction.links['list_the_edit_mode'], ), })
def signup(request): if request.method == 'POST': form = SignUpForm(request.POST) if form.is_valid(): with db_transaction_atomic(): form.save() m.Account.objects.create(user_id=form.instance.pk) username = form.cleaned_data.get('username') raw_password = form.cleaned_data.get('password1') user = authenticate(username=username, password=raw_password) login(request, user) return redirect('account:update_account') else: form = SignUpForm() return render(request=request, template_name='registration/signup.html', context={'form': form})
def except_protected_error(self): if self.request.POST.get('delete_anyway'): self.object = self.get_object() success_url = self.get_success_url() with db_transaction_atomic(): ta_m.Transaction.objects.filter( owner=self.request.user, contact=self.object).update(contact=None) self.object.delete() messages.success(self.request, self.success_message) return HttpResponseRedirect(success_url) messages.info( self.request, _('Use checkbox below for delete this contact and unlink all transactions from ' 'this contact.')) return super().except_protected_error()
def form_valid(self, form): # ManyToMany objects for add and for remove. def mtm_objects_for_add_and_remove(old_set, new_set): should_be_removed = [] for obj in old_set: # If existing tag does not exists in new set of tags, then it should be removed if obj not in new_set: should_be_removed.append(obj) should_be_added = [] for obj in new_set: # If new tag does not exists in existing set of tags, then it should be added if obj not in old_set: should_be_added.append(obj) return should_be_added, should_be_removed fcd = form.cleaned_data self.ta1.date = fcd.get('date') self.ta1.value = fcd.get('value1') self.ta1.wallet = fcd.get('wallet1') self.ta1.category = fcd.get('category') self.ta1.description = fcd.get('description1') # tag below self.ta1.currency = fcd.get('currency') self.ta1.value_in_curr = fcd.get('value_in_curr') self.ta1.contact = fcd.get('contact') self.ta1.bank_date = fcd.get('bank_date1') self.ta1.bank_ta_id = fcd.get('bank_ta_id1') self.ta2.date = self.ta1.date self.ta2.value = fcd.get('value2') self.ta2.wallet = fcd.get('wallet2') self.ta2.category = self.ta1.category self.ta2.description = fcd.get('description2') # tag below self.ta2.currency = self.ta1.currency self.ta2.value_in_curr = self.ta1.value_in_curr * -1 self.ta2.contact = self.ta1.contact self.ta2.bank_date = fcd.get('bank_date2') self.ta2.bank_ta_id = fcd.get('bank_ta_id2') ta1_tags_add, ta1_tags_rmv = mtm_objects_for_add_and_remove( self.ta1.tag.all(), fcd.get('tag1')) ta2_tags_add, ta2_tags_rmv = mtm_objects_for_add_and_remove( self.ta2.tag.all(), fcd.get('tag2')) with db_transaction_atomic(): self.ta1.save(update_fields=('date', 'value', 'wallet', 'category', 'description', 'currency', 'value_in_curr', 'contact', 'bank_date', 'bank_ta_id')) self.ta2.save(update_fields=('date', 'value', 'wallet', 'category', 'description', 'currency', 'value_in_curr', 'contact', 'bank_date', 'bank_ta_id')) self.ta1.tag.add(*ta1_tags_add) self.ta2.tag.add(*ta2_tags_add) self.ta1.tag.remove(*ta1_tags_rmv) self.ta2.tag.remove(*ta2_tags_rmv) messages.success( self.request, _('Transactions (Pair of Money Transfer) was updated.')) return super().form_valid(form)
def db_recorder_of_transaction(path_to_csv, import_from_file, request_user, dict_with_wallets, dict_with_categories, dict_with_tags, dict_with_contacts): with open(path_to_csv, 'r', encoding='utf-8') as file_csv: csv_data = csv.reader(file_csv) csv_data = iter(csv_data) next(csv_data) pair_of_transfer_dict = {} counter = 0 for csv_row in csv_data: counter += 1 if counter <= import_from_file.num_imported_rows: continue row_data_dict = vxccb.csv_row_for_transaction_form(csv_row) # row_data_dict['wallet_curr'] = dict_with_wallets[csv_row[5]].currency # Here could be used "CreateEditIncomeExpenseForm" from transaction.forms, but it makes too many DB queries. form = f.Transaction(row_data_dict) form.is_valid() fcd = form.cleaned_data if not fcd.get('transfer'): ta = ta_m.Transaction( owner=request_user, date=fcd.get('date'), value=fcd.get('value'), wallet=dict_with_wallets[fcd.get('wallet').name], category=dict_with_categories[fcd.get('category')] if fcd.get('category') else None, description=fcd.get('description'), # tag below currency=fcd.get('currency'), value_in_curr=fcd.get('value_in_curr'), contact=dict_with_contacts[fcd.get('contact')] if fcd.get('contact') else None, not_ignore=fcd.get('not_ignore'), bank_date=fcd.get('bank_date'), bank_ta_id=fcd.get('bank_ta_id'), ) tags_for_ta = tags_for_transaction(dict_with_tags, fcd.get('tag')) import_from_file.num_imported_rows += 1 with db_transaction_atomic(): ta.save() ta.tag.add(*tags_for_ta) import_from_file.save( update_fields=('num_imported_rows', )) elif fcd.get('transfer') and fcd.get('value') > 0: row_data_dict = vxccb.csv_row_of_positive_ta_for_ta_pair_transfer_form( row_data_dict) pair_of_transfer_dict.update(row_data_dict) elif fcd.get('transfer') and fcd.get('value') < 0: row_data_dict = vxccb.csv_row_of_negative_ta_for_ta_pair_transfer_form( row_data_dict) pair_of_transfer_dict.update(row_data_dict) form = f.TransactionPairTransfer(pair_of_transfer_dict) form.is_valid() fcd = form.cleaned_data ta1 = ta_m.Transaction( owner=request_user, transfer=True, date=fcd.get('date'), value=fcd.get('value1'), wallet=dict_with_wallets[fcd.get('wallet1').name], category=dict_with_categories[fcd.get('category')] if fcd.get('category') else None, description=fcd.get('description1'), # tag below currency=fcd.get('currency'), value_in_curr=fcd.get('value_in_curr'), contact=dict_with_contacts[fcd.get('contact')] if fcd.get('contact') else None, bank_date=fcd.get('bank_date1'), bank_ta_id=fcd.get('bank_ta_id1'), ) ta2 = ta_m.Transaction( owner=request_user, transfer=True, date=ta1.date, value=fcd.get('value2'), wallet=dict_with_wallets[fcd.get('wallet2').name], category=ta1.category, description=fcd.get('description2'), # tag below currency=ta1.currency, value_in_curr=ta1.value_in_curr * -1, contact=ta1.contact, bank_date=fcd.get('bank_date2'), bank_ta_id=fcd.get('bank_ta_id2'), ) tags_for_ta1 = tags_for_transaction(dict_with_tags, fcd.get('tag1')) tags_for_ta2 = tags_for_transaction(dict_with_tags, fcd.get('tag2')) import_from_file.num_imported_rows += 2 with db_transaction_atomic(): ta1.save() ta2.transfer_related = ta1 ta2.save() ta1.tag.add(*tags_for_ta1) ta2.tag.add(*tags_for_ta2) import_from_file.save( update_fields=('num_imported_rows', ))
def rub_sberbank_db_records(request, pk): statement = get_object_or_404(m.ImportFromFile, owner=request.user, pk=pk, variety=1, bank='rub_sberbank') if not statement.checked or not statement.no_error: return redirect(statement.get_check_url()) existing_bank_ta_id = ta_m.Transaction.objects.filter(owner=request.user, wallet=statement.wallet)\ .values_list('bank_ta_id', flat=True) with open(statement.file.path, 'r') as file_csv: csv_data = csv.reader(file_csv, delimiter=';') csv_data = iter(csv_data) # Needs to skip first iter because first row of the CSV is titles of cols. next(csv_data) counter = 0 new_transactions = [] for csv_row in csv_data: counter += 1 if counter <= statement.num_imported_rows: continue # FOR DEBUG: # if counter >= 2: # continue row_data_dict = csv_row_for_rub_sberbank_form(csv_row, statement.wallet.currency) form = RubSberbankForm(row_data_dict) # We will not check form valid or not because we believe form is valid because we checked CSV file before, # but anyway we should to call "is_valid()" for got the "cleaned_data" form.is_valid() cd = form.cleaned_data if cd.get('bank_ta_id') == '0': ta_with_0_bank_ta_id = ta_m.Transaction.objects.filter( owner=request.user, wallet=statement.wallet, value=cd.get('value'), bank_ta_id='0', bank_date=cd.get('bank_date')).values_list('id', flat=True) if ta_with_0_bank_ta_id: continue elif cd.get('bank_ta_id') in existing_bank_ta_id: continue new_transactions.append(ta_m.Transaction( owner=request.user, wallet=statement.wallet, date=cd.get('date'), bank_date=cd.get('bank_date'), bank_ta_id=cd.get('bank_ta_id'), value_in_curr=value_in_curr_multiply_to_minus_1(cd.get('value_in_curr'), cd.get('value')), currency=cd.get('currency'), value=cd.get('value'), description=cd.get('description'), )) statement.num_imported_rows += 1 if not counter % ta_m.Transaction.MAX_NUM_OF_RECORDS_PER_BULK: with db_transaction_atomic(): statement.save(update_fields=('num_imported_rows',)) ta_m.Transaction.objects.bulk_create(new_transactions) new_transactions = [] else: if new_transactions: with db_transaction_atomic(): statement.save(update_fields=('num_imported_rows',)) ta_m.Transaction.objects.bulk_create(new_transactions) statement.mark_as_finished() msg = _('Success. All transactions from your file was added. Your file completely imported.') messages.success(request, msg) return redirect(reverse_lazy('import_from_file:list'))