From 033a3f994662aa7507930919e3ef5706f0d8b5bf Mon Sep 17 00:00:00 2001 From: DJ Gillespie Date: Mon, 25 Nov 2019 19:51:26 -0700 Subject: [PATCH] QRTR-2 Finalized v1 of api setup for storage and access. --- api/__pycache__/models.cpython-37.pyc | Bin 165 -> 179 bytes api/__pycache__/serializers.cpython-37.pyc | Bin 1014 -> 3030 bytes api/models.py | 1 - api/serializers.py | 36 +++++++++++++++- connection/admin.py | 5 ++- connection/models.py | 10 ++++- core/__pycache__/settings.cpython-37.pyc | Bin 2528 -> 2722 bytes core/__pycache__/urls.cpython-37.pyc | Bin 1349 -> 1656 bytes core/settings.py | 10 +++++ core/urls.py | 15 ++++++- db.sqlite3 | Bin 180224 -> 262144 bytes qrtr_account/models.py | 47 ++++++++++++++++----- qrtr_account/views.py | 38 ++++++++++++++++- 13 files changed, 146 insertions(+), 16 deletions(-) diff --git a/api/__pycache__/models.cpython-37.pyc b/api/__pycache__/models.cpython-37.pyc index b999c7d7410f74a0e2b90c3ffcbfd94ea5f41b9e..d54e204f16be1c1c8ef313a14ff5a71b9aae6904 100644 GIT binary patch delta 43 xcmZ3=xS5gHiI32#`{yQ~HV|t>cy07byYe_9Nd_&1bVy2dFDcMZy)bX9v_1(1Y*Hh2;l-)`iY141& z+H;NB%=txQ4!15^w}#&)i_7X{sh5@xSv=MtOQW=$kfq65WNDR_E?L^FLzYfy>5=7x zb;;5#Eq$`|Sf4EY(lTI!SK8?GZ(5Hw(xvrW%okTAv?E>wi=2xfoim=0r9ny@Ch?Ms zd}K=J+u3Zs$O>sb3$shv_#w-SxL6eNJd=&rBFyq|28DWh-_5g(D{Y2x)*pj}DLwg+ z8m{>|)BGCEP-iuoVePi&8_b~DnX>&84gTtG{2edO+RGPPUbu0q`6fIugPF_%;mGkV z=90hqvcKzZ{DK#uG!`O}F4mldDVG*c!#I(41R}X?&u=o$f^fBJ(nFTU*+y?&$Nc6_ zJsa854FWg{0_g>yxJV#3gW%mFOjiF0Adr?qEbTWjPgwq&CO#soYX13Z@^+r`3A>0U zQJf?^XZ(8dor`)E-)otC=#Um2WMyBXt zgg%-98kjeuuB3;sVJo=w(mAnTiW^e>h(5?>j z6Y7nit${+X2(*m?b$}*vdx~Lpi^u)a!Q99trgdWKE&IFvwtzO@i9)Pvfb?c}WluKZ zt@7w*@$6F780S1p!feK+6V8I-{S}uU3Hjn2@*ecq$w#0Eta8_zRd)Sj>W{2g!-rlG z{^{1aa3BWQGE;g!wD*U5U2X8IMBW1p2gDK3KF1U)7l1FR_h;~c)li{?UKQEa>3IMd zra7f2N2K=^fyktEwJ2Tf<#4aN4L0eru;4|Ua)I=c4x@7;PVzk@v0IKHIl{~;lSFUO zTa$!dk>p@=@i+hy(VAkg51c!X_IcVcJd}Dkevbe)!3-(`dqTa(@KB~6^s~{a9I}fr zi{@i0LxqUX$Kj%QJ62bXT;NsN-}A!iM$#5MFM>CMPSl&ZxD=S1-`}ooYe(uZP-RJN zGh~S0-4wp{YXBjK-&0i+Nt|7B_5!!cO;FUuLg3UCNNMpH4YEKW`~pkbcXCVj>(#~T X8=c`sfqv!N&`l|L{z%O0$ delta 451 zcmca6{*9f_iIP=qao z9Vo&M72!zX2xidaocK+DavWpuL|M+sD_Qs^pJ3$SN@s~;O<@H}vQ2)%Xgt}C$&Q;J zXhji-_@zC$pGh)3u^>~wIJGD0tq%CE@lD}9E?S*ljWJG)`LWDvE(J@ruu2Jp_>I# zS;Pw>_&@~Qoe&n-RFHKb6;OAvkmxQcps_+g?I5Sa90ub1X>v|J$rUg;id)tKy8vx)pN^JlD diff --git a/api/models.py b/api/models.py index 71a8362..beeb308 100644 --- a/api/models.py +++ b/api/models.py @@ -1,3 +1,2 @@ from django.db import models -# Create your models here. diff --git a/api/serializers.py b/api/serializers.py index 427e4e5..59858e5 100755 --- a/api/serializers.py +++ b/api/serializers.py @@ -1,15 +1,49 @@ 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 +from connection.models import Connection class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = get_user_model() - fields = ['url', 'username', 'email', 'groups'] + fields = ['url', 'username', 'email', 'groups', 'owned_accounts', + 'admin_accounts', 'view_accounts'] class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group fields = ['url', 'name'] + + +class AccountSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Account + fields = ['url','owner', 'name', 'admin_users', 'view_users'] + + +class BankSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Bank + fields = ['url','qrtr_account', 'connection', 'institution', 'nickname', + 'balance', 'ac_type', 'ac_subtype'] + + +class InstitutionSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Institution + fields = ['url','name'] + + +class TransactionSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Transaction + fields = ['url', 'datetime', 'Bank', 'details'] + + +class ConnectionSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Connection + fields = ['url', 'name'] \ No newline at end of file diff --git a/connection/admin.py b/connection/admin.py index 8c38f3f..e03e319 100644 --- a/connection/admin.py +++ b/connection/admin.py @@ -1,3 +1,6 @@ from django.contrib import admin +from .models import Connection -# Register your models here. +@admin.register(Connection) +class ConnectionAdmin(admin.ModelAdmin): + pass diff --git a/connection/models.py b/connection/models.py index 71a8362..744b447 100644 --- a/connection/models.py +++ b/connection/models.py @@ -1,3 +1,11 @@ from django.db import models +import jsonfield -# Create your models here. + +class Connection(models.Model): + name = models.CharField(max_length=255) + connection_path = models.CharField(max_length=255) + credentials = jsonfield.JSONField() + + def __str__(self): + return f"{self.name}" diff --git a/core/__pycache__/settings.cpython-37.pyc b/core/__pycache__/settings.cpython-37.pyc index c14f2eeb28173ab39d008ec6fe3c229f2b61c6b8..476bff1a2ed400db56cf9a45e6fb09d5c64bb92c 100644 GIT binary patch delta 508 zcmZWmO=}ZT6rDF6W0N#h(@c`K(fZLk)|i>}!&a+^w1@`8;v^zGkPzlPUZzYkb>6gE z7rN-iot3w7(S?djag)6(m;Qp_LhvuR>dKdZAb8-Md+*^aF8BVN_-I<|nM_Jk`1bn8 zlghZJ{Td8^kyXuYMRD}jdh`l8n8@=iO`$;3DAF-ZVhYnJDLsudn88_|q#2yUd9KrO zT%ac~%QYC7!$nxQgn4fG1eXsDPUuOL=_y=6g^?}&eU>F)f6(C^>OP?psL~u3u&B}t zSQ=`1d04Lcgd5bv3e97c7GTh#;-umfuF+}eb#4B7FGmh^tDo}1ZkKtnA9m^3(~-YS`o81R8BUH8Cf?9vOlsXUm9O+vmM9V zYmO6yUMpyaB3@gnR;w@a16%y(_ih|JASBiMp0Efh$=}D{6sWne>DHT@ZtZUELG$sw zTI0_BTD>9nM?br>>fq5pj#iy^*kKN~xWoM*U;=E{dFVFWp;QEmc72ZtN3G5r!Q$BO la$#@p^+#`ZLhJfgM7_QT#UvbqNbjz|*4)#hFE28N0{Qsp-x07iJG(-xzt4^s9v-#OVk7JqRpyMzciGlc?}u`uLCZ41Dt}} zKnjkbS#Ss34YwEp6P|ms&JryRuvimJ=CT&^Rt9Uc&Z?}muF|%ai1qY&TBcp4^}(2J zsVE(DLs@jy{msq2L3`}hVQF{p>Bm>&eAmj!gCI!KSiT71>=0ybkNx=V)xmob3mM8( zhDls#N8FEvA6(a350f~C|0F9Fz(rn}@+3VGwC4XwBXaAtN+2i>V{!Y+TjW^&a}~KA z6n@#~@<-Iqo|^YiJ9}?#KlVt`B%9gN;25scVuI+}*_IS2-e(X+|XWCM5APZnVSB6F<4a7P80 W2qRao@}OE%`?XmisDnBtM!x}v%BW)i delta 286 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 delta 580 zcmWkqT}V@582;Y#v$L(a_e?uY){iGp7-8EvPO*&G20}#C90Y}p+|ry%x#6_vCJs>- zSr@Y}I?#=g;8lTm$dim<30_29h(#1F8QxWfM0Dk%zFj;oywCghJg;HMhOw)-*B2s$ zv@^6Z0K>_d_DEBRgpN4HI)ghb5hSn z!4gvZfzR+G-oY!FVlz<`ah)iHrosu$-5~M@otdf0k%8<)ZYr+;ABLf^%y>38aCJ00 zk(nILjTf5P1))je4?F3XaO?h{o8@lQ2_{g-C%Az>@jAZ7dpLp?yPzP|qwkyDs1e-4 zuUN)KoW*IphFLs=8td4NR7-r|gPszV`jSlbpvNkuem6Gi9jd1HM6{l+NT{P*@6wP!;%~Yk^AD`j+!9YvJ2jhbQqKCLH3nxH*oHes}}& zOx$mtN&}kHZ@DFb8DFMJ`GqO3a@}U^9XIDV5p(!2beZX4Xrnj7l6hm5^V@|CM8Up$ z8Cta66yrqEyF$Dx%+gD*^VTsCPu~{fW_24>`}+n2zyVkx nSYh>bG%MQ>WW*-HO-6h|d-ES0h*_#pMVgjXwo;wXbAA5-0~o9( diff --git a/qrtr_account/models.py b/qrtr_account/models.py index 8a27b8f..6f77a9d 100644 --- a/qrtr_account/models.py +++ b/qrtr_account/models.py @@ -1,21 +1,48 @@ from django.db import models from user.models import User +import jsonfield class Account(models.Model): - owner = models.ForeignKey(User, on_delete=models.CASCADE) - admin_users = models.ManyToManyField(User, related_name="admins") - view_users = models.ManyToManyField(User, related_name="viewer") + owner = models.ForeignKey(User, on_delete=models.CASCADE, + related_name="owned_accounts") + admin_users = models.ManyToManyField(User, related_name="admin_accounts", + blank=True) + view_users = models.ManyToManyField(User, related_name="view_accounts", + blank=True) name = models.CharField(max_length=250) + def __str__(self): + return f"{self.owner}" -class InstitutionAccount(models.Model): + +class Institution(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return f"{self.name}" + + +class Bank(models.Model): qrtr_account = models.ForeignKey(Account, on_delete=models.CASCADE) - name = models.CharField(max_length=250) - id = models.CharField(max_length=150) - balance = models.DecimalField() - ac_type = models.CharField() - ac_subtype = models.CharField() + connection = models.ForeignKey('connection.Connection', + on_delete=models.CASCADE) + institution = models.ForeignKey(Institution, on_delete=models.CASCADE, + related_name="banks") + nickname = models.CharField(max_length=250) + balance = models.DecimalField(decimal_places=3, max_digits=100) + ac_type = models.CharField(max_length=250, blank=True) + ac_subtype = models.CharField(max_length=250, blank=True) + + def __str__(self): + return f"{self.nickname}" + class Transaction(models.Model): - pass + datetime = models.DateTimeField() + Bank = models.ForeignKey(Bank, on_delete=models.CASCADE, + related_name='transactions') + details = jsonfield.JSONField() + + def __str__(self): + return f"{self.Bank} - {self.datetime}" diff --git a/qrtr_account/views.py b/qrtr_account/views.py index 91ea44a..378c726 100644 --- a/qrtr_account/views.py +++ b/qrtr_account/views.py @@ -1,3 +1,39 @@ from django.shortcuts import render +from rest_framework import viewsets +from .models import Account, Bank, Institution, Transaction +from connection.models import Connection +from api.serializers import (AccountSerializer, + BankSerializer, + InstitutionSerializer, + TransactionSerializer, + ConnectionSerializer) -# Create your views here. + +class AccountViewSet(viewsets.ModelViewSet): + """API endpoint that allows accounts to be viewed or edited + """ + queryset = Account.objects.all() + serializer_class = AccountSerializer + + +class BankViewSet(viewsets.ModelViewSet): + """API endpoint that allows Banks to be viewed or edited + """ + queryset = Bank.objects.all() + serializer_class = BankSerializer + +class InstitutionViewSet(viewsets.ModelViewSet): + """API endpoint that allows Banks to be viewed or edited + """ + queryset = Institution.objects.all() + serializer_class = InstitutionSerializer + +class TransactionViewSet(viewsets.ModelViewSet): + """API endpoint that allows Banks to be viewed or edited + """ + queryset = Transaction.objects.all() + serializer_class = TransactionSerializer + +class ConnectionViewSet(viewsets.ModelViewSet): + queryset = Connection.objects.all() + serializer_class = ConnectionSerializer \ No newline at end of file