refactor: Replace use publish_realtime with msgprint for cleaner flow

This commit is contained in:
khushi8112
2025-11-26 11:09:26 +05:30
parent ae7db7ea5a
commit 3a4c1a9f9a
3 changed files with 238 additions and 255 deletions

View File

@@ -282,59 +282,6 @@ class SalesInvoice(SellingController):
self.indicator_color = "green"
self.indicator_title = _("Paid")
def before_print(self, settings=None):
from frappe.contacts.doctype.address.address import get_address_display_list
super().before_print(settings)
company_details = frappe.get_value(
"Company", self.company, ["company_logo", "website", "phone_no", "email"], as_dict=True
)
required_fields = [
company_details.get("company_logo"),
company_details.get("phone_no"),
company_details.get("email"),
]
if not all(required_fields) and not frappe.has_permission("Company", "write", throw=False):
frappe.msgprint(
_(
"Some required Company details are missing. You don't have permission to update them. Please contact your System Manager."
)
)
return
if not self.company_address and not frappe.has_permission("Sales Invoice", "write", throw=False):
frappe.msgprint(
_(
"Company Address is missing. You don't have permission to update it. Please contact your System Manager."
)
)
return
address_display_list = get_address_display_list("Company", self.company)
address_line = address_display_list[0].get("address_line1") if address_display_list else ""
required_fields.append(self.company_address)
required_fields.append(address_line)
if not all(required_fields):
frappe.publish_realtime(
"sales_invoice_before_print",
{
"company_logo": company_details.get("company_logo"),
"website": company_details.get("website"),
"phone_no": company_details.get("phone_no"),
"email": company_details.get("email"),
"address_line": address_line,
"company": self.company,
"company_address": self.company_address,
"name": self.name,
},
user=frappe.session.user,
)
def validate(self):
self.validate_auto_set_posting_time()
super().validate()
@@ -2948,59 +2895,6 @@ def get_loyalty_programs(customer):
return lp_details
@frappe.whitelist()
def save_company_master_details(name, company, details):
from frappe.utils import validate_email_address
if isinstance(details, str):
details = frappe.parse_json(details)
if details.get("email"):
validate_email_address(details.get("email"), throw=True)
company_fields = ["company_logo", "website", "phone_no", "email"]
company_fields_to_update = {field: details.get(field) for field in company_fields if details.get(field)}
if company_fields_to_update:
frappe.db.set_value("Company", company, company_fields_to_update)
company_address = details.get("company_address")
if details.get("address_line1"):
address_doc = frappe.get_doc(
{
"doctype": "Address",
"address_title": details.get("address_title"),
"address_type": details.get("address_type"),
"address_line1": details.get("address_line1"),
"address_line2": details.get("address_line2"),
"city": details.get("city"),
"state": details.get("state"),
"pincode": details.get("pincode"),
"country": details.get("country"),
"is_your_company_address": 1,
"links": [{"link_doctype": "Company", "link_name": company}],
}
)
address_doc.insert()
company_address = address_doc.name
if company_address:
company_address_display = frappe.db.get_value("Sales Invoice", name, "company_address_display")
if not company_address_display or details.get("address_line1"):
from frappe.query_builder import DocType
SalesInvoice = DocType("Sales Invoice")
(
frappe.qb.update(SalesInvoice)
.set(SalesInvoice.company_address, company_address)
.set(SalesInvoice.company_address_display, get_address_display(company_address))
.where(SalesInvoice.name == name)
).run()
return True
@frappe.whitelist()
def create_invoice_discounting(source_name, target_doc=None):
invoice = frappe.get_doc("Sales Invoice", source_name)

View File

