예제 #1
0
    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()
예제 #2
0
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,
        })
예제 #3
0
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,),
    })
예제 #4
0
 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)
예제 #5
0
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),
        })
예제 #6
0
    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)
예제 #7
0
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'],
                      ),
                  })
예제 #8
0
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})
예제 #9
0
    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()
예제 #10
0
    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)
예제 #11
0
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', ))
예제 #12
0
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'))