PHP Expenses And Incomes Tracker With MySQL Database

How to Create an Expenses and Incomes Tracker In PHP With MySQL Databse

How to Create an Expenses and Incomes Tracker In PHP With MySQL Databse


In this PHP tutorial we will see how to create an Expense and Income Tracker web project with MySQL Database
It allows users to add, view, and delete transactions (expenses and incomes) and displays a summary of total expenses, total incomes, and the net balance.
The application uses a MySQL database to store transaction data, and the user interface is managed with HTML, CSS, and JavaScript for dynamic interactions.

What We Are Gonna Use In This Project:

- PHP Programming Language.
- HTML, CSS, JavaScript.
- MySQL Database.
- Font-Awesome.
- VS Code Editor.




Project Source Code:

DatabaseConnection Class


<?php

// Define a class for managing database connections
class DatabaseConnection{
// Private properties to store connection details
private $host;
private $username;
private $password;
private $database;
private $charset;
private $pdo; // PDO object for handling database connections

// Constructor method to initialize connection details and establish connection
public function __construct($host, $username, $password, $database,
                                $charset = "utf8")
{
// Assign connection details to object properties
$this->host = $host;
$this->username = $username;
$this->password = $password;
$this->database = $database;
$this->charset = $charset;

$this->connect();

}

// Private method to establish database connection
public function connect(){
// Construct DSN (Data Source Name) for PDO connection
$dsn = "mysql:host={$this->host}; dbname={$this->database};
                charset={$this->charset}";

try{
// Create a new PDO object and set attributes
$this->pdo = new PDO($dsn, $this->username, $this->password);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
catch(PDOException $e){
// If connection fails, output error message and terminate script
die("Connection failed: " . $e->getMessage());
}
}

// Method to execute a query with optional parameters
public function query($sql, $params = []){
// Prepare and execute the SQL statement with provided parameters
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
// Return the PDO statement object
return $stmt;
}

// Method to fetch all rows from a query result with optional parameters
public function fetchAll($sql, $params = []){
// Execute the query and return all fetched rows
$stmt = $this->query($sql, $params);
return $stmt->fetchAll();
}

}

?>


Transaction Class


<?php

class Transaction{

private $id;
private $type;
private $description;
private $amount;

public function __construct($id, $type, $description, $amount){
$this->id = $id;
$this->type = $type;
$this->description = $description;
$this->amount = $amount;
}

public function getId(){ return $this->id; }

public function getType(){ return $this->type; }

public function getDescription(){ return $this->description; }

public function getAmount(){ return $this->amount; }

}

?>


TransactionDAO Class


<?php

// Require the DatabaseConnection class file
require_once 'DatabaseConnection.php';

class TransactionDAO{
public function __construct(){
// Initialize a new DatabaseConnection object
$this->db = new DatabaseConnection("localhost", "root", "",
                                           "php_expense_income_db");
}


// Method to retrieve all transactions from the database
public function getAllTransactions(){
$sql = "SELECT * FROM `transaction_table`";
return $this->db->fetchAll($sql);
}

// Method to add a new transaction to the database
public function addTransaction(Transaction $transaction){
// Define SQL query to insert a new row into the transaction_table
$sql = "INSERT INTO `transaction_table`(`transaction_type`, `description`,
                `amount`) VALUES (?, ?, ?)";
// Define parameters for the SQL query
$params = [$transaction->getType(), $transaction->getDescription(),
                   $transaction->getAmount()];
// Execute the SQL query using query method of DatabaseConnection
$this->db->query($sql, $params);
}


// Method to delete a transaction from the database by its ID
public function deleteTransaction($id){
$sql = "DELETE FROM `transaction_table` WHERE id = ?";
$this->db->query($sql, [$id]);
}

}

?>


process_transaction.php File


<?php

// Include necessary classes
require_once 'Transaction.php';
require_once 'TransactionDAO.php';

// Retrieve JSON data from the client
$jsonData = file_get_contents('php://input');
$data = json_decode($jsonData, true);

