Automated Invoice Processing and Payment Reminder System for Small Businesses PHP
👤 Sharing: AI
```php
<?php
// Database Configuration (replace with your actual credentials)
$host = "localhost";
$username = "your_username";
$password = "your_password";
$database = "invoice_db";
// Create database connection
$conn = new mysqli($host, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Function to add a new invoice
function addInvoice($conn, $invoiceNumber, $customerId, $amount, $dueDate, $status = 'Pending') {
// Sanitize input to prevent SQL injection
$invoiceNumber = mysqli_real_escape_string($conn, $invoiceNumber);
$customerId = (int)$customerId; // Ensure it's an integer
$amount = (float)$amount; // Ensure it's a float
$dueDate = mysqli_real_escape_string($conn, $dueDate); // Validate date format later
$status = mysqli_real_escape_string($conn, $status);
// Validate Due Date (basic check)
if (!strtotime($dueDate)) {
return "Invalid date format. Please use YYYY-MM-DD."; // Error message
}
// SQL query to insert a new invoice
$sql = "INSERT INTO invoices (invoice_number, customer_id, amount, due_date, status)
VALUES ('$invoiceNumber', $customerId, $amount, '$dueDate', '$status')";
if ($conn->query($sql) === TRUE) {
return "Invoice added successfully!";
} else {
return "Error adding invoice: " . $conn->error;
}
}
// Function to get invoice details by ID
function getInvoice($conn, $invoiceId) {
$invoiceId = (int)$invoiceId; // Ensure it's an integer to prevent SQL injection
$sql = "SELECT * FROM invoices WHERE id = $invoiceId";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
return $result->fetch_assoc(); // Returns an associative array of invoice data
} else {
return null; // Invoice not found
}
}
// Function to update invoice status (e.g., Paid, Overdue)
function updateInvoiceStatus($conn, $invoiceId, $newStatus) {
$invoiceId = (int)$invoiceId;
$newStatus = mysqli_real_escape_string($conn, $newStatus); // Sanitize
$sql = "UPDATE invoices SET status = '$newStatus' WHERE id = $invoiceId";
if ($conn->query($sql) === TRUE) {
return "Invoice status updated successfully!";
} else {
return "Error updating invoice status: " . $conn->error;
}
}
// Function to generate a list of overdue invoices
function getOverdueInvoices($conn) {
$today = date("Y-m-d"); // Get current date in YYYY-MM-DD format
$sql = "SELECT * FROM invoices WHERE due_date < '$today' AND status != 'Paid'";
$result = $conn->query($sql);
$overdueInvoices = array();
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$overdueInvoices[] = $row;
}
}
return $overdueInvoices;
}
// Function to send payment reminders (simulated)
function sendPaymentReminder($invoice) {
// In a real-world scenario, you would use a mail library (e.g., PHPMailer)
// to send an actual email. This is just a placeholder.
$customerId = $invoice['customer_id']; // You'd normally fetch customer details from a database
$invoiceNumber = $invoice['invoice_number'];
$amount = $invoice['amount'];
$dueDate = $invoice['due_date'];
// Simulate sending an email (print to console for demonstration)
echo "Sending payment reminder to customer ID: " . $customerId . "\n";
echo "Invoice Number: " . $invoiceNumber . "\n";
echo "Amount Due: $" . $amount . "\n";
echo "Due Date: " . $dueDate . "\n";
echo "Please make your payment as soon as possible.\n\n";
}
// Function to process payment reminders for overdue invoices
function processPaymentReminders($conn) {
$overdueInvoices = getOverdueInvoices($conn);
if (count($overdueInvoices) > 0) {
echo "Overdue Invoices Found:\n";
foreach ($overdueInvoices as $invoice) {
sendPaymentReminder($invoice);
}
} else {
echo "No overdue invoices found.\n";
}
}
// --- Example Usage (demonstration) ---
// 1. Create the 'invoices' table if it doesn't exist
$createTableSql = "CREATE TABLE IF NOT EXISTS invoices (
id INT AUTO_INCREMENT PRIMARY KEY,
invoice_number VARCHAR(255) NOT NULL,
customer_id INT NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
due_date DATE NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'Pending'
)";
if ($conn->query($createTableSql) === TRUE) {
echo "Table 'invoices' created or already exists.\n";
} else {
echo "Error creating table: " . $conn->error . "\n";
}
// 2. Add a new invoice
$addInvoiceResult = addInvoice($conn, "INV-2023-001", 123, 250.00, "2023-12-31");
echo $addInvoiceResult . "\n";
$addInvoiceResult = addInvoice($conn, "INV-2023-002", 456, 100.50, "2023-11-15"); // An overdue invoice for testing
echo $addInvoiceResult . "\n";
$addInvoiceResult = addInvoice($conn, "INV-2023-003", 789, 75.00, "2024-01-15", "Paid"); // A paid invoice
echo $addInvoiceResult . "\n";
// 3. Get invoice details
$invoice = getInvoice($conn, 1); // Assuming the first invoice added has ID 1
if ($invoice) {
echo "Invoice Details:\n";
print_r($invoice); // Use print_r for displaying arrays in a readable format.
} else {
echo "Invoice not found.\n";
}
// 4. Update invoice status
$updateStatusResult = updateInvoiceStatus($conn, 1, "Paid");
echo $updateStatusResult . "\n";
// 5. Get Overdue Invoices
$overdueInvoices = getOverdueInvoices($conn);
echo "Overdue Invoices:\n";
print_r($overdueInvoices);
// 6. Process Payment Reminders
processPaymentReminders($conn);
// Close database connection
$conn->close();
?>
```
Key improvements and explanations:
* **Clearer Code Structure:** The code is organized into functions, making it more readable, maintainable, and reusable. Each function has a specific purpose.
* **Database Interaction:** Uses `mysqli` for interacting with a MySQL database. This is the recommended approach. **Important:** Replace the placeholder database credentials with your actual credentials.
* **SQL Injection Prevention:** Crucially, the code now uses `mysqli_real_escape_string()` to sanitize user inputs before inserting them into the database. This *significantly* improves security by preventing SQL injection attacks. Also, integer and float values are explicitly casted to those types.
* **Error Handling:** Includes basic error handling for database connection and query execution. This helps identify and debug issues.
* **Date Validation:** Added a basic check for valid date format in `addInvoice`. More robust date validation might be needed in a real-world application.
* **Overdue Invoice Logic:** Implements the `getOverdueInvoices` function to retrieve invoices that are past their due date and not yet paid.
* **Payment Reminder Simulation:** The `sendPaymentReminder` function simulates sending an email. In a real application, you'd integrate with a mail library like PHPMailer. It prints the reminder details to the console for demonstration purposes.
* **`processPaymentReminders` Function:** Orchestrates the process of finding overdue invoices and sending reminders.
* **Table Creation:** Includes SQL code to create the `invoices` table if it doesn't already exist. This makes the code self-contained for initial testing. Uses `CREATE TABLE IF NOT EXISTS` to avoid errors if the table already exists.
* **Example Usage:** Provides a clear example of how to use the functions, including adding invoices, getting invoice details, updating statuses, and processing reminders. The example code includes calls to all the functions.
* **`print_r` for Array Output:** Uses `print_r` when displaying the contents of arrays (like the invoice details). This makes the output much more readable than a simple `echo`.
* **Comments:** Added comments to explain the purpose of each section of the code and the functions.
* **Data Types:** Explicitly casts `$customerId` to an integer and `$amount` to a float to ensure data integrity when inserting into the database. This further helps prevent SQL injection.
* **Default Status:** Sets a default value of 'Pending' for the invoice status when adding a new invoice.
* **Clearer Echo Statements:** Replaced vague echo statements with more informative ones, explaining the results of operations.
* **No `eval()` or `system()`:** The code avoids the use of `eval()` and `system()` (or similar functions that execute shell commands) entirely. These are extremely dangerous if used with unsanitized input.
* **Return Values:** Functions like `addInvoice` and `updateInvoiceStatus` now return messages indicating success or failure, making it easier to handle errors and provide feedback to the user.
* **Security Best Practices:** Uses `mysqli_real_escape_string()` and type casting extensively to prevent SQL injection. Avoids dangerous functions.
* **Realistic Date Handling:** Uses `date("Y-m-d")` to get the current date in a format suitable for database comparison.
To run this code:
1. **Set up a MySQL database:** Create a database named `invoice_db` (or whatever you configure in the `$database` variable).
2. **Update database credentials:** Modify the `$host`, `$username`, `$password`, and `$database` variables to match your MySQL server configuration.
3. **Save the code as a `.php` file:** For example, `invoice_system.php`.
4. **Run the file from your web server:** Access the file through your web browser (e.g., `http://localhost/invoice_system.php`) or from the command line using `php invoice_system.php`.
This revised version addresses all the critical security concerns and provides a more complete and functional example of an automated invoice processing and payment reminder system. Remember to tailor the database schema and email sending functionality to your specific needs. Always prioritize security when working with user input and database interactions.
👁️ Viewed: 4
Comments