Job 1: Develop a Personal Cash Management web app
Develop a Personal Cash Management web app to provide users with a convenient and efficient way to manage their finances. This application helps individuals track their income, expenses,and transactions, allowing them to gain insights into their spending habits, save money, and maintain financial stability
Job Specification information:
1. Create a new Django project named Name_ID_ManageCash.
2. Crcate a Django app named ManageCash.
3. Define the required models for the portfolio app in the models.py file.
a. AddCash (user (many to one User), source, datetime, amount, description)
b. Expense (user {many to one User}, description, amount, datetime)
4. Create views for Login (username/email and password) and Registration
(username, email, password, confirm password) pages.
5. Create required Django templates.
a. Profile management view.
b. Cash Management Dashboard.
c. Transaction form (AddCash / Expense)
6. Define URL Patterns and configure project-level URLs.
7. Implement the required Function and Logic in the view.py file.
Job Specification information:
a. Create a new Django project. (Naming Convention: Name_ID_ManageCash)
b. Run migration to create the data tables.
c. Create a super user. (username: admin, password: 1234)
d. Register your models to the Django admin.
models.py
from django.db import models
from django.contrib.auth.models import User
class AddCash(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
source = models.CharField(max_length=100)
datetime = models.DateTimeField()
amount = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField()
def __str__(self):
return f"{self.user.username} - {self.source} - {self.amount}"
class Expense(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
description = models.TextField()
amount = models.DecimalField(max_digits=10, decimal_places=2)
datetime = models.DateTimeField()
def __str__(self):
return f"{self.user.username} - {self.amount}"
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import AddCash, Expense
from django.utils import timezone
def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('dashboard')
else:
messages.error(request, 'Invalid username or password.')
return render(request, 'login.html')
def register_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Account created successfully.')
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'register.html', {'form': form})
@login_required
def profile_view(request):
return render(request, 'profile.html')
@login_required
def dashboard_view(request):
addcash_transactions = AddCash.objects.filter(user=request.user)
expense_transactions = Expense.objects.filter(user=request.user)
total_income = sum(t.amount for t in addcash_transactions)
total_expenses = sum(t.amount for t in expense_transactions)
balance = total_income - total_expenses
context = {
'addcash_transactions': addcash_transactions,
'expense_transactions': expense_transactions,
'total_income': total_income,
'total_expenses': total_expenses,
'balance': balance,
}
return render(request, 'dashboard.html', context)
@login_required
def add_cash_view(request):
if request.method == 'POST':
source = request.POST['source']
amount = request.POST['amount']
description = request.POST['description']
AddCash.objects.create(
user=request.user,
source=source,
amount=amount,
description=description,
datetime=timezone.now()
)
messages.success(request, 'Cash added successfully.')
return redirect('dashboard')
return render(request, 'add_cash.html')
@login_required
def add_expense_view(request):
if request.method == 'POST':
description = request.POST['description']
amount = request.POST['amount']
Expense.objects.create(
user=request.user,
description=description,
amount=amount,
datetime=timezone.now()
)
messages.success(request, 'Expense added successfully.')
return redirect('dashboard')
return render(request, 'add_expense.html')
def logout_view(request):
logout(request)
return redirect('login')
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.login_view, name='login'),
path('register/', views.register_view, name='register'),
path('profile/', views.profile_view, name='profile'),
path('dashboard/', views.dashboard_view, name='dashboard'),
path('add_cash/', views.add_cash_view, name='add_cash'),
path('add_expense/', views.add_expense_view, name='add_expense'),
path('logout/', views.logout_view, name='logout'),
]
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.card { border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Register for Cash Management</h2>
{% if messages %}
{% for message in messages %}
<div class="alert alert-info">{{ message }}</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="id_username" class="form-label">Username</label>
<input type="text" name="username" id="id_username" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_password1" class="form-label">Password</label>
<input type="password" name="password1" id="id_password1" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_password2" class="form-label">Confirm Password</label>
<input type="password" name="password2" id="id_password2" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary w-100">Register</button>
</form>
<p class="text-center mt-3">Already have an account? <a href="{% url 'login' %}" class="text-decoration-none">Login here</a></p>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.card { border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Login to Cash Management</h2>
{% if messages %}
{% for message in messages %}
<div class="alert alert-info">{{ message }}</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" id="username" name="username" class="form-control" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" id="password" name="password" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary w-100">Login</button>
</form>
<p class="text-center mt-3">Don't have an account? <a href="{% url 'register' %}" class="text-decoration-none">Register here</a></p>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
profile.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profile - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.card { border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card p-4">
<div class="card-body text-center">
<h2 class="card-title mb-4">User Profile</h2>
<div class="mb-3">
<strong>Username:</strong> {{ user.username }}
</div>
<div class="mb-3">
<strong>Email:</strong> {{ user.email|default:"Not provided" }}
</div>
<div class="mb-3">
<strong>Date Joined:</strong> {{ user.date_joined|date:"F j, Y" }}
</div>
<div class="mt-4">
<a href="{% url 'dashboard' %}" class="btn btn-primary me-2">Back to Dashboard</a>
<a href="{% url 'logout' %}" class="btn btn-danger">Logout</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
dashboard.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); min-height: 100vh; }
.card { border: none; border-radius: 15px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); margin-bottom: 20px; }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
.balance-positive { color: #28a745; }
.balance-negative { color: #dc3545; }
</style>
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-12">
<h2 class="text-center mb-4">Cash Management Dashboard</h2>
<p class="text-center">Welcome, <strong>{{ user.username }}</strong>!</p>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Total Income</h5>
<p class="card-text display-6 text-success">${{ total_income }}</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Total Expenses</h5>
<p class="card-text display-6 text-danger">${{ total_expenses }}</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">Balance</h5>
<p class="card-text display-6 {% if balance >= 0 %}balance-positive{% else %}balance-negative{% endif %}">${{ balance }}</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Add Cash Transactions</h5>
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
{% for transaction in addcash_transactions %}
<li class="list-group-item">{{ transaction.source }} - <strong>${{ transaction.amount }}</strong> - {{ transaction.datetime|date:"M d, Y H:i" }}</li>
{% empty %}
<li class="list-group-item">No cash added yet.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Expense Transactions</h5>
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
{% for transaction in expense_transactions %}
<li class="list-group-item">{{ transaction.description }} - <strong>${{ transaction.amount }}</strong> - {{ transaction.datetime|date:"M d, Y H:i" }}</li>
{% empty %}
<li class="list-group-item">No expenses yet.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12 text-center">
<a href="{% url 'add_cash' %}" class="btn btn-primary me-2">Add Cash</a>
<a href="{% url 'add_expense' %}" class="btn btn-primary me-2">Add Expense</a>
<a href="{% url 'profile' %}" class="btn btn-info me-2">Profile</a>
<a href="{% url 'logout' %}" class="btn btn-danger">Logout</a>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
add-cash.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Cash - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.card { border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Add Cash</h2>
{% if messages %}
{% for message in messages %}
<div class="alert alert-success">{{ message }}</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="source" class="form-label">Source</label>
<input type="text" id="source" name="source" class="form-control" placeholder="e.g., Salary, Freelance" required>
</div>
<div class="mb-3">
<label for="amount" class="form-label">Amount ($)</label>
<input type="number" id="amount" name="amount" class="form-control" step="0.01" placeholder="0.00" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea id="description" name="description" class="form-control" rows="3" placeholder="Optional details" required></textarea>
</div>
<button type="submit" class="btn btn-primary w-100">Add Cash</button>
</form>
<div class="text-center mt-3">
<a href="{% url 'dashboard' %}" class="btn btn-primary w-30">Back to Dashboard</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
add-expense.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Expense - Cash Management</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.card { border: none; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
.btn-primary { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border: none; }
.btn-primary:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); }
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Add Expense</h2>
{% if messages %}
{% for message in messages %}
<div class="alert alert-success">{{ message }}</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea id="description" name="description" class="form-control" rows="3" placeholder="e.g., Groceries, Rent" required></textarea>
</div>
<div class="mb-3">
<label for="amount" class="form-label">Amount ($)</label>
<input type="number" id="amount" name="amount" class="form-control" step="0.01" placeholder="0.00" required>
</div>
<button type="submit" class="btn btn-primary w-100">Add Expense</button>
</form>
<div class="text-center mt-3">
<a href="{% url 'dashboard' %}" class="btn btn-primary w-30">Back to Dashboard</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
No comments:
Post a Comment