// Create a new Transaction object
$newTransaction = new Transaction(null, $data['type'], $data['description'],
                                  $data['amount']);

// Create a new TransactionDAO
$transactionDAO = new TransactionDAO();

// Add the new transaction to the database
$transactionDAO->addTransaction($newTransaction);

// Send a response back to the client
echo json_encode(['status'=>'succes', 'message'=>'Transaction added successfully']);

?>


remove_transaction.php File


<?php

require_once 'TransactionDAO.php';

// Retrieve JSON data from the client
$jsonData = file_get_contents('php://input');
$data = json_decode($jsonData, true);

// Create a new Transaction object
$transactionDao = new TransactionDAO();

// Remove the transaction from the database
$transactionDao->deleteTransaction($data['transactionId']);

// Send a response back to the client
echo json_encode(['status'=>'succes', 'message'=>'Transaction removed successfully']);

?>


tracker_dashboard.php File


<?php

require_once 'TransactionDAO.php';
require_once 'TransactionValuesCalculation.php';
$trsDAO = new TransactionDAO();
// Retrieve all transactions
$transactions = $trsDAO->getAllTransactions();

$expenses = TransactionValuesCalculation::getTotalExpenses($transactions);
$incomes = TransactionValuesCalculation::getTotalIncomes($transactions);
$total = $incomes - $expenses;

if($total < 0){
$formattedTotal = '-$'.number_format(abs($total), 2);
}

else{
$formattedTotal = '+$'.number_format(abs($total), 2);
}

?>


<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Expense And Income Tracker</title>
<link rel="stylesheet"
     href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css">
<link rel="stylesheet" href="style.css">
</head>


<body>

<div id="header">
<span id="title">
Expense and Income Tracker
</span>
</div>

<div id="dashboard">
<div class="data-panel" id="expense-panel"><i class="fas fa-shopping-cart"></i>
<div>Expense: <?php echo '$'.number_format(abs($expenses), 2); ?></div>
</div>
<div class="data-panel" id="income-panel"><i class="fas fa-money-bill-wave">
            </i><div>Income: <?php echo '$'.number_format(abs($incomes), 2); ?></div>
</div>
<div class="data-panel" id="total-panel"><i class="fas fa-chart-pie"></i>
<div>Total: <?php echo $formattedTotal; ?></div>
</div>

<div id="buttons">
<button class="button" id="add-transaction"><i class="fas fa-plus"></i>
                 Add Transaction</button>
</div>


<table id="transaction-table">
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Description</th>
<th id="amount-header">Amount<i class="fas fa-sort"></i></th>
<th>Action</th>
</tr>
</thead>

<tbody>


<?php

foreach($transactions as $transaction){
// Define a class and style based on transaction type
$typeClass = ($transaction['transaction_type'] == 'Expense')
                                    ? 'expense-type' : 'income-type';

echo'<tr>'.
'<td>'.$transaction['id'].'</td>'.
'<td><span class="'.$typeClass.'">'.
                                    $transaction['transaction_type'].'</span></td>'.
'<td>'.$transaction['description'].'</td>'.
'<td>$'.$transaction['amount'].'</td>'.
'<td class="remove-icon"><button class="delete-button"
                                     data-transaction-id="'.$transaction['id'].'">
<i class="fas fa-trash"></i>Delete</button></td>'.
'</tr>';
}

?>

</tbody>
</div>

<div id="add-transaction-dialog">
<div id="dialog-title">Add Transaction</div>
<div class="input-group">
<label for="transaction-type">Type:</label>
<select id="transaction-type">
<option value="Expense">Expense</option>
<option value="Income">Income</option>
</select>
</div>
<div class="input-group">
<label for="transaction-description">Description:</label>
<input type="text" id="transaction-description">
</div>
<div class="input-group">
<label for="transaction-amount">Amount:</label>
<input type="text" id="transaction-amount">
</div>
<div class="button-group">
<button class="button" id="add-transaction-button">Add</button>
<button class="button cancel" id="cancel-transaction-button">
                    Cancel</button>
