frappe.provide("ns_app.customer"); // Preserve original quick entry const _make_quick_entry = frappe.ui.form.make_quick_entry; // Override frappe.ui.form.make_quick_entry = function (doctype, after_insert) { if (doctype === "Customer" && frappe.route_options) { console.log("NS App: Intercepted Customer Quick Entry"); ns_app.customer.open_quick_entry({ callback: after_insert, route_options: frappe.route_options || {} }); return; } return _make_quick_entry.apply(this, arguments); }; ns_app.customer.open_quick_entry = function (opts = {}) { console.log("NS App: Custom Customer Quick Entry OPENED"); const d = new frappe.ui.Dialog({ title: "New Customer", size: "large", fields: [ // ───────── CUSTOMER ───────── { fieldtype: "Section Break", label: "Customer" }, { fieldname: "customer_name", label: "Customer Name", fieldtype: "Data", reqd: 1, default: opts.route_options?.customer_name || "" }, { fieldname: "customer_type", label: "Customer Type", fieldtype: "Select", options: "Company\nIndividual", default: "Company", reqd: 1 }, { fieldname: "customer_group", label: "Customer Group", fieldtype: "Link", options: "Customer Group", default: "Commercial", reqd: 1 }, { fieldname: "custom_send_via", label: "Send Via", fieldtype: "Select", options: "mail\nemail\nfax" }, // ───────── CONTACT ───────── { fieldtype: "Section Break", label: "Primary Contact" }, { fieldname: "email_id", label: "Email", fieldtype: "Data", options: "Email" }, { fieldname: "mobile_no", label: "Mobile", fieldtype: "Data", reqd: 1 }, // ───────── ADDRESS ───────── { fieldtype: "Section Break", label: "Address" }, { fieldname: "address_line1", label: "Address Line 1", fieldtype: "Data", reqd: 1 }, { fieldname: "address_line2", label: "Address Line 2", fieldtype: "Data" }, { fieldname: "pincode", label: "ZIP Code", fieldtype: "Data", reqd: 1 }, { fieldname: "city", label: "City", fieldtype: "Data" }, { fieldname: "state", label: "State", fieldtype: "Data" }, { fieldname: "country", label: "Country", fieldtype: "Link", options: "Country", default: "United States" } ], primary_action_label: "Create Customer", primary_action(values) { console.log("NS App: Create Customer clicked", values); d.disable_primary_action(); frappe.call({ method: "ns_app.api.customer.create_customer_full", args: values, callback(r) { console.log("NS App: Customer created", r.message); d.hide(); frappe.show_alert({ message: "Customer created via NS App", indicator: "green" }); if (opts.callback && r.message) { opts.callback(r.message.name || r.message); } }, always() { d.enable_primary_action(); } }); } }); // ZIP auto-fill d.fields_dict.pincode.df.onchange = () => { const zip = d.get_value("pincode"); if (!zip || zip.length < 5) return; console.log("NS App: ZIP lookup", zip); fetch(`https://api.zippopotam.us/us/${zip}`) .then(r => r.ok ? r.json() : null) .then(data => { if (!data || !data.places?.length) return; const p = data.places[0]; d.set_value("city", p["place name"]); d.set_value("state", p["state"]); d.set_value("country", data.country); console.log("NS App: ZIP autofill success"); }) .catch(() => {}); }; d.show(); let autoPayField = d.get_field("custom_auto_pay_enabled"); // Initial state d.set_df_property( "custom_auto_pay_id", "hidden", !d.get_value("custom_auto_pay_enabled") ); // When checkbox changes autoPayField.$input.on("change", () => { let isChecked = d.get_value("custom_auto_pay_enabled"); d.set_df_property("custom_auto_pay_id", "hidden", !isChecked); }); // Prevent Enter from submitting unless primary button is focused d.$wrapper.on("keydown", "input, select, textarea", function (e) { if (e.key === "Enter") { const active = document.activeElement; // Allow Enter ONLY if primary action button is focused if ( active && active.classList.contains("btn-primary") ) { return; } e.preventDefault(); // Move to next field const fields = d.$wrapper .find("input, select, textarea") .filter(":visible:not([disabled])"); const index = fields.index(this); if (index > -1 && index + 1 < fields.length) { fields.eq(index + 1).focus(); } } }); };