@@ -7,6 +7,7 @@ from collections import defaultdict
import frappe
from frappe import _, bold, qb, throw
from frappe.contacts.doctype.address.address import get_address_display
from frappe.model.workflow import get_workflow_name, is_transition_condition_satisfied
from frappe.query_builder import Criterion, DocType
from frappe.query_builder.custom import ConstantColumn
@@ -4167,3 +4168,109 @@ def update_gl_dict_with_regional_fields(doc, gl_dict):
def update_gl_dict_with_app_based_fields(doc, gl_dict):
for method in frappe.get_hooks("update_gl_dict_with_app_based_fields", default=[]):
frappe.get_attr(method)(doc, gl_dict)
@frappe.whitelist()
def get_missing_company_details(doctype, docname):
from frappe.contacts.doctype.address.address import get_address_display_list
company = frappe.db.get_value(doctype, docname, "company")
company_address = frappe.db.get_value(doctype, docname, "company_address")
company_details = frappe.get_value(
"Company", company, ["company_logo", "website", "phone_no", "email"], as_dict=True
)
required_fields = [
company_details.get("company_logo"),
company_details.get("phone_no"),
company_details.get("email"),
]
if not all(required_fields) and not frappe.has_permission("Company", "write", throw=False):
frappe.msgprint(
_(
"Some required Company details are missing. You don't have permission to update them. Please contact your System Manager."
)
)
return
if not company_address and not frappe.has_permission("Sales Invoice", "write", throw=False):
frappe.msgprint(
_(
"Company Address is missing. You don't have permission to update it. Please contact your System Manager."
)
)
return
address_display_list = get_address_display_list("Company", company)
address_line = address_display_list[0].get("address_line1") if address_display_list else ""
required_fields.append(company_address)
required_fields.append(address_line)
if all(required_fields):
return False
return {
"company_logo": company_details.get("company_logo"),
"website": company_details.get("website"),
"phone_no": company_details.get("phone_no"),
"email": company_details.get("email"),
"address_line": address_line,
"company": company,
"company_address": company_address,
"name": docname,
}
@frappe.whitelist()
def update_company_master_and_address(name, company, details):
from frappe.utils import validate_email_address
if isinstance(details, str):
details = frappe.parse_json(details)
if details.get("email"):
validate_email_address(details.get("email"), throw=True)
company_fields = ["company_logo", "website", "phone_no", "email"]
company_fields_to_update = {field: details.get(field) for field in company_fields if details.get(field)}
if company_fields_to_update:
frappe.db.set_value("Company", company, company_fields_to_update)
company_address = details.get("company_address")
if details.get("address_line1"):
address_doc = frappe.get_doc(
{
"doctype": "Address",
"address_title": details.get("address_title"),
"address_type": details.get("address_type"),
"address_line1": details.get("address_line1"),
"address_line2": details.get("address_line2"),
"city": details.get("city"),
"state": details.get("state"),
"pincode": details.get("pincode"),
"country": details.get("country"),
"is_your_company_address": 1,
"links": [{"link_doctype": "Company", "link_name": company}],
}
)
address_doc.insert()
company_address = address_doc.name
if company_address:
company_address_display = frappe.db.get_value("Sales Invoice", name, "company_address_display")
if not company_address_display or details.get("address_line1"):
from frappe.query_builder import DocType
SalesInvoice = DocType("Sales Invoice")
(
frappe.qb.update(SalesInvoice)
.set(SalesInvoice.company_address, company_address)
.set(SalesInvoice.company_address_display, get_address_display(company_address))
.where(SalesInvoice.name == name)
).run()
return True

View File