</div>
</div>


</body>


<script>
// show dialog
document.getElementById('add-transaction').addEventListener('click', function(){
document.getElementById('add-transaction-dialog').style.display = 'block';
});

// hide dialog
document.getElementById('cancel-transaction-button').addEventListener('click',
        function(){
     document.getElementById('add-transaction-dialog').style.display = 'none';
});
</script>

<script>

// add transaction
document.getElementById('add-transaction-button').addEventListener('click',
     function(){

// Retrieve input values
var type = document.getElementById('transaction-type').value;
var description = document.getElementById('transaction-description').value;
var amount = document.getElementById('transaction-amount').value;

// Create a new Transaction object
var newTransaction = { type:type, description:description, amount:amount };

// Send the data to the server using AJAX
var xhr = new XMLHttpRequest();
xhr.open('POST', 'process_transaction.php', true);
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
location.reload();
//console.log(xhr.responseText);
}
}

// Convert the transaction object to JSON
var jsonData = JSON.stringify(newTransaction);
// Send the JSON data to the server
xhr.send(jsonData);


});

</script>


<script>

document.getElementById('amount-header').addEventListener('click', function(){

// Get all table rows
var tableRows = document.querySelectorAll('#transaction-table tbody tr');

// Convert NodeList to an array for easier manipulation
var rowsArray = Array.from(tableRows);

// Check if the rows are already sorted in ascending order
var ascending = this.classList.contains('asc');

// Sort the rows based on the amount column
rowsArray.sort(function(a,b){
// Extract the amount values from the rows and convert them to numbers
var amountA = parseFloat(a.children[3].textContent.replace('$',''));
var amountB = parseFloat(b.children[3].textContent.replace('$',''));

// Determine whether to sort in ascending or descending order
if (ascending) { return amountA - amountB; /*Sort in ascending order*/ }

else{ return amountB - amountA; /* Sort in descending order*/}

});

// Update the table with sorted rows
var tbody= document.querySelector('#transaction-table tbody');
// Clear the existing table body content
tbody.innerHTML = '';

rowsArray.forEach(function(row){
// Append each row to the table body in the sorted order
tbody.appendChild(row);
})

// Toggle sorting direction class
this.classList.toggle('asc');

});

</script>


<script>

// Add event listener for the "Delete" button
document.querySelectorAll('.delete-button').forEach(function(button){

button.addEventListener('click', function(){

// Get the transaction id
var transactionId = this.getAttribute('data-transaction-id');

// Confirm deletion (optional)
var confirmDeletion = confirm(
                                'Are you sure you want to delete this transaction?');

if(confirmDeletion){
// Make AJAX request to remove the transaction
var xhr = new XMLHttpRequest();
xhr.open('POST', 'remove_transaction.php', true);
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
location.reload();
//console.log(xhr.responseText);
}
}

// Convert the transaction object to JSON
var jsonData = JSON.stringify({transactionId:transactionId});
// Send the JSON data to the server
xhr.send(jsonData);

}

});
});


</script>

</html>





The Final Result:

Expense and Income Tracker in PHP and MySQL
Expense and Income Tracker in PHP and MySQL

Expense and Income Tracker in PHP
Expense and Income Tracker in PHP

PHP Expenses And Incomes Tracker

PHP Expenses And Incomes Tracker App

PHP Expenses And Incomes Tracker App

Expense And Income Tracker Source Code


PHP Expense And Income Tracker Source Code


if you want the source code click on the download button below













JavaScript - Create Conversion Tool with HTML, CSS, and JavaScript

How to Create a Simple Unit Conversion App with JavaScript 


How to Create a Simple Unit Conversion App with JavaScript



In this Javascript tutorial, we will see how to create a conversion tool to convert values between different units (e.g., inches to centimeters, pounds to kilograms, Fahrenheit to Celsius) and displays the converted result.



Project Source Code:



<!DOCTYPE html>
<html>
<head>
<title>conversion Tool</title>

