576 lines
15 KiB
PHP
576 lines
15 KiB
PHP
<div class="container mt-4">
|
|
<div class="card modern-card shadow-sm border-0 rounded-4">
|
|
<div class="card-body p-4">
|
|
|
|
<div class="d-flex justify-content-between mb-3">
|
|
<h5>
|
|
<?php if($active_menu == 'invoice_unpaid') echo 'Invoice Berjalan'; ?>
|
|
<?php if($active_menu == 'invoice_paid') echo 'Riwayat Invoice'; ?>
|
|
<?php if($active_menu == 'invoice_draft') echo 'Draft Invoice'; ?>
|
|
</h5>
|
|
|
|
<?php if($active_menu == 'invoice_draft') : ?>
|
|
<button class="btn btn-warning btn-add">Buat Invoice</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table modern-table align-middle w-100" id="tableInvoice">
|
|
<!-- <table id="tableInvoice" class="table table-bordered"> -->
|
|
<thead>
|
|
<tr>
|
|
<th>No</th>
|
|
<th>No Invoice</th>
|
|
<th>Tanggal</th>
|
|
<th>Jatuh Tempo</th>
|
|
<th>Customer</th>
|
|
<th>Total</th>
|
|
<th>Terbayar</th>
|
|
<th>Sisa</th>
|
|
<th>Status</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MODAL -->
|
|
<div class="modal fade" id="modalInvoice">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-warning text-white">
|
|
<h5>Buat Invoice</h5>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="form-group mt-2">
|
|
<label for="customer_id">Customer</label>
|
|
<select id="customer_id" class="form-control mb-2"></select>
|
|
</div>
|
|
|
|
<div class="form-group mt-2">
|
|
<label for="tanggal">Tanggal</label>
|
|
<input type="date" id="tanggal" class="form-control mb-2">
|
|
</div>
|
|
|
|
<div class="form-group mt-2">
|
|
<label for="jatuh_tempo">Jatuh Tempo</label>
|
|
<input type="date" id="jatuh_tempo" class="form-control mb-3">
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button class="btn btn-warning" id="btnSimpan">Simpan</button>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="modal fade" id="modalBayar">
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-warning text-white">
|
|
<h5>
|
|
Bayar Invoice -
|
|
<span id="customerName"></span>
|
|
</h5>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<input type="hidden" id="bayar_invoice_id">
|
|
|
|
<!-- INFO BOX -->
|
|
<div class="row mb-3">
|
|
|
|
<div class="col-md-4">
|
|
<div class="p-2 border rounded">
|
|
<small>Total Invoice</small>
|
|
<h5 id="invoiceTotal">0</h5>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="p-2 border rounded">
|
|
<small>Total Bayar</small>
|
|
<h5 id="totalBayar">0</h5>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="p-2 border rounded">
|
|
<small>Sisa (Balance)</small>
|
|
<h5 id="balance">0</h5>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<label>Tanggal Bayar</label>
|
|
<input type="date" id="tanggal_bayar" class="form-control mb-2">
|
|
|
|
<table class="table" id="tableBayar">
|
|
<thead>
|
|
<tr>
|
|
<th>Account</th>
|
|
<th>Debit</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
|
|
<button class="btn btn-sm btn-primary btn-add-bayar">
|
|
+ Tambah Pembayaran
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button class="btn btn-warning" id="btnProsesBayar">
|
|
Proses Bayar
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
$(function(){
|
|
|
|
let url = "";
|
|
let accountOptions = '';
|
|
let accountOptionsAssets = '';
|
|
|
|
// =========================
|
|
// URL BY MENU
|
|
// =========================
|
|
<?php if($active_menu == 'invoice_unpaid'): ?>
|
|
url = "<?= base_url('invoices/get_data/unpaid'); ?>";
|
|
<?php elseif($active_menu == 'invoice_paid'): ?>
|
|
url = "<?= base_url('invoices/get_data/paid'); ?>";
|
|
<?php elseif($active_menu == 'invoice_draft'): ?>
|
|
url = "<?= base_url('invoices/get_data/draft'); ?>";
|
|
<?php endif; ?>
|
|
|
|
|
|
// =========================
|
|
// LOAD CUSTOMER
|
|
// =========================
|
|
$.get("<?= base_url('invoices/get_customers'); ?>", res => {
|
|
let opt = '<option value="">Pilih Customer</option>';
|
|
res.forEach(c => opt += `<option value="${c.id}">${c.nama}</option>`);
|
|
$('#customer_id').html(opt);
|
|
}, 'json');
|
|
|
|
|
|
// =========================
|
|
// LOAD ACCOUNT (PENDAPATAN)
|
|
// =========================
|
|
$.get("<?= base_url('invoices/get_accounts'); ?>", res => {
|
|
accountOptions = '<option value="">Pilih Akun</option>';
|
|
res.forEach(a => {
|
|
accountOptions += `<option value="${a.id}">${a.kode_akun} - ${a.nama_akun}</option>`;
|
|
});
|
|
}, 'json');
|
|
|
|
|
|
// =========================
|
|
// LOAD ACCOUNT (ASSET / KAS)
|
|
// =========================
|
|
$.get("<?= base_url('invoices/get_accounts_assets'); ?>", res => {
|
|
accountOptionsAssets = '<option value="">Pilih Akun</option>';
|
|
res.forEach(a => {
|
|
accountOptionsAssets += `<option value="${a.id}">${a.kode_akun} - ${a.nama_akun}</option>`;
|
|
});
|
|
}, 'json');
|
|
|
|
|
|
// =========================
|
|
// DATATABLE
|
|
// =========================
|
|
let table = $('#tableInvoice').DataTable({
|
|
ajax:{
|
|
url: url,
|
|
type:"POST"
|
|
},
|
|
columnDefs:[
|
|
{ targets:[3], className:'text-end' }
|
|
]
|
|
});
|
|
|
|
|
|
// =========================
|
|
// ADD ITEM ROW
|
|
// =========================
|
|
$('.btn-add-row').click(function(){
|
|
|
|
if(!accountOptions){
|
|
Swal.fire('Warning','Account belum siap, tunggu sebentar','warning');
|
|
return;
|
|
}
|
|
|
|
$('#tableDetail tbody').append(`
|
|
<tr>
|
|
<td>
|
|
<select class="form-control account_id">${accountOptions}</select>
|
|
</td>
|
|
<td><input type="text" class="form-control nama_item"></td>
|
|
<td><input type="number" class="form-control qty" value="1"></td>
|
|
<td><input type="text" class="form-control harga format-rupiah"></td>
|
|
<td class="subtotal text-end">0</td>
|
|
<td><button class="btn btn-danger btn-remove">X</button></td>
|
|
</tr>
|
|
`);
|
|
});
|
|
|
|
|
|
// =========================
|
|
// HITUNG SUBTOTAL
|
|
// =========================
|
|
$(document).on('input','.qty,.harga',function(){
|
|
|
|
let tr = $(this).closest('tr');
|
|
let qty = parseFloat(tr.find('.qty').val()) || 0;
|
|
let harga = parseFloat(tr.find('.harga').val()) || 0;
|
|
|
|
let sub = qty * harga;
|
|
|
|
tr.find('.subtotal').text(sub.toLocaleString('id-ID'));
|
|
calcTotal();
|
|
});
|
|
|
|
|
|
// =========================
|
|
// TOTAL
|
|
// =========================
|
|
function calcTotal(){
|
|
let total = 0;
|
|
|
|
$('.subtotal').each(function(){
|
|
total += parseFloat($(this).text().replace(/\./g,'')) || 0;
|
|
});
|
|
|
|
$('#grandTotal').text(total.toLocaleString('id-ID'));
|
|
}
|
|
|
|
|
|
// =========================
|
|
// REMOVE ROW (GLOBAL)
|
|
// =========================
|
|
$(document).on('click','.btn-remove',function(){
|
|
$(this).closest('tr').remove();
|
|
calcTotal();
|
|
hitungBayar();
|
|
});
|
|
|
|
|
|
// =========================
|
|
// OPEN MODAL INVOICE
|
|
// =========================
|
|
$('.btn-add').click(function(){
|
|
$('#modalInvoice').modal('show');
|
|
$('#tableDetail tbody').html('');
|
|
$('#grandTotal').text('0');
|
|
});
|
|
|
|
// =========================
|
|
// SIMPAN INVOICE
|
|
// =========================
|
|
$('#btnSimpan').click(function(){
|
|
|
|
let nama_item=[], qty=[], harga=[], account_id=[];
|
|
|
|
$('#tableDetail tbody tr').each(function(){
|
|
nama_item.push($(this).find('.nama_item').val());
|
|
qty.push($(this).find('.qty').val());
|
|
harga.push($(this).find('.harga').val());
|
|
account_id.push($(this).find('.account_id').val());
|
|
});
|
|
|
|
$.post("<?= base_url('invoices/save'); ?>",{
|
|
customer_id: $('#customer_id').val(),
|
|
tanggal: $('#tanggal').val(),
|
|
jatuh_tempo: $('#jatuh_tempo').val()
|
|
}, function(res){
|
|
|
|
if(res.status){
|
|
Swal.fire({
|
|
icon:'success',
|
|
title:'Berhasil',
|
|
text:'Invoice berhasil disimpan',
|
|
timer:1500,
|
|
showConfirmButton:false
|
|
}).then(()=>{
|
|
window.location.href = "<?= base_url('invoices/detail/'); ?>" + res.invoice_id;
|
|
});
|
|
}else{
|
|
Swal.fire('Error', res.message || 'Gagal simpan', 'error');
|
|
}
|
|
|
|
},'json');
|
|
});
|
|
|
|
// =========================
|
|
// DETAIL
|
|
// =========================
|
|
$(document).on('click','.btn-detail',function(){
|
|
let id = $(this).data('id');
|
|
window.location.href = "<?= base_url('invoices/detail/'); ?>" + id;
|
|
});
|
|
|
|
|
|
// =========================
|
|
// OPEN MODAL BAYAR
|
|
// =========================
|
|
$(document).on('click','.btn-bayar',function(){
|
|
|
|
let id = $(this).data('id');
|
|
let total = parseFloat($(this).data('total') - $(this).data('terbayar')) || 0;
|
|
let customer = $(this).data('customer');
|
|
|
|
$('#bayar_invoice_id').val(id);
|
|
$('#customerName').text(customer);
|
|
|
|
$('#invoiceTotal').text(total.toLocaleString('id-ID'));
|
|
|
|
$('#tableBayar tbody').html('');
|
|
$('#totalBayar').text('0');
|
|
$('#balance').text(total.toLocaleString('id-ID'));
|
|
|
|
$('#modalBayar').modal('show');
|
|
});
|
|
|
|
|
|
// =========================
|
|
// ADD ROW BAYAR
|
|
// =========================
|
|
$('.btn-add-bayar').click(function(){
|
|
|
|
if(!accountOptionsAssets){
|
|
Swal.fire('Warning','Account belum siap','warning');
|
|
return;
|
|
}
|
|
|
|
$('#tableBayar tbody').append(`
|
|
<tr>
|
|
<td style="width: 60%;"><select class="form-control account_id select-search">${accountOptionsAssets}</select></td>
|
|
<td><input type="text" class="form-control debit text-end format-rupiah"></td>
|
|
<td><button class="btn btn-danger btn-remove">X</button></td>
|
|
</tr>
|
|
`);
|
|
});
|
|
|
|
|
|
// =========================
|
|
// HITUNG BAYAR
|
|
// =========================
|
|
$(document).on('input','.debit',function(){
|
|
hitungBayar();
|
|
});
|
|
|
|
function hitungBayar(){
|
|
|
|
let totalBayar = 0;
|
|
|
|
$('#tableBayar .debit').each(function(){
|
|
totalBayar += parseFloat($(this).val()) || 0;
|
|
});
|
|
|
|
let invoiceTotal = parseFloat($('#invoiceTotal').text().replace(/\./g,'')) || 0;
|
|
let balance = invoiceTotal - totalBayar;
|
|
|
|
$('#totalBayar').text(totalBayar.toLocaleString('id-ID'));
|
|
$('#balance').text(balance.toLocaleString('id-ID'));
|
|
|
|
if(balance < 0){
|
|
$('#balance').css('color','red');
|
|
}else if(balance === 0){
|
|
$('#balance').css('color','green');
|
|
}else{
|
|
$('#balance').css('color','orange');
|
|
}
|
|
}
|
|
|
|
|
|
// =========================
|
|
// PROSES BAYAR
|
|
// =========================
|
|
$('#btnProsesBayar').click(function(){
|
|
|
|
let id = $('#bayar_invoice_id').val();
|
|
let tanggal_bayar = $('#tanggal_bayar').val();
|
|
|
|
if(!tanggal_bayar){
|
|
Swal.fire('Warning','Tanggal bayar wajib diisi','warning');
|
|
return;
|
|
}
|
|
|
|
let detail = [];
|
|
let totalBayar = 0;
|
|
|
|
$('#tableBayar tbody tr').each(function(){
|
|
|
|
let account_id = $(this).find('.account_id').val();
|
|
let debit = parseFloat($(this).find('.debit').val()) || 0;
|
|
|
|
if(account_id && debit > 0){
|
|
detail.push({ account_id, amount: debit });
|
|
totalBayar += debit;
|
|
}
|
|
});
|
|
|
|
if(detail.length === 0){
|
|
Swal.fire('Warning','Isi minimal 1 pembayaran','warning');
|
|
return;
|
|
}
|
|
|
|
let invoiceTotal = parseFloat($('#invoiceTotal').text().replace(/\./g,'')) || 0;
|
|
|
|
if(totalBayar > invoiceTotal){
|
|
Swal.fire('Error','Pembayaran melebihi total invoice','error');
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
title:'Memproses...',
|
|
allowOutsideClick:false,
|
|
didOpen:()=>Swal.showLoading()
|
|
});
|
|
|
|
$.post("<?= base_url('invoices/bayar'); ?>", {
|
|
invoice_id: id,
|
|
tanggal_bayar,
|
|
detail
|
|
}, function(res){
|
|
|
|
if(res.status){
|
|
Swal.fire('Success','Pembayaran sukses','success');
|
|
$('#modalBayar').modal('hide');
|
|
table.ajax.reload(null,false);
|
|
}else{
|
|
Swal.fire('Error', res.message || 'Gagal', 'error');
|
|
}
|
|
|
|
}, 'json');
|
|
});
|
|
|
|
|
|
// =========================
|
|
// POSTING
|
|
// =========================
|
|
$(document).on('click','.btn-posting',function(){
|
|
|
|
let id = $(this).data('id');
|
|
|
|
Swal.fire({
|
|
title:'Posting Invoice?',
|
|
text:'Akan masuk ke piutang',
|
|
icon:'warning',
|
|
showCancelButton:true
|
|
}).then(result=>{
|
|
|
|
if(result.isConfirmed){
|
|
|
|
Swal.fire({
|
|
title:'Processing...',
|
|
allowOutsideClick:false,
|
|
didOpen:()=>Swal.showLoading()
|
|
});
|
|
|
|
$.post("<?= base_url('invoices/posting'); ?>",{invoice_id:id},function(){
|
|
Swal.fire('Success','Berhasil diposting','success');
|
|
table.ajax.reload(null,false);
|
|
},'json');
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
// =========================
|
|
// DELETE
|
|
// =========================
|
|
$(document).on('click', '.btn-delete', function () {
|
|
|
|
let id = $(this).data('id');
|
|
|
|
Swal.fire({
|
|
title: 'Hapus Invoice?',
|
|
text: 'Data tidak bisa dikembalikan',
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#dc3545',
|
|
confirmButtonText: 'Ya, Hapus',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
|
|
if (result.isConfirmed) {
|
|
|
|
Swal.fire({
|
|
title: 'Menghapus...',
|
|
allowOutsideClick: false,
|
|
didOpen: () => Swal.showLoading()
|
|
});
|
|
|
|
$.ajax({
|
|
url: "<?= base_url('invoices/delete/'); ?>" + id,
|
|
type: "GET",
|
|
dataType: "json"
|
|
})
|
|
.done(function (res) {
|
|
|
|
if (res.status) {
|
|
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil',
|
|
text: 'Invoice berhasil dihapus'
|
|
});
|
|
|
|
// reload datatable
|
|
if (typeof table !== 'undefined') {
|
|
table.ajax.reload(null, false);
|
|
}
|
|
|
|
} else {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Gagal',
|
|
text: res.message || 'Tidak bisa dihapus'
|
|
});
|
|
|
|
}
|
|
|
|
})
|
|
.fail(function () {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Terjadi kesalahan koneksi'
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
});
|
|
});
|
|
|
|
});
|
|
</script>
|
|
|
|
|
|
|