From d635f722fc7f7c38c4988fdd77eddf2b77e3ae1c Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 11 Feb 2019 15:16:25 +0530 Subject: [PATCH 01/10] fix(stock_balance): Make balance qty and value columns more visible --- erpnext/stock/report/stock_balance/stock_balance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index 14b1852a7f..d6b171f93c 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -79,14 +79,14 @@ def get_columns(): {"label": _("Description"), "fieldname": "description", "width": 140}, {"label": _("Warehouse"), "fieldname": "warehouse", "fieldtype": "Link", "options": "Warehouse", "width": 100}, {"label": _("Stock UOM"), "fieldname": "stock_uom", "fieldtype": "Link", "options": "UOM", "width": 90}, + {"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, + {"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100}, {"label": _("Opening Qty"), "fieldname": "opening_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, {"label": _("Opening Value"), "fieldname": "opening_val", "fieldtype": "Float", "width": 110}, {"label": _("In Qty"), "fieldname": "in_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("In Value"), "fieldname": "in_val", "fieldtype": "Float", "width": 80}, {"label": _("Out Qty"), "fieldname": "out_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Out Value"), "fieldname": "out_val", "fieldtype": "Float", "width": 80}, - {"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, - {"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100}, {"label": _("Valuation Rate"), "fieldname": "val_rate", "fieldtype": "Currency", "width": 90, "convertible": "rate"}, {"label": _("Reorder Level"), "fieldname": "reorder_level", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Reorder Qty"), "fieldname": "reorder_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, From 1ac17ec1c4e402d384200954a0dc077d8083c662 Mon Sep 17 00:00:00 2001 From: Jigar Tarpara Date: Tue, 19 Feb 2019 10:21:01 +0530 Subject: [PATCH 02/10] Add credit month in validation --- .../doctype/payment_terms_template/payment_terms_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py index 7042df0594..2b2b6afe79 100644 --- a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py +++ b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py @@ -32,7 +32,7 @@ class PaymentTermsTemplate(Document): def check_duplicate_terms(self): terms = [] for term in self.terms: - term_info = (term.credit_days, term.due_date_based_on) + term_info = (term.credit_days, term.credit_months, term.due_date_based_on) if term_info in terms: frappe.msgprint( _('The Payment Term at row {0} is possibly a duplicate.').format(term.idx), From 3d0121369f5321cd4f91e236a4ffd48ec02e7744 Mon Sep 17 00:00:00 2001 From: Joyce Babu Date: Wed, 6 Mar 2019 13:04:45 +0530 Subject: [PATCH 03/10] Add 'Half-Yearly' option to Earned Leave Frequency in addition to the current values of Monthly, Quarterly and Yearly --- erpnext/hr/doctype/leave_type/leave_type.json | 2 +- erpnext/hr/utils.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/leave_type/leave_type.json b/erpnext/hr/doctype/leave_type/leave_type.json index 8f7b5a876c..6a7a80a784 100644 --- a/erpnext/hr/doctype/leave_type/leave_type.json +++ b/erpnext/hr/doctype/leave_type/leave_type.json @@ -561,7 +561,7 @@ "label": "Earned Leave Frequency", "length": 0, "no_copy": 0, - "options": "Monthly\nQuarterly\nYearly", + "options": "Monthly\nQuarterly\nHalf-Yearly\nYearly", "permlevel": 0, "precision": "", "print_hide": 0, diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py index 02262012f1..e0b6a51d1a 100644 --- a/erpnext/hr/utils.py +++ b/erpnext/hr/utils.py @@ -260,7 +260,7 @@ def allocate_earned_leaves(): fields=["name", "max_leaves_allowed", "earned_leave_frequency", "rounding"], filters={'is_earned_leave' : 1}) today = getdate() - divide_by_frequency = {"Yearly": 1, "Quarterly": 4, "Monthly": 12} + divide_by_frequency = {"Yearly": 1, "Half-Yearly": 6, "Quarterly": 4, "Monthly": 12} if e_leave_types: for e_leave_type in e_leave_types: leave_allocations = frappe.db.sql("""select name, employee, from_date, to_date from `tabLeave Allocation` where '{0}' @@ -297,6 +297,9 @@ def check_frequency_hit(from_date, to_date, frequency): if frequency == "Quarterly": if not months % 3: return True + elif frequency == "Half-Yearly": + if not months % 6: + return True elif frequency == "Yearly": if not months % 12: return True From e66f59654e67649611f309d172087b05ac7ea023 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Wed, 6 Mar 2019 15:42:32 +0530 Subject: [PATCH 04/10] fix(report): Incorrectdata for balance quantity and value in Stock Balance report --- erpnext/stock/report/stock_balance/stock_balance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index d6b171f93c..ae919b6019 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -43,11 +43,11 @@ def execute(filters=None): item_map[item]["item_group"], item_map[item]["brand"], item_map[item]["description"], warehouse, - item_map[item]["stock_uom"], qty_dict.opening_qty, + item_map[item]["stock_uom"], qty_dict.bal_qty, + qty_dict.bal_val, qty_dict.opening_qty, qty_dict.opening_val, qty_dict.in_qty, qty_dict.in_val, qty_dict.out_qty, - qty_dict.out_val, qty_dict.bal_qty, - qty_dict.bal_val, qty_dict.val_rate, + qty_dict.out_val, qty_dict.val_rate, item_reorder_level, item_reorder_qty, company From 5327d0253d7904419b8c21ec573c8c3875d3fb79 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 14 Feb 2019 13:20:50 +0530 Subject: [PATCH 05/10] feat(issue): Create tasks from issues --- erpnext/support/doctype/issue/issue.js | 9 ++++++++- erpnext/support/doctype/issue/issue.py | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) mode change 100644 => 100755 erpnext/support/doctype/issue/issue.js mode change 100644 => 100755 erpnext/support/doctype/issue/issue.py diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js old mode 100644 new mode 100755 index d0a9bf3808..05c9130378 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -9,6 +9,13 @@ frappe.ui.form.on("Issue", { frm.set_value("status", "Closed"); frm.save(); }); + + frm.add_custom_button(__("Task"), function () { + frappe.model.open_mapped_doc({ + method: "erpnext.support.doctype.issue.issue.make_task", + frm: frm + }); + }, __("Make")); } else { frm.add_custom_button(__("Reopen"), function() { frm.set_value("status", "Open"); @@ -37,7 +44,7 @@ frappe.ui.form.on("Issue", { if (!frm.timeline.wrapper.find('.btn-split-issue').length) { let split_issue = __("Split Issue") $(``) .appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])')) if (!frm.timeline.wrapper.data("split-issue-event-attached")){ diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py old mode 100644 new mode 100755 index 0b5eb539c8..3e498c8269 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -7,11 +7,13 @@ import json from frappe import _ from frappe.model.document import Document +from frappe.model.mapper import get_mapped_doc from frappe.utils import now from frappe.utils.user import is_website_user sender_field = "raised_by" + class Issue(Document): def get_feed(self): return "{0}: {1}".format(_(self.status), self.subject) @@ -97,6 +99,7 @@ class Issue(Document): doc.save(ignore_permissions=True) return replicated_issue.name + def get_list_context(context=None): return { "title": _("Issues"), @@ -107,6 +110,7 @@ def get_list_context(context=None): 'no_breadcrumbs': True } + def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by=None): from frappe.www.list import get_list user = frappe.session.user @@ -124,12 +128,14 @@ def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, ord return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions) + @frappe.whitelist() def set_status(name, status): st = frappe.get_doc("Issue", name) st.status = status st.save() + def auto_close_tickets(): """ auto close the replied support tickets after 7 days """ auto_close_after_days = frappe.db.get_value("Support Settings", "Support Settings", "close_issue_after_days") or 7 @@ -150,6 +156,7 @@ def set_multiple_status(names, status): for name in names: set_status(name, status) + def has_website_permission(doc, ptype, user, verbose=False): from erpnext.controllers.website_list_for_contact import has_website_permission permission_based_on_customer = has_website_permission(doc, ptype, user, verbose) @@ -160,3 +167,18 @@ def has_website_permission(doc, ptype, user, verbose=False): def update_issue(contact, method): """Called when Contact is deleted""" frappe.db.sql("""UPDATE `tabIssue` set contact='' where contact=%s""", contact.name) + + +@frappe.whitelist() +def make_task(source_name, target_doc=None): + def set_missing_values(source, target): + if not target.project: + target.project = frappe.db.get_value("Project", {"customer": source.customer}) + + doclist = get_mapped_doc("Issue", source_name, { + "Issue": { + "doctype": "Task" + } + }, target_doc, set_missing_values) + + return doclist From 2ba21fb66c8109a93c4170c2c828960da61903cb Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 14 Feb 2019 16:27:57 +0530 Subject: [PATCH 06/10] fix(issue): Add issue name in Task and fix description in Issue --- erpnext/projects/doctype/task/task.json | 126 +++++++++++++++-------- erpnext/support/doctype/issue/issue.json | 12 ++- erpnext/support/doctype/issue/issue.py | 38 ++++--- 3 files changed, 113 insertions(+), 63 deletions(-) diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json index d904d7092b..2602aef626 100644 --- a/erpnext/projects/doctype/task/task.json +++ b/erpnext/projects/doctype/task/task.json @@ -79,6 +79,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "issue", + "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": "Issue", + "length": 0, + "no_copy": 0, + "options": "Issue", + "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, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -213,6 +246,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "color", + "fieldtype": "Color", + "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": "Color", + "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, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -251,11 +316,11 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, - "collapsible_depends_on": "", + "collapsible": 1, + "collapsible_depends_on": "eval:doc.__islocal", "columns": 0, "depends_on": "", - "fieldname": "section_break_10", + "fieldname": "sb_timeline", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -264,6 +329,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Timeline", "length": 0, "no_copy": 0, "permlevel": 0, @@ -513,38 +579,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "color", - "fieldtype": "Color", - "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": "Color", - "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, - "translatable": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -554,7 +588,7 @@ "collapsible_depends_on": "", "columns": 0, "depends_on": "", - "fieldname": "section_break0", + "fieldname": "sb_details", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -563,10 +597,11 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Details", "length": 0, "no_copy": 0, "oldfieldtype": "Section Break", - "options": "Simple", + "options": "", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -596,7 +631,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Details", + "label": "Task Description", "length": 0, "no_copy": 0, "oldfieldname": "description", @@ -624,7 +659,7 @@ "collapsible_depends_on": "", "columns": 0, "depends_on": "", - "fieldname": "section_break", + "fieldname": "sb_depends_on", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -726,7 +761,7 @@ "columns": 0, "depends_on": "", "description": "", - "fieldname": "actual", + "fieldname": "sb_actual", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -893,10 +928,10 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, + "collapsible": 1, "columns": 0, "depends_on": "", - "fieldname": "section_break_17", + "fieldname": "sb_costing", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -905,6 +940,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Costing", "length": 0, "no_copy": 0, "permlevel": 0, @@ -1058,9 +1094,9 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, + "collapsible": 1, "columns": 0, - "fieldname": "more_details", + "fieldname": "sb_more_info", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -1069,7 +1105,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "", + "label": "More Info", "length": 0, "no_copy": 0, "permlevel": 0, diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json index 21cf2f7848..7cb0df28a5 100644 --- a/erpnext/support/doctype/issue/issue.json +++ b/erpnext/support/doctype/issue/issue.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -349,8 +350,9 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "collapsible_depends_on": "eval:doc.status!=\"Closed\"", "columns": 0, - "fieldname": "section_break_7", + "fieldname": "sb_details", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -416,7 +418,7 @@ "bold": 0, "collapsible": 1, "columns": 0, - "fieldname": "response", + "fieldname": "sb_response", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -511,7 +513,7 @@ "bold": 0, "collapsible": 1, "columns": 0, - "fieldname": "additional_info", + "fieldname": "sb_additional_info", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -736,7 +738,7 @@ "bold": 0, "collapsible": 1, "columns": 0, - "fieldname": "section_break_19", + "fieldname": "sb_resoution", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -1035,7 +1037,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-08-21 14:44:27.615004", + "modified": "2019-02-14 02:55:47.562611", "modified_by": "Administrator", "module": "Support", "name": "Issue", diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index 3e498c8269..7e13947ee9 100755 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -19,10 +19,12 @@ class Issue(Document): return "{0}: {1}".format(_(self.status), self.subject) def validate(self): - if (self.get("__islocal") and self.via_customer_portal): + if self.is_new() and self.via_customer_portal: self.flags.create_communication = True + if not self.raised_by: self.raised_by = frappe.session.user + self.update_status() self.set_lead_contact(self.raised_by) @@ -32,16 +34,18 @@ class Issue(Document): def on_update(self): # create the communication email and remove the description - if (self.flags.create_communication and self.via_customer_portal): + if self.flags.create_communication and self.via_customer_portal: self.create_communication() self.flags.communication_created = None def set_lead_contact(self, email_id): import email.utils + email_id = email.utils.parseaddr(email_id)[1] if email_id: if not self.lead: self.lead = frappe.db.get_value("Lead", {"email_id": email_id}) + if not self.contact and not self.customer: self.contact = frappe.db.get_value("Contact", {"email_id": email_id}) @@ -81,22 +85,27 @@ class Issue(Document): communication.ignore_mandatory = True communication.save() - self.db_set("description", "") - def split_issue(self, subject, communication_id): # Bug: Pressing enter doesn't send subject from copy import deepcopy + replicated_issue = deepcopy(self) replicated_issue.subject = subject frappe.get_doc(replicated_issue).insert() + # Replicate linked Communications - # todo get all communications in timeline before this, and modify them to append them to new doc + # TODO: get all communications in timeline before this, and modify them to append them to new doc comm_to_split_from = frappe.get_doc("Communication", communication_id) - communications = frappe.get_all("Communication", filters={"reference_name": comm_to_split_from.reference_name, "reference_doctype": "Issue", "creation": ('>=', comm_to_split_from.creation)}) + communications = frappe.get_all("Communication", + filters={"reference_doctype": "Issue", + "reference_name": comm_to_split_from.reference_name, + "creation": ('>=', comm_to_split_from.creation)}) + for communication in communications: doc = frappe.get_doc("Communication", communication.name) doc.reference_name = replicated_issue.name doc.save(ignore_permissions=True) + return replicated_issue.name @@ -113,9 +122,11 @@ def get_list_context(context=None): def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by=None): from frappe.www.list import get_list + user = frappe.session.user contact = frappe.db.get_value('Contact', {'user': user}, 'name') customer = None + if contact: contact_doc = frappe.get_doc('Contact', contact) customer = contact_doc.get_link_for('Customer') @@ -129,6 +140,13 @@ def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, ord return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions) +@frappe.whitelist() +def set_multiple_status(names, status): + names = json.loads(names) + for name in names: + set_status(name, status) + + @frappe.whitelist() def set_status(name, status): st = frappe.get_doc("Issue", name) @@ -137,7 +155,7 @@ def set_status(name, status): def auto_close_tickets(): - """ auto close the replied support tickets after 7 days """ + """Auto-close replied support tickets after 7 days""" auto_close_after_days = frappe.db.get_value("Support Settings", "Support Settings", "close_issue_after_days") or 7 issues = frappe.db.sql(""" select name from tabIssue where status='Replied' and @@ -150,12 +168,6 @@ def auto_close_tickets(): doc.flags.ignore_mandatory = True doc.save() -@frappe.whitelist() -def set_multiple_status(names, status): - names = json.loads(names) - for name in names: - set_status(name, status) - def has_website_permission(doc, ptype, user, verbose=False): from erpnext.controllers.website_list_for_contact import has_website_permission From fa77b591ace3929aeb373d725173fcc55a38cda2 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 14 Feb 2019 16:32:11 +0530 Subject: [PATCH 07/10] fix(issue): View Tasks against an Issue --- erpnext/support/doctype/issue/issue.js | 4 ++++ erpnext/support/doctype/issue/issue.py | 0 2 files changed, 4 insertions(+) mode change 100755 => 100644 erpnext/support/doctype/issue/issue.js mode change 100755 => 100644 erpnext/support/doctype/issue/issue.py diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js old mode 100755 new mode 100644 index 05c9130378..27bb46986b --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -4,6 +4,10 @@ frappe.ui.form.on("Issue", { }, refresh: function(frm) { + frm.add_custom_button(__("Task"), function () { + frappe.set_route("List", "Task", { "issue": frm.doc.name }); + }, __("View")); + if(frm.doc.status!=="Closed") { frm.add_custom_button(__("Close"), function() { frm.set_value("status", "Closed"); diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py old mode 100755 new mode 100644 From bf7c69f3c4f5b5c268e4ed6a762e0bba3703a40f Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Fri, 15 Feb 2019 14:21:10 +0530 Subject: [PATCH 08/10] fix(issue): Don't auto-set project --- erpnext/support/doctype/issue/issue.js | 8 ++++---- erpnext/support/doctype/issue/issue.py | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index 27bb46986b..03e1aa4f87 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -3,13 +3,13 @@ frappe.ui.form.on("Issue", { frm.email_field = "raised_by"; }, - refresh: function(frm) { + refresh: function (frm) { frm.add_custom_button(__("Task"), function () { frappe.set_route("List", "Task", { "issue": frm.doc.name }); }, __("View")); - if(frm.doc.status!=="Closed") { - frm.add_custom_button(__("Close"), function() { + if (frm.doc.status !== "Closed") { + frm.add_custom_button(__("Close"), function () { frm.set_value("status", "Closed"); frm.save(); }); @@ -21,7 +21,7 @@ frappe.ui.form.on("Issue", { }); }, __("Make")); } else { - frm.add_custom_button(__("Reopen"), function() { + frm.add_custom_button(__("Reopen"), function () { frm.set_value("status", "Open"); frm.save(); }); diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index 7e13947ee9..de3d144a7e 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -33,7 +33,7 @@ class Issue(Document): clear(self.doctype, self.name) def on_update(self): - # create the communication email and remove the description + # Add a communication in the issue timeline if self.flags.create_communication and self.via_customer_portal: self.create_communication() self.flags.communication_created = None @@ -183,14 +183,8 @@ def update_issue(contact, method): @frappe.whitelist() def make_task(source_name, target_doc=None): - def set_missing_values(source, target): - if not target.project: - target.project = frappe.db.get_value("Project", {"customer": source.customer}) - - doclist = get_mapped_doc("Issue", source_name, { + return get_mapped_doc("Issue", source_name, { "Issue": { "doctype": "Task" } - }, target_doc, set_missing_values) - - return doclist + }, target_doc) From f4bce6a66e6701b05fed036ef5b5e4ee7295109d Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 18 Feb 2019 12:53:11 +0530 Subject: [PATCH 09/10] fix(issue): Replace Make buttons on Issue and Task with a dashboard --- erpnext/projects/doctype/task/task.js | 13 ------------- .../projects/doctype/task/task_dashboard.py | 19 +++++++++++++++++++ erpnext/support/doctype/issue/issue.js | 4 ---- .../support/doctype/issue/issue_dashboard.py | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 erpnext/projects/doctype/task/task_dashboard.py create mode 100644 erpnext/support/doctype/issue/issue_dashboard.py diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js index 93423db762..9a8af69426 100644 --- a/erpnext/projects/doctype/task/task.js +++ b/erpnext/projects/doctype/task/task.js @@ -35,19 +35,6 @@ frappe.ui.form.on("Task", { } if(!doc.__islocal) { - if(frappe.model.can_read("Timesheet")) { - frm.add_custom_button(__("Timesheet"), function() { - frappe.route_options = {"project": doc.project, "task": doc.name} - frappe.set_route("List", "Timesheet"); - }, __("View"), true); - } - if(frappe.model.can_read("Expense Claim")) { - frm.add_custom_button(__("Expense Claims"), function() { - frappe.route_options = {"project": doc.project, "task": doc.name} - frappe.set_route("List", "Expense Claim"); - }, __("View"), true); - } - if(frm.perm[0].write) { if(frm.doc.status!=="Completed" && frm.doc.status!=="Cancelled") { frm.add_custom_button(__("Completed"), function() { diff --git a/erpnext/projects/doctype/task/task_dashboard.py b/erpnext/projects/doctype/task/task_dashboard.py new file mode 100644 index 0000000000..b776b98f67 --- /dev/null +++ b/erpnext/projects/doctype/task/task_dashboard.py @@ -0,0 +1,19 @@ +from __future__ import unicode_literals + +from frappe import _ + + +def get_data(): + return { + 'fieldname': 'task', + 'transactions': [ + { + 'label': _('Activity'), + 'items': ['Timesheet'] + }, + { + 'label': _('Accounting'), + 'items': ['Expense Claim'] + } + ] + } diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index 03e1aa4f87..ce75304e77 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -4,10 +4,6 @@ frappe.ui.form.on("Issue", { }, refresh: function (frm) { - frm.add_custom_button(__("Task"), function () { - frappe.set_route("List", "Task", { "issue": frm.doc.name }); - }, __("View")); - if (frm.doc.status !== "Closed") { frm.add_custom_button(__("Close"), function () { frm.set_value("status", "Closed"); diff --git a/erpnext/support/doctype/issue/issue_dashboard.py b/erpnext/support/doctype/issue/issue_dashboard.py new file mode 100644 index 0000000000..2ac7c81615 --- /dev/null +++ b/erpnext/support/doctype/issue/issue_dashboard.py @@ -0,0 +1,15 @@ +from __future__ import unicode_literals + +from frappe import _ + + +def get_data(): + return { + 'fieldname': 'issue', + 'transactions': [ + { + 'label': _('Activity'), + 'items': ['Task'] + } + ] + } From b3434072367a214361e0932a9cdc4350a71fcd30 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Sat, 16 Mar 2019 13:38:53 +0530 Subject: [PATCH 10/10] refactor: change validate email add to validate email address --- erpnext/crm/doctype/lead/lead.py | 4 ++-- erpnext/hr/doctype/employee/employee.py | 6 +++--- erpnext/hr/doctype/job_applicant/job_applicant.py | 4 ++-- erpnext/non_profit/doctype/member/member.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 29ca71bd88..442b6c2db2 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import (cstr, validate_email_add, cint, comma_and, has_gravatar, now, getdate, nowdate) +from frappe.utils import (cstr, validate_email_address, cint, comma_and, has_gravatar, now, getdate, nowdate) from frappe.model.mapper import get_mapped_doc from erpnext.controllers.selling_controller import SellingController @@ -38,7 +38,7 @@ class Lead(SellingController): if self.email_id: if not self.flags.ignore_email_validation: - validate_email_add(self.email_id, True) + validate_email_address(self.email_id, True) if self.email_id == self.lead_owner: frappe.throw(_("Lead Owner cannot be same as the Lead")) diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index d518cd8995..a403c393b9 100755 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import getdate, validate_email_add, today, add_years, format_datetime +from frappe.utils import getdate, validate_email_address, today, add_years, format_datetime from frappe.model.naming import set_name_by_naming_series from frappe import throw, _, scrub from frappe.permissions import add_user_permission, remove_user_permission, \ @@ -142,9 +142,9 @@ class Employee(NestedSet): def validate_email(self): if self.company_email: - validate_email_add(self.company_email, True) + validate_email_address(self.company_email, True) if self.personal_email: - validate_email_add(self.personal_email, True) + validate_email_address(self.personal_email, True) def validate_status(self): if self.status == 'Left': diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.py b/erpnext/hr/doctype/job_applicant/job_applicant.py index ea81fe793d..4fc7719f38 100644 --- a/erpnext/hr/doctype/job_applicant/job_applicant.py +++ b/erpnext/hr/doctype/job_applicant/job_applicant.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from frappe.model.document import Document import frappe from frappe import _ -from frappe.utils import comma_and, validate_email_add +from frappe.utils import comma_and, validate_email_address sender_field = "email_id" @@ -28,7 +28,7 @@ class JobApplicant(Document): def validate(self): self.check_email_id_is_unique() if self.email_id: - validate_email_add(self.email_id, True) + validate_email_address(self.email_id, True) if not self.applicant_name and self.email_id: guess = self.email_id.split('@')[0] diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py index b9b2dd8fc9..9afaf90e7a 100644 --- a/erpnext/non_profit/doctype/member/member.py +++ b/erpnext/non_profit/doctype/member/member.py @@ -17,5 +17,5 @@ class Member(Document): self.validate_email_type(self.email) def validate_email_type(self, email): - from frappe.utils import validate_email_add - validate_email_add(email.strip(), True) \ No newline at end of file + from frappe.utils import validate_email_address + validate_email_address(email.strip(), True) \ No newline at end of file