mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-17 00:25:01 +00:00
Merge pull request #50749 from khushi8112/replace-use-of-publish-realtime-before-print
refactor: company details popup
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,130 @@ 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")
|
||||
if doctype == "Purchase Order":
|
||||
company_address = frappe.db.get_value(doctype, docname, "billing_address")
|
||||
else:
|
||||
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(doctype, "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(current_doctype, 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
|
||||
|
||||
update_doc_company_address(current_doctype, name, company_address, details)
|
||||
|
||||
|
||||
def update_doc_company_address(current_doctype, docname, company_address, details):
|
||||
if not company_address:
|
||||
return
|
||||
|
||||
address_field_map = {
|
||||
"Purchase Order": ("billing_address", "billing_address_display"),
|
||||
"Sales Invoice": ("company_address", "company_address_display"),
|
||||
"Delivery Note": ("company_address", "company_address_display"),
|
||||
"POS Invoice": ("company_address", "company_address_display"),
|
||||
}
|
||||
|
||||
address_field, display_field = address_field_map.get(
|
||||
current_doctype, ("company_address", "company_address_display")
|
||||
)
|
||||
|
||||
current_display = frappe.db.get_value(current_doctype, docname, display_field)
|
||||
|
||||
if current_display and not details.get("address_line1"):
|
||||
return
|
||||
|
||||
from frappe.query_builder import DocType
|
||||
|
||||
DocType = DocType(current_doctype)
|
||||
|
||||
(
|
||||
frappe.qb.update(DocType)
|
||||
.set(getattr(DocType, address_field), company_address)
|
||||
.set(getattr(DocType, display_field), get_address_display(company_address))
|
||||
.where(DocType.name == docname)
|
||||
).run()
|
||||
|
||||
@@ -1,155 +1,147 @@
|
||||
let beforePrintHandled = false;
|
||||
const doctype_list = ["Sales Invoice", "Delivery Note", "Purchase Order", "POS Invoice"];
|
||||
const allowed_print_formats = [
|
||||
"Sales Invoice Standard",
|
||||
"Sales Invoice with Item Image",
|
||||
"Delivery Note Standard",
|
||||
"Delivery Note with Item Image",
|
||||
"Purchase Order Standard",
|
||||
"Purchase Order with Item Image",
|
||||
"POS Invoice Standard",
|
||||
"POS 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(current_doctype, current_docname) {
|
||||
frappe.call({
|
||||
method: "erpnext.controllers.accounts_controller.get_missing_company_details",
|
||||
args: { doctype: current_doctype, docname: current_docname },
|
||||
callback: function (r) {
|
||||
if (r && r.message) {
|
||||
open_company_details_dialog(r.message, current_doctype);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function open_company_details_dialog(data, current_doctype) {
|
||||
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, current_doctype);
|
||||
},
|
||||
});
|
||||
|
||||
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, current_doctype) {
|
||||
frappe.call({
|
||||
method: "erpnext.controllers.accounts_controller.update_company_master_and_address",
|
||||
args: {
|
||||
name: data.name,
|
||||
company: data.company,
|
||||
details: values,
|
||||
current_doctype: current_doctype,
|
||||
},
|
||||
callback() {
|
||||
dialog.hide();
|
||||
frappe.msgprint(__("Updating details."));
|
||||
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1000);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user