Skip to content

Commit 136a90f

Browse files
authored
Merge pull request #9 from saadmk11/v2.0
Adding new version
2 parents 1f0092f + 3e82f85 commit 136a90f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1144
-962
lines changed

.gitignore

100755100644
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@ bin/
44
include/
55
pip-selfcheck.json
66

7-
db.sqlite3
7+
course_import.py
88
.idea/
9+
dist/
10+
.vscode/
11+
db.json
12+
htmlcov/
913
media/
10-
celerybeat-schedule.db
14+
db.sqlite3
15+
staticfiles/
16+
.env
17+
.coverage
1118
celerybeat.pid
19+
celerybeat-schedule
1220

1321
# Byte-compiled / optimized / DLL files
1422
__pycache__/
@@ -23,7 +31,6 @@ __pycache__/
2331
env/
2432
build/
2533
develop-eggs/
26-
dist/
2734
downloads/
2835
eggs/
2936
.eggs/

README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
1-
# Online Banking System
1+
# Online Banking System V2.0
22

33
This is a Online Banking Concept created using Django Web Framework.
44

55
## Features
66

77
* Create Bank Account.
8-
* Load account Details Using Account Number & password.
9-
* Deposit & Withdraw Money.
10-
* Transaction Detail Page.
11-
* Count Monthly Interest Using Celery.
8+
* Deposit & Withdraw Money
9+
* Bank Account Type Support
10+
* Interest calculation depending on the Account type
11+
* Transaction report with a date range filter and balance after every transaction
12+
* Count Monthly Interest Using Celery
13+
* More efficient and accurate interest calculation and balance update
14+
* Ability to add Minimum and Maximum Transaction amount restriction
15+
* Modern UI with Tailwind CSS
16+
1217

1318
## Prerequisites
1419

1520
Be sure you have the following installed on your development machine:
1621

17-
+ Python >= 3.6.3
22+
+ Python >= 3.7
1823
+ Redis Server
19-
+ Git
24+
+ Git
2025
+ pip
2126
+ Virtualenv (virtualenvwrapper is recommended)
2227

2328
## Requirements
2429

25-
+ celery==4.1.0
26-
+ Django==1.11.20
27-
+ django-celery-beat==1.0.1
28-
+ django-crispy-forms==1.6.1
29-
+ Pillow==4.2.1
30-
+ redis==2.10.6
30+
+ celery==4.4.7
31+
+ Django==3.1
32+
+ django-celery-beat==2.0.0
33+
+ python-dateutil==2.8.1
34+
+ redis==3.5.3
3135

3236
## Install Redis Server
3337

@@ -84,14 +88,12 @@ python manage.py createsuperuser
8488
Run Celery
8589
(Different Terminal Window with Virtual Environment Activated)
8690
```bash
87-
celery -A bankingsystem worker -l info
91+
celery -A banking_system worker -l info
8892

89-
celery -A bankingsystem beat -l info
93+
celery -A banking_system beat -l info
9094
```
9195

