billing2/customers/.hta_slug/generate-invoice.php

324 lines
16 KiB
PHP

<?php
require('../.hta_config/conf.php');
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_GET['customerId'])) {
try {
$db = new PDO("mysql:host=$mariaServer;dbname=$mariaDb", $mariaUser, $mariaPass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$totalAmount = $_POST['totalAmount'];
$tenure = $_POST['tenure'];
$frequency = $_POST['frequency'];
$bookingDate = $_POST['bookingDate'];
$paymentMode = $_POST['paymentMode'];
$salesAgent = $_POST['salesAgent'];
$adminNote = $_POST['adminNote'];
$invoiceId = $_POST['invoiceId'];
$customerName = $_POST['customerName'];
$customerAddress = $_POST['customerAddress'];
$marketingAgents = $_POST['marketingAgent'];
$marketingAgentList = implode(", ", $marketingAgents);
$item = $_POST['item'];
$description = $_POST['description'];
$quantity = $_POST['quantity'];
$rate = $_POST['rate'];
$tax = $_POST['tax'];
$taxAmount = $_POST['taxAmount'];
// EMI Calculation
$emiAmount = round($totalAmount / $tenure, 2);
$outstandingAmount = $totalAmount;
$emiDate = new DateTime($bookingDate); // Set initial date
$stmt = $db->prepare("INSERT INTO emi (customerId, emiNumber, emiAmount, emiDate, totalAmount, outstanding, tenure, frequency, bookingDate, invoiceId) VALUES (:customerId, :emiNumber, :emiAmount, :emiDate, :totalAmount, :outstanding, :tenure, :frequency, :bookingDate, :invoiceId)");
for ($i = 1; $i <= $tenure; $i++) {
$outstandingAmount -= $emiAmount;
$emiDateFormatted = $emiDate->format('Y-m-d');
$stmt->bindParam(':customerId', $_GET['customerId']);
$stmt->bindParam(':emiNumber', $i);
$stmt->bindParam(':emiAmount', $emiAmount);
$stmt->bindParam(':emiDate', $emiDateFormatted);
$stmt->bindParam(':totalAmount', $totalAmount);
$stmt->bindParam(':outstanding', $outstandingAmount);
$stmt->bindParam(':tenure', $tenure);
$stmt->bindParam(':frequency', $frequency);
$stmt->bindParam(':bookingDate', $bookingDate);
$stmt->bindParam(':invoiceId', $invoiceId);
$stmt->execute();
// Move to the next EMI date
if (trim(strtolower($frequency)) === 'weekly') {
$emiDate->modify('+1 week');
} elseif (trim(strtolower($frequency)) === 'monthly') {
$emiDate->modify('+1 month');
}
}
// Insert into invoice table
$stmt2 = $db->prepare("INSERT INTO invoice (customerId, invoiceId, customerName, address, frequency, invoiceDate, paymentMode, salesAgent, marketingAgent, tenure, item, description, qty, rate, tax, totalAmount, adminNote, taxAmount) VALUES (:customerId, :invoiceId, :customerName, :address, :frequency, :invoiceDate, :paymentMode, :salesAgent, :marketingAgent, :tenure, :item, :description, :qty, :rate, :tax, :totalAmount, :adminNote, :taxAmount)");
$stmt2->bindParam(':customerId', $_GET['customerId']);
$stmt2->bindParam(':invoiceId', $invoiceId);
$stmt2->bindParam(':customerName', $customerName);
$stmt2->bindParam(':address', $customerAddress);
$stmt2->bindParam(':frequency', $frequency);
$stmt2->bindParam(':invoiceDate', $bookingDate);
$stmt2->bindParam(':paymentMode', $paymentMode);
$stmt2->bindParam(':salesAgent', $salesAgent);
$stmt2->bindParam(':marketingAgent', $marketingAgentList);
$stmt2->bindParam(':tenure', $tenure);
$stmt2->bindParam(':item', $item);
$stmt2->bindParam(':description', $description);
$stmt2->bindParam(':qty', $quantity);
$stmt2->bindParam(':rate', $rate);
$stmt2->bindParam(':tax', $tax);
$stmt2->bindParam(':totalAmount', $totalAmount);
$stmt2->bindParam(':adminNote', $adminNote);
$stmt2->bindParam(':taxAmount', $taxAmount);
$stmt2->execute();
echo '<div class="alert alert-success">New EMI Plan Saved Successfully!</div>';
echo '<script>
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("printBtn").classList.remove("visually-hidden");
});
</script>';
} catch (PDOException $e) {
echo '<div class="alert alert-danger">Error: ' . $e->getMessage() . '</div>';
}
}
$customer = null;
if (!empty($_GET['customerId'])) {
try {
$db = new PDO("mysql:host=$mariaServer;dbname=$mariaDb", $mariaUser, $mariaPass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("SELECT * FROM customers WHERE customerId = :customerId");
$stmt->bindParam(':customerId', $_GET['customerId']);
if ($stmt->execute()) {
$customer = $stmt->fetch(PDO::FETCH_ASSOC);
}
$stmt = $db->prepare("SELECT * FROM address WHERE customerId = :customerId");
$stmt->bindParam(':customerId', $_GET['customerId']);
if ($stmt->execute()) {
$customerAddress = $stmt->fetch(PDO::FETCH_ASSOC);
}
$stmt = $db->query("SELECT id FROM invoice WHERE DATE(invoiceDate) = CURDATE() ORDER BY id DESC LIMIT 1");
$lastInvoice = $stmt->fetch(PDO::FETCH_ASSOC);
$invoiceId = "CB" . date('my') . ($lastInvoice ? ($lastInvoice['id'] + 1) : '1');
$stmt = $db->query("SELECT invoiceId FROM invoice ORDER BY id DESC LIMIT 1");
$lastInvoicePrint = $stmt->fetch(PDO::FETCH_ASSOC);
// $invoiceIdPrint = "ASDQ-" . ($lastInvoice ? ($lastInvoice['id'] + 1) : '1');
} catch (PDOException $e) {
echo '<div class="alert alert-danger">Error: ' . $e->getMessage() . '</div>';
}
}
?>
<div class="container mt-4">
<h4>Create New Invoice</h4>
<hr>
<form method="POST">
<div class="d-flex justify-content-between gap-4">
<div class="w-100">
<div class="mb-3">
<label for="invoiceId" class="form-label">Invoice Id:</label>
<input type="text" class="form-control bg-white" id="invoiceId" name="invoiceId" value="<?= $invoiceId; ?>">
</div>
<div class="mb-3">
<label for="name" class="form-label">Customer:</label>
<input readonly type="text" class="form-control bg-white" id="customerName" name="customerName" value="<?= htmlspecialchars($customer['name']); ?>">
</div>
<div class="mb-3">
<label for="address" class="form-label">Address:</label>
<input id="address" readonly name="customerAddress" class="form-control bg-white" type="text" value="<?= htmlspecialchars($customer['address']); ?>">
</div>
<div class="mb-3">
<label for="frequency" class="form-label">Frequency:</label>
<select name="frequency" class="form-control"required>
<option value="">-Select-</option>
<option value="Weekly">Weekly</option>
<option value="Monthly">Monthly</option>
</select>
</div>
<div class="d-flex w-100 gap-2">
<div class="mb-3 w-100">
<label for="bookingDate" class="form-label">Invoice Date:</label>
<input type="date" class="form-control" id="bookingDate" name="bookingDate" value="" required>
</div>
</div>
</div>
<div class="w-100">
<div class="mb-3">
<label for="paymentMode" class="form-label">Payment Mode:</label>
<select name="paymentMode" class="form-control"required>
<option value="">-Select-</option>
<option value="UPI">UPI</option>
<option value="Credit Card">Credit Card</option>
<option value="Debit Card">Debit Card</option>
<option value="Cash">Cash</option>
</select>
</div>
<div class="mb-3">
<label for="salesAgent" class="form-label">Sales Agent:</label>
<select name="salesAgent" class="form-control"required>
<option value="">-Select-</option>
<option value="Prabhat Mishra">Prabhat Mishra</option>
<option value="Suvojit Mishra">Suvojit Mishra</option>
</select>
</div>
<div class="mb-3">
<label for="marketingAgent" class="form-label">Marketing Agent:</label>
<select name="marketingAgent[]" class="form-control"required multiple>
<option value="Prabhat Mishra">Prabhat Mishra</option>
<option value="Suvojit Mishra">Suvojit Mishra</option>
<option value="Prabhat Mishra">Prabhat Mishra</option>
<option value="Suvojit Mishra">Suvojit Mishra</option>
<option value="Prabhat Mishra">Prabhat Mishra</option>
<option value="Suvojit Mishra">Suvojit Mishra</option>
<option value="Prabhat Mishra">Prabhat Mishra</option>
<option value="Suvojit Mishra">Suvojit Mishra</option>
</select>
</div>
<div class="mb-3">
<label for="tenure" class="form-label">Total Cycles:</label>
<select onchange="changeTenureField();" id="tenureAuto" name="tenure" class="form-control" required>
<option value="">-Select-</option>
<option value="1">One Time</option>
<option value="3">3</option>
<option value="6">6</option>
<option value="9">9</option>
<option value="12">12</option>
<option value="0">Custom</option>
</select>
<input type="text" name="tenure" id="tenureCustom" class="form-control visually-hidden" placeholder="Enter custom value" disabled onblur="restoreDropdown(this)" />
</div>
<div class="mb-3">
<label for="adminNote" class="form-label">Admin Note:</label>
<textarea class="form-control" name="adminNote" id="adminNote" cols="30" rows="4"></textarea>
</div>
</div>
</div>
<div>
<table class="w-100">
<thead>
<tr class="bg-secondary text-white">
<th class="p-2">Item</th>
<th class="p-2">Description</th>
<th class="p-2">Qty</th>
<th class="p-2">Rate</th>
<th class="p-2">Tax % </th>
<th class="p-2">Tax Amount</th>
<th class="p-2">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="text" class="form-control w-100" name="item" id="item" rows="3" />
</td>
<td>
<input type="text" class="form-control w-100" name="description" id="description" rows="3" />
</td>
<td>
<input class="form-control w-100" name="quantity" id="quantity" />
</td>
<td>
<input class="form-control w-100" name="rate" id="rate" />
</td>
<td>
<select name="tax" id="tax" class="form-control">
<option value="0">No Tax</option>
<option value="5">5 %</option>
<option value="10">10 %</option>
<option value="12">12 %</option>
<option value="18">18 %</option>
</select>
</td>
<td>
<input readonly class="form-control" name="taxAmount" id="taxAmount" />
</td>
<td>
<input readonly class="form-control" name="totalAmount" id="totalAmount" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex justify-content-end align-items-center">
<div>
<button class="btn btn-secondary">Discard</button>
<button type="submit" class="btn btn-primary">Save</button>
<a href="/customers/print-invoice/?customerId=<?= $_GET['customerId'] . '&invoiceId='. $lastInvoicePrint['invoiceId']; ?>" id="printBtn" class="btn btn-primary visually-">Print Invoice</a>
</div>
</div>
</form>
</div>
<script>
const today = new Date();
const formattedDate = today.toISOString().split('T')[0];
document.getElementById('bookingDate').value = formattedDate;
function changeTenureField() {
const tenureAuto = document.getElementById('tenureAuto');
const tenureCustom = document.getElementById('tenureCustom');
if (tenureAuto.value === "0") {
tenureAuto.classList.add('visually-hidden');
tenureCustom.classList.remove('visually-hidden');
tenureCustom.removeAttribute('disabled');
tenureAuto.setAttribute('disabled', 'true');
tenureAuto.removeAttribute('name');
tenureCustom.setAttribute('name', 'tenure');
tenureCustom.focus();
}
}
function restoreDropdown(input) {
const tenureAuto = document.getElementById('tenureAuto');
if (input.value.trim() === "") {
tenureAuto.classList.remove('visually-hidden');
input.classList.add('visually-hidden');
input.setAttribute('disabled', 'true');
input.removeAttribute('name');
tenureAuto.removeAttribute('disabled');
tenureAuto.setAttribute('name', 'tenure');
tenureAuto.value = "";
}
}
document.addEventListener("DOMContentLoaded", function () {
const quantityInput = document.getElementById("quantity");
const rateInput = document.getElementById("rate");
const taxSelect = document.getElementById("tax");
const taxAmountInput = document.getElementById("taxAmount");
const totalAmountInput = document.getElementById("totalAmount");
function calculateTotal() {
const quantity = parseFloat(quantityInput.value) || 0;
const rate = parseFloat(rateInput.value) || 0;
const tax = parseFloat(taxSelect.value) || 0;
let subtotal = quantity * rate;
let taxAmount = (subtotal * tax) / 100;
let grandTotal = subtotal + taxAmount;
taxAmountInput.value = taxAmount.toFixed(2); // Format Tax Amount
totalAmountInput.value = grandTotal.toFixed(2); // Format Total Amount
}
// Event listeners for real-time calculation
quantityInput.addEventListener("input", calculateTotal);
rateInput.addEventListener("input", calculateTotal);
taxSelect.addEventListener("change", calculateTotal);
});
</script>