This commit is contained in:
mirrerror
2023-10-27 21:06:16 +03:00
8 changed files with 107 additions and 20 deletions

View File

@@ -1,3 +1,68 @@
# ExpenseTrackerFAF
# Expense Tracker App
## Description
Expense Tracker is a web application that helps you keep track of your expenses and incomes. It provides a user-friendly interface to enter and visualize your financial data, making it easier to manage your finances.
## Features
- Single-page application for a smooth and responsive user experience.
- Reactive graph updates to visualize your financial data.
- Ability to add incomes and expenses to your account.
- Full-fledged authorization system to secure your data.
- Hosted database for seamless data storage and retrieval.
## Tech Stack
### Frontend
- Svelte
- Chart.js
- Axios
### Backend
- Spring
- Spring Boot
- Spring Security
### Database
- MySQL
- phpMyAdmin
## Installation Instructions
To run the Expense Tracker application, follow these steps:
1. Clone the project repository to your local machine.
2. Install the required Maven dependencies for the backend. In the project directory, run:
3. Run the backend Spring application to start the server.
4. For the frontend, navigate to the `web` directory and run:
```bash
npm install
```
```bash
npm run dev
```
This will start the frontend development server and open the application in your web browser.
Now you can access the Expense Tracker application at http://localhost:5173/auth/login and start tracking your expenses and incomes visually.
Please note that you need to configure the database connection details and other environment-specific settings in the application properties before running the backend.
### Configuration
Make sure to update the configuration files with your specific database settings, security configurations, and other environment variables as needed. You can find these configuration files in the backend project.
Feel free to customize the application further and adapt it to your specific use case.
Happy expense tracking!
Expense tracker project made in Spring by a group of senior full-stack Nobel winner students.

View File

@@ -61,14 +61,18 @@ public class ExpenseController {
}
// TODO: has to be checked on auto extracting Uuid
@PatchMapping()
public ResponseEntity<ExpenseDTO> updateExpense(@RequestBody ExpenseCreationDTO expenseDTO,
// TODO: check if the expense belongs to the user
@PatchMapping("/update/{id}")
public ResponseEntity<Void> updateExpense(@PathVariable long id, @RequestBody ExpenseCreationDTO expenseDTO,
BindingResult bindingResult) {
Expense expense = expenseMapper.toExpense(expenseDTO);
Expense expense = expenseService.getTransactionById(id);
ExpenseCategory category = expenseCategoryService.getCategoryById(expenseDTO.getExpenseCategory());
expense.setCategory(category);
expense.setAmount(expenseDTO.getAmount());
if (!bindingResult.hasErrors()) {
expenseService.createOrUpdate(expense);
return ResponseEntity.ok(expenseMapper.toDto(expense));
return ResponseEntity.status(HttpStatus.CREATED).build();
} else {
return ResponseEntity.notFound().build();
}
@@ -98,4 +102,9 @@ public class ExpenseController {
if (!categories.isEmpty()) return ResponseEntity.ok(categories);
else return ResponseEntity.notFound().build();
}
@DeleteMapping("/delete/{id}")
public void deleteCategory(@PathVariable long id) {
expenseService.deleteExpenseById(id);
}
}

View File

@@ -3,9 +3,7 @@ package com.faf223.expensetrackerfaf.controller;
import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO;
import com.faf223.expensetrackerfaf.dto.IncomeDTO;
import com.faf223.expensetrackerfaf.dto.mappers.IncomeMapper;
import com.faf223.expensetrackerfaf.model.Income;
import com.faf223.expensetrackerfaf.model.IncomeCategory;
import com.faf223.expensetrackerfaf.model.User;
import com.faf223.expensetrackerfaf.model.*;
import com.faf223.expensetrackerfaf.service.IncomeCategoryService;
import com.faf223.expensetrackerfaf.service.IncomeService;
import com.faf223.expensetrackerfaf.service.UserService;
@@ -60,13 +58,18 @@ public class IncomeController {
return ResponseEntity.notFound().build();
}
@PatchMapping()
public ResponseEntity<IncomeDTO> updateIncome(@RequestBody IncomeCreationDTO incomeDTO,
// TODO: check if the income belongs to the user, extract logic into service
@PatchMapping("/update/{id}")
public ResponseEntity<Void> updateIncome(@PathVariable long id, @RequestBody IncomeCreationDTO incomeDTO,
BindingResult bindingResult) {
Income income = incomeMapper.toIncome(incomeDTO);
Income income = incomeService.getTransactionById(id);
IncomeCategory category = incomeCategoryService.getCategoryById(incomeDTO.getIncomeCategory());
income.setCategory(category);
income.setAmount(incomeDTO.getAmount());
if (!bindingResult.hasErrors()) {
incomeService.createOrUpdate(income);
return ResponseEntity.ok(incomeMapper.toDto(income));
return ResponseEntity.status(HttpStatus.CREATED).build();
} else {
return ResponseEntity.notFound().build();
}
@@ -96,4 +99,9 @@ public class IncomeController {
if (!categories.isEmpty()) return ResponseEntity.ok(categories);
else return ResponseEntity.notFound().build();
}
@DeleteMapping("/delete/{id}")
public void deleteIncome(@PathVariable long id) {
incomeService.deleteIncomeById(id);
}
}

View File

@@ -40,4 +40,8 @@ public class ExpenseService implements ITransactionService {
public Expense getTransactionById(long id) {
return expenseRepository.findById(id).orElse(null);
}
public void deleteExpenseById(long id) {
expenseRepository.deleteById(id);
}
}

View File

@@ -40,4 +40,8 @@ public class IncomeService implements ITransactionService {
public Income getTransactionById(long id) {
return incomeRepository.findById(id).orElse(null);
}
public void deleteIncomeById(long id) {
incomeRepository.deleteById(id);
}
}

View File

@@ -2,7 +2,6 @@
"name": "expensetracker",
"version": "0.0.1",
"scripts": {
"g": "vite dev -- --open",
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",

View File

@@ -15,8 +15,6 @@
const today = new Date().toISOString().split('T')[0];
const expenseCategory = $expenseTypes.find(incomeType => incomeType.id === id);
console.log(amount);
if (expenseCategory) {
const newIncome = {
incomeId: 0,
@@ -27,7 +25,7 @@
},
expenseCategory: expenseCategory,
date: today,
amount: amount
amount: parseInt(amount)
};
newData = $expenseData;

View File

@@ -42,7 +42,7 @@
const selectedIncome = $incomeTypes.find(income => income.id === $selectedIncomeId);
const data = {
incomeCategory: selectedIncome.id,
amount: amount,
amount: parseInt(amount),
};
addNewIncome(selectedIncome.id, amount);