CHANGE_Client Invoice

This commit is contained in:
venba-Inspriron-3558 2025-11-13 15:28:52 +05:30
parent f7db3c4513
commit 78ba1fc582
6 changed files with 128 additions and 41 deletions

View File

@ -27,6 +27,7 @@ use Mpdf\Mpdf;
use CodeIgniter\API\ResponseTrait;
use App\Helpers\InvNoHelper;
use App\Helpers\ClientDetailsUpdate;
use Config\Services;
class Invoice extends BaseController
{
@ -145,6 +146,8 @@ class Invoice extends BaseController
'status'=> $status,
'isactive' => 1,
'branch_id'=> $this->session->get('logged_user_branch_id'),
'paid_advance' => $this->request->getPost('paid_advance'),
'discount' => $this->request->getPost('discount'),
];
@ -299,10 +302,11 @@ class Invoice extends BaseController
}
public function download_invoice($invoice_id)
public function download_invoice($enc_id)
{
if(!$this->session->has('logged_user')) { return redirect()->to(base_url()); }
// Fetch the invoice data based on $invoice_id
$invoice_id = base64_decode($enc_id);
$InvoiceModel = new InvoiceModel();
$InvoiceChildModel = new InvoiceChildModel();

View File

@ -6,7 +6,7 @@ class InvoiceModel extends Model
protected $table = 'invoice';
protected $primaryKey = 'invoice_id';
protected $allowedFields = ['invoice_id','invoice_number','sale_order','invoice_date','sales_commision','client_name','status','vehicle_reg_number','billing_address','billing_city','billing_state','billing_country','billing_postal_code','terms_condition','job_card_id','isactive',
'type','mobile_no','email','invoice_child_id','order_number','mode_of_payment','subtotal','tax','discount','total','terms_condition','branch_id','vehicle_id' ];
'type','mobile_no','email','invoice_child_id','order_number','mode_of_payment','subtotal','tax','discount','total','terms_condition','branch_id','vehicle_id','paid_advance' ];
protected $beforeInsert = ['setCreatedBy'];
protected $beforeUpdate = ['setUpdatedBy'];

View File

