:: **Zploit** v1.0 | Current Path: **/home/kreativepixelz/www/crm/quatation/**
:: Editing File: vendor_invoice_add.php
<?php include_once("session.php"); include("header.php"); include("db.php"); ?> <main> <div class="container-fluid"> <div class="row m-1"> <div class="col-12"> <h4 class="main-title">Add Vendor Invoice</h4> <ul class="app-line-breadcrumbs mb-3"> <li><a class="f-s-14 f-w-500" href="dashboard.php"><i class="ph-duotone ph-bank f-s-16"></i> Home</a></li> <li><a class="f-s-14 f-w-500" href="vendor_invoice_list.php"><i class="ph-duotone ph-table f-s-16"></i> Vendor Invoice List</a></li> <li class="active"><a class="f-s-14 f-w-500" href="#">Add Vendor Invoice</a></li> </ul> </div> </div> <div class="row"> <div class="col-12"> <div class="card"> <div class="card-body"> <?php if (isset($_SESSION['success'])) { echo '<div class="alert alert-success">' . $_SESSION['success'] . '</div>'; unset($_SESSION['success']); } if (isset($_SESSION['error'])) { echo '<div class="alert alert-danger">' . $_SESSION['error'] . '</div>'; unset($_SESSION['error']); } ?> <form class="row g-3 app-form" method="post" action="save_vendor_invoice.php" enctype="multipart/form-data"> <input type="hidden" name="user_id" value="<?php echo $_SESSION['user_id']; ?>"> <h5 class="mt-3">Invoice Details</h5> <div class="col-md-4"> <label class="form-label">Invoice Date <span style="color:#ff0000">*</span></label> <input class="form-control" type="date" name="invoice_date" value="<?php echo date('Y-m-d'); ?>" required> </div> <div class="col-md-4"> <label class="form-label">Invoice No <span style="color:#ff0000">*</span></label> <input class="form-control" name="invoice_no" placeholder="Invoice No" required> </div> <div class="col-md-4"> <label class="form-label">Vehicle Number </label> <input class="form-control" name="vehicle_number" placeholder="Vehicle Number" > </div> <h5 class="mt-3">Vendor Information</h5> <div class="col-md-6"> <label class="form-label">Vendor Name <span style="color:#ff0000">*</span></label> <select class="form-control form-select" id="vendor_id" name="vendor_id" required> <option value="">Select Vendor</option> <?php $query = "SELECT id, name FROM party WHERE type='Vendor' ORDER BY name ASC"; $result = mysqli_query($conn, $query); while ($row = mysqli_fetch_assoc($result)) { echo "<option value='" . $row['id'] . "'>" . $row['name'] . "</option>"; } ?> </select> </div> <div class="col-md-6"> <label class="form-label">Product Name </label> <input type="text" class="form-control" id="product_name" name="product_name"> </div> <h5 class="mt-3">Billing Information </h5> <div class="col-md-12"> <label class="form-label">Billing Company Name <span style="color:#ff0000">*</span></label> <select class="form-control form-select" id="billing_id" name="billing_id" required> <option value="">Select Company</option> <?php // Fetch company list from billing_companies table $query = "SELECT id, company_name FROM billing ORDER BY company_name ASC"; $result = mysqli_query($conn, $query); while ($row = mysqli_fetch_assoc($result)) { echo "<option value='" . $row['id'] . "'>" . $row['company_name'] . "</option>"; } ?> </select> </div> <h5 class="mt-3">Terms Of Delivery</h5> <div class="col-md-12"> <textarea class="form-control" name="terms_of_delivery" placeholder="Terms of Delivery" rows="3"></textarea> </div> <h5 class="mt-3">Invoice Items</h5> <div id="items_container" class="col-12"> <div class="row g-2 mb-1 fw-bold d-none d-md-flex"> <div class="col-md-3">Description</div> <div class="col-md-2">Pack Type</div> <div class="col-md-1">Qty</div> <div class="col-md-2">Net Weight (Kg)</div> <div class="col-md-1">Rate</div> <div class="col-md-1">Amount</div> <div class="col-md-1"></div> </div> </div> <div class="col-12"> <button type="button" class="btn btn-sm btn-outline-primary" onclick="addItem()">+ Add Item</button><br><br> </div> <?php $sql_taxes = "SELECT id, tax_name, tax_percentage FROM taxes WHERE status = 'active' ORDER BY tax_percentage ASC"; $result_taxes = mysqli_query($conn, $sql_taxes); $cgst_options = []; $sgst_options = []; if ($result_taxes && mysqli_num_rows($result_taxes) > 0) { while ($row = mysqli_fetch_assoc($result_taxes)) { $tax_name_upper = strtoupper($row['tax_name']); $value = $row['id']; $display_text = htmlspecialchars($row['tax_percentage']) . ' %'; $option_value = htmlspecialchars($row['id']); $option_text = htmlspecialchars($row['tax_name']) . ' (' . htmlspecialchars($row['tax_percentage']) . ' %)'; if (strpos($tax_name_upper, 'CGST') !== false) { $cgst_options[] = "<option value=\"{$option_value}\">{$option_text}</option>"; } elseif (strpos($tax_name_upper, 'SGST') !== false) { $sgst_options[] = "<option value=\"{$option_value}\">{$option_text}</option>"; } } } ?> <div class="row"> <div class="col-md-3"> <label class="form-label fw-bold">Total</label> <input type="text" class="form-control fw-bold" id="total_amount" name="total_amount" readonly> </div> <div class="col-md-3"> <label class="form-label fw-bold">CGST</label> <select name="tax_cgst" class="form-control form-select"> <option value="">Select CGST</option> <?php echo implode('', $cgst_options); ?> </select> </div> <div class="col-md-3"> <label class="form-label fw-bold">SGST</label> <select name="tax_sgst" class="form-control form-select"> <option value="">Select SGST</option> <?php echo implode('', $sgst_options); ?> </select> </div> <div class="col-md-3"> <label class="form-label fw-bold">Grand Total</label> <input type="text" class="form-control fw-bold" id="grand_total" name="grand_total" readonly> </div> </div> <div class="col-md-12 mt-3"> <label class="form-label">Upload Invoice Copy (PDF/JPG)</label> <input type="file" name="invoice_copy" class="form-control"> </div> <div class="col-12 mt-4"> <button type="submit" class="btn btn-primary">Save Invoice</button> </div> </form> </div> </div> </div> </div> </div> </main> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> /* function addItem() { const itemsContainer = document.getElementById('items_container'); const itemRow = document.createElement('div'); itemRow.classList.add('row','g-2','mb-2','item-row'); itemRow.innerHTML = ` <div class="col-md-3"><input class="form-control" name="item_desc[]" placeholder="Description" required></div> <div class="col-md-2"><input class="form-control" name="pack_type[]" placeholder="Pack Type"></div> <div class="col-md-1"><input type="number" step="any" class="form-control item_qty" name="qty[]" placeholder="Qty"></div> <div class="col-md-2"><input type="number" step="any" class="form-control item_weight" name="net_weight[]" placeholder="Weight (Kg)"></div> <div class="col-md-1"><input type="number" step="any"class="form-control item_rate" name="rate[]" placeholder="Rate"></div> <div class="col-md-1"><input type="number" step="any" class="form-control item_amount" name="amount[]" placeholder="Amount" readonly></div> <div class="col-md-1"><button type="button" class="btn btn-danger btn-sm remove-item">X</button></div> `; itemsContainer.appendChild(itemRow); // when qty or rate changes -> recalc amount & grand total const qtyEl = itemRow.querySelector('.item_qty'); const rateEl = itemRow.querySelector('.item_rate'); const amtEl = itemRow.querySelector('.item_amount'); const amtWt = itemRow.querySelector('.item_weight'); function calcRowAmount() { const qty = parseFloat(qtyEl.value) || 0; const rate = parseFloat(rateEl.value) || 0; const netWeight = parseFloat(amtWt.value) || 0; amtEl.value = (netWeight * rate).toFixed(2); // two decimals calculateGrandTotal(); } qtyEl.addEventListener('input', calcRowAmount); rateEl.addEventListener('input', calcRowAmount); itemRow.querySelector('.remove-item').addEventListener('click', function(){ itemRow.remove(); calculateGrandTotal(); }); } // Example grand total function function calculateGrandTotal() { let total = 0; document.querySelectorAll('.item_amount').forEach(function(el){ total += parseFloat(el.value) || 0; }); document.getElementById('grand_total').value = total.toFixed(2); } // default one row document.addEventListener('DOMContentLoaded', addItem); $(document).ready(function(){ $("#vendor_id").change(function(){ var vid = $(this).val(); if(vid){ $.ajax({ url: "get_vendor_details.php", type: "POST", data: {vendor_id: vid}, dataType: "json", success: function(data){ $("#vendor_code").val(data.vendor_code); } }); } else { $("#vendor_code").val(""); } }); }); */ // --- CORE ITEM LOGIC --- // Function to add a new item row function addItem() { const itemsContainer = document.getElementById('items_container'); const itemRow = document.createElement('div'); itemRow.classList.add('row','g-2','mb-2','item-row'); itemRow.innerHTML = ` <div class="col-md-3"><input class="form-control" name="item_desc[]" placeholder="Description"></div> <div class="col-md-2"><input class="form-control" name="pack_type[]" placeholder="Pack Type"></div> <div class="col-md-1"><input type="number" step="any" class="form-control item_qty" name="qty[]" placeholder="Qty"></div> <div class="col-md-2"><input type="number" step="any" class="form-control item_weight" name="net_weight[]" placeholder="Weight (Kg)"></div> <div class="col-md-1"><input type="number" step="any"class="form-control item_rate" name="rate[]" placeholder="Rate"></div> <div class="col-md-1"><input type="number" step="any" class="form-control item_amount" name="amount[]" placeholder="Amount" readonly></div> <div class="col-md-1"><button type="button" class="btn btn-danger btn-sm remove-item">X</button></div> `; itemsContainer.appendChild(itemRow); const qtyEl = itemRow.querySelector('.item_qty'); const rateEl = itemRow.querySelector('.item_rate'); const amtEl = itemRow.querySelector('.item_amount'); const amtWt = itemRow.querySelector('.item_weight'); // Net Weight is used for Amount calculation // Function to calculate Amount for a single row: Amount = Net Weight * Rate function calcRowAmount() { const rate = parseFloat(rateEl.value) || 0; const netWeight = parseFloat(amtWt.value) || 0; // Calculate Amount and set the value amtEl.value = (netWeight * rate).toFixed(2); // After updating the row amount, recalculate all totals calculateFinalTotals(); } // Attach event listeners to trigger row calculation on input change qtyEl.addEventListener('input', calcRowAmount); rateEl.addEventListener('input', calcRowAmount); amtWt.addEventListener('input', calcRowAmount); // Watch Net Weight as well // Attach listener to remove button itemRow.querySelector('.remove-item').addEventListener('click', function(){ itemRow.remove(); calculateFinalTotals(); // Recalculate after removal }); } // Ensure at least one item row exists on load document.addEventListener('DOMContentLoaded', addItem); // --- VENDOR LOGIC (Keep existing AJAX) --- $(document).ready(function(){ $("#vendor_id").change(function(){ var vid = $(this).val(); if(vid){ $.ajax({ url: "get_vendor_details.php", type: "POST", data: {vendor_id: vid}, dataType: "json", success: function(data){ $("#vendor_code").val(data.vendor_code); } }); } else { $("#vendor_code").val(""); } }); // --- TAX CALCULATION BINDING (New) --- // Bind the calculation function to the change events of the tax dropdowns // The select elements use the database ID as the value, so we need to fetch the percentage. $('select[name="tax_cgst"], select[name="tax_sgst"]').on('change', function() { // Fetch the tax percentage for the selected ID (via AJAX or data-attribute) // Since we don't have get_tax_percentage.php, we will use a temporary function for demo: // *** REAL WORLD: YOU MUST FETCH THE PERCENTAGE FROM THE DATABASE USING THE ID *** // For this demo, we will use the ID to represent the percentage rate (e.g., ID 2.5 is 2.5%) calculateFinalTotals(); }); }); // --- CORE TOTALS CALCULATION FUNCTION --- /** * Calculates the Total Amount, applies CGST/SGST, and updates the Grand Total. */ function calculateFinalTotals() { // 1. Calculate Sub-Total (Sum of all item amounts) let subTotal = 0; document.querySelectorAll('.item-row .item_amount').forEach(function(el){ subTotal += parseFloat(el.value) || 0; }); // Update the Total field $('#total_amount').val(subTotal.toFixed(2)); // 2. Get the Tax IDs (not percentage) const cgstID = $('#tax_cgst').val(); const sgstID = $('#tax_sgst').val(); // *** IMPORTANT: Fetch the percentage rate using the selected ID *** // This is a simplified function. In a production app, you'd use AJAX // to look up the rate in the 'taxes' table using the ID. // For now, let's assume the percentage is stored in a hidden field or fetch from an attribute. // Since the PHP code only provided the ID and Name, we'll try to extract the percentage from the text: function getRateFromSelect(selectElement, defaultRate = 0) { const selectedOption = selectElement.find('option:selected').text(); // Regex to find a number followed by '%' in the option text, e.g., "(2.5 %)" const match = selectedOption.match(/\(([\d.]+)\s*%\)/); return match ? parseFloat(match[1]) : defaultRate; } const cgstRate = getRateFromSelect($('select[name="tax_cgst"]')); const sgstRate = getRateFromSelect($('select[name="tax_sgst"]')); // 3. Calculate Tax Amounts const cgstAmount = (subTotal * cgstRate) / 100; const sgstAmount = (subTotal * sgstRate) / 100; // For display, we should create separate inputs for CGST/SGST amounts // (You don't have them in your HTML, so we'll just use the grand total) // If you want to show the amount breakdown, add these inputs to your HTML: // <input type="text" id="cgst_amount_display" readonly> // <input type="text" id="sgst_amount_display" readonly> // 4. Calculate Grand Total const grandTotal = subTotal + cgstAmount + sgstAmount; // 5. Update the Grand Total field $('#grand_total').val(grandTotal.toFixed(2)); // *If you add the display inputs, uncomment these lines:* // $('#cgst_amount_display').val(cgstAmount.toFixed(2)); // $('#sgst_amount_display').val(sgstAmount.toFixed(2)); } // Trigger calculation on page load to set initial values // And bind tax changes to the full calculation $(document).on('change', 'select[name="tax_cgst"], select[name="tax_sgst"]', calculateFinalTotals); calculateFinalTotals(); </script> <?php include("footer.php"); ?>