@@ -1,155 +1,137 @@
let beforePrintHandled = false;
const doctype_list = ["Sales Invoice"];
const allowed_print_formats = ["Sales Invoice Standard", "Sales Invoice with Item Image"];
const allowed_letterheads = ["Company Letterhead", "Company Letterhead - Grey"];
frappe.realtime.on("sales_invoice_before_print", (data) => {
let print_format = $('input[data-fieldname="print_format"]').val();
let letterhead = $('input[data-fieldname="letterhead"]').val();
let allowed_print_formats = ["Sales Invoice Standard", "Sales Invoice with Item Image"];
let allowed_letterheads = ["Company Letterhead", "Company Letterhead - Grey"];
if (!allowed_print_formats.includes(print_format) && !allowed_letterheads.includes(letterhead)) {
return;
}
handle_route_event();
function handle_route_event() {
const route = frappe.get_route();
const current_doctype = route[1];
const current_docname = route[2];
if (!beforePrintHandled && route[0] === "print" && route[1] === "Sales Invoice") {
beforePrintHandled = true;
if (!doctype_list.includes(current_doctype)) return;
let companyDetailsDialog = new frappe.ui.Dialog({
title: "Enter Company Details",
fields: [
{
label: "Company Logo",
fieldname: "company_logo",
fieldtype: "Attach Image",
reqd: data.company_logo ? 0 : 1,
hidden: data.company_logo ? 1 : 0,
setTimeout(() => {
if (should_fetch_company_details()) {
fetch_company_details(current_doctype, current_docname);
}
}, 500);
}
function should_fetch_company_details() {
const print_format = $('input[data-fieldname="print_format"]').val();
const letterhead = $('input[data-fieldname="letterhead"]').val();
return allowed_print_formats.includes(print_format) || allowed_letterheads.includes(letterhead);
}
function fetch_company_details(doctype, docname) {
frappe.call({
method: "erpnext.controllers.accounts_controller.get_missing_company_details",
args: { doctype, docname },
callback: function (r) {
if (r && r.message) {
open_company_details_dialog(r.message);
}
},
});
}
function open_company_details_dialog(data) {
const dialog = new frappe.ui.Dialog({
title: "Enter Company Details",
fields: build_dialog_fields(data),
primary_action_label: "Save",
primary_action(values) {
save_company_details(dialog, data, values);
},
});
dialog.show();
}
function build_dialog_fields(data) {
return [
make_field("Company Logo", "company_logo", "Attach Image", data.company_logo),
make_field("Website", "website", "Data", data.website),
make_field("Phone No", "phone_no", "Data", data.phone_no),
{
label: "Email",
fieldname: "email",
fieldtype: "Data",
options: "Email",
reqd: data.email ? 0 : 1,
hidden: data.email ? 1 : 0,
},
{ fieldtype: "Section Break" },
make_field("Address Title", "address_title", "Data", data.address_line),
{
label: "Address Type",
fieldname: "address_type",
fieldtype: "Select",
options: ["Billing", "Shipping"],
default: "Billing",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
make_field("Address Line 1", "address_line1", "Data", data.address_line),
make_field("Address Line 2", "address_line2", "Data", data.address_line, false),
make_field("City", "city", "Data", data.address_line),
make_field("State", "state", "Data", data.address_line, false),
{
label: "Country",
fieldname: "country",
fieldtype: "Link",
options: "Country",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
make_field("Postal Code", "pincode", "Data", data.address_line, false),
{
label: "Select Company Address",
fieldname: "company_address",
fieldtype: "Link",
options: "Address",
get_query: () => ({
query: "frappe.contacts.doctype.address.address.address_query",
filters: {
link_doctype: "Company",
link_name: data.company,
},
{
label: "Website",
fieldname: "website",
fieldtype: "Data",
hidden: data.website ? 1 : 0,
},
{
label: "Phone No",
fieldname: "phone_no",
fieldtype: "Data",
reqd: data.phone_no ? 0 : 1,
hidden: data.phone_no ? 1 : 0,
},
{
label: "Email",
fieldname: "email",
fieldtype: "Data",
options: "Email",
reqd: data.email ? 0 : 1,
hidden: data.email ? 1 : 0,
},
{
fieldname: "section_break_1",
fieldtype: "Section Break",
},
{
label: "Address Title",
fieldname: "address_title",
fieldtype: "Data",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
{
label: "Address Type",
fieldname: "address_type",
fieldtype: "Select",
options: ["Billing", "Shipping"],
default: "Billing",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
{
label: "Address Line 1",
fieldname: "address_line1",
fieldtype: "Data",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
{
label: "Address Line 2",
fieldname: "address_line2",
fieldtype: "Data",
hidden: data.address_line ? 1 : 0,
},
{
label: "City",
fieldname: "city",
fieldtype: "Data",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
{
label: "State",
fieldname: "state",
fieldtype: "Data",
hidden: data.address_line ? 1 : 0,
},
{
label: "Country",
fieldname: "country",
fieldtype: "Link",
options: "Country",
reqd: data.address_line ? 0 : 1,
hidden: data.address_line ? 1 : 0,
},
{
label: "Postal Code",
fieldname: "pincode",
fieldtype: "Data",
hidden: data.address_line ? 1 : 0,
},
{
label: "Select Company Address",
fieldname: "company_address",
fieldtype: "Link",
options: "Address",
get_query: function () {
return {
query: "frappe.contacts.doctype.address.address.address_query",
filters: {
link_doctype: "Company",
link_name: data.company,
},
};
},
reqd: data.address_line && !data.company_address ? 1 : 0,
hidden: data.address_line && !data.company_address ? 0 : 1,
},
],
primary_action_label: "Save",
primary_action(values) {
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.save_company_master_details",
args: {
name: data.name,
company: data.company,
details: values,
},
callback: function () {
companyDetailsDialog.hide();
frappe.msgprint(__("Updating details."));
setTimeout(() => {
window.location.reload();
}, 1000);
},
});
},
});
companyDetailsDialog.show();
}
});
frappe.router.on("change", () => {
const route = frappe.get_route();
if (route[0] !== "print" || route[1] !== "Sales Invoice") {
beforePrintHandled = false;
}
});
}),
reqd: data.address_line && !data.company_address ? 1 : 0,
hidden: data.address_line && !data.company_address ? 0 : 1,
},
];
}
function make_field(label, fieldname, fieldtype, existing_value, required_if_empty = true) {
return {
label,
fieldname,
fieldtype,
reqd: existing_value ? 0 : required_if_empty ? 1 : 0,
hidden: existing_value ? 1 : 0,
};
}
function save_company_details(dialog, data, values) {
frappe.call({
method: "erpnext.controllers.accounts_controller.update_company_master_and_address",
args: {
name: data.name,
company: data.company,
details: values,
},
callback() {
dialog.hide();
frappe.msgprint("Updating details.");
setTimeout(() => {
location.reload();
}, 1000);
},
});
}