@ -342,19 +342,23 @@
<input type="text" class="form-control" id="invoicetax" name="invoice_tax" readonly
value="<?= isset($invoice['tax']) ? $invoice['tax'] : '' ?>">
</div>
<!-- <div class="form-group">
<label for="discount">Discount Amount</label>
<input type="number" class="form-control" id="discount" name="discount" onchange="calculateGrandTotal(this.value)" min="0" readonly value="<?= isset($invoice['discount']) ? $invoice['discount'] : '' ?>" >
</div> -->
<div class="form-group">
<label for="grandtotal">Total</label>
<label for="grandtotal">Total Amount</label>
<input type="text" class="form-control" id="grandtotal" name="grand_total" readonly
value="<?= isset($invoice['total']) ? $invoice['total'] : '' ?>">
</div>
<div class="form-group">
<label for="discount">Discount Amount</label>
<input type="number" class="form-control" id="discount" name="discount" onchange="calculateBalance()" min="0" value="<?= isset($invoice['discount']) ? $invoice['discount'] : '' ?>" >
</div>
<div class="form-group">
<label for="advance">Paid Advance</label>
<input type="number" class="form-control" id="paid_advance" name="paid_advance" onchange="calculateBalance()" min="0" value="<?= isset($invoice['paid_advance']) ? $invoice['paid_advance'] : '0.00' ?>" >
</div>
<div class="form-group">
<label for="balance">Balance Amount</label>
<input type="text" class="form-control" id="balance" readonly >
</div>
</div>
@ -1047,32 +1051,28 @@ $(document).ready(function() {
// Function to calculate total discount
function calculateDiscount() {
var totalDiscount = 0;
$('.item-discount-amount').each(function(index, element) {
var discountAmount = parseFloat($(element).val()) || 0;
var discountType = $(element).closest('tr').find('.item-discount-type').val();
if (discountType === '%') {
var rate = $(element).closest('tr').find('.item-rate').val();
var quantity = $(element).closest('tr').find('.item-quantity').val();
var amount = rate * quantity;
discountAmount = amount * discountAmount / 100;
}
totalDiscount += discountAmount;
});
return totalDiscount;
}
// function calculateDiscount() {
// var totalDiscount = 0;
// $('.item-discount-amount').each(function(index, element) {
// var discountAmount = parseFloat($(element).val()) || 0;
// var discountType = $(element).closest('tr').find('.item-discount-type').val();
// if (discountType === '%') {
// var rate = $(element).closest('tr').find('.item-rate').val();
// var quantity = $(element).closest('tr').find('.item-quantity').val();
// var amount = rate * quantity;
// discountAmount = amount * discountAmount / 100;
// }
// totalDiscount += discountAmount;
// });
// return totalDiscount;
// }
// Function to calculate total
function calculateTotal() {
var subtotal = calculateSubtotal();
var total_tax_amount = $('#invoicetax').val();
// console.log(total_tax_amount + parseInt(subtotal));
var discount = calculateDiscount();
var total = parseFloat(total_tax_amount) + parseFloat(subtotal) - discount;
var total = parseFloat(total_tax_amount) + parseFloat(subtotal);
// return total;
return Math.round(total);
}
@ -1081,8 +1081,9 @@ $(document).ready(function() {
function updateCalculations() {
$('#subtotal').val(calculateSubtotal().toFixed(2));
$('#invoicetax').val(calculateTax().toFixed(2));
$('#discount').val(calculateDiscount().toFixed(2));
// $('#discount').val(calculateDiscount().toFixed(2));
$('#grandtotal').val(calculateTotal().toFixed(2));
calculateBalance();
}
// Event listener for discount change
@ -1139,6 +1140,8 @@ $(document).ready(function() {
$('#itemTable tbody').append(newRow);
$('#discount').val(0);
$('#paid_advance').val(0);
initializeSelect2();
updateCalculations();
initializeRowCalculations(newRow);
@ -1160,8 +1163,7 @@ function initializeRowCalculations(row) {
calculateAmount(row);
updateCalculations();
}
</script>
<script>
// Event listener for removing item
// Event listener for removing item
$(document).on('click', '.remove-item', function() {
@ -1180,6 +1182,7 @@ $(document).on('click', '.remove-item', function() {
// If successful, remove the row from the table
$(this).closest('tr').remove();
updateCalculations(); // Update calculations after removing the row
calculateBalance();
} else {
// If not successful, display an error message
// alert('Error occurred while deleting the item.');
@ -1780,4 +1783,48 @@ $(document).ready(function() {
});
</script>
<script>
function calculateBalance() {
var total = parseFloat($('#grandtotal').val()) || 0;
var discount = parseFloat($('#discount').val()) || 0;
var advance = parseFloat($('#paid_advance').val()) || 0;
// Ensure discount or advance not negative
if (discount < 0) discount = 0;
if (advance < 0) advance = 0;
// If total of discount + advance exceeds total, fix it
if (discount + advance > total) {
var excess = (discount + advance) - total;
// Determine which field caused the excess (the last changed one)
// We can check active element
var lastChanged = document.activeElement.id;
if (lastChanged === 'discount') {
discount = total - advance;
$('#discount').val(discount.toFixed(2));
} else if (lastChanged === 'paid_advance') {
advance = total - discount;
$('#paid_advance').val(advance.toFixed(2));
} else {
// If unknown, just cap both
if (discount > total) discount = total;
if (advance > total - discount) advance = total - discount;
$('#discount').val(discount.toFixed(2));
$('#paid_advance').val(advance.toFixed(2));
}
}
// Calculate balance
var balance = total - (discount + advance);
if (balance < 0) balance = 0;
// Update fields
$('#discount').val(discount.toFixed(2));
$('#paid_advance').val(advance.toFixed(2));
$('#balance').val(balance.toFixed(2));
}
</script>

View File

@ -79,7 +79,8 @@
<div class="dropdown-menu dropdown-menu-right">
<a href="<?= "invoices/new/" . $value['invoice_id']; ?>" class="dropdown-item edit-button" onclick="datatableInvoice('invoice_tr<?php echo $index+1; ?>')"><i class="ri-pencil-line mr-2 text-muted font-18 vertical-middle"></i>Edit</a>
<!-- <a href="<?= "invoices/delete/" . $value['invoice_id']; ?>" class="dropdown-item delete-button" onclick="datatableInvoice('invoice_tr<?php echo $index+1; ?>')"><i class="ri-delete-bin-line mr-2 text-muted font-18 vertical-middle"></i>Delete</a> -->
<a href="#" data-invoices-id="<?= $value['invoice_id']; ?>" class="dropdown-item preview-invoice" href="#" title="Preview Invoice"><i class="ri-book-read-line mr-2 text-muted font-18 vertical-middle"></i>Preview Invoice</a>
<a href="#" data-invoices-id="<?= $value['invoice_id']; ?>" data-enc-id="<?= base64_encode($value['invoice_id']); ?>" class="dropdown-item preview-invoice" href="#" title="Preview Invoice"><i class="ri-book-read-line mr-2 text-muted font-18 vertical-middle"></i>Preview Invoice</a>
<a href="#" data-invoices-id="<?= $value['invoice_id']; ?>" data-enc-id="<?= base64_encode($value['invoice_id']); ?>" class="dropdown-item pdf-invoice-link" href="#" title="Invoice pdf link"><i class="ri-file-copy-2-fill mr-2 text-muted font-18 vertical-middle"></i>Copy Invoice PDF as Link</a>
</div>
</div>
</td>
@ -201,6 +202,8 @@
$(document).on('click', '.preview-invoice', function() {
var Id = $(this).data('invoices-id');
var encId = $(this).data('enc-id');
var link = '<?= base_url("invoices/download/") ?>' + encId;
$.ajax({
type: 'GET',
url: 'invoices/preview/'+Id,
@ -210,7 +213,7 @@
$('#PreviewInvoiceModal').modal('show');
$('#PreviewInvoiceModalLabel').text('Invoice Preview ');
$('#PreviewInvoiceModal .modal-body').html(response.data);
$('#downloadInvoiceButton').attr('href', '<?= base_url("invoices/download/") ?>' + Id);
$('#downloadInvoiceButton').attr('href', link);
$('#printInvoiceButton').attr('data-id', Id);
}else{
$('#PreviewInvoiceModal').modal('hide');
@ -271,4 +274,20 @@
}
});
});
$(document).on('click', '.pdf-invoice-link', function(e) {
e.preventDefault();
var Id = $(this).data('invoices-id');
var encId = $(this).data('enc-id');
var link = '<?= base_url("invoices/download/") ?>' + encId;
// Copy the link to clipboard
navigator.clipboard.writeText(link).then(() => {
alert("Invoice link copied! You can paste it into WhatsApp.");
}).catch(() => {
alert("Failed to copy link.");
});
});
</script>

View File

@ -228,16 +228,32 @@
<td style="width: 33.3333%; height: 36px; text-align: right; font-size: small">Total</td>
<td style="width: 25.7946%; height: 36px; text-align: right; font-size: small"><?= number_format($subTotal+$subTax, 2, '.', ''); ?></td>
</tr>
<tr style="height: 21px;">
<td style="width: 33.3333%; height: 21px;">&nbsp;</td>
<td style="width: 33.3333%; height: 21px; text-align: right; font-size: small">Discount</td>
<td style="width: 25.7946%; height: 21px; text-align: right; font-size: small">0.00</td>
</tr>
<tr style="height: 36px;">
<td style="width: 33.3333%; height: 36px;">&nbsp;</td>
<td style="width: 33.3333%; height: 36px; text-align: right; font-size: small"><strong>Grand Total</strong></td>
<td style="width: 25.7946%; height: 36px; text-align: right; font-size: small"><strong>&#8377;&nbsp;<?= number_format($grandTotal, 2, '.', ''); ?></strong></td>
</tr>
<tr style="height: 36px;">
<td style="width: 33.3333%; height: 36px;">&nbsp;</td>
<td style="width: 33.3333%; height: 36px; text-align: right; font-size: small">Discount</td>
<td style="width: 25.7946%; height: 36px; text-align: right; font-size: small"><?= isset($invoice[0]->discount) ? number_format((float)$invoice[0]->discount, 2, '.', '') : '0.00'; ?></td>
</tr>
<tr style="height: 36px;">
<td style="width: 33.3333%; height: 36px;">&nbsp;</td>
<td style="width: 33.3333%; height: 36px; text-align: right; font-size: small">Paid Advance</td>
<td style="width: 25.7946%; height: 36px; text-align: right; font-size: small"><?= isset($invoice[0]->paid_advance) ? number_format((float)$invoice[0]->paid_advance, 2, '.', '') : '0.00'; ?></td>
</tr>
<tr style="height: 36px;">
<td style="width: 33.3333%; height: 36px;">&nbsp;</td>
<td style="width: 33.3333%; height: 36px; text-align: right; font-size: small">Balance Amount</td>
<td style="width: 25.7946%; height: 36px; text-align: right; font-size: small">
<?php
$discount = (float) $invoice[0]->discount;
$paid_advance = (float) $invoice[0]->paid_advance;
$balance = $grandTotal - ($discount + $paid_advance); ?>
<strong>&#8377;&nbsp;<?= number_format(max(0, $balance), 2, '.', ''); ?></strong>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>

View File

@ -421,6 +421,7 @@ $(document).ready(function() {
}else{
var total_amount = parseFloat($("input[name='total_amount']").val());
var unitPrice = total_amount / parseFloat((tax / 100) + 1);
if (isNaN(unitPrice)) unitPrice = 0;
$("input[name='unit_price']").val(unitPrice.toFixed(2));
}