From 7fa97fa7b58a83266c669c6fd7d170f66f162154 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Tue, 21 Nov 2023 15:14:55 +0530 Subject: [PATCH] fix: unset discount amount based on coupon code (cherry picked from commit 6518582ed3be49dd3bc6a62745dae3e6faed2658) # Conflicts: # erpnext/public/js/utils/sales_common.js --- erpnext/public/js/utils/sales_common.js | 431 ++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 erpnext/public/js/utils/sales_common.js diff --git a/erpnext/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js new file mode 100644 index 000000000000..5514963c966c --- /dev/null +++ b/erpnext/public/js/utils/sales_common.js @@ -0,0 +1,431 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.provide("erpnext.selling"); + +erpnext.sales_common = { + setup_selling_controller:function() { + erpnext.selling.SellingController = class SellingController extends erpnext.TransactionController { + setup() { + super.setup(); + this.toggle_enable_for_stock_uom("allow_to_edit_stock_uom_qty_for_sales"); + this.frm.email_field = "contact_email"; + } + + onload() { + super.onload(); + this.setup_queries(); + this.frm.set_query('shipping_rule', function() { + return { + filters: { + "shipping_rule_type": "Selling" + } + }; + }); + } + + setup_queries() { + var me = this; + + $.each([["customer", "customer"], + ["lead", "lead"]], + function(i, opts) { + if(me.frm.fields_dict[opts[0]]) + me.frm.set_query(opts[0], erpnext.queries[opts[1]]); + }); + + me.frm.set_query('contact_person', erpnext.queries.contact_query); + me.frm.set_query('customer_address', erpnext.queries.address_query); + me.frm.set_query('shipping_address_name', erpnext.queries.address_query); + me.frm.set_query('dispatch_address_name', erpnext.queries.dispatch_address_query); + + erpnext.accounts.dimensions.setup_dimension_filters(me.frm, me.frm.doctype); + + if(this.frm.fields_dict.selling_price_list) { + this.frm.set_query("selling_price_list", function() { + return { filters: { selling: 1 } }; + }); + } + + if(this.frm.fields_dict.tc_name) { + this.frm.set_query("tc_name", function() { + return { filters: { selling: 1 } }; + }); + } + + if(!this.frm.fields_dict["items"]) { + return; + } + + if(this.frm.fields_dict["items"].grid.get_field('item_code')) { + this.frm.set_query("item_code", "items", function() { + return { + query: "erpnext.controllers.queries.item_query", + filters: {'is_sales_item': 1, 'customer': me.frm.doc.customer, 'has_variants': 0} + } + }); + } + + if(this.frm.fields_dict["packed_items"] && + this.frm.fields_dict["packed_items"].grid.get_field('batch_no')) { + this.frm.set_query("batch_no", "packed_items", function(doc, cdt, cdn) { + return me.set_query_for_batch(doc, cdt, cdn) + }); + } + + if(this.frm.fields_dict["items"].grid.get_field('item_code')) { + this.frm.set_query("item_tax_template", "items", function(doc, cdt, cdn) { + return me.set_query_for_item_tax_template(doc, cdt, cdn) + }); + } + + } + + refresh() { + super.refresh(); + + frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'} + + this.frm.toggle_display("customer_name", + (this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer)); + + this.toggle_editable_price_list_rate(); + } + + customer() { + var me = this; + erpnext.utils.get_party_details(this.frm, null, null, function() { + me.apply_price_list(); + }); + } + + customer_address() { + erpnext.utils.get_address_display(this.frm, "customer_address"); + erpnext.utils.set_taxes_from_address(this.frm, "customer_address", "customer_address", "shipping_address_name"); + } + + shipping_address_name() { + erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address"); + erpnext.utils.set_taxes_from_address(this.frm, "shipping_address_name", "customer_address", "shipping_address_name"); + } + + dispatch_address_name() { + erpnext.utils.get_address_display(this.frm, "dispatch_address_name", "dispatch_address"); + } + + sales_partner() { + this.apply_pricing_rule(); + } + + campaign() { + this.apply_pricing_rule(); + } + + selling_price_list() { + this.apply_price_list(); + this.set_dynamic_labels(); + } + + discount_percentage(doc, cdt, cdn) { + var item = frappe.get_doc(cdt, cdn); + item.discount_amount = 0.0; + this.apply_discount_on_item(doc, cdt, cdn, 'discount_percentage'); + } + + discount_amount(doc, cdt, cdn) { + + if(doc.name === cdn) { + return; + } + + var item = frappe.get_doc(cdt, cdn); + item.discount_percentage = 0.0; + this.apply_discount_on_item(doc, cdt, cdn, 'discount_amount'); + } + + commission_rate() { + this.calculate_commission(); + } + + total_commission() { + frappe.model.round_floats_in(this.frm.doc, ["amount_eligible_for_commission", "total_commission"]); + + const { amount_eligible_for_commission } = this.frm.doc; + if(!amount_eligible_for_commission) return; + + this.frm.set_value( + "commission_rate", flt( + this.frm.doc.total_commission * 100.0 / amount_eligible_for_commission + ) + ); + } + + allocated_percentage(doc, cdt, cdn) { + var sales_person = frappe.get_doc(cdt, cdn); + if(sales_person.allocated_percentage) { + + sales_person.allocated_percentage = flt(sales_person.allocated_percentage, + precision("allocated_percentage", sales_person)); + + sales_person.allocated_amount = flt(this.frm.doc.amount_eligible_for_commission * + sales_person.allocated_percentage / 100.0, + precision("allocated_amount", sales_person)); + refresh_field(["allocated_amount"], sales_person); + + this.calculate_incentive(sales_person); + refresh_field(["allocated_percentage", "allocated_amount", "commission_rate","incentives"], sales_person.name, + sales_person.parentfield); + } + } + + sales_person(doc, cdt, cdn) { + var row = frappe.get_doc(cdt, cdn); + this.calculate_incentive(row); + refresh_field("incentives",row.name,row.parentfield); + } + + toggle_editable_price_list_rate() { + var df = frappe.meta.get_docfield(this.frm.doc.doctype + " Item", "price_list_rate", this.frm.doc.name); + var editable_price_list_rate = cint(frappe.defaults.get_default("editable_price_list_rate")); + + if(df && editable_price_list_rate) { + const parent_field = frappe.meta.get_parentfield(this.frm.doc.doctype, this.frm.doc.doctype + " Item"); + if (!this.frm.fields_dict[parent_field]) return; + + this.frm.fields_dict[parent_field].grid.update_docfield_property( + 'price_list_rate', 'read_only', 0 + ); + } + } + + calculate_commission() { + if(!this.frm.fields_dict.commission_rate || this.frm.doc.docstatus === 1) return; + + if(this.frm.doc.commission_rate > 100) { + this.frm.set_value("commission_rate", 100); + frappe.throw(`${__(frappe.meta.get_label( + this.frm.doc.doctype, "commission_rate", this.frm.doc.name + ))} ${__("cannot be greater than 100")}`); + } + + this.frm.doc.amount_eligible_for_commission = this.frm.doc.items.reduce( + (sum, item) => item.grant_commission ? sum + item.base_net_amount : sum, 0 + ) + + this.frm.doc.total_commission = flt( + this.frm.doc.amount_eligible_for_commission * this.frm.doc.commission_rate / 100.0, + precision("total_commission") + ); + + refresh_field(["amount_eligible_for_commission", "total_commission"]); + } + + calculate_contribution() { + var me = this; + $.each(this.frm.doc.doctype.sales_team || [], function(i, sales_person) { + frappe.model.round_floats_in(sales_person); + if (!sales_person.allocated_percentage) return; + + sales_person.allocated_amount = flt( + me.frm.doc.amount_eligible_for_commission + * sales_person.allocated_percentage + / 100.0, + precision("allocated_amount", sales_person) + ); + }); + } + + calculate_incentive(row) { + if(row.allocated_amount) + { + row.incentives = flt( + row.allocated_amount * row.commission_rate / 100.0, + precision("incentives", row)); + } + } + + set_dynamic_labels() { + super.set_dynamic_labels(); + this.set_product_bundle_help(this.frm.doc); + } + + set_product_bundle_help(doc) { + if(!this.frm.fields_dict.packing_list) return; + if ((doc.packed_items || []).length) { + $(this.frm.fields_dict.packing_list.row.wrapper).toggle(true); + + if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) { + var help_msg = "
" + + __("For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+ + "
"; + frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = help_msg; + } + } else { + $(this.frm.fields_dict.packing_list.row.wrapper).toggle(false); + if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) { + frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = ''; + } + } + refresh_field('product_bundle_help'); + } + + company_address() { + var me = this; + if(this.frm.doc.company_address) { + frappe.call({ + method: "frappe.contacts.doctype.address.address.get_address_display", + args: {"address_dict": this.frm.doc.company_address }, + callback: function(r) { + if(r.message) { + me.frm.set_value("company_address_display", r.message) + } + } + }) + } else { + this.frm.set_value("company_address_display", ""); + } + } + + conversion_factor(doc, cdt, cdn, dont_fetch_price_list_rate) { + super.conversion_factor(doc, cdt, cdn, dont_fetch_price_list_rate); + } + + qty(doc, cdt, cdn) { + super.qty(doc, cdt, cdn); + } + + pick_serial_and_batch(doc, cdt, cdn) { + let item = locals[cdt][cdn]; + let me = this; + let path = "assets/erpnext/js/utils/serial_no_batch_selector.js"; + + frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"]) + .then((r) => { + if (r.message && (r.message.has_batch_no || r.message.has_serial_no)) { + item.has_serial_no = r.message.has_serial_no; + item.has_batch_no = r.message.has_batch_no; + item.type_of_transaction = item.qty > 0 ? "Outward":"Inward"; + + item.title = item.has_serial_no ? + __("Select Serial No") : __("Select Batch No"); + + if (item.has_serial_no && item.has_batch_no) { + item.title = __("Select Serial and Batch"); + } + + frappe.require(path, function() { + new erpnext.SerialBatchPackageSelector( + me.frm, item, (r) => { + if (r) { + frappe.model.set_value(item.doctype, item.name, { + "serial_and_batch_bundle": r.name, + "qty": Math.abs(r.total_qty) + }); + } + } + ); + }); + } + }); + } + + update_auto_repeat_reference(doc) { + if (doc.auto_repeat) { + frappe.call({ + method:"frappe.automation.doctype.auto_repeat.auto_repeat.update_reference", + args:{ + docname: doc.auto_repeat, + reference:doc.name + }, + callback: function(r){ + if (r.message=="success") { + frappe.show_alert({message:__("Auto repeat document updated"), indicator:'green'}); + } else { + frappe.show_alert({message:__("An error occurred during the update process"), indicator:'red'}); + } + } + }) + } + } + + project() { + let me = this; + if(in_list(["Delivery Note", "Sales Invoice", "Sales Order"], this.frm.doc.doctype)) { + if(this.frm.doc.project) { + frappe.call({ + method:'erpnext.projects.doctype.project.project.get_cost_center_name' , + args: {project: this.frm.doc.project}, + callback: function(r, rt) { + if(!r.exc) { + $.each(me.frm.doc["items"] || [], function(i, row) { + if(r.message) { + frappe.model.set_value(row.doctype, row.name, "cost_center", r.message); + frappe.msgprint(__("Cost Center For Item with Item Code {0} has been Changed to {1}", [row.item_name, r.message])); + } + }) + } + } + }) + } + } + } + + coupon_code() { + this.frm.set_value("discount_amount", 0); + this.frm.set_value("additional_discount_percentage", 0); + } + }; + } +} + +erpnext.pre_sales = { + set_as_lost: function(doctype) { + frappe.ui.form.on(doctype, { + set_as_lost_dialog: function(frm) { + var dialog = new frappe.ui.Dialog({ + title: __("Set as Lost"), + fields: [ + { + "fieldtype": "Table MultiSelect", + "label": __("Lost Reasons"), + "fieldname": "lost_reason", + "options": frm.doctype === 'Opportunity' ? 'Opportunity Lost Reason Detail': 'Quotation Lost Reason Detail', + "reqd": 1 + }, + { + "fieldtype": "Table MultiSelect", + "label": __("Competitors"), + "fieldname": "competitors", + "options": "Competitor Detail" + }, + { + "fieldtype": "Small Text", + "label": __("Detailed Reason"), + "fieldname": "detailed_reason" + }, + ], + primary_action: function() { + let values = dialog.get_values(); + + frm.call({ + doc: frm.doc, + method: 'declare_enquiry_lost', + args: { + 'lost_reasons_list': values.lost_reason, + 'competitors': values.competitors ? values.competitors : [], + 'detailed_reason': values.detailed_reason + }, + callback: function(r) { + dialog.hide(); + frm.reload_doc(); + }, + }); + }, + primary_action_label: __('Declare Lost') + }); + + dialog.show(); + } + }); + } +} \ No newline at end of file