diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 929db4895ad..a425d507f7b 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -279,6 +279,29 @@ 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 + + company_logo = frappe.get_value("Company", self.company, ["company_logo"]) + address_display_list = get_address_display_list("Company", self.company) + + address_line = "" + if address_display_list and len(address_display_list) > 0: + address_line = address_display_list[0]["address_line1"] + + if not address_line or not company_logo or not self.company_address: + frappe.publish_realtime( + "sales_invoice_before_print", + { + "company_logo": company_logo, + "address_line": address_line, + "company": self.company, + "company_address_display": self.company_address, + "name": self.name, + }, + user=frappe.session.user, + ) + def validate(self): self.validate_auto_set_posting_time() super().validate() @@ -2802,6 +2825,56 @@ def get_loyalty_programs(customer): return lp_details +@frappe.whitelist() +def save_company_master_details(name, company, details): + if isinstance(details, str): + details = frappe.parse_json(details) + + if details.get("company_logo"): + frappe.db.set_value( + "Company", + company, + { + "company_logo": details.get("company_logo"), + }, + ) + + company_address = None + if details.get("address_line1"): + address = frappe.get_doc( + { + "doctype": "Address", + "address_title": details.get("address_title"), + "address_type": details.get("address_type"), + "address_line1": details.get("address_line1"), + "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}], + } + ).insert(ignore_permissions=True) + + company_address = address.name + else: + company_address = details.get("company_address") + + if company_address: + current_display = frappe.db.get_value("Sales Invoice", name, "company_address_display") + if not current_display or details.get("address_line1"): + frappe.db.set_value( + "Sales Invoice", + name, + { + "company_address": company_address, + "company_address_display": get_address_display(company_address), + }, + ) + + return True + + @frappe.whitelist() def create_invoice_discounting(source_name, target_doc=None): invoice = frappe.get_doc("Sales Invoice", source_name) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 234dcc6eac1..3582eb7c30d 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -51,6 +51,8 @@ doctype_list_js = { ], } +page_js = {"print": "public/js/print.js"} + extend_doctype_class = {"Address": "erpnext.accounts.custom.address.ERPNextAddress"} override_whitelisted_methods = {"frappe.www.contact.send_message": "erpnext.templates.utils.send_message"} diff --git a/erpnext/public/js/print.js b/erpnext/public/js/print.js new file mode 100644 index 00000000000..20a040f45c4 --- /dev/null +++ b/erpnext/public/js/print.js @@ -0,0 +1,112 @@ +let beforePrintHandled = false; + +frappe.realtime.on("sales_invoice_before_print", (data) => { + const route = frappe.get_route(); + + if (!beforePrintHandled && route[0] === "print" && route[1] === "Sales Invoice") { + beforePrintHandled = true; + 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, + }, + { + label: "Address Title", + fieldname: "address_title", + fieldtype: "Data", + 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 Type", + fieldname: "address_type", + fieldtype: "Select", + options: ["Billing", "Shipping"], + default: "Billing", + reqd: data.address_line ? 0 : 1, + 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 { + filters: { + link_doctype: "Company", + link_name: data.company, + }, + }; + }, + reqd: data.address_line ? 1 : 0, + hidden: data.address_line ? 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(__("Saving document...")); + 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; + } +});