[enhance] Add Issue Type and Opportunity Type masters (#11598)

* [enhance] added & linked Issue Type & Opportunity Type with opportunity

* [patch] create issue and opportunity type from the custom field if available

* [minor] issue_type and opportunity type should be mandatory

* [patches] removed try catch from the patch

* [fix] patch

* [refactor] cleanup issue/opportunity type
This commit is contained in:
Rushabh Mehta 2017-11-16 17:03:52 +05:30 committed by GitHub
parent 46be9896a9
commit a5ebebd09c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 522 additions and 81 deletions

View File

@ -254,7 +254,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
}
})
}, __("Get items from"));
// Get items from Opportunity
// Get items from Opportunity
this.frm.add_custom_button(__('Opportunity'),
function() {
erpnext.utils.map_current_doc({
@ -264,11 +264,8 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
setters: {
company: me.frm.doc.company
},
get_query_filters: {
enquiry_type: "Sales"
}
})
}, __("Get items from"));
}, __("Get items from"));
// Get items from open Material Requests based on supplier
this.frm.add_custom_button(__('Possible Supplier'), function() {
// Create a dialog window for the user to pick their supplier

View File

@ -270,8 +270,8 @@
"collapsible": 0,
"columns": 0,
"default": "Sales",
"fieldname": "enquiry_type",
"fieldtype": "Select",
"fieldname": "opportunity_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -284,14 +284,14 @@
"no_copy": 0,
"oldfieldname": "enquiry_type",
"oldfieldtype": "Select",
"options": "Sales\nMaintenance",
"options": "Opportunity Type",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -1189,7 +1189,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-08-21 02:07:46.486433",
"modified": "2017-11-15 17:44:46.241548",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",
@ -1239,7 +1239,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "status,transaction_date,customer,lead,enquiry_type,territory,company",
"search_fields": "status,transaction_date,customer,lead,opportunity_type,territory,company",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",

View File

@ -246,7 +246,7 @@ def make_quotation(source_name, target_doc=None):
"doctype": "Quotation",
"field_map": {
"enquiry_from": "quotation_to",
"enquiry_type": "order_type",
"opportunity_type": "order_type",
"name": "enq_no",
}
},
@ -267,10 +267,7 @@ def make_quotation(source_name, target_doc=None):
def make_request_for_quotation(source_name, target_doc=None):
doclist = get_mapped_doc("Opportunity", source_name, {
"Opportunity": {
"doctype": "Request for Quotation",
"validation": {
"enquiry_type": ["=", "Sales"]
}
"doctype": "Request for Quotation"
},
"Opportunity Item": {
"doctype": "Request for Quotation Item",

View File

@ -1,5 +1,5 @@
frappe.listview_settings['Opportunity'] = {
add_fields: ["customer_name", "enquiry_type", "enquiry_from", "status"],
add_fields: ["customer_name", "opportunity_type", "enquiry_from", "status"],
get_indicator: function(doc) {
var indicator = [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status];
if(doc.status=="Quotation") {

View File

@ -30,7 +30,7 @@ class TestOpportunity(unittest.TestCase):
args = {
"doctype": "Opportunity",
"contact_email":"new.opportunity@example.com",
"enquiry_type": "Sales",
"opportunity_type": "Sales",
"with_items": 0,
"transaction_date": today()
}
@ -65,7 +65,7 @@ def make_opportunity(**args):
opp_doc = frappe.get_doc({
"doctype": "Opportunity",
"enquiry_from": args.enquiry_from or "Customer",
"enquiry_type": "Sales",
"opportunity_type": "Sales",
"with_items": args.with_items or 0,
"transaction_date": today()
})

View File

@ -0,0 +1,8 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Opportunity Type', {
refresh: function(frm) {
}
});

View File

@ -0,0 +1,135 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "Prompt",
"beta": 0,
"creation": "2017-10-06 12:55:43.318773",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-15 17:27:12.271303",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity Type",
"name_case": "Title Case",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class OpportunityType(Document):
pass

View File

@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Opportunity Type", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Opportunity Type
() => frappe.tests.make('Opportunity Type', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
class TestOpportunityType(unittest.TestCase):
pass

View File

@ -54,7 +54,7 @@ def make_opportunity():
"doctype": "Opportunity",
"enquiry_from": "Customer",
"customer": get_random("Customer"),
"enquiry_type": "Sales",
"opportunity_type": "Sales",
"with_items": 1,
"transaction_date": frappe.flags.current_date,
})

View File

@ -20,7 +20,7 @@ def post_process(remote_doc=None, local_doc=None, **kwargs):
opportunity = frappe.get_doc({
'doctype': 'Opportunity',
'naming_series': 'OPTY-',
'enquiry_type': 'Sales',
'opportunity_type': 'Hub',
'enquiry_from': 'Lead',
'status': 'Open',
'lead': lead.name,

View File

@ -462,3 +462,4 @@ erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
erpnext.patches.v9_0.update_employee_loan_details
erpnext.patches.v9_2.delete_healthcare_domain_default_items
erpnext.patches.v9_1.create_issue_opportunity_type

View File

View File

@ -0,0 +1,34 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
def execute():
# delete custom field if exists
for fieldname in ('issue_type', 'opportunity_type'):
custom_field = frappe.db.get_value("Custom Field", {"fieldname": fieldname})
if custom_field:
frappe.delete_doc("Custom Field", custom_field, ignore_permissions=True)
frappe.reload_doc('support', 'doctype', 'issue_type')
frappe.reload_doc('support', 'doctype', 'issue')
frappe.reload_doc('crm', 'doctype', 'opportunity_type')
frappe.reload_doc('crm', 'doctype', 'opportunity')
# rename enquiry_type -> opportunity_type
from frappe.model.utils.rename_field import rename_field
rename_field('Opportunity', 'enquiry_type', 'opportunity_type')
# create values if already set
for opts in (('Issue', 'issue_type', 'Issue Type'),
('Opportunity', 'opportunity_type', 'Opportunity Type')):
for d in frappe.db.sql('select distinct {0} from `tab{1}`'.format(opts[1], opts[0])):
if not frappe.db.exists(opts[2], d[0]):
frappe.get_doc(dict(doctype = opts[2], name=d[0])).insert()
# fixtures
for name in ('Hub', _('Sales'), _('Support'), _('Maintenance')):
if not frappe.db.exists('Opportunity', name):
frappe.get_doc(dict(doctype = 'Opportunity Type', name=name)).insert()

View File

@ -212,6 +212,11 @@ def install(country=None):
{'doctype': "Party Type", "party_type": "Supplier"},
{'doctype': "Party Type", "party_type": "Employee"},
{'doctype': "Opportunity Type", "name": "Hub"},
{'doctype': "Opportunity Type", "name": _("Sales")},
{'doctype': "Opportunity Type", "name": _("Support")},
{'doctype': "Opportunity Type", "name": _("Maintenance")},
{'doctype': "Project Type", "project_type": "Internal"},
{'doctype': "Project Type", "project_type": "External"},
{'doctype': "Project Type", "project_type": "Other"},

View File

@ -38,7 +38,7 @@ def make_opportunity(items, customer):
"doctype": "Opportunity",
"enquiry_from": "Customer",
"customer": customer,
"enquiry_type": "Sales",
"opportunity_type": _("Sales"),
"with_items": 1
})

View File

@ -105,11 +105,11 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mins_to_first_response",
"fieldtype": "Float",
"fieldname": "issue_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -117,14 +117,15 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Mins to First Response",
"label": "Issue Type",
"length": 0,
"no_copy": 0,
"options": "Issue Type",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@ -324,10 +325,10 @@
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"fieldname": "response",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -335,6 +336,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Response",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -352,12 +354,11 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "resolution_date",
"fieldtype": "Datetime",
"fieldname": "mins_to_first_response",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -365,12 +366,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Resolution Date",
"label": "Mins to First Response",
"length": 0,
"no_copy": 1,
"oldfieldname": "resolution_date",
"oldfieldtype": "Date",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
@ -425,7 +425,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Contact",
"label": "Reference",
"length": 0,
"no_copy": 0,
"options": "fa fa-pushpin",
@ -591,6 +591,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -629,7 +659,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "resolution_details",
"fieldtype": "Text Editor",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -752,8 +782,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"depends_on": "eval:!doc.__islocal",
"fieldname": "resolution_date",
"fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -761,14 +792,15 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"label": "Resolution Date",
"length": 0,
"no_copy": 0,
"options": "Company",
"no_copy": 1,
"oldfieldname": "resolution_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 1,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@ -847,7 +879,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:19.581715",
"modified": "2017-11-15 17:15:40.347362",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",

View File

@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Issue", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Issue
() => frappe.tests.make('Issue', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@ -0,0 +1,8 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Issue Type', {
refresh: function(frm) {
}
});

View File

@ -0,0 +1,115 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "Prompt",
"beta": 0,
"creation": "2017-10-06 12:53:34.714153",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-15 17:27:19.796807",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue Type",
"name_case": "Title Case",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Support Team",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class IssueType(Document):
pass

View File

@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Issue Type", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Issue Type
() => frappe.tests.make('Issue Type', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
class TestIssueType(unittest.TestCase):
pass

View File

@ -9,16 +9,16 @@ from frappe.utils import cint, formatdate
@frappe.whitelist(allow_guest=True)
def send_message(subject="Website Query", message="", sender="", status="Open"):
from frappe.www.contact import send_message as website_send_message
lead = customer = None
from frappe.www.contact import send_message as website_send_message
lead = customer = None
website_send_message(subject, message, sender)
website_send_message(subject, message, sender)
customer = frappe.db.sql("""select distinct dl.link_name from `tabDynamic Link` dl
left join `tabContact` c on dl.parent=c.name where dl.link_doctype='Customer'
and c.email_id='{email_id}'""".format(email_id=sender))
customer = frappe.db.sql("""select distinct dl.link_name from `tabDynamic Link` dl
left join `tabContact` c on dl.parent=c.name where dl.link_doctype='Customer'
and c.email_id='{email_id}'""".format(email_id=sender))
if not customer:
if not customer:
lead = frappe.db.get_value('Lead', dict(email_id=sender))
if not lead:
new_lead = frappe.get_doc(dict(
@ -27,33 +27,33 @@ def send_message(subject="Website Query", message="", sender="", status="Open"):
lead_name = sender.split('@')[0].title()
)).insert(ignore_permissions=True)
opportunity = frappe.get_doc(dict(
doctype ='Opportunity',
enquiry_from = 'Customer' if customer else 'Lead',
status = 'Open',
title = subject,
contact_email = sender,
to_discuss = message
))
opportunity = frappe.get_doc(dict(
doctype ='Opportunity',
enquiry_from = 'Customer' if customer else 'Lead',
status = 'Open',
title = subject,
contact_email = sender,
to_discuss = message
))
if customer:
opportunity.customer = customer[0][0]
elif lead:
opportunity.lead = lead
else:
opportunity.lead = new_lead.name
if customer:
opportunity.customer = customer[0][0]
elif lead:
opportunity.lead = lead
else:
opportunity.lead = new_lead.name
opportunity.insert(ignore_permissions=True)
opportunity.insert(ignore_permissions=True)
comm = frappe.get_doc({
"doctype":"Communication",
"subject": subject,
"content": message,
"sender": sender,
"sent_or_received": "Received",
'reference_doctype': 'Opportunity',
'reference_name': opportunity.name
})
comm.insert(ignore_permissions=True)
comm = frappe.get_doc({
"doctype":"Communication",
"subject": subject,
"content": message,
"sender": sender,
"sent_or_received": "Received",
'reference_doctype': 'Opportunity',
'reference_name': opportunity.name
})
comm.insert(ignore_permissions=True)
return "okay"
return "okay"