diff --git a/crm/fcrm/doctype/crm_products/crm_products.py b/crm/fcrm/doctype/crm_products/crm_products.py index e8a34bb8..e77b5ab5 100644 --- a/crm/fcrm/doctype/crm_products/crm_products.py +++ b/crm/fcrm/doctype/crm_products/crm_products.py @@ -1,9 +1,111 @@ # Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document class CRMProducts(Document): pass + + +def create_product_details_script(doctype): + if not frappe.db.exists("CRM Form Script", "Product Details Script for " + doctype): + script = get_product_details_script() + frappe.get_doc( + { + "doctype": "CRM Form Script", + "name": "Product Details Script for " + doctype, + "dt": doctype, + "view": "Form", + "script": script, + "enabled": 1, + "is_standard": 1, + } + ).insert() + + +def get_product_details_script(doctype): + doctype_class = "class " + doctype.replace(" ", "") + + return ( + doctype_class + + """ + { + update_total() { + let total = 0 + let total_qty = 0 + let net_total = 0 + let discount_applied = false + + this.doc.products.forEach((d) => { + total += d.amount + total_qty += d.qty + net_total += d.net_amount + if (d.discount_percentage > 0) { + discount_applied = true + } + }) + + this.doc.total = total + this.doc.net_total = net_total || total + + if (!net_total && discount_applied) { + this.doc.net_total = net_total + } + } +} + +class CRMProducts { + products_add() { + let row = this.doc.getRow('products') + row.trigger('qty') + this.doc.trigger('update_total') + } + + products_remove() { + this.doc.trigger('update_total') + } + + async product_code(idx) { + let row = this.doc.getRow('products', idx) + + let a = await call("frappe.client.get_value", { + doctype: "CRM Product", + filters: { name: row.product_code }, + fieldname: ["product_name", "standard_rate"], + }) + + row.product_name = a.product_name + if (a.standard_rate && !row.rate) { + row.rate = a.standard_rate + row.trigger("rate") + } + } + + qty(idx) { + let row = this.doc.getRow('products', idx) + row.amount = row.qty * row.rate + row.trigger('discount_percentage', idx) + } + + rate() { + let row = this.doc.getRow('products') + row.amount = row.qty * row.rate + row.trigger('discount_percentage') + } + + discount_percentage(idx) { + let row = this.doc.getRow('products', idx) + if (!row.discount_percentage) { + row.net_amount = row.amount + row.discount_amount = 0 + } + if (row.discount_percentage && row.amount) { + row.discount_amount = (row.discount_percentage / 100) * row.amount + row.net_amount = row.amount - row.discount_amount + } + this.doc.trigger('update_total') + } +}""" + ) diff --git a/crm/install.py b/crm/install.py index 1e0d816f..5f25e7d0 100644 --- a/crm/install.py +++ b/crm/install.py @@ -4,6 +4,8 @@ import click import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields +from crm.fcrm.doctype.crm_products.crm_products import create_product_details_script + def before_install(): pass @@ -19,6 +21,7 @@ def after_install(force=False): add_default_industries() add_default_lead_sources() add_standard_dropdown_items() + add_default_scripts() frappe.db.commit() @@ -353,3 +356,8 @@ def add_standard_dropdown_items(): crm_settings.append("dropdown_items", item) crm_settings.save() + + +def add_default_scripts(): + for doctype in ["CRM Lead", "CRM Deal"]: + create_product_details_script(doctype)