362 lines
16 KiB
PHP
362 lines
16 KiB
PHP
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div class="card">
|
|
|
|
<div class="card-body">
|
|
|
|
<div class="row gy-3">
|
|
|
|
<div class="col-md-6">
|
|
<div class="row align-items-center">
|
|
<div class="col-1">
|
|
{{ html()->label('Date:')->class('form-label') }}
|
|
</div>
|
|
<div class="col-6">
|
|
{{ html()->text('date')->class('form-control flatpickr-date bg-light border-0')->placeholder('Date')->required() }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
<div class="row align-items-center justify-content-end">
|
|
<div class="col-2">
|
|
{{ html()->label('Estimate#')->class('form-label') }}
|
|
</div>
|
|
|
|
@php
|
|
if ($editable) {
|
|
$estimateNumber = $estimate->estimate_no;
|
|
} else {
|
|
$estimateNumber = generateEstimateNumber();
|
|
}
|
|
@endphp
|
|
|
|
<div class="col-6">
|
|
{{ html()->text('estimate_no', $estimateNumber)->class('form-control bg-light border-0') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-8">
|
|
{{ html()->label('Customer')->class('form-label') }}
|
|
{{ html()->select('customer_id', $customerList)->class('form-control select2')->placeholder('Customer Name')->required() }}
|
|
</div>
|
|
|
|
<div class="col-4">
|
|
{{ html()->label('Validity')->class('form-label') }}
|
|
{{ html()->text('validity')->class('form-control flatpickr-date bg-light border-0')->required() }}
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
{{ html()->label('Estimate for')->class('form-label') }}
|
|
{{ html()->text('title')->class('form-control')->placeholder('Estimate for')->required() }}
|
|
</div>
|
|
|
|
<div class="col-md-6">
|
|
{{ html()->label('Condition')->class('form-label') }}
|
|
{{ html()->text('conditions')->class('form-control')->placeholder('Conditions')->required() }}
|
|
</div>
|
|
|
|
|
|
<div class="col-12 mt-4">
|
|
<fieldset class="rounded p-3 border-1 border-muted">
|
|
<legend class="fs-6">Estimate Details</legend>
|
|
|
|
<div class="row gy-3 align-items-end">
|
|
<div class="col-lg-3">
|
|
{{ html()->label('Item')->class('form-label') }}
|
|
{{ html()->select(null, $billingComponentList)->class('form-control select2 item')->placeholder('Billing Component') }}
|
|
</div>
|
|
|
|
<div class="col-lg-2">
|
|
{{ html()->label('Price')->class('form-label') }}
|
|
{{ html()->number(null)->class('form-control price')->placeholder('Price') }}
|
|
</div>
|
|
|
|
<div class="col-lg-2">
|
|
{{ html()->label('Qty')->class('form-label') }}
|
|
{{ html()->number(null)->class('form-control qty')->placeholder('Quantity') }}
|
|
</div>
|
|
|
|
<div class="col-lg-3">
|
|
{{ html()->label('Taxable')->class('form-label') }}
|
|
{{ html()->select(null, ['1' => 'Yes', '0' => 'No'], 1)->class('form-control select2 taxable')->placeholder('Yes/No') }}
|
|
</div>
|
|
|
|
<div class="col-lg-2 text-end">
|
|
<a href="javascript:void(0)"
|
|
class="btn btn-soft-secondary fw-medium add-item-btn"><i
|
|
class="ri-add-fill me-1 align-bottom"></i> Add Item</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-3">
|
|
<div class="col-12">
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered border-muted table-sm">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th scope="col">S.N</th>
|
|
<th scope="col">Particular</th>
|
|
<th scope="col">Qty</th>
|
|
<th scope="col">Rate</th>
|
|
<th scope="col" width=20%>Non-Taxable</th>
|
|
<th scope="col" width=20%>Taxable</th>
|
|
<th scope="col">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@if ($editable)
|
|
@foreach ($estimate->estimateDetails as $index => $item)
|
|
<tr>
|
|
<th scope="row">
|
|
{{$index + 1}}
|
|
</th>
|
|
<td>${item->text}</td>
|
|
<td>${price.value}</td>
|
|
<td>${qty.value}</td>
|
|
<td class="non-taxable-amount">${taxable.value == 1 ? '-' : qty.value * price.value}</td>
|
|
<td class="taxable-amount">${taxable.value == 0 ? '-' : qty.value * price.value}</td>
|
|
<td>
|
|
<a href="javascript:void(0)" class="btn btn-sm btn-soft-danger remove-item-btn" data-index=${index}>
|
|
<i class="ri-subtract-line align-middle"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
@endif
|
|
</tbody>
|
|
|
|
<tfoot>
|
|
<tr>
|
|
<td>Total</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td>
|
|
{{ html()->text('totalNonTaxable')->class('form-control border-0')->id('non-taxable-total')->placeholder('0.00')->isReadOnly(true) }}
|
|
</td>
|
|
<td>
|
|
{{ html()->text('totalTaxable')->class('form-control border-0')->id('taxable-total')->placeholder('0.00')->isReadOnly(true) }}
|
|
</td>
|
|
<td></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-end mb-2">
|
|
<table class="table-borderless align-middle">
|
|
<tbody>
|
|
<tr>
|
|
<th scope="row">Tax(13%)</th>
|
|
<td>
|
|
{{ html()->text('tax')->class('form-control bg-light border-0')->id('tax')->placeholder('0.00')->isReadOnly(true) }}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Total Tax</th>
|
|
<td>
|
|
{{ html()->text('amountWithTax')->class('form-control bg-light border-0')->id('amount-with-tax')->placeholder('0.00')->isReadOnly(true) }}
|
|
</td>
|
|
</tr>
|
|
<tr class="border-top border-top-dashed">
|
|
<th scope="row">Grand Total</th>
|
|
<td>
|
|
{{ html()->text('grandTotal')->class('form-control bg-light border-0')->id('grand-total')->placeholder('0.00')->isReadOnly(true) }}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<x-form-buttons :editable="$editable" label="Add" href="{{ route('estimate.index') }}" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
<!-- end card body -->
|
|
</div>
|
|
<!-- end card -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@push('js')
|
|
<script src="{{ asset('assets/js/pages/form-validation.init.js') }}"></script>
|
|
|
|
<script type="text/javascript">
|
|
$(document).ready(function() {
|
|
|
|
let dataArray = [];
|
|
|
|
let index = 0;
|
|
|
|
$('.add-item-btn').click(function() {
|
|
|
|
const selectedElements = $('.item, .price, .qty, .taxable');
|
|
|
|
let entry = getSelectedValues(selectedElements);
|
|
|
|
console.log(entry);
|
|
|
|
if (entry) {
|
|
updateTable(entry);
|
|
calculate();
|
|
$('.price, .qty').val('');
|
|
}
|
|
});
|
|
|
|
function getSelectedValues(selectedElements) {
|
|
let isEmpty = false;
|
|
let selectedValues = selectedElements.map((_, el) => {
|
|
try {
|
|
const $el = $(el);
|
|
|
|
if ($el.val() === '') {
|
|
$el.focus();
|
|
isEmpty = true;
|
|
throw new Error('Empty value encountered');
|
|
}
|
|
|
|
if ($el.is('select')) {
|
|
return {
|
|
text: $el.find('option:selected').text().trim(),
|
|
value: $el.val(),
|
|
};
|
|
} else {
|
|
return {
|
|
value: $el.val(),
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error("An error occurred:", error);
|
|
return null;
|
|
}
|
|
}).get();
|
|
|
|
if (isEmpty) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
return selectedValues;
|
|
|
|
}
|
|
}
|
|
|
|
function updateTable(entry) {
|
|
|
|
const [item, price, qty, taxable] = entry;
|
|
|
|
try {
|
|
|
|
const data = {
|
|
billing_component_id: item.value,
|
|
price: price.value,
|
|
qty: qty.value,
|
|
taxable: taxable.value,
|
|
tax_amount: taxable.value ? price.value * qty.value : 0,
|
|
};
|
|
|
|
dataArray.push(data);
|
|
|
|
console.log(dataArray);
|
|
|
|
let tableBody = $('.table tbody');
|
|
let html = `
|
|
<tr>
|
|
<th scope="row">
|
|
${tableBody.children().length + 1}
|
|
</th>
|
|
<td>${item.text}</td>
|
|
<td>${price.value}</td>
|
|
<td>${qty.value}</td>
|
|
<td class="non-taxable-amount">${taxable.value == 1 ? '-' : qty.value * price.value}</td>
|
|
<td class="taxable-amount">${taxable.value == 0 ? '-' : qty.value * price.value}</td>
|
|
<td>
|
|
<a href="javascript:void(0)" class="btn btn-sm btn-soft-danger remove-item-btn" data-index=${index}>
|
|
<i class="ri-subtract-line align-middle"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
tableBody.append(html);
|
|
|
|
index++;
|
|
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
function calculate() {
|
|
let totalTaxable = 0;
|
|
let totalNonTaxable = 0;
|
|
let amountWithTax = 0;
|
|
let grandTotal = 0;
|
|
|
|
$('.taxable-amount').each(function() {
|
|
var value = parseFloat($(this).text());
|
|
if (!isNaN(value)) {
|
|
totalTaxable += value;
|
|
}
|
|
});
|
|
|
|
$('.non-taxable-amount').each(function() {
|
|
var value = parseFloat($(this).text());
|
|
if (!isNaN(value)) {
|
|
totalNonTaxable += value;
|
|
}
|
|
});
|
|
|
|
taxAmount = (totalTaxable * 0.13).toFixed(2);
|
|
amountWithTax = totalTaxable + parseFloat(taxAmount);
|
|
grandTotal = (totalNonTaxable + parseFloat(amountWithTax)).toFixed(2);
|
|
|
|
$('#tax').val(taxAmount);
|
|
$('#amount-with-tax').val(amountWithTax);
|
|
$('#grand-total').val(grandTotal);
|
|
$('#non-taxable-total').val(totalNonTaxable);
|
|
$('#taxable-total').val(totalTaxable);
|
|
}
|
|
|
|
$(".table").on('click', '.remove-item-btn', function() {
|
|
removeItem(this);
|
|
});
|
|
|
|
function removeItem(element) {
|
|
$(element).closest('tr').remove();
|
|
const dataIndex = $(element).data('index');
|
|
console.log(dataIndex);
|
|
dataArray.splice(dataIndex, 1);
|
|
console.log(dataArray);
|
|
calculate();
|
|
};
|
|
|
|
$(document).on('submit', '#storeUpdateForm', function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
let estimateDetails = JSON.stringify(dataArray);
|
|
|
|
let hiddenInput = $("<input>")
|
|
.attr("type", "hidden")
|
|
.attr("name", "estimateDetails")
|
|
.val(estimateDetails);
|
|
|
|
$('#storeUpdateForm').append(hiddenInput);
|
|
|
|
this.submit();
|
|
});
|
|
});
|
|
</script>
|
|
@endpush
|