Merge pull request #29499 from deepeshgarg007/overseas_gst_tax
fix(India): Tax calculation for overseas suppliers
diff --git a/erpnext/crm/doctype/campaign/campaign.js b/erpnext/crm/doctype/campaign/campaign.js
index 11bfa74..cac45c6 100644
--- a/erpnext/crm/doctype/campaign/campaign.js
+++ b/erpnext/crm/doctype/campaign/campaign.js
@@ -5,7 +5,7 @@
refresh: function(frm) {
erpnext.toggle_naming_series();
- if (frm.doc.__islocal) {
+ if (frm.is_new()) {
frm.toggle_display("naming_series", frappe.boot.sysdefaults.campaign_naming_by=="Naming Series");
} else {
cur_frm.add_custom_button(__("View Leads"), function() {
diff --git a/erpnext/crm/doctype/crm_settings/crm_settings.py b/erpnext/crm/doctype/crm_settings/crm_settings.py
index bde5254..98cf7d8 100644
--- a/erpnext/crm/doctype/crm_settings/crm_settings.py
+++ b/erpnext/crm/doctype/crm_settings/crm_settings.py
@@ -1,9 +1,10 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
-# import frappe
+import frappe
from frappe.model.document import Document
class CRMSettings(Document):
- pass
+ def validate(self):
+ frappe.db.set_default("campaign_naming_by", self.get("campaign_naming_by", ""))
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index f8376e6..8e7d67e 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -24,6 +24,14 @@
frm.trigger('set_contact_link');
}
},
+
+ validate: function(frm) {
+ if (frm.doc.status == "Lost" && !frm.doc.lost_reasons.length) {
+ frm.trigger('set_as_lost_dialog');
+ frappe.throw(__("Lost Reasons are required in case opportunity is Lost."));
+ }
+ },
+
contact_date: function(frm) {
if(frm.doc.contact_date < frappe.datetime.now_datetime()){
frm.set_value("contact_date", "");
@@ -82,7 +90,7 @@
frm.trigger('setup_opportunity_from');
erpnext.toggle_naming_series();
- if(!doc.__islocal && doc.status!=="Lost") {
+ if(!frm.is_new() && doc.status!=="Lost") {
if(doc.with_items){
frm.add_custom_button(__('Supplier Quotation'),
function() {
@@ -187,11 +195,11 @@
change_form_labels: function(frm) {
let company_currency = erpnext.get_currency(frm.doc.company);
- frm.set_currency_labels(["base_opportunity_amount", "base_total", "base_grand_total"], company_currency);
- frm.set_currency_labels(["opportunity_amount", "total", "grand_total"], frm.doc.currency);
+ frm.set_currency_labels(["base_opportunity_amount", "base_total"], company_currency);
+ frm.set_currency_labels(["opportunity_amount", "total"], frm.doc.currency);
// toggle fields
- frm.toggle_display(["conversion_rate", "base_opportunity_amount", "base_total", "base_grand_total"],
+ frm.toggle_display(["conversion_rate", "base_opportunity_amount", "base_total"],
frm.doc.currency != company_currency);
},
@@ -209,20 +217,15 @@
},
calculate_total: function(frm) {
- let total = 0, base_total = 0, grand_total = 0, base_grand_total = 0;
+ let total = 0, base_total = 0;
frm.doc.items.forEach(item => {
total += item.amount;
base_total += item.base_amount;
})
- base_grand_total = base_total + frm.doc.base_opportunity_amount;
- grand_total = total + frm.doc.opportunity_amount;
-
frm.set_value({
'total': flt(total),
- 'base_total': flt(base_total),
- 'grand_total': flt(grand_total),
- 'base_grand_total': flt(base_grand_total)
+ 'base_total': flt(base_total)
});
}
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index dc32d9a..089f2d2 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -42,10 +42,8 @@
"items",
"section_break_32",
"base_total",
- "base_grand_total",
"column_break_33",
"total",
- "grand_total",
"contact_info",
"customer_address",
"address_display",
@@ -476,21 +474,6 @@
"fieldtype": "Column Break"
},
{
- "fieldname": "base_grand_total",
- "fieldtype": "Currency",
- "label": "Grand Total (Company Currency)",
- "options": "Company:company:default_currency",
- "print_hide": 1,
- "read_only": 1
- },
- {
- "fieldname": "grand_total",
- "fieldtype": "Currency",
- "label": "Grand Total",
- "options": "currency",
- "read_only": 1
- },
- {
"fieldname": "lost_detail_section",
"fieldtype": "Section Break",
"label": "Lost Reasons"
@@ -510,7 +493,7 @@
"icon": "fa fa-info-sign",
"idx": 195,
"links": [],
- "modified": "2021-10-21 12:04:30.151379",
+ "modified": "2022-01-29 19:32:26.382896",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",
@@ -547,6 +530,7 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
+ "states": [],
"subject_field": "title",
"timeline_field": "party_name",
"title_field": "title",
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index a4fd765..2d53874 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -69,8 +69,6 @@
self.total = flt(total)
self.base_total = flt(base_total)
- self.grand_total = flt(self.total) + flt(self.opportunity_amount)
- self.base_grand_total = flt(self.base_total) + flt(self.base_opportunity_amount)
def make_new_lead_if_required(self):
"""Set lead against new opportunity"""
diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js
index 67018e1..8721a5b 100644
--- a/erpnext/crm/doctype/prospect/prospect.js
+++ b/erpnext/crm/doctype/prospect/prospect.js
@@ -3,6 +3,8 @@
frappe.ui.form.on('Prospect', {
refresh (frm) {
+ frappe.dynamic_link = { doc: frm.doc, fieldname: "name", doctype: frm.doctype };
+
if (!frm.is_new() && frappe.boot.user.can_create.includes("Customer")) {
frm.add_custom_button(__("Customer"), function() {
frappe.model.open_mapped_doc({
diff --git a/erpnext/crm/module_onboarding/crm/crm.json b/erpnext/crm/module_onboarding/crm/crm.json
index 8315218..0faad1d 100644
--- a/erpnext/crm/module_onboarding/crm/crm.json
+++ b/erpnext/crm/module_onboarding/crm/crm.json
@@ -16,7 +16,7 @@
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
"idx": 0,
"is_complete": 0,
- "modified": "2020-07-08 14:05:42.644448",
+ "modified": "2022-01-29 20:14:29.502145",
"modified_by": "Administrator",
"module": "CRM",
"name": "CRM",
@@ -33,6 +33,9 @@
},
{
"step": "Create and Send Quotation"
+ },
+ {
+ "step": "CRM Settings"
}
],
"subtitle": "Lead, Opportunity, Customer, and more.",
diff --git a/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json b/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json
index 78f7e4d..f0f50de 100644
--- a/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json
+++ b/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json
@@ -5,7 +5,6 @@
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2020-05-28 21:07:11.461172",
@@ -13,6 +12,7 @@
"name": "Create and Send Quotation",
"owner": "Administrator",
"reference_document": "Quotation",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Create and Send Quotation",
"validate_action": 1
diff --git a/erpnext/crm/onboarding_step/create_lead/create_lead.json b/erpnext/crm/onboarding_step/create_lead/create_lead.json
index c45e8b0..cb5cce6 100644
--- a/erpnext/crm/onboarding_step/create_lead/create_lead.json
+++ b/erpnext/crm/onboarding_step/create_lead/create_lead.json
@@ -5,7 +5,6 @@
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2020-05-28 21:07:01.373403",
@@ -13,6 +12,7 @@
"name": "Create Lead",
"owner": "Administrator",
"reference_document": "Lead",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Create Lead",
"validate_action": 1
diff --git a/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
index 0ee9317..96e0256 100644
--- a/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
+++ b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
@@ -5,7 +5,6 @@
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2021-01-21 15:28:52.483839",
@@ -13,6 +12,7 @@
"name": "Create Opportunity",
"owner": "Administrator",
"reference_document": "Opportunity",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Create Opportunity",
"validate_action": 1
diff --git a/erpnext/crm/onboarding_step/crm_settings/crm_settings.json b/erpnext/crm/onboarding_step/crm_settings/crm_settings.json
new file mode 100644
index 0000000..555d795
--- /dev/null
+++ b/erpnext/crm/onboarding_step/crm_settings/crm_settings.json
@@ -0,0 +1,21 @@
+{
+ "action": "Go to Page",
+ "creation": "2022-01-29 20:14:24.803844",
+ "description": "# CRM Settings\n\nCRM module\u2019s features are configurable as per your business needs. CRM Settings is the place where you can set your preferences for:\n- Campaign\n- Lead\n- Opportunity\n- Quotation",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_single": 1,
+ "is_skipped": 0,
+ "modified": "2022-01-29 20:14:24.803844",
+ "modified_by": "Administrator",
+ "name": "CRM Settings",
+ "owner": "Administrator",
+ "path": "#crm-settings/CRM%20Settings",
+ "reference_document": "CRM Settings",
+ "show_form_tour": 0,
+ "show_full_form": 0,
+ "title": "CRM Settings",
+ "validate_action": 1
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json b/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
index fa26921a..8871753 100644
--- a/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
+++ b/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
@@ -5,13 +5,13 @@
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2020-05-14 17:28:16.448676",
"modified_by": "Administrator",
"name": "Introduction to CRM",
"owner": "Administrator",
+ "show_form_tour": 0,
"show_full_form": 0,
"title": "Introduction to CRM",
"validate_action": 1,
diff --git a/erpnext/hr/doctype/interview/interview.py b/erpnext/hr/doctype/interview/interview.py
index 4bb003d..a3b111c 100644
--- a/erpnext/hr/doctype/interview/interview.py
+++ b/erpnext/hr/doctype/interview/interview.py
@@ -7,7 +7,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe.utils import cstr, get_datetime, get_link_to_form
+from frappe.utils import cstr, flt, get_datetime, get_link_to_form
class DuplicateInterviewRoundError(frappe.ValidationError):
@@ -18,6 +18,7 @@
self.validate_duplicate_interview()
self.validate_designation()
self.validate_overlap()
+ self.set_average_rating()
def on_submit(self):
if self.status not in ['Cleared', 'Rejected']:
@@ -67,6 +68,13 @@
overlapping_details = _('Interview overlaps with {0}').format(get_link_to_form('Interview', overlaps[0][0]))
frappe.throw(overlapping_details, title=_('Overlap'))
+ def set_average_rating(self):
+ total_rating = 0
+ for entry in self.interview_details:
+ if entry.average_rating:
+ total_rating += entry.average_rating
+
+ self.average_rating = flt(total_rating / len(self.interview_details) if len(self.interview_details) else 0)
@frappe.whitelist()
def reschedule_interview(self, scheduled_on, from_time, to_time):
diff --git a/erpnext/hr/doctype/interview/test_interview.py b/erpnext/hr/doctype/interview/test_interview.py
index 1a2257a..fdb11af 100644
--- a/erpnext/hr/doctype/interview/test_interview.py
+++ b/erpnext/hr/doctype/interview/test_interview.py
@@ -12,6 +12,7 @@
from erpnext.hr.doctype.designation.test_designation import create_designation
from erpnext.hr.doctype.interview.interview import DuplicateInterviewRoundError
+from erpnext.hr.doctype.job_applicant.job_applicant import get_interview_details
from erpnext.hr.doctype.job_applicant.test_job_applicant import create_job_applicant
@@ -70,6 +71,20 @@
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
self.assertTrue("Subject: Interview Feedback Reminder" in email_queue[0].message)
+ def test_get_interview_details_for_applicant_dashboard(self):
+ job_applicant = create_job_applicant()
+ interview = create_interview_and_dependencies(job_applicant.name)
+
+ details = get_interview_details(job_applicant.name)
+ self.assertEqual(details.get('stars'), 5)
+ self.assertEqual(details.get('interviews').get(interview.name), {
+ 'name': interview.name,
+ 'interview_round': interview.interview_round,
+ 'expected_average_rating': interview.expected_average_rating * 5,
+ 'average_rating': interview.average_rating * 5,
+ 'status': 'Pending'
+ })
+
def tearDown(self):
frappe.db.rollback()
@@ -106,7 +121,8 @@
interview_round = frappe.new_doc("Interview Round")
interview_round.round_name = name
interview_round.interview_type = create_interview_type()
- interview_round.expected_average_rating = 4
+ # average rating = 4
+ interview_round.expected_average_rating = 0.8
if designation:
interview_round.designation = designation
diff --git a/erpnext/hr/doctype/interview_feedback/interview_feedback.py b/erpnext/hr/doctype/interview_feedback/interview_feedback.py
index d046458..2ff00c1 100644
--- a/erpnext/hr/doctype/interview_feedback/interview_feedback.py
+++ b/erpnext/hr/doctype/interview_feedback/interview_feedback.py
@@ -57,7 +57,6 @@
def update_interview_details(self):
doc = frappe.get_doc('Interview', self.interview)
- total_rating = 0
if self.docstatus == 2:
for entry in doc.interview_details:
@@ -72,10 +71,6 @@
entry.comments = self.feedback
entry.result = self.result
- if entry.average_rating:
- total_rating += entry.average_rating
-
- doc.average_rating = flt(total_rating / len(doc.interview_details) if len(doc.interview_details) else 0)
doc.save()
doc.notify_update()
diff --git a/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py b/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py
index d2ec5b9..19c4642 100644
--- a/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py
+++ b/erpnext/hr/doctype/interview_feedback/test_interview_feedback.py
@@ -24,7 +24,7 @@
create_skill_set(['Leadership'])
interview_feedback = create_interview_feedback(interview.name, interviewer, skill_ratings)
- interview_feedback.append("skill_assessment", {"skill": 'Leadership', 'rating': 4})
+ interview_feedback.append("skill_assessment", {"skill": 'Leadership', 'rating': 0.8})
frappe.set_user(interviewer)
self.assertRaises(frappe.ValidationError, interview_feedback.save)
@@ -50,7 +50,7 @@
avg_rating = flt(total_rating / len(feedback_1.skill_assessment) if len(feedback_1.skill_assessment) else 0)
- self.assertEqual(flt(avg_rating, 3), feedback_1.average_rating)
+ self.assertEqual(flt(avg_rating, 2), flt(feedback_1.average_rating, 2))
avg_on_interview_detail = frappe.db.get_value('Interview Detail', {
'parent': feedback_1.interview,
@@ -59,7 +59,7 @@
}, 'average_rating')
# 1. average should be reflected in Interview Detail.
- self.assertEqual(avg_on_interview_detail, feedback_1.average_rating)
+ self.assertEqual(flt(avg_on_interview_detail, 2), flt(feedback_1.average_rating, 2))
'''For Second Interviewer Feedback'''
interviewer = interview.interview_details[1].interviewer
@@ -97,5 +97,5 @@
skills = frappe.get_all("Expected Skill Set", filters={"parent": interview_round}, fields = ["skill"])
for d in skills:
- d["rating"] = random.randint(1, 5)
+ d["rating"] = random.random()
return skills
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.js b/erpnext/hr/doctype/job_applicant/job_applicant.js
index d7b1c6c..c1e8257 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.js
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.js
@@ -21,9 +21,9 @@
create_custom_buttons: function(frm) {
if (!frm.doc.__islocal && frm.doc.status !== "Rejected" && frm.doc.status !== "Accepted") {
- frm.add_custom_button(__("Create Interview"), function() {
+ frm.add_custom_button(__("Interview"), function() {
frm.events.create_dialog(frm);
- });
+ }, __("Create"));
}
if (!frm.doc.__islocal) {
@@ -40,10 +40,10 @@
frappe.route_options = {
"job_applicant": frm.doc.name,
"applicant_name": frm.doc.applicant_name,
- "designation": frm.doc.job_opening,
+ "designation": frm.doc.job_opening || frm.doc.designation,
};
frappe.new_doc("Job Offer");
- });
+ }, __("Create"));
}
}
},
@@ -55,13 +55,16 @@
job_applicant: frm.doc.name
},
callback: function(r) {
- $("div").remove(".form-dashboard-section.custom");
- frm.dashboard.add_section(
- frappe.render_template('job_applicant_dashboard', {
- data: r.message
- }),
- __("Interview Summary")
- );
+ if (r.message) {
+ $("div").remove(".form-dashboard-section.custom");
+ frm.dashboard.add_section(
+ frappe.render_template("job_applicant_dashboard", {
+ data: r.message.interviews,
+ number_of_stars: r.message.stars
+ }),
+ __("Interview Summary")
+ );
+ }
}
});
},
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.py b/erpnext/hr/doctype/job_applicant/job_applicant.py
index 5b3d9bf..ccc21ce 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.py
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.py
@@ -81,8 +81,13 @@
fields=["name", "interview_round", "expected_average_rating", "average_rating", "status"]
)
interview_detail_map = {}
+ meta = frappe.get_meta("Interview")
+ number_of_stars = meta.get_options("expected_average_rating") or 5
for detail in interview_details:
+ detail.expected_average_rating = detail.expected_average_rating * number_of_stars if detail.expected_average_rating else 0
+ detail.average_rating = detail.average_rating * number_of_stars if detail.average_rating else 0
+
interview_detail_map[detail.name] = detail
- return interview_detail_map
+ return {"interviews": interview_detail_map, "stars": number_of_stars}
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html
index c286787..734b2fe 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html
+++ b/erpnext/hr/doctype/job_applicant/job_applicant_dashboard.html
@@ -17,24 +17,33 @@
<td class="text-left"> {%= key %} </td>
<td class="text-left"> {%= value["interview_round"] %} </td>
<td class="text-left"> {%= value["status"] %} </td>
- <td class="text-left">
- {% for (i = 0; i < value["expected_average_rating"]; i++) { %}
- <span class="fa fa-star " style="color: #F6C35E;"></span>
- {% } %}
- {% for (i = 0; i < (5-value["expected_average_rating"]); i++) { %}
- <span class="fa fa-star " style="color: #E7E9EB;"></span>
- {% } %}
- </td>
- <td class="text-left">
- {% if(value["average_rating"]){ %}
- {% for (i = 0; i < value["average_rating"]; i++) { %}
- <span class="fa fa-star " style="color: #F6C35E;"></span>
- {% } %}
- {% for (i = 0; i < (5-value["average_rating"]); i++) { %}
- <span class="fa fa-star " style="color: #E7E9EB;"></span>
- {% } %}
- {% } %}
- </td>
+ {% let right_class = ''; %}
+ {% let left_class = ''; %}
+
+ {% $.each([value["expected_average_rating"], value["average_rating"]], (_, val) => { %}
+ <td class="text-left">
+ <div class="rating">
+ {% for (let i = 1; i <= number_of_stars; i++) { %}
+ {% if (i <= val) { %}
+ {% right_class = 'star-click'; %}
+ {% } else { %}
+ {% right_class = ''; %}
+ {% } %}
+
+ {% if ((i <= val) || ((i - 0.5) == val)) { %}
+ {% left_class = 'star-click'; %}
+ {% } else { %}
+ {% left_class = ''; %}
+ {% } %}
+
+ <svg class="icon icon-md" data-rating={{i}} viewBox="0 0 24 24" fill="none">
+ <path class="right-half {{ right_class }}" d="M11.9987 3.00011C12.177 3.00011 12.3554 3.09303 12.4471 3.27888L14.8213 8.09112C14.8941 8.23872 15.0349 8.34102 15.1978 8.3647L20.5069 9.13641C20.917 9.19602 21.0807 9.69992 20.7841 9.9892L16.9421 13.7354C16.8243 13.8503 16.7706 14.0157 16.7984 14.1779L17.7053 19.4674C17.7753 19.8759 17.3466 20.1874 16.9798 19.9945L12.2314 17.4973C12.1586 17.459 12.0786 17.4398 11.9987 17.4398V3.00011Z" fill="var(--star-fill)" stroke="var(--star-fill)"/>
+ <path class="left-half {{ left_class }}" d="M11.9987 3.00011C11.8207 3.00011 11.6428 3.09261 11.5509 3.27762L9.15562 8.09836C9.08253 8.24546 8.94185 8.34728 8.77927 8.37075L3.42887 9.14298C3.01771 9.20233 2.85405 9.70811 3.1525 9.99707L7.01978 13.7414C7.13858 13.8564 7.19283 14.0228 7.16469 14.1857L6.25116 19.4762C6.18071 19.8842 6.6083 20.1961 6.97531 20.0045L11.7672 17.5022C11.8397 17.4643 11.9192 17.4454 11.9987 17.4454V3.00011Z" fill="var(--star-fill)" stroke="var(--star-fill)"/>
+ </svg>
+ {% } %}
+ </div>
+ </td>
+ {% }); %}
</tr>
{% } %}
</tbody>
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py
index fb86e61..e1ef635 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.py
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.py
@@ -16,7 +16,7 @@
self.toggle_editable_rate_for_bundle_items()
def validate(self):
- for key in ["cust_master_name", "campaign_naming_by", "customer_group", "territory",
+ for key in ["cust_master_name", "customer_group", "territory",
"maintain_same_sales_rate", "editable_price_list_rate", "selling_price_list"]:
frappe.db.set_default(key, self.get(key, ""))
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 540aca2..bd3b41f 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -486,7 +486,7 @@
"options": "Competitor Detail"
},
{
- "fieldtype": "Text",
+ "fieldtype": "Small Text",
"label": __("Detailed Reason"),
"fieldname": "detailed_reason"
},