Files
2026-09-17 00:51:53 +07:00

76 lines
24 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$monthNames=array(1=>'Januari',2=>'Februari',3=>'Maret',4=>'April',5=>'Mei',6=>'Juni',7=>'Juli',8=>'Agustus',9=>'September',10=>'Oktober',11=>'November',12=>'Desember');
$accountTypes=array('asset'=>'Aset','liability'=>'Liabilitas','equity'=>'Ekuitas','revenue'=>'Pendapatan','expense'=>'Beban');
$periodLabel=function($period)use($monthNames){$parts=explode('-',(string)$period);return isset($parts[1])?($monthNames[(int)$parts[1]].' '.$parts[0]):$period;};
?>
<div class="container-fluid py-3 budget-page">
<header class="budget-hero">
<div><small>PERENCANAAN KEUANGAN</small><h4>Budgeting</h4><p>Kelola nominal tetap per akun dan pantau akumulasinya untuk periode yang dipilih.</p></div>
<?php if($can_create):?><button type="button" class="btn btn-primary add-budget"><i class="bi bi-plus-lg me-1"></i> Tambah Budget</button><?php endif?>
</header>
<?php if($this->session->flashdata('success')):?><div class="alert alert-success"><?=html_escape($this->session->flashdata('success'))?></div><?php endif?>
<?php if($this->session->flashdata('error')):?><div class="alert alert-danger"><?=html_escape($this->session->flashdata('error'))?></div><?php endif?>
<nav class="budget-section-nav" aria-label="Bagian Budgeting">
<a class="<?=$active_tab==='list'?'active':''?>" href="<?=base_url('budgets?tab=list')?>"><i class="bi bi-card-checklist"></i><span>Daftar Budget</span><b><?=count($entries)?></b></a>
<a class="<?=$active_tab==='accounts'?'active':''?>" href="<?=base_url('budgets?tab=accounts')?>"><i class="bi bi-pie-chart"></i><span>Budget Per Akun</span><b><?=$budget_account_count?></b></a>
</nav>
<?php if($reminders):?><section class="budget-reminder-alert"><div class="reminder-icon"><i class="bi bi-bell"></i></div><div class="flex-grow-1"><strong><?=count($reminders)?> pengingat pembayaran perlu diperhatikan</strong><div class="reminder-items"><?php foreach(array_slice($reminders,0,4)as$reminder):?><span class="<?=$reminder->reminder_state==='overdue'?'overdue':''?>"><?=html_escape($reminder->title)?> · tanggal <?=$reminder->reminder_day?></span><?php endforeach?><?php if(count($reminders)>4):?><span>+<?=count($reminders)-4?> lainnya</span><?php endif?></div></div></section><?php endif?>
<?php if($active_tab==='list'):?>
<section class="budget-card">
<div class="budget-card-head"><div><h5>Daftar Budget</h5><p>Setiap kebutuhan dibuat sebagai jadwal tersendiri. Beberapa jadwal boleh menggunakan akun yang sama dan semuanya dijumlahkan.</p></div><?php if($can_export):?><div class="btn-group"><button type="button" class="btn btn-outline-danger budget-pdf" data-title="Daftar Budget" data-url="<?=base_url('budgets/export_list/pdf?'.http_build_query(array('list_account_id'=>$list_account_id)))?>"><i class="bi bi-file-earmark-pdf me-1"></i>PDF</button><a class="btn btn-outline-success" href="<?=base_url('budgets/export_list/excel?'.http_build_query(array('list_account_id'=>$list_account_id)))?>"><i class="bi bi-file-earmark-excel me-1"></i>Excel</a></div><?php endif?></div>
<form class="budget-filter" method="get"><input type="hidden" name="tab" value="list"><div><label class="form-label">Filter Akun</label><select class="form-select" name="list_account_id"><option value="">Semua akun</option><?php foreach($accounts as$a):?><option value="<?=$a->id?>" <?=$list_account_id==$a->id?'selected':''?>><?=html_escape($a->kode_akun.' - '.$a->nama_akun)?></option><?php endforeach?></select></div><button class="btn btn-outline-primary"><i class="bi bi-funnel me-1"></i>Tampilkan</button><?php if($list_account_id):?><a href="<?=base_url('budgets?tab=list')?>" class="btn btn-light">Reset</a><?php endif?><div class="budget-filter-total"><span>Total Budget</span><strong>Rp <?=number_format($list_total_budget,2,',','.')?></strong></div></form>
<div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Budget / Akun</th><th>Pola</th><th>Mulai / Bulan</th><th class="text-end">Nominal Budget</th><th>Pengingat</th><th>Keterangan</th><th>Diperbarui</th><th>Aksi</th></tr></thead><tbody>
<?php foreach($entries as$entry):?><tr>
<td><strong><?=html_escape($entry->title)?></strong><small class="d-block text-muted"><?=html_escape($entry->kode_akun.' - '.$entry->nama_akun.' · '.($accountTypes[$entry->tipe]??ucfirst($entry->tipe)))?></small></td>
<td><?php if($entry->entry_type==='recurring'):?><span class="badge bg-primary-subtle text-primary">Berulang</span><small class="d-block text-muted mt-1">Ditambahkan setiap bulan</small><?php else:?><span class="badge bg-warning-subtle text-warning-emphasis">Satu Bulan</span><small class="d-block text-muted mt-1">Hanya bulan yang dipilih</small><?php endif?></td>
<td><?=html_escape($periodLabel($entry->period))?></td><td class="text-end fw-semibold">Rp <?=number_format($entry->amount,2,',','.')?></td>
<td><?php if(!(int)$entry->reminder_enabled):?><span class="text-muted">Tidak ada</span><?php else:?><strong><?=$entry->entry_type==='recurring'?'Setiap tanggal ':'Tanggal '?><?=$entry->reminder_day?></strong><?php $reminderLabels=array('completed'=>array('success','Selesai bulan ini'),'overdue'=>array('danger','Terlambat'),'due'=>array('danger','Jatuh tempo hari ini'),'upcoming'=>array('warning text-dark','Segera jatuh tempo'),'scheduled'=>array('secondary','Terjadwal'),'future'=>array('info text-dark','Belum berlaku'),'inactive_period'=>array('secondary','Bukan bulan berjalan'));$rl=$reminderLabels[$entry->reminder_state]??array('secondary','Terjadwal');?><small class="d-block mt-1"><span class="badge bg-<?=$rl[0]?>"><?=$rl[1]?></span></small><?php endif?></td>
<td><?=html_escape($entry->notes?:'-')?></td><td><small><?=html_escape($entry->updated_at?:$entry->created_at)?></small><small class="d-block text-muted"><?=html_escape($entry->updater_name?:$entry->creator_name?:'-')?></small></td>
<td class="text-nowrap"><?php if($can_update&&in_array($entry->reminder_state,array('scheduled','upcoming','due','overdue'),true)):?><button type="button" class="btn btn-sm btn-outline-success complete-reminder" data-id="<?=$entry->id?>" data-label="<?=html_escape($entry->title)?>"><i class="bi bi-check2"></i> Selesai Bulan Ini</button><?php endif?> <?php if($can_update):?><button type="button" class="btn btn-sm btn-outline-primary edit-budget" data-id="<?=$entry->id?>" data-title="<?=html_escape($entry->title)?>" data-account="<?=$entry->account_id?>" data-period="<?=html_escape($entry->period)?>" data-type="<?=html_escape($entry->entry_type)?>" data-amount="<?=html_escape($entry->amount)?>" data-reminder="<?=(int)$entry->reminder_enabled?>" data-day="<?=html_escape($entry->reminder_day)?>" data-notes="<?=html_escape($entry->notes)?>"><i class="bi bi-pencil"></i> Edit</button><?php endif?> <?php if($can_delete):?><button type="button" class="btn btn-sm btn-outline-danger delete-budget" data-id="<?=$entry->id?>" data-label="<?=html_escape($entry->title)?>"><i class="bi bi-x-circle"></i> Nonaktifkan</button><?php endif?></td>
</tr><?php endforeach?>
<?php if(!$entries):?><tr><td colspan="8" class="empty-state"><i class="bi bi-wallet2"></i><strong>Belum ada budget</strong><span>Tambahkan budget tetap untuk akun yang diperlukan.</span></td></tr><?php endif?>
</tbody></table></div>
</section>
<?php else:?>
<section class="budget-card">
<div class="budget-card-head"><div><h5>Budget Per Akun</h5><p>Hanya akun yang mempunyai budget yang ditampilkan. Budget berulang dihitung otomatis untuk setiap bulan dalam rentang.</p></div><?php if($can_export):?><div class="btn-group"><button type="button" class="btn btn-outline-danger budget-pdf" data-title="Budget Per Akun" data-url="<?=base_url('budgets/export_accounts/pdf?'.http_build_query($filters))?>"><i class="bi bi-file-earmark-pdf me-1"></i>PDF</button><a class="btn btn-outline-success" href="<?=base_url('budgets/export_accounts/excel?'.http_build_query($filters))?>"><i class="bi bi-file-earmark-excel me-1"></i>Excel</a></div><?php endif?></div>
<form class="budget-filter budget-period-filter" method="get"><input type="hidden" name="tab" value="accounts"><div class="budget-month-field"><label class="form-label">Dari Bulan</label><input type="month" class="form-control" name="from" value="<?=html_escape($filters['from'])?>" required></div><div class="budget-month-field"><label class="form-label">Sampai Bulan</label><input type="month" class="form-control" name="to" value="<?=html_escape($filters['to'])?>" required></div><div class="budget-account-field"><label class="form-label">Akun</label><select class="form-select" name="account_id"><option value="">Semua akun yang memiliki budget</option><?php foreach($budget_accounts as$a):?><option value="<?=$a->id?>" <?=$filters['account_id']==$a->id?'selected':''?>><?=html_escape($a->kode_akun.' - '.$a->nama_akun)?></option><?php endforeach?></select></div><button class="btn btn-primary"><i class="bi bi-search me-1"></i>Tampilkan</button><div class="budget-filter-total"><span>Total Budget</span><strong>Rp <?=number_format($account_total_budget,2,',','.')?></strong></div></form>
<div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Akun</th><th class="text-end">Akumulasi Budget</th><th class="text-end">Realisasi</th><th class="text-end">Komitmen PO</th><th class="text-end">Total Pemakaian</th><th class="text-end">Sisa</th><th class="text-end">%</th><th>Kondisi</th></tr></thead><tbody>
<?php foreach($report_rows as$row):?><tr><td><strong><?=html_escape($row['kode_akun'].' - '.$row['nama_akun'])?></strong><small class="d-block text-muted"><?=html_escape($accountTypes[$row['tipe']]??ucfirst($row['tipe']))?></small></td><?php foreach(array('budget','actual','commitment','usage','remaining')as$key):?><td class="text-end <?=$key==='budget'?'fw-semibold':''?>">Rp <?=number_format($row[$key],2,',','.')?></td><?php endforeach?><td class="text-end"><?=number_format($row['percentage'],2,',','.')?>%</td><td><span class="badge bg-<?=$row['indicator']==='over'?'danger':($row['indicator']==='warning'?'warning text-dark':'success')?>"><?=$row['indicator']==='over'?'Melebihi':($row['indicator']==='warning'?'Mendekati Batas':'Aman')?></span></td></tr><?php endforeach?>
<?php if(!$report_rows):?><tr><td colspan="8" class="empty-state"><i class="bi bi-bar-chart"></i><strong>Belum ada budget pada periode ini</strong><span>Buat budget berulang atau budget khusus bulan terlebih dahulu.</span></td></tr><?php endif?>
</tbody></table></div>
</section>
<?php endif?>
</div>
<div class="modal fade" id="budgetModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false"><div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"><form class="modal-content" id="budgetForm" action="<?=base_url('budgets/save_entry')?>" method="post"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="id" id="budgetId"><div class="modal-header"><div><small class="text-muted">BUDGET PER AKUN</small><h5 class="modal-title">Tambah Budget</h5></div><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body">
<label class="form-label">Nama Budget <span class="text-danger">*</span></label><input type="text" class="form-control mb-3" name="title" id="budgetTitle" maxlength="150" placeholder="Contoh: Pembayaran Listrik Kantor 1" required>
<label class="form-label">Akun <span class="text-danger">*</span></label><select class="form-select mb-3" name="account_id" id="budgetAccount" required><option value="">Pilih akun</option><?php foreach($accounts as$a):?><option value="<?=$a->id?>"><?=html_escape($a->kode_akun.' - '.$a->nama_akun.' · '.($accountTypes[$a->tipe]??ucfirst($a->tipe)))?></option><?php endforeach?></select>
<label class="form-label">Pola Budget <span class="text-danger">*</span></label><div class="budget-type-options mb-3"><label><input type="radio" name="entry_type" value="recurring" checked><span><b>Budget Berulang</b><small>Nominal ditambahkan setiap bulan mulai dari bulan yang dipilih.</small></span></label><label><input type="radio" name="entry_type" value="override"><span><b>Budget Satu Bulan</b><small>Nominal hanya ditambahkan pada satu bulan yang dipilih.</small></span></label></div>
<label class="form-label" id="periodLabel">Berlaku Mulai Bulan <span class="text-danger">*</span></label><input type="month" class="form-control mb-3" name="period" id="budgetPeriod" value="<?=date('Y-m')?>" required>
<label class="form-label">Nominal Budget per Bulan <span class="text-danger">*</span></label><div class="input-group mb-3"><span class="input-group-text">Rp</span><input type="text" class="form-control format-rupiah" inputmode="decimal" name="amount" id="budgetAmount" placeholder="0,00" required></div>
<div class="budget-reminder-option mb-3"><div class="form-check form-switch"><input class="form-check-input" type="checkbox" name="reminder_enabled" value="1" id="budgetReminder"><label class="form-check-label fw-semibold" for="budgetReminder">Aktifkan pengingat pembayaran bulanan</label></div><small class="text-muted">Pengingat akan muncul tujuh hari sebelum tanggal pembayaran.</small><div class="mt-3 d-none" id="reminderDayWrap"><label class="form-label">Tanggal Pembayaran <span class="text-danger">*</span></label><input type="number" class="form-control" name="reminder_day" id="budgetReminderDay" min="1" max="31" inputmode="numeric" placeholder="1–31"><small class="text-muted">Jika bulan lebih pendek, tanggal otomatis memakai hari terakhir bulan tersebut.</small></div></div>
<label class="form-label">Keterangan</label><textarea class="form-control" name="notes" id="budgetNotes" rows="3" placeholder="Contoh: Biaya sewa kantor tetap"></textarea>
</div><div class="modal-footer"><button type="button" class="btn btn-light" data-bs-dismiss="modal">Batal</button><button class="btn btn-primary" id="saveBudget"><i class="bi bi-check2-circle me-1"></i>Simpan Budget</button></div></form></div></div>
<div class="modal fade" id="budgetPdfModal" tabindex="-1"><div class="modal-dialog modal-xl modal-dialog-centered"><div class="modal-content budget-pdf-content"><div class="modal-header"><h5 class="modal-title">Pratinjau PDF Budget</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body p-0"><iframe title="Pratinjau PDF Budget"></iframe></div></div></div></div>
<style>
.budget-page{--budget-blue:#176bff}.budget-hero{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:18px}.budget-hero small{font-size:.7rem;letter-spacing:.15em;color:#758199}.budget-hero h4{margin:2px 0 3px}.budget-hero p,.budget-card-head p{margin:0;color:#69758a}.budget-section-nav{display:grid;grid-template-columns:repeat(2,minmax(180px,1fr));gap:8px;padding:8px;margin-bottom:16px;background:#fff;border:1px solid #e4e9f1;border-radius:14px}.budget-section-nav a{display:flex;align-items:center;justify-content:center;gap:9px;min-height:48px;padding:10px 14px;border-radius:9px;color:#526079;text-decoration:none;font-weight:600}.budget-section-nav a:hover{background:#f3f7ff;color:var(--budget-blue)}.budget-section-nav a.active{background:var(--budget-blue);color:#fff;box-shadow:0 5px 14px rgba(23,107,255,.2)}.budget-section-nav b{min-width:22px;padding:2px 6px;border-radius:20px;background:rgba(255,255,255,.22);font-size:.72rem;text-align:center}.budget-section-nav a:not(.active) b{background:#eef2f8}.budget-card{overflow:hidden;background:#fff;border:1px solid #e4e9f1;border-radius:14px;box-shadow:0 6px 22px rgba(22,34,55,.05)}.budget-card-head{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:17px 18px;border-bottom:1px solid #e8ecf2}.budget-card-head h5{margin:0 0 3px}.budget-filter{display:flex;align-items:end;gap:10px;padding:14px 18px;background:#fafbfd;border-bottom:1px solid #e8ecf2;flex-wrap:wrap}.budget-filter:not(.budget-period-filter)>div:not(.budget-filter-total){min-width:min(360px,100%)}.budget-period-filter .budget-month-field{flex:0 0 180px;min-width:180px}.budget-period-filter .budget-account-field{flex:0 1 320px;min-width:240px;max-width:360px}.budget-card .table th{padding:12px 14px;background:#f6f8fb;color:#59657a;font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap}.budget-card .table td{padding:13px 14px}.empty-state{text-align:center!important;padding:54px 20px!important;color:#768196}.empty-state i,.empty-state strong,.empty-state span{display:block}.empty-state i{margin-bottom:8px;font-size:1.8rem}.empty-state strong{color:#344054}.budget-type-options{display:grid;gap:8px}.budget-type-options label{display:flex;gap:10px;padding:12px;border:1px solid #dfe5ee;border-radius:10px;cursor:pointer}.budget-type-options label:has(input:checked){border-color:var(--budget-blue);background:#f2f7ff}.budget-type-options input{margin-top:3px}.budget-type-options span,.budget-type-options small{display:block}.budget-type-options small{margin-top:2px;color:#6f7b8f;font-weight:400}@media(max-width:767.98px){.budget-hero{align-items:flex-start}.budget-section-nav{display:flex;overflow:auto}.budget-section-nav a{flex:1;white-space:nowrap}.budget-filter,.budget-period-filter{display:grid;grid-template-columns:1fr}.budget-filter>div,.budget-period-filter .budget-month-field,.budget-period-filter .budget-account-field{width:100%;min-width:0;max-width:none}.budget-card-head{align-items:flex-start}.budget-card .table td,.budget-card .table th{white-space:nowrap}.modal-dialog{margin:.5rem}}
.budget-reminder-alert{display:flex;align-items:flex-start;gap:12px;margin-bottom:16px;padding:14px 16px;border:1px solid #ffd89a;border-radius:13px;background:#fff8e8;color:#6c4a09}.reminder-icon{display:grid;place-items:center;width:38px;height:38px;flex:0 0 38px;border-radius:10px;background:#ffedc4;color:#e48300;font-size:1.1rem}.reminder-items{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}.reminder-items span{padding:4px 9px;border-radius:20px;background:#fff;border:1px solid #f2d79c;font-size:.78rem}.reminder-items span.overdue{border-color:#f2b8b8;background:#fff0f0;color:#b42318}.budget-reminder-option{padding:13px 14px;border:1px solid #dfe5ee;border-radius:10px;background:#fafbfd}
.budget-filter-total{display:flex;align-items:center;justify-content:flex-end;gap:12px;min-width:0;margin-left:auto;align-self:center;white-space:nowrap}.budget-filter-total span{color:#69758a;font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.budget-filter-total strong{color:#172b4d;font-size:1.05rem}.budget-pdf-content{height:min(90vh,900px)}.budget-pdf-content .modal-body{min-height:0}.budget-pdf-content iframe{width:100%;height:100%;border:0}.budget-card-head .btn-group{flex:0 0 auto}@media(max-width:575.98px){.budget-card-head{flex-direction:column}.budget-card-head .btn-group{width:100%}.budget-card-head .btn-group>*{flex:1}.budget-filter-total{width:100%;margin-left:0;justify-content:space-between}}
</style>
<script>
document.addEventListener('DOMContentLoaded',function(){
const modalEl=document.getElementById('budgetModal'),modal=modalEl?bootstrap.Modal.getOrCreateInstance(modalEl):null,form=document.getElementById('budgetForm'),money=n=>Number(n||0).toLocaleString('id-ID',{minimumFractionDigits:2,maximumFractionDigits:2});
function reset(){form.reset();document.getElementById('budgetId').value='';document.getElementById('budgetPeriod').value='<?=date('Y-m')?>';document.querySelector('#budgetModal .modal-title').textContent='Tambah Budget';updatePeriodLabel();updateReminder()}
function updatePeriodLabel(){const recurring=form.querySelector('[name="entry_type"]:checked')?.value==='recurring';document.getElementById('periodLabel').innerHTML=(recurring?'Berlaku Mulai Bulan':'Bulan Budget')+' <span class="text-danger">*</span>'}
function updateReminder(){const enabled=document.getElementById('budgetReminder').checked,wrap=document.getElementById('reminderDayWrap'),day=document.getElementById('budgetReminderDay');wrap.classList.toggle('d-none',!enabled);day.required=enabled;if(!enabled)day.value=''}
document.querySelectorAll('[name="entry_type"]').forEach(x=>x.addEventListener('change',updatePeriodLabel));
document.getElementById('budgetReminder')?.addEventListener('change',updateReminder);
document.querySelector('.add-budget')?.addEventListener('click',()=>{reset();modal.show()});
document.querySelectorAll('.edit-budget').forEach(button=>button.addEventListener('click',()=>{reset();document.getElementById('budgetId').value=button.dataset.id;document.getElementById('budgetTitle').value=button.dataset.title||'';document.getElementById('budgetAccount').value=button.dataset.account;document.getElementById('budgetPeriod').value=button.dataset.period;document.getElementById('budgetAmount').value=money(button.dataset.amount);document.getElementById('budgetNotes').value=button.dataset.notes||'';document.getElementById('budgetReminder').checked=button.dataset.reminder==='1';document.getElementById('budgetReminderDay').value=button.dataset.day||'';const type=form.querySelector('[name="entry_type"][value="'+button.dataset.type+'"]');if(type)type.checked=true;document.querySelector('#budgetModal .modal-title').textContent='Edit Budget';updatePeriodLabel();updateReminder();modal.show()}));
form?.addEventListener('submit',async function(event){event.preventDefault();const button=document.getElementById('saveBudget');button.disabled=true;try{const response=await fetch(form.action,{method:'POST',headers:{'X-Requested-With':'XMLHttpRequest'},body:new FormData(form)}),result=await response.json().catch(()=>({status:false,message:'Respons server tidak valid.'}));if(!response.ok||!result.status)throw Error(result.message||'Budget gagal disimpan.');modal.hide();if(window.AppAlert)AppAlert.toast(result.message,'success');setTimeout(()=>location.href='<?=base_url('budgets?tab=list')?>',500)}catch(error){if(window.AppAlert)AppAlert.toast(error.message,'error');else Swal.fire({icon:'error',title:'Gagal',text:error.message})}finally{button.disabled=false}});
document.querySelectorAll('.delete-budget').forEach(button=>button.addEventListener('click',async()=>{const ask=window.AppAlert?await AppAlert.confirm({title:'Nonaktifkan budget?',text:button.dataset.label+' tidak lagi dipakai dalam perhitungan.',confirmButtonText:'Ya, Nonaktifkan'}):await Swal.fire({title:'Nonaktifkan budget?',text:button.dataset.label,icon:'warning',showCancelButton:true});if(!ask.isConfirmed)return;try{const body=new FormData();body.append('<?=$this->security->get_csrf_token_name()?>','<?=$this->security->get_csrf_hash()?>');const response=await fetch('<?=base_url('budgets/delete_entry/')?>'+button.dataset.id,{method:'POST',headers:{'X-Requested-With':'XMLHttpRequest'},body:body}),result=await response.json().catch(()=>({status:false,message:'Respons server tidak valid.'}));if(!response.ok||!result.status)throw Error(result.message||'Budget gagal dinonaktifkan.');if(window.AppAlert)AppAlert.toast(result.message,'success');setTimeout(()=>location.reload(),500)}catch(error){if(window.AppAlert)AppAlert.toast(error.message,'error');else Swal.fire({icon:'error',title:'Gagal',text:error.message})}}));
document.querySelectorAll('.complete-reminder').forEach(button=>button.addEventListener('click',async()=>{const ask=window.AppAlert?await AppAlert.confirm({title:'Tandai pembayaran selesai?',text:button.dataset.label+' tidak akan muncul lagi sebagai pengingat pada bulan ini.',confirmButtonText:'Ya, Sudah Selesai'}):await Swal.fire({title:'Tandai pembayaran selesai?',text:button.dataset.label,icon:'question',showCancelButton:true});if(!ask.isConfirmed)return;try{const body=new FormData();body.append('<?=$this->security->get_csrf_token_name()?>','<?=$this->security->get_csrf_hash()?>');const response=await fetch('<?=base_url('budgets/complete_reminder/')?>'+button.dataset.id,{method:'POST',headers:{'X-Requested-With':'XMLHttpRequest'},body:body}),result=await response.json().catch(()=>({status:false,message:'Respons server tidak valid.'}));if(!response.ok||!result.status)throw Error(result.message||'Pengingat gagal diperbarui.');if(window.AppAlert)AppAlert.toast(result.message,'success');setTimeout(()=>location.reload(),500)}catch(error){if(window.AppAlert)AppAlert.toast(error.message,'error');else Swal.fire({icon:'error',title:'Gagal',text:error.message})}}));
document.querySelectorAll('.budget-pdf').forEach(button=>button.addEventListener('click',()=>{const pdfModal=document.getElementById('budgetPdfModal');pdfModal.querySelector('.modal-title').textContent=button.dataset.title||'Pratinjau PDF Budget';pdfModal.querySelector('iframe').src=button.dataset.url;bootstrap.Modal.getOrCreateInstance(pdfModal).show()}));document.getElementById('budgetPdfModal')?.addEventListener('hidden.bs.modal',function(){this.querySelector('iframe').src='about:blank'});
});
</script>