9296
## Images:
93-
![alt text](https://i.imgur.com/QZwaEHX.png)
94-
#
95-
![alt text](https://i.imgur.com/HTcqWcw.png)
97+
![alt text](https://i.imgur.com/FvgmEJL.png)
9698
#
97-
![alt text](https://i.imgur.com/HHsmJVD.png)
99+
![alt text](https://i.imgur.com/aWzj44Y.png)

accounts/__init__.py

100755100644
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
default_app_config = 'accounts.apps.AccountsConfig'

accounts/admin.py

100755100644
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from django.contrib import admin
22

3-
from .models import User, AccountDetails, UserAddress
3+
from .models import BankAccountType, User, UserAddress, UserBankAccount
44

55

6+
admin.site.register(BankAccountType)
67
admin.site.register(User)
7-
admin.site.register(AccountDetails)
88
admin.site.register(UserAddress)
9+
admin.site.register(UserBankAccount)

accounts/apps.py

100755100644
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,3 @@
33

44
class AccountsConfig(AppConfig):
55
name = 'accounts'
6-
7-
def ready(self):
8-
import accounts.signals

accounts/backends.py

Lines changed: 0 additions & 21 deletions
This file was deleted.

accounts/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
MALE = 'M'
2+
FEMALE = 'F'
3+
4+
GENDER_CHOICE = (
5+
(MALE, "Male"),
6+
(FEMALE, "Female"),
7+
)

accounts/forms.py

100755100644
Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,86 @@
1-
import datetime
21
from django import forms
3-
from django.contrib.auth import authenticate
2+
from django.conf import settings
43
from django.contrib.auth.forms import UserCreationForm
4+
from django.db import transaction
55

6-
from .models import User, AccountDetails, UserAddress
6+
from .models import User, BankAccountType, UserBankAccount, UserAddress
7+
from .constants import GENDER_CHOICE
78

89

9-
class UserRegistrationForm(UserCreationForm):
10+
class UserAddressForm(forms.ModelForm):
1011

1112
class Meta:
12-
model = User
13+
model = UserAddress
1314
fields = [
14-
"first_name",
15-
"last_name",
16-
"email",
17-
"contact_no",
18-
"password1",
19-
"password2"
15+
'street_address',
16+
'city',
17+
'postal_code',
18+
'country'
2019
]
2120

21+
def __init__(self, *args, **kwargs):
22+
super().__init__(*args, **kwargs)
2223

23-
class AccountDetailsForm(forms.ModelForm):
24+
for field in self.fields:
25+
self.fields[field].widget.attrs.update({
26+
'class': (
27+
'appearance-none block w-full bg-gray-200 '
28+
'text-gray-700 border border-gray-200 rounded '
29+
'py-3 px-4 leading-tight focus:outline-none '
30+
'focus:bg-white focus:border-gray-500'
31+
)
32+
})
2433

25-
class Meta:
26-
model = AccountDetails
27-
fields = [
28-
'gender',
29-
'birth_date',
30-
'picture'
31-
]
3234

33-
34-
class UserAddressForm(forms.ModelForm):
35+
class UserRegistrationForm(UserCreationForm):
36+
account_type = forms.ModelChoiceField(
37+
queryset=BankAccountType.objects.all()
38+
)
39+
gender = forms.ChoiceField(choices=GENDER_CHOICE)
40+
birth_date = forms.DateField()
3541

3642
class Meta:
37-
model = UserAddress
43+
model = User
3844
fields = [
39-
'street_address',
40-
'city',
41-
'postal_code',
42-
'country'
45+
'first_name',
46+
'last_name',
47+
'email',
48+
'password1',
49+
'password2',
4350
]
4451

52+
def __init__(self, *args, **kwargs):
53+
super().__init__(*args, **kwargs)
4554

46-
class UserLoginForm(forms.Form):
47-
account_no = forms.IntegerField(label="Account Number")
48-
password = forms.CharField(widget=forms.PasswordInput)
49-
50-
def clean(self, *args, **kwargs):
51-
account_no = self.cleaned_data.get("account_no")
52-
password = self.cleaned_data.get("password")
55+
for field in self.fields:
56+
self.fields[field].widget.attrs.update({
57+
'class': (
58+
'appearance-none block w-full bg-gray-200 '
59+
'text-gray-700 border border-gray-200 '
60+
'rounded py-3 px-4 leading-tight '
61+
'focus:outline-none focus:bg-white '
62+
'focus:border-gray-500'
63+
)
64+
})
5365

54-
if account_no and password:
55-
user = authenticate(account_no=account_no, password=password)
56-
if not user:
57-
raise forms.ValidationError("Account Does Not Exist.")
58-
if not user.check_password(password):
59-
raise forms.ValidationError("Password Does not Match.")
60-
if not user.is_active:
61-
raise forms.ValidationError("Account is not Active.")
66+
@transaction.atomic
67+
def save(self, commit=True):
68+
user = super().save(commit=False)
69+
user.set_password(self.cleaned_data["password1"])
70+
if commit:
71+
user.save()
72+
account_type = self.cleaned_data.get('account_type')
73+
gender = self.cleaned_data.get('gender')
74+
birth_date = self.cleaned_data.get('birth_date')
6275

63-
return super(UserLoginForm, self).clean(*args, **kwargs)
76+
UserBankAccount.objects.create(
77+
user=user,
78+
gender=gender,
79+
birth_date=birth_date,
80+
account_type=account_type,
81+
account_no=(
82+
user.id +
83+
settings.ACCOUNT_NUMBER_START_FROM
84+
)
85+
)
86+
return user

accounts/managers.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.contrib import auth
12
from django.contrib.auth.base_user import BaseUserManager
23

34

@@ -6,19 +7,22 @@ class UserManager(BaseUserManager):
67

78
def _create_user(self, email, password, **extra_fields):
89
"""
9-
Create and save a user with the given account_no and password.
10+
Create and save a user with the given email, and password.
1011
"""
12+
if not email:
13+
raise ValueError('The given email must be set')
14+
email = self.normalize_email(email)
1115
user = self.model(email=email, **extra_fields)
1216
user.set_password(password)
1317
user.save(using=self._db)
1418
return user
1519

16-
def create_user(self, email, password=None, **extra_fields):
20+
def create_user(self, email=None, password=None, **extra_fields):
1721
extra_fields.setdefault('is_staff', False)
1822
extra_fields.setdefault('is_superuser', False)
1923
return self._create_user(email, password, **extra_fields)
2024

21-
def create_superuser(self, email, password, **extra_fields):
25+
def create_superuser(self, email, password=None, **extra_fields):
2226
extra_fields.setdefault('is_staff', True)
2327
extra_fields.setdefault('is_superuser', True)
2428

@@ -28,3 +32,29 @@ def create_superuser(self, email, password, **extra_fields):
2832
raise ValueError('Superuser must have is_superuser=True.')
2933

3034
return self._create_user(email, password, **extra_fields)
35+
36+
def with_perm(self, perm, is_active=True, include_superusers=True, backend=None, obj=None):
37+
if backend is None:
38+
backends = auth._get_backends(return_tuples=True)
39+
if len(backends) == 1:
40+
backend, _ = backends[0]
41+
else:
42+
raise ValueError(
43+
'You have multiple authentication backends configured and '
44+
'therefore must provide the `backend` argument.'
45+
)
46+
elif not isinstance(backend, str):
47+
raise TypeError(
48+
'backend must be a dotted import path string (got %r).'
49+
% backend
50+
)
51+
else:
52+
backend = auth.load_backend(backend)
53+
if hasattr(backend, 'with_perm'):
54+
return backend.with_perm(
55+
perm,
56+
is_active=is_active,
57+
include_superusers=include_superusers,
58+
obj=obj,
59+
)
60+
return self.none()

0 commit comments

Comments
 (0)