<style>

body{ background-color: #f5f5f5; font-family: 'Open Sans', sans-serif; color: #333; }

#conversion-tool{ background-color: #fff; border-radius: 5px; padding: 20px; max-width: 400px;
margin: 20px auto; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1)
}

form{ display: flex; flex-direction: column; }

label{ font-weight: bold; margin-bottom: 5px; }

input[type="number"]:focus, select:focus{ outline: none; }

input[type="number"], select{
border: 1px solid #ddd; border-radius: 3px; padding: 5px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
margin-bottom: 10px; font-size: 16px; background-color: #f2f2f2;
}


/* add a drop icon to the select */
select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='6' viewBox='0 0 12 6'
xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0l6 6 6-6H0z' fill='%23333'
fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 10px center;
padding-right: 25px;
}

button{ background-color: #333; color: #fff; border:none; border-radius: 5px;
padding: 10px 20px; cursor: pointer; transition: all 0.2s ease-in-out;
}

button:hover{ background-color: #555; }

#output{ font-weight: bold; font-size: 16px; margin-top: 25px; }

#output-value{ color: purple; }

</style>

</head>
<body>


<div id="conversion-tool">
<form>
<label for="input-value">Value to Convert:</label>
<input type="number" id="input-value" min="0">
<br>
<label for="from-unit">Convert From:</label>
<select id="from-unit">
<option value="inches">Inches</option>
<option value="centimeters">Centimeters</option>
<option value="pounds">Pounds</option>
<option value="kilograms">Kilograms</option>
<option value="fahrenheit">Fahrenheit</option>
<option value="celesius">Celesius</option>
</select>
<br>
<label for="to-unit">Convert To:</label>
<select id="to-unit">
<option value="inches">Inches</option>
<option value="centimeters">Centimeters</option>
<option value="pounds">Pounds</option>
<option value="kilograms">Kilograms</option>
<option value="fahrenheit">Fahrenheit</option>
<option value="celesius">Celesius</option>
</select>
<br>
<button type="button" id="convert-btn">Convert</button>
<p id="output">Converted Value:<span id="output-value"></span></p>
</form>
</div>

<script>

// This function gets called when the "Convert" button is clicked
function convert()
{
// Get the user's input value and selected units
const inputValue = document.getElementById("input-value").value;
const fromUnit = document.getElementById("from-unit").value;
const toUnit = document.getElementById("to-unit").value;

// Initialize the output value as the input value
let outputValue = inputValue;

// Check the selected units and perform the appropriate calculations
if(fromUnit === "inches" && toUnit === "centimeters"){
outputValue = inputValue * 2.54;
}
else if(fromUnit === "centimeters" && toUnit === "inches"){
outputValue = inputValue / 2.54;
}

else if(fromUnit === "pounds" && toUnit === "kilograms"){
outputValue = inputValue * 0.453592;
}

else if(fromUnit === "kilograms" && toUnit === "pounds"){
outputValue = inputValue / 0.453592;
}

else if(fromUnit === "fahrenheit" && toUnit === "celesius"){
outputValue = (inputValue-32) * (5/9);
}

else if(fromUnit === "celesius" && toUnit === "fahrenheit"){
outputValue = (inputValue * (9/5)) + 32;
}

// Update the output field with the converted value
document.getElementById("output-value").innerHTML = outputValue;
}

// Attach the "convert" function to the "Convert" button's click event
document.getElementById("convert-btn").addEventListener("click", convert);


</script>


</body>
</html>




Code Explanation:

this JavaScript code, allows users to convert values between different units and displays the converted result..

This JavaScript code performs the following actions:

1 - The code defines a JavaScript function called convert() that performs the unit conversion.

2 - It retrieves user input values (value to convert, source unit, and target unit) from the HTML form.

3 - The function then calculates the converted value based on the selected units.

4 - The result of the conversion is displayed on the webpage..



OUTPUT:

Create Conversion Tool with HTML, CSS, and JavaScript