added slice name and id filtering to transactions, added transaction grouping by slice, changed bank name, and changed slice budget name.

This commit is contained in:
DJ Gillespie 2023-07-19 19:08:31 -06:00
parent ca4dc5dd0c
commit b6e8c0f108
9 changed files with 93 additions and 41 deletions

View File

@ -1,7 +1,7 @@
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from rest_framework import serializers
from qrtr_account.models import Account, Bank, Institution, Transaction, Slice, Rule
from qrtr_account.models import Account, BankAccount, Institution, Transaction, Slice, Rule
from user.models import User
from connection.models import Connection, ConnectionType
from connection.serializers import ConnectionTypeSerializer, ConnectionSerializer
@ -42,13 +42,14 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ['url', 'name']
fields = ['pk', 'url', 'name']
class BankSerializer(serializers.HyperlinkedModelSerializer):
class BankAccountSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Bank
model = BankAccount
fields = [
'pk',
'url',
'qrtr_account',
'connection',
@ -67,10 +68,10 @@ class BankSerializer(serializers.HyperlinkedModelSerializer):
}
class BankSerializerPOST(BankSerializer):
class BankAccountSerializerPOST(BankAccountSerializer):
"""Separate Serializer for POST requests to create a new bank. This adds
a new field called connection_details that is used to create a new
connection record to go with the new Bank. This field is only allowed on
connection record to go with the new BankAccount. This field is only allowed on
POST because we don't want to expose this information to the user, or allow
them to change it b/c that could lead to an integrity problem, breaking
their bank functionality.
@ -83,8 +84,9 @@ class BankSerializerPOST(BankSerializer):
# "credentials": {}})
class Meta:
model = Bank
model = BankAccount
fields = [
'pk',
'url',
'qrtr_account',
'connection',
@ -107,13 +109,13 @@ class BankSerializerPOST(BankSerializer):
class InstitutionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Institution
fields = ['url', 'name']
fields = ['pk', 'url', 'name']
class TransactionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Transaction
fields = ['url', 'authorized_date',
fields = ['pk', 'url', 'authorized_date',
'bank', 'name','details','slice','trans_id',
'updated_at','created_at']
@ -121,9 +123,15 @@ class TransactionSerializer(serializers.HyperlinkedModelSerializer):
class SliceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Slice
fields = ['url', 'name', 'icon', 'budget', 'slice_of']
fields = ['pk', 'url', 'name', 'icon', 'budget', 'slice_of']
class SliceTransactionSerializer(serializers.ModelSerializer):
transactions = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Slice
fields = ['pk', 'url', 'name', 'icon', 'budget', 'slice_of', 'transactions']
class RuleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Rule

View File

@ -1,4 +1,4 @@
from qrtr_account.models import Transaction, Bank, Account
from qrtr_account.models import Transaction, BankAccount, Account
from connection.models import Connection
@ -15,7 +15,7 @@ def get_and_save_transactions(connection, start_date=None, end_date=None):
defaults={"authorized_date": trns.get("authorized_date"),
"trans_id": trns.get("transaction_id"),
"details": trns,
"bank": Bank.objects.get(acc_id=trns.get("account_id")),
"bank": BankAccount.objects.get(acc_id=trns.get("account_id")),
"name": trns.get("name")})
return True

View File

@ -27,10 +27,10 @@ from user.views import (UserViewSet,
)
from qrtr_account.views import (AccountViewSet,
BankViewSet,
BankAccountViewSet,
InstitutionViewSet,
TransactionViewSet,
SliceViewSet,
SliceViewSet, SliceTransactionViewSet,
FacebookLogin,
TwitterLogin)
@ -59,10 +59,12 @@ router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)
router.register(r'accounts', AccountViewSet)
router.register(r'banks', BankViewSet)
router.register(r'bank-accounts', BankAccountViewSet)
router.register(r'institutions', InstitutionViewSet)
router.register(r'transactions', TransactionViewSet)
router.register(r'slices', SliceViewSet)
router.register(r'slices/(?P<slice_pk>\d+)/transactions',
SliceTransactionViewSet, basename='slices')
#router.register(r'connections',ConnectionViewSet)
router.register(r'connectiontypes', ConnectionTypeViewSet)

View File

@ -1,5 +1,5 @@
from django.contrib import admin
from .models import Account, Institution, Bank, Transaction, Slice
from .models import Account, Institution, BankAccount, Transaction, Slice
@admin.register(Account)
@ -12,8 +12,8 @@ class InstitutionAdmin(admin.ModelAdmin):
pass
@admin.register(Bank)
class BankAdmin(admin.ModelAdmin):
@admin.register(BankAccount)
class BankAccountAdmin(admin.ModelAdmin):
pass

View File

@ -1,9 +1,9 @@
from qrtr_account.models import Account, Institution, Bank
from qrtr_account.models import Account, Institution, BankAccount
from connection.models import Connection
dummy_ac = Account.objects.all()[0]
dummy_isnt = Institution.objects.all()[0]
dummy_bank = Bank.objects.all()[0]
dummy_bank = BankAccount.objects.all()[0]
conn_dummy = Connection.objects.all()[0]
@ -142,5 +142,5 @@ for account in accounts:
"balance":account.get("balances",{}).get("current"),
"balance_limit":account.get("balances",{}).get("limit")
}
Bank.objects.update_or_create(qrtr_account=dummy_ac, acc_id=account.get("account_id"),
BankAccount.objects.update_or_create(qrtr_account=dummy_ac, acc_id=account.get("account_id"),
defaults=fields)

View File

@ -669,11 +669,11 @@ transactions = [
print(len(transactions))
for transaction in transactions:
bank = Bank.objects.filter(acc_id=transaction.get("account_id",[None]))[0]
bank = BankAccount.objects.filter(acc_id=transaction.get("account_id",[None]))[0]
print(bank)
if bank:
fields = {
"datetime":datetime.strptime(transaction.get("date"),"%Y-%m-%d"),
"details":transaction
}
Transaction.objects.update_or_create(Bank=bank,defaults=fields)
Transaction.objects.update_or_create(BankAccount=bank,defaults=fields)

View File

@ -0,0 +1,29 @@
# Generated by Django 3.2.3 on 2023-07-20 01:05
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('connection', '0003_auto_20201125_2242'),
('qrtr_account', '0013_auto_20211229_1935'),
]
operations = [
migrations.RenameModel(
old_name='Bank',
new_name='BankAccount',
),
migrations.RenameField(
model_name='slice',
old_name='budget',
new_name='balance',
),
migrations.AlterField(
model_name='transaction',
name='slice',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transactions', to='qrtr_account.slice'),
),
]

View File

@ -33,12 +33,12 @@ class Institution(models.Model):
return f"{self.name}"
class Bank(models.Model):
class BankAccount(models.Model):
qrtr_account = models.ForeignKey(Account, on_delete=models.CASCADE)
connection = models.ForeignKey('connection.Connection',
on_delete=models.CASCADE)
institution = models.ForeignKey(Institution, on_delete=models.CASCADE,
related_name="banks")
related_name="bank_accounts")
acc_id = models.CharField(max_length=250, primary_key=True)
nickname = models.CharField(max_length=250)
official_name = models.CharField(max_length=250,blank=True, null=True)
@ -59,7 +59,7 @@ class Bank(models.Model):
class Slice(models.Model):
name = models.CharField(max_length=250)
icon = models.CharField(max_length=250)
budget = models.DecimalField(decimal_places=3, max_digits=100)
balance = models.DecimalField(decimal_places=3, max_digits=100)
description = models.TextField(max_length=255, null=True, blank=True)
avail_parents = models.Q(
app_label='qrtr_account',
@ -114,11 +114,11 @@ class Rule(models.Model):
class Transaction(models.Model):
authorized_date = models.DateField(null=True)
bank = models.ForeignKey(Bank, on_delete=models.CASCADE,
bank = models.ForeignKey(BankAccount, on_delete=models.CASCADE,
related_name='transactions')
name = models.CharField(max_length=255)
details = models.JSONField()
slice = models.ForeignKey(Slice, on_delete=models.SET_NULL, null=True)
slice = models.ForeignKey(Slice, on_delete=models.SET_NULL, null=True, related_name='transactions')
trans_id = models.CharField(max_length=255)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)

View File

@ -1,16 +1,16 @@
from django.shortcuts import render
from rest_framework import viewsets, mixins
from .models import Account, Bank, Institution, Transaction, Slice, Rule
from .models import Account, BankAccount, Institution, Transaction, Slice, Rule
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from connection.models import Connection, ConnectionType
from api.serializers import (AccountReadSerializer, AccountWriteSerializer,
BankSerializer, BankSerializerPOST,
BankAccountSerializer, BankAccountSerializerPOST,
InstitutionSerializer,
TransactionSerializer,
ConnectionSerializer,
ConnectionTypeSerializer,
SliceSerializer,
SliceSerializer, SliceTransactionSerializer,
RuleSerializer)
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from dj_rest_auth.registration.views import SocialLoginView
@ -36,39 +36,43 @@ class AccountViewSet(ReadWriteSerializerMixin, viewsets.ModelViewSet):
write_serializer_class = AccountWriteSerializer
class BankViewSet(viewsets.ModelViewSet):
"""API endpoint that allows Banks to be viewed or edited
class BankAccountViewSet(viewsets.ModelViewSet):
"""API endpoint that allows BankAccounts to be viewed or edited
"""
queryset = Bank.objects.all()
# serializer_class = BankSerializer
queryset = BankAccount.objects.all()
# serializer_class = BankAccountSerializer
def get_serializer_class(self):
if self.action == 'create':
return BankSerializerPOST
return BankSerializer
return BankAccountSerializerPOST
return BankAccountSerializer
class SliceViewSet(viewsets.ModelViewSet):
"""API endpoint that allows Banks to be viewed.
"""API endpoint that allows BankAccounts to be viewed.
"""
queryset = Slice.objects.all()
serializer_class = SliceSerializer
class InstitutionViewSet(viewsets.ReadOnlyModelViewSet):
"""API endpoint that allows Banks to be viewed.
"""API endpoint that allows BankAccounts to be viewed.
"""
queryset = Institution.objects.all()
serializer_class = InstitutionSerializer
class TransactionViewSet(viewsets.ModelViewSet):
"""API endpoint that allows Banks to be viewed.
"""API endpoint that allows BankAccounts to be viewed.
"""
queryset = Transaction.objects.filter(is_split=False)
serializer_class = TransactionSerializer
search_fields = ['name', 'slice__name', 'bank__nickname',
'bank__official_name']
filterset_fields = {
'slice__id': ['exact', 'isnull'],
'slice__name': ['exact', ],
'authorized_date': ['exact', 'lte', 'gte', 'isnull'],
'updated_at': ['exact', 'lte', 'gte', 'isnull'],
'created_at': ['exact', 'lte', 'gte', 'isnull'],
@ -92,8 +96,17 @@ class TransactionViewSet(viewsets.ModelViewSet):
child2.name = f"{child1.name}.split2"
class SliceTransactionViewSet(viewsets.ModelViewSet):
serializer_class = SliceTransactionSerializer
queryset = Slice.objects.all()
# def get_queryset(self):
# return Transaction.objects.filter(slice__pk=self.kwargs.get('slice_pk'))
class RuleViewSet(viewsets.ReadOnlyModelViewSet):
"""API endpoint that allows Banks to be viewed.
"""API endpoint that allows BankAccounts to be viewed.
"""
queryset = Rule.objects.all()
serializer_class = RuleSerializer