frappe.ui.form.on("Sales Invoice", { refresh(frm) { frm.clear_custom_buttons(); // Only on submitted invoices if (frm.doc.docstatus !== 1) return; if (!frm.doc.customer) return; // Already paid if (frm.doc.outstanding_amount <= 0) { frm.dashboard.add_indicator("Paid", "green"); return; } frm.dashboard.add_indicator("Unpaid", "red"); frm.add_custom_button("Run Payment", () => { run_payment_flow(frm); }, "Actions"); } }); function run_payment_flow(frm) { frm.disable_save(); frappe.call({ method: "ns_app.api.payments.check_autopay", args: { customer: frm.doc.customer }, callback(r) { if (!r.message) { frm.enable_save(); return; } if (r.message.autopay_enabled && r.message.autopay_id) { run_autopay(frm); } else { open_manual_payment_form(frm); } } }); } function run_autopay(frm) { frappe.confirm( `Run AutoPay for $${frm.doc.outstanding_amount}?`, () => { frappe.call({ method: "ns_app.api.payments.run_autopay_payment", args: { invoice: frm.doc.name }, callback(r) { frappe.msgprint("Payment successful"); frm.reload_doc(); } }); }, () => { frm.enable_save(); } ); } function open_manual_payment_form(frm) { const dialog = new frappe.ui.Dialog({ title: "Secure Payment", size: "large", fields: [ { fieldtype: "HTML", fieldname: "loader", options: `