Update besar apk finance

This commit is contained in:
Wian Drs
2026-09-11 16:03:00 +07:00
parent d42483b350
commit 4ef15c22ae
897 changed files with 98056 additions and 15979 deletions
+65 -259
View File
@@ -1,261 +1,67 @@
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<?php
$CI=&get_instance();
$routeClass=strtolower((string)$CI->router->fetch_class());
$routeMethod=strtolower((string)$CI->router->fetch_method());
if(!isset($active_menu)||$active_menu===''){
$routeMenus=array(
'attendancmonthly'=>'attendance_monthly',
'attendancemonthly'=>'attendance_monthly',
'attendancemonitoring'=>'attendance_monitoring',
'generateschedule'=>'generate_schedule',
'accountingperiods'=>'accounting_periods',
'inventoryprofessional'=>$routeMethod==='operations'?'inventory_operations':($routeMethod==='locations'?'inventory_locations':($routeMethod==='reports'?'inventory_reports':'inventory_overview')),
'professionalreports'=>'professional_reports',
'hrpayroll'=>'hr_payroll',
'fixedassets'=>'fixed_assets',
'kodebarang'=>'kode_barang',
'lokasiasset'=>'lokasiasset',
'teknisi'=>'peralatan_teknisi'
);
$active_menu=isset($routeMenus[$routeClass])?$routeMenus[$routeClass]:$routeClass;
if($routeClass==='invoices')$active_menu='sales_invoice';
if($routeClass==='items'&&$routeMethod==='draft_items')$active_menu='draft_items';
if($routeClass==='items'&&$routeMethod==='item_barcodes_history')$active_menu='item_historys';
}
$CI->config->load('ui_assets',true);
$uiAssets=$CI->config->item('ui_assets');
$dataPages=isset($uiAssets['ui_data_pages'])?$uiAssets['ui_data_pages']:array();
$selectPages=isset($uiAssets['ui_select_pages'])?$uiAssets['ui_select_pages']:array();
?></main></section></div>
<nav class="mobile-action-bar d-lg-none" aria-label="Aksi utama"><a href="<?=base_url()?>"><i class="bi bi-house"></i><span>Home</span></a><button data-bs-toggle="modal" data-bs-target="#quickActions"><i class="bi bi-lightning"></i><span>Aksi</span></button><a href="<?=base_url('inventoryprofessional')?>"><i class="bi bi-qr-code-scan"></i><span>Scan</span></a><button data-bs-toggle="offcanvas" data-bs-target="#mobileMenu"><i class="bi bi-grid"></i><span>Menu</span></button></nav>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" onerror="this.onerror=null;this.src='<?=base_url('assets/vendor/bootstrap.bundle.min.js')?>'"></script>
<?php if(in_array($active_menu,array('inventory_professional','inventory_overview','item_historys','camera_qr','fixed_assets'),true)):?><script src="https://unpkg.com/html5-qrcode"></script><?php endif?>
<script>window.APP_BASE_URL=<?=json_encode(base_url())?>;window.APP_CSRF={name:<?=json_encode($this->security->get_csrf_token_name())?>,value:<?=json_encode($this->security->get_csrf_hash())?>};</script><script src="<?=base_url('assets/js/app-ui.min.js').'?v='.filemtime(FCPATH.'assets/js/app-ui.min.js')?>" defer></script><script src="<?=base_url('assets/js/app-network.js').'?v='.filemtime(FCPATH.'assets/js/app-network.js')?>" defer></script>
<script>
// =====================================================
// 🔥 FORMAT NUMBER
// contoh:
// 1000 => 1,000
// 1000.5 => 1,000.5
// 1000.55 => 1,000.55
// =====================================================
function formatNumber(value){
if(value === null || value === undefined){
return '';
}
value = value.toString();
// hanya angka dan titik
value = value.replace(/[^0-9.]/g, '');
// hanya boleh 1 titik
let parts = value.split('.');
let integerPart = parts[0] || '';
let decimalPart = parts[1] || '';
// format ribuan pakai koma
integerPart = integerPart.replace(/,/g, '');
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// max 2 digit decimal
decimalPart = decimalPart.substring(0,2);
// kalau ada desimal
if(parts.length > 1 || value.endsWith('.')){
return integerPart + '.' + decimalPart;
}
return integerPart;
}
// =====================================================
// 🔥 CLEAN NUMBER
// hasil:
// 1,000.25 => 1000.25
// =====================================================
function cleanNumber(value){
if(!value) return '';
return value.toString().replace(/,/g, '');
}
// =====================================================
// 🔥 AUTO FORMAT INPUT
// =====================================================
$(document).on('input', '.format-rupiah', function(){
let cursorPos = this.selectionStart;
let beforeLength = $(this).val().length;
let formatted = formatNumber($(this).val());
$(this).val(formatted);
let afterLength = formatted.length;
cursorPos = cursorPos + (afterLength - beforeLength);
this.setSelectionRange(cursorPos, cursorPos);
});
// =====================================================
// 🔥 FORMAT SAAT BLUR
// =====================================================
$(document).on('blur', '.format-rupiah', function(){
$(this).val(
formatNumber($(this).val())
);
});
// =====================================================
// 🔥 AUTO CLEAN SAAT SUBMIT
// =====================================================
$(document).on('submit', 'form', function(){
$(this).find('.format-rupiah').each(function(){
$(this).val(
cleanNumber($(this).val())
);
});
});
// =====================================================
// 🔥 AUTO FORMAT VALUE AWAL
// =====================================================
$(document).ready(function(){
$('.format-rupiah').each(function(){
let val = $(this).val();
if(val !== ''){
$(this).val(
formatNumber(val)
);
}
});
});
// =====================================================
// 🔥 OVERRIDE jQuery .val()
// =====================================================
(function($){
const originalVal = $.fn.val;
$.fn.val = function(value){
// setter
if(typeof value !== 'undefined'){
if(this.hasClass('format-rupiah')){
return originalVal.call(
this,
formatNumber(value)
);
}
return originalVal.apply(this, arguments);
}
// getter
if(this.hasClass('format-rupiah')){
return cleanNumber(
originalVal.call(this)
);
}
return originalVal.call(this);
};
})(jQuery);
(function(){
if(!window.Swal)return;
var nativeFire=Swal.fire.bind(Swal);
window.AppAlert={
toast:function(message,icon){return nativeFire({toast:true,position:'top-end',showConfirmButton:false,timer:3200,timerProgressBar:true,icon:icon||'success',title:message});},
confirm:function(options){return nativeFire(Object.assign({icon:'warning',position:'center',showCancelButton:true,confirmButtonText:'Ya, lanjutkan',cancelButtonText:'Batal',reverseButtons:true,focusCancel:true},options||{}));},
prompt:function(options){return nativeFire(Object.assign({position:'center',showCancelButton:true,confirmButtonText:'Simpan',cancelButtonText:'Batal'},options||{}));}
};
// Menyeragamkan pemanggilan Swal lama: pesan biasa menjadi toast kanan atas,
// sedangkan konfirmasi dan form input tetap berupa dialog di tengah.
Swal.fire=function(first,text,icon){
var options=typeof first==='object'?Object.assign({},first):{title:first,text:text,icon:icon};
var requiresInteraction=!!(options.showCancelButton||options.showDenyButton||options.input||options.preConfirm||options.inputValidator);
if(requiresInteraction){options.position='center';return nativeFire(options);}
return nativeFire(Object.assign(options,{toast:true,position:'top-end',showConfirmButton:false,timer:options.timer||3200,timerProgressBar:options.timerProgressBar!==false}));
};
document.querySelectorAll('.modal-dialog').forEach(function(dialog){dialog.classList.add('modal-dialog-centered');});
document.querySelectorAll('[data-app-toast]').forEach(function(el){AppAlert.toast(el.dataset.message||'',el.dataset.icon||'success');});
var focusId=new URLSearchParams(location.search).get('focus');
if(focusId){
var focusDocument=function(){var escaped=window.CSS&&CSS.escape?CSS.escape(focusId):focusId.replace(/[^0-9]/g,'');var candidates=document.querySelectorAll('[data-id="'+escaped+'"],a[href$="/'+escaped+'"],form[action$="/'+escaped+'"]');for(var i=0;i<candidates.length;i++){var row=candidates[i].closest('tr,.card');if(row&&row.offsetParent!==null&&!row.classList.contains('approval-focus')){row.classList.add('approval-focus');row.scrollIntoView({behavior:'smooth',block:'center'});return true;}}return false;};
if(!focusDocument()){var observer=new MutationObserver(function(){if(focusDocument())observer.disconnect();});observer.observe(document.body,{childList:true,subtree:true});setTimeout(function(){observer.disconnect();},8000);}
}
document.addEventListener('submit',function(event){
var form=event.target.closest('form.js-confirm');if(!form||form.dataset.confirmed==='1')return;
event.preventDefault();
AppAlert.confirm({title:form.dataset.confirmTitle||'Konfirmasi tindakan',text:form.dataset.confirmText||'Apakah Anda yakin?',confirmButtonText:form.dataset.confirmButton||'Ya, lanjutkan'}).then(function(result){if(result.isConfirmed){form.dataset.confirmed='1';form.requestSubmit();}});
},true);
})();
</script>
<script>
function formatRupiah(num){
return 'Rp ' + new Intl.NumberFormat('id-ID').format(num || 0);
}
function formatTglIndo(dateString){
if(!dateString) return '-';
let date = new Date(dateString);
const bulan = [
"Januari","Februari","Maret","April","Mei","Juni",
"Juli","Agustus","September","Oktober","November","Desember"
];
let tgl = date.getDate();
let bln = bulan[date.getMonth()];
let thn = date.getFullYear();
return `${tgl} ${bln} ${thn}`;
}
</script>
<script>
$(function(){
function initSelectSearch(scope = document){
if (typeof $.fn.select2 === 'undefined') {
console.error('Select2 belum ke-load!');
return;
}
$(scope).find('select.select-search').each(function(){
let $this = $(this);
if ($this.hasClass("select2-hidden-accessible")) return;
let parent = $this.closest('.modal');
parent = parent.length ? parent : $(document.body);
$this.select2({
width: '100%',
placeholder: $this.attr('placeholder') || '-- Pilih --',
allowClear: true,
dropdownParent: parent
});
});
}
// ✅ INIT AWAL
initSelectSearch();
// $(window).on('load', function(){
// setTimeout(() => {
// initSelectSearch();
// }, 100);
// });
// ✅ AUTO INIT untuk dynamic content (modal, ajax, dll)
const observer = new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
mutation.addedNodes.forEach(function(node){
if (node.nodeType === 1){ // element
initSelectSearch(node);
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
</script>
</body>
</html>
<?php if(in_array($active_menu,$selectPages,true)):?><script>$(function(){$('select.select-search').each(function(){if(!$(this).hasClass('select2-hidden-accessible'))$(this).select2({width:'100%',dropdownParent:$(this).closest('.modal').length?$(this).closest('.modal'):$(document.body)});});});</script><?php endif?>
</body></html>