(function ($) { "use strict"; var C = window.FIXED_ASSET_PAGE || {}, B = C.base || "/", P = C.permissions || {}, files = [], table, currentAsset = null, warehouseUnitCost = 0; function esc(v) { return $("
") .text(v == null ? "" : v) .html(); } function rp(v) { return ( "Rp " + Number(v || 0).toLocaleString("id-ID", { minimumFractionDigits: 2, maximumFractionDigits: 2, }) ); } function q(v) { return Number(v || 0).toLocaleString("id-ID", { maximumFractionDigits: 4 }); } function fd(obj) { var f = new FormData(); Object.keys(obj || {}).forEach(function (k) { f.append(k, obj[k] == null ? "" : obj[k]); }); if (window.APP_CSRF) f.append(APP_CSRF.name, APP_CSRF.value); return f; } function request(url, opt) { opt = opt || {}; if ( opt.body instanceof FormData && window.APP_CSRF && !opt.body.has(APP_CSRF.name) ) opt.body.append(APP_CSRF.name, APP_CSRF.value); opt.headers = Object.assign( { Accept: "application/json", "X-Requested-With": "XMLHttpRequest" }, opt.headers || {}, ); return fetch(url, opt).then(function (r) { return r.text().then(function (t) { var x; try { x = JSON.parse(t); } catch (e) { throw Error("Server tidak mengirim JSON yang valid."); } if (!r.ok || x.status === false) throw Error(x.message || "Proses gagal."); return x; }); }); } function toast(m, i) { return AppAlert.toast(m, i || "success"); } function fail(e) { toast(e.message || String(e), "error"); } function reload() { if (table) table.ajax.reload(null, false); } function status(v) { var label = { draft: "DRAFT", submitted: "MENUNGGU APPROVAL", approved: "SIAP KAPITALISASI", capitalized: "TERKAPITALISASI", rejected: "DITOLAK", active: "AKTIF", fully_depreciated: "TERSUSUT PENUH", disposed: "DILEPAS", lost: "HILANG", damaged: "RUSAK", }; return ( '' + esc(label[v] || String(v || "-").toUpperCase()) + "" ); } function initTable() { table = $("#assetTable").DataTable({ processing: true, serverSide: true, responsive: true, searching: false, pageLength: 10, order: [], ajax: { url: B + "fixedassets/data", data: function (d) { d.search = { value: $("#assetSearch").val() }; d.category_id = $("#filterCategory").val(); d.workflow_status = $("#filterWorkflow").val(); d.lifecycle_status = $("#filterLifecycle").val(); }, }, columns: [ { data: null, render: function (_, t, r) { return ( "" + esc(r.kode_asset) + "
" + esc(r.nama_asset) + "" ); }, }, { data: null, render: function (_, t, r) { return ( esc(r.category_name || "-") + "
" + esc(r.location_name || "-") + "" ); }, }, { data: "source_type", render: function (v, t, r) { return ( esc(v === "warehouse" ? "Gudang" : "Input langsung") + (r.barcode ? "
" + esc(r.barcode) + "" : "") ); }, }, { data: null, render: function (_, t, r) { return ( status(r.workflow_status) + "
" + status(r.lifecycle_status) ); }, }, { data: "nilai_perolehan", className: "text-end", render: function (v) { return rp(v); }, }, { data: "nilai_buku", className: "text-end", render: function (v) { return rp(v); }, }, { data: "id", orderable: false, render: function (id) { return ( '' ); }, }, ], language: { processing: "Memuat data…", emptyTable: "Belum ada aset.", info: "Menampilkan _START_–_END_ dari _TOTAL_", infoEmpty: "Tidak ada data", lengthMenu: "Tampilkan _MENU_", paginate: { previous: "‹", next: "›" }, }, }); var timer; $("#assetSearch").on("input", function () { clearTimeout(timer); timer = setTimeout(function () { table.ajax.reload(); }, 350); }); $("#filterCategory,#filterWorkflow,#filterLifecycle").on( "change", function () { table.ajax.reload(); }, ); } function initSelects() { if (!$.fn.select2) return; $("#inventoryLookup") .select2({ width: "100%", dropdownParent: $("#assetFormModal"), placeholder: "Cari barang/barcode gudang", ajax: { url: B + "fixedassets/lookup_inventory", delay: 300, data: function (p) { return { q: p.term || "", page: p.page || 1 }; }, processResults: function (r) { return { results: r.results || [], pagination: r.pagination || { more: false }, }; }, }, }) .on("select2:select", function (e) { var r = e.params.data.data || {}; $("[name=item_id]").val(r.item_id); $("[name=barcode_id]").val(r.barcode_id); $("[name=warehouse_id]").val(r.warehouse_id); $("[name=bin_id]").val(r.bin_id || ""); $("[name=nama_asset]").val(r.nama_barang); warehouseUnitCost = Number(r.ledger_unit_cost || 0); $("[name=qty]").val( q(r.tracking_type === "UNIT" ? 1 : r.available_qty), ); updateWarehouseValue(); $("#inventoryInfo").html( "" + esc(r.kode_detail) + " - " + esc(r.nama_barang) + "
Barcode " + esc(r.barcode) + (r.serial_number ? " · SN " + esc(r.serial_number) : "") + " · " + esc(r.warehouse_name) + " · tersedia " + q(r.available_qty) + " · biaya ledger per unit " + rp(warehouseUnitCost), ); }); $("#employeeLookup").select2({ width: "100%", dropdownParent: $("#assetFormModal"), allowClear: true, placeholder: "Cari karyawan", ajax: { url: B + "fixedassets/lookup_employees", delay: 300, data: function (p) { return { q: p.term || "", page: p.page || 1 }; }, processResults: function (r) { return { results: r.results || [], pagination: r.pagination || { more: false }, }; }, }, }); $("#journalLookup").select2({ width: "100%", dropdownParent: $("#assetFormModal"), placeholder: "Cari nomor jurnal", ajax: { url: B + "fixedassets/lookup_journals", delay: 300, data: function (p) { return { q: p.term || "" }; }, processResults: function (r) { return { results: r.results || [] }; }, }, }); } function resetForm() { var f = document.getElementById("assetForm"); f.reset(); warehouseUnitCost = 0; files = []; renderFiles(); f.elements.idempotency_key.value = "AST-" + Date.now() + "-" + Math.random().toString(36).slice(2); f.elements.tanggal_perolehan.value = new Date().toISOString().slice(0, 10); f.elements.capitalization_date.value = f.elements.tanggal_perolehan.value; $("#inventoryLookup,#employeeLookup,#journalLookup") .val(null) .trigger("change"); toggleSource(); toggleJournal(); } function updateWarehouseValue() { if ($("[name=source_type]:checked").val() !== "warehouse") return; var qty = Number( window.cleanNumber ? window.cleanNumber($("[name=qty]").val()) : $("[name=qty]").val(), ) || 0, value = warehouseUnitCost * qty; $("[name=nilai_perolehan]").val( window.formatNumber ? window.formatNumber(value.toFixed(2)) : value.toFixed(2), ); } function toggleSource() { var w = $("[name=source_type]:checked").val() === "warehouse", value = $("[name=nilai_perolehan]"); $(".warehouse-source").toggleClass("d-none", !w); $(".manual-source").toggleClass("d-none", w); value.prop("readonly", w); $("#acquisitionValueLabel").text( w ? "Nilai perolehan dari ledger" : "Nilai perolehan", ); if (w && warehouseUnitCost <= 0 && $("[name=barcode_id]").val()) { var qty = Number( window.cleanNumber ? window.cleanNumber($("[name=qty]").val()) : $("[name=qty]").val(), ) || 0, total = Number( window.cleanNumber ? window.cleanNumber(value.val()) : value.val(), ) || 0; warehouseUnitCost = qty > 0 ? total / qty : 0; } if (w) updateWarehouseValue(); $("[name=source_journal_mode]").val( w ? "post_journal" : $("[name=source_journal_mode]").val() || "post_journal", ); toggleJournal(); } function toggleJournal() { var mode = $("[name=source_journal_mode]").val(); $(".linked-journal").toggleClass("d-none", mode !== "linked_journal"); $(".credit-account").toggleClass("d-none", mode !== "post_journal"); } $(document).on("input", "[name=qty]", updateWarehouseValue); function renderFiles() { var add = $("#assetFiles .file-add").detach(); $("#assetFiles").empty(); files.forEach(function (f, i) { var tile = $('
'); if (f.type.indexOf("image/") === 0) { var img = $('Preview'); img.attr("src", URL.createObjectURL(f)); tile.append(img); } else tile.append( 'PDF', ); tile.append( $('').on( "click", function () { files.splice(i, 1); renderFiles(); }, ), ); $("#assetFiles").append(tile); }); $("#assetFiles").append(add); } function uploadFiles(id) { return files.reduce(function (chain, file) { return chain.then(function () { var f = new FormData(); f.append("entity_type", "asset"); f.append("entity_id", id); f.append("attachment", file); if (window.APP_CSRF) f.append(APP_CSRF.name, APP_CSRF.value); return request(B + "accountingattachments/upload", { method: "POST", body: f, }); }); }, Promise.resolve()); } function uploadEntity(type, id, file) { var f = new FormData(); f.append("entity_type", type); f.append("entity_id", id); f.append("attachment", file); return request(B + "accountingattachments/upload", { method: "POST", body: f, }); } function saveAsset(e) { e.preventDefault(); var form = e.currentTarget, button = $(form).find("[type=submit]").prop("disabled", true); request(B + "fixedassets/save", { method: "POST", body: new FormData(form), }) .then(function (r) { var id = r.result; return uploadFiles(id).then(function () { return r; }); }) .then(function (r) { bootstrap.Modal.getInstance( document.getElementById("assetFormModal"), ).hide(); toast(r.message); reload(); }) .catch(fail) .finally(function () { button.prop("disabled", false); }); } function attachments(list) { if (!list || !list.length) return '
Belum ada lampiran.
'; return ( '
' + list .map(function (f) { var isPdf = (f.mime_type || "").indexOf("pdf") >= 0; return ( '" ); }) .join("") + "
" ); } function detailHtml(a) { var ev = (a.events || []) .map(function (x) { return ( "
" + esc(x.event_no || x.event_type) + "
" + esc(x.event_type) + " · " + esc(x.event_date) + " · " + rp(x.amount) + "
" + esc(x.notes || "-") + (x.journal_no ? " · Jurnal " + esc(x.journal_no) : "") + "
" ); }) .join("") || 'Belum ada event.'; return ( '
' + esc(a.kode_asset) + " · " + esc(a.nama_asset) + '
Dokumen' + esc(a.document_no) + "Status
" + status(a.workflow_status) + " " + status(a.lifecycle_status) + "
Kategori" + esc(a.category_name || "-") + "Lokasi / PIC" + esc(a.location_name || "-") + " / " + esc(a.responsible_name || "-") + "Sumber" + esc(a.source_type) + (a.kode_detail ? " · " + esc(a.kode_detail) : "") + "Barcode / SN" + esc(a.barcode || "-") + " / " + esc(a.serial_number || "-") + "Perolehan" + rp(a.nilai_perolehan) + "Residu" + rp(a.nilai_residu) + "Akumulasi" + rp(a.akumulasi_penyusutan) + "Nilai buku" + rp(a.nilai_buku) + "Pembuat" + esc(a.creator_name || "-") + "Penyetuju" + esc(a.approver_name || "-") + '
Dokumen Pendukung
' + attachments(a.attachments) + '
Riwayat Mutasi & Jurnal
' + ev + '
Catatan

' + esc(a.keterangan || "-") + "

Jadwal Penyusutan

" + (a.schedule || []).length + " periode tercatat · " + (a.maintenance || []).length + " maintenance

" ); } function detailActions(a) { var out = ''; if (P.export) out += '"; if (P.update && a.workflow_status === "draft") out += ''; if (P.create && a.workflow_status === "draft") out += ''; if (P.approve && a.workflow_status === "submitted") out += ''; if (P.post && a.workflow_status === "approved") out += ''; if ( P.post && a.workflow_status === "capitalized" && ["active", "fully_depreciated"].indexOf(a.lifecycle_status) >= 0 ) out += ''; if (P.update && a.workflow_status === "capitalized") out += ''; return out; } function openDetail(id) { request(B + "fixedassets/detail/" + id) .then(function (r) { currentAsset = r.asset; $("#assetDetailBody").html(detailHtml(r.asset)); $("#assetDetailActions").html(detailActions(r.asset)); bootstrap.Modal.getOrCreateInstance( document.getElementById("assetDetailModal"), ).show(); }) .catch(fail); } function editAsset() { var a = currentAsset; if (!a) return; resetForm(); var f = document.getElementById("assetForm"), names = [ "id", "idempotency_key", "nama_asset", "tanggal_perolehan", "capitalization_date", "category_id", "lokasi_asset_id", "source_reference_no", "qty", "nilai_perolehan", "nilai_residu", "masa_manfaat", "depreciation_method", "asset_account_id", "accumulated_depreciation_account_id", "depreciation_expense_account_id", "source_journal_mode", "account_kredit_id", "source_journal_id", "item_id", "barcode_id", "warehouse_id", "bin_id", "keterangan", ]; names.forEach(function (n) { if (f.elements[n] && a[n] != null) $(f.elements[n]).val(a[n]); }); $('[name=source_type][value="' + a.source_type + '"]').prop( "checked", true, ); if (a.responsible_employee_id) $("#employeeLookup") .append( new Option( a.responsible_name || "Karyawan", a.responsible_employee_id, true, true, ), ) .trigger("change"); if (a.source_journal_id) $("#journalLookup") .append( new Option( a.source_journal_no || "Jurnal sumber", a.source_journal_id, true, true, ), ) .trigger("change"); if (a.barcode_id) $("#inventoryLookup") .append( new Option( (a.kode_detail || "Barang") + " - " + (a.barcode || ""), a.barcode_id, true, true, ), ) .trigger("change"); toggleSource(); toggleJournal(); bootstrap.Modal.getInstance( document.getElementById("assetDetailModal"), ).hide(); bootstrap.Modal.getOrCreateInstance( document.getElementById("assetFormModal"), ).show(); } function postAction(action, id, extra) { var labels = { submit: "Ajukan dokumen aset?", approve: "Setujui dokumen aset?", capitalize: "Kapitalisasi aset dan posting jurnal?", }; if (action === "reject") return AppAlert.prompt({ title: "Tolak dokumen aset", input: "textarea", inputLabel: "Alasan penolakan wajib diisi", inputValidator: function (v) { if (!v) return "Alasan wajib diisi."; }, }).then(function (x) { if (x.isConfirmed) doPost(action, id, { reason: x.value }); }); AppAlert.confirm({ title: labels[action] || "Lanjutkan proses?", text: "Tindakan akan dicatat pada audit trail.", }).then(function (x) { if (x.isConfirmed) doPost(action, id, extra || {}); }); } function doPost(action, id, obj) { obj = obj || {}; var uploads = obj._files || []; delete obj._files; request(B + "fixedassets/" + action + "/" + id, { method: "POST", body: fd(obj), }) .then(function (r) { if (!uploads.length) return r; return Promise.all( uploads.map(function (file) { return uploadEntity("asset_maintenance", r.result, file); }), ).then(function () { return r; }); }) .then(function (r) { toast(r.message); var modal = bootstrap.Modal.getInstance( document.getElementById("assetDetailModal"), ); if (modal) modal.hide(); reload(); }) .catch(fail); } function process(kind, id) { var today = new Date().toISOString().slice(0, 10), html = "", title = ""; if (kind === "depreciate") { title = "Proses Penyusutan"; html = ''; } if (kind === "transfer") { title = "Transfer Lokasi"; html = ''; } if (kind === "maintenance") { title = "Catat Maintenance"; html = ''; } if (kind === "mutate") { title = "Mutasi Bernilai"; html = ''; } AppAlert.prompt({ title: title, html: html, preConfirm: function () { var o = { date: $("#sw-date").val() }; if (kind === "depreciate") o.through_date = o.date; if (kind === "transfer") { o.location_id = $("#sw-location").val(); o.notes = $("#sw-notes").val(); } if (kind === "maintenance") { o.vendor = $("#sw-vendor").val(); o.description = $("#sw-description").val(); o.cost = $("#sw-cost").val(); o.next_due_date = $("#sw-next").val(); o.idempotency_key = "MNT-" + Date.now(); o._files = Array.from(($("#sw-file")[0] || {}).files || []); } if (kind === "mutate") { o.type = $("#sw-type").val(); o.amount = $("#sw-amount").val(); o.account_id = $("#sw-account").val(); o.notes = $("#sw-notes").val(); } return o; }, }).then(function (x) { if (x.isConfirmed) doPost(kind, id, x.value); }); } function pdf(url) { $("#pdfModal iframe").attr("src", url); bootstrap.Modal.getOrCreateInstance( document.getElementById("pdfModal"), ).show(); } function master(type, row) { row = row || {}; var account = '' + C.accounts .map(function (a) { return ( '" ); }) .join(""); var h = '
'; if (type === "category") h += '
"; else h += '
"; h += '
'; $("#masterFields").html(h); if (type === "category") { $("[name=method]").val(row.depreciation_method || "straight_line"); $("[name=asset_account_id]").val(row.asset_account_id || ""); $("[name=accumulated_account_id]").val( row.accumulated_depreciation_account_id || "", ); $("[name=expense_account_id]").val( row.depreciation_expense_account_id || "", ); } bootstrap.Modal.getOrCreateInstance( document.getElementById("masterModal"), ).show(); } function saveMaster(e) { e.preventDefault(); var form = e.currentTarget, type = form.elements.master_type.value; request(B + "fixedassets/save_" + type, { method: "POST", body: new FormData(form), }) .then(function (r) { toast(r.message); location.reload(); }) .catch(fail); } function newOpname() { var opts = C.locations .filter(function (x) { return Number(x.is_active); }) .map(function (x) { return ( '" ); }) .join(""); AppAlert.prompt({ title: "Buat Asset Opname", html: '', preConfirm: function () { return { location_id: $("#op-location").val(), date: $("#op-date").val(), notes: $("#op-notes").val(), idempotency_key: "AOP-" + Date.now(), }; }, }).then(function (x) { if (x.isConfirmed) request(B + "fixedassets/opname_create", { method: "POST", body: fd(x.value), }) .then(function (r) { toast(r.message); location.reload(); }) .catch(fail); }); } function openOpname(id) { request(B + "fixedassets/opname_detail/" + id) .then(function (r) { var o = r.opname, lines = (o.lines || []) .map(function (l) { return ( '
' + esc(l.kode_asset) + "
" + esc(l.nama_asset) + '
' ); }) .join(""); $("#opnameBody").html( '
Dokumen' + esc(o.opname_no) + "Lokasi/Tanggal" + esc(o.location_name) + " / " + esc(o.opname_date) + "Status
" + status(o.status) + '
Hasil hilang/rusak tidak langsung membuat jurnal. Setelah opname diposting, proses mutasi Hilang/Rusak pada aset terkait agar nilai buku dan jurnal tetap terkontrol.
' + lines, ); $(".opname-line-grid").each(function (i) { $(this).find(".actual-status").val(o.lines[i].actual_status); }); var a = ''; if (P.update && o.status === "draft") a += ''; if (P.create && o.status === "draft") a += ''; if (P.approve && o.status === "submitted") a += ''; if (P.post && o.status === "approved") a += ''; $("#opnameActions").html(a); bootstrap.Modal.getOrCreateInstance( document.getElementById("opnameModal"), ).show(); }) .catch(fail); } function reportUrl(kind) { var p = new URLSearchParams({ type: $("#reportType").val(), date_from: $("#reportFrom").val(), date_to: $("#reportTo").val(), }); return B + "fixedassets/" + kind + "?" + p.toString(); } function runReport() { request(reportUrl("report_data")) .then(function (r) { var data = r.data || []; if (!data.length) { $("#reportResult").html( '
Tidak ada data.
', ); return; } var keys = Object.keys(data[0]).filter(function (k) { return typeof data[0][k] !== "object"; }), h = '' + keys .map(function (k) { return ""; }) .join("") + ""; data.forEach(function (x) { h += "" + keys .map(function (k) { return ""; }) .join("") + ""; }); $("#reportResult").html(h + "
" + esc(k.replaceAll("_", " ")) + "
" + esc(x[k]) + "
"); }) .catch(fail); } $(function () { initTable(); initSelects(); $("#btnNewAsset").on("click", function () { resetForm(); bootstrap.Modal.getOrCreateInstance( document.getElementById("assetFormModal"), ).show(); }); $("[name=source_type]").on("change", toggleSource); $("[name=source_journal_mode]").on("change", toggleJournal); $("[name=category_id]").on("change", function () { var o = this.options[this.selectedIndex]; $("[name=masa_manfaat]").val(o.dataset.life || ""); $("[name=depreciation_method]").val(o.dataset.method || "straight_line"); $("[name=asset_account_id]").val(o.dataset.asset || ""); $("[name=accumulated_depreciation_account_id]").val( o.dataset.accum || "", ); $("[name=depreciation_expense_account_id]").val(o.dataset.expense || ""); }); $("#assetFileInput").on("change", function () { Array.from(this.files).forEach(function (f) { if (files.length < 10) files.push(f); }); this.value = ""; renderFiles(); }); $("#assetForm").on("submit", saveAsset); $(document) .on("click", ".btn-detail", function () { openDetail(this.dataset.id); }) .on("click", ".btn-pdf", function () { pdf(this.dataset.url); }) .on("click", ".preview-file", function () { pdf(this.dataset.url); }) .on("click", ".action-post", function () { postAction(this.dataset.action, this.dataset.id); }) .on("click", ".asset-process", function () { process(this.dataset.kind, this.dataset.id); }) .on("click", "[data-master]", function () { master(this.dataset.master); }) .on("click", ".edit-category", function () { master("category", JSON.parse(this.dataset.row)); }) .on("click", ".edit-location", function () { master("location", JSON.parse(this.dataset.row)); }) .on("click", ".btn-opname", function () { openOpname(this.dataset.id); }); $("#masterForm").on("submit", saveMaster); $("#btnNewOpname").on("click", newOpname); $("#btnRunReport").on("click", runReport); $("#btnReportPdf").on("click", function () { pdf(reportUrl("report_pdf")); }); $("#btnReportExcel").on("click", function () { location.href = reportUrl("report_excel"); }); $(document) .on("click", ".save-opname", function () { var id = this.dataset.id, lines = []; $(".opname-line-grid").each(function () { lines.push({ id: this.dataset.line, is_found: $(this).find(".found").prop("checked") ? 1 : 0, actual_location_id: $(this).find(".actual-location").val(), actual_status: $(this).find(".actual-status").val(), notes: $(this).find(".notes").val(), }); }); request(B + "fixedassets/opname_save/" + id, { method: "POST", body: fd({ lines: JSON.stringify(lines) }), }) .then(function (r) { toast(r.message); openOpname(id); }) .catch(fail); }) .on("click", ".state-opname", function () { var id = this.dataset.id, action = this.dataset.action; AppAlert.confirm({ title: "Proses " + action + " opname?", text: "Status dan audit trail akan diperbarui.", }).then(function (x) { if (x.isConfirmed) request(B + "fixedassets/opname_state/" + id, { method: "POST", body: fd({ action: action }), }) .then(function (r) { toast(r.message); location.reload(); }) .catch(fail); }); }); }); var currentOpnameId = 0, assetScanner = null; var assetSwalLabels = { "sw-date": "Tanggal proses", "sw-location": "Lokasi tujuan", "sw-notes": "Alasan / keterangan", "sw-vendor": "Vendor maintenance", "sw-description": "Pekerjaan maintenance", "sw-cost": "Biaya maintenance", "sw-next": "Jadwal maintenance berikutnya", "sw-file": "Bukti maintenance", "sw-type": "Jenis mutasi", "sw-amount": "Nilai transaksi / hasil pelepasan", "sw-account": "Akun lawan", "op-location": "Lokasi yang akan diperiksa", "op-date": "Tanggal asset opname", "op-notes": "Ruang lingkup / catatan", "pic-select": "Penanggung jawab baru", "pic-date": "Tanggal efektif", "pic-notes": "Alasan pergantian", "rev-date": "Tanggal reversal", "rev-reason": "Alasan reversal", }; function styleAssetSwal(root) { Object.keys(assetSwalLabels).forEach(function (id) { var input = (root || document).querySelector("#" + id); if ( !input || (input.previousElementSibling && input.previousElementSibling.classList.contains("asset-swal-label")) ) return; var label = document.createElement("label"); label.className = "asset-swal-label"; label.htmlFor = id; label.textContent = assetSwalLabels[id]; input.parentNode.insertBefore(label, input); }); } new MutationObserver(function (records) { records.forEach(function (record) { Array.from(record.addedNodes || []).forEach(function (node) { if (node.nodeType === 1) styleAssetSwal(node); }); }); }).observe(document.body, { childList: true, subtree: true }); var baseDetailActions = detailActions; detailActions = function (a) { var out = baseDetailActions(a); if ( P.update && a.workflow_status === "capitalized" && ["active", "fully_depreciated"].indexOf(a.lifecycle_status) >= 0 ) out += ''; var latest = (a.events || [])[0]; if ( P.post && latest && latest.event_type !== "acquisition" && latest.event_type !== "reversal" ) out += ''; return out; }; $(document).on("click", ".change-pic", function (e) { e.preventDefault(); e.stopImmediatePropagation(); var id = this.dataset.id, today = new Date().toISOString().slice(0, 10); AppAlert.prompt({ title: "Ganti Penanggung Jawab", html: '', didOpen: function () { $("#pic-select").select2({ dropdownParent: $(".swal2-container"), placeholder: "Cari karyawan", ajax: { url: B + "fixedassets/lookup_employees", delay: 250, data: function (p) { return { q: p.term || "", page: p.page || 1 }; }, processResults: function (r) { return { results: r.results || [], pagination: r.pagination || { more: false }, }; }, }, }); }, preConfirm: function () { return { employee_id: $("#pic-select").val(), date: $("#pic-date").val(), notes: $("#pic-notes").val(), }; }, }).then(function (x) { if (x.isConfirmed) doPost("responsibility", id, x.value); }); }); $(document).on("click", ".reverse-event", function (e) { e.preventDefault(); e.stopImmediatePropagation(); var id = this.dataset.id, today = new Date().toISOString().slice(0, 10); AppAlert.prompt({ title: "Reversal Event Aset", html: '', preConfirm: function () { var reason = $("#rev-reason").val(); if (!reason) { Swal.showValidationMessage("Alasan reversal wajib diisi."); return false; } return { date: $("#rev-date").val(), reason: reason }; }, }).then(function (x) { if (x.isConfirmed) doPost("reverse", id, x.value); }); }); $(document).on("click", ".btn-opname", function () { currentOpnameId = this.dataset.id || 0; }); $("#opnameModal") .on("shown.bs.modal", function () { if (!currentOpnameId) return; request(B + "fixedassets/opname_detail/" + currentOpnameId) .then(function (r) { var o = r.opname, box = $( '
Pindai & Bukti Asset Opname
', ); if (o.status === "draft") box.append( '
', ); box.append(attachments(o.attachments)); if (o.status === "draft" && P.create) box.append( '', ); $("#opnameProof").remove(); $("#opnameBody").append(box); }) .catch(fail); }) .on("hidden.bs.modal", function () { if (assetScanner && assetScanner.clear) assetScanner.clear().catch(function () {}); assetScanner = null; }); function applyAssetScan(raw) { var code = decodeURIComponent( String(raw || "") .trim() .split("/") .filter(Boolean) .pop() || "", ).replace(/^ASSET:/i, ""), found = false; $(".opname-line-grid").each(function () { var label = $(this).find("b").text().trim(); if (label.indexOf(code) === 0) { $(this).find(".found").prop("checked", true); this.scrollIntoView({ behavior: "smooth", block: "center" }); $(this).addClass("approval-focus"); found = true; return false; } }); toast( found ? "Aset " + code + " ditandai ditemukan." : "Kode aset tidak ada pada dokumen opname.", found ? "success" : "warning", ); } $(document) .on("click", ".apply-asset-scan", function () { applyAssetScan($("#assetScanValue").val()); }) .on("keydown", "#assetScanValue", function (e) { if (e.key === "Enter") { e.preventDefault(); applyAssetScan(this.value); } }) .on("click", ".start-asset-camera", function () { if (typeof Html5QrcodeScanner === "undefined") { toast( "Library kamera QR belum tersedia. Gunakan scanner atau input kode.", "warning", ); return; } $("#assetQrReader").removeClass("d-none"); if (assetScanner) return; assetScanner = new Html5QrcodeScanner( "assetQrReader", { fps: 10, qrbox: { width: 220, height: 220 } }, false, ); assetScanner.render( function (text) { $("#assetScanValue").val(text); applyAssetScan(text); }, function () {}, ); }); $(document).on("change", ".opname-upload", function () { var input = this, id = currentOpnameId, list = Array.from(input.files || []); list .reduce(function (chain, file) { return chain.then(function () { return uploadEntity("asset_opname", id, file); }); }, Promise.resolve()) .then(function () { toast("Bukti opname berhasil diunggah."); input.value = ""; $("#opnameModal").trigger("shown.bs.modal"); }) .catch(fail); }); $(document).on("click", '.state-opname[data-action="reject"]', function (e) { e.preventDefault(); e.stopImmediatePropagation(); var id = this.dataset.id; AppAlert.prompt({ title: "Tolak Asset Opname", input: "textarea", inputLabel: "Alasan penolakan wajib diisi", inputValidator: function (v) { if (!v) return "Alasan wajib diisi."; }, }).then(function (x) { if (x.isConfirmed) request(B + "fixedassets/opname_state/" + id, { method: "POST", body: fd({ action: "reject", reason: x.value }), }) .then(function (r) { toast(r.message); location.reload(); }) .catch(fail); }); }); $(document).on("click", ".edit-asset", editAsset); })(jQuery);