diff --git a/msp/hooks.py b/msp/hooks.py index 5df4a86..9fdebce 100644 --- a/msp/hooks.py +++ b/msp/hooks.py @@ -39,6 +39,8 @@ jenv = { # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} # doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"} +doctype_js = {"Location" : "public/js/location.js"} + # Home Pages # ---------- @@ -87,11 +89,11 @@ jenv = { # --------------- # Hook on document methods and events -# doc_events = { -# "Customer": { -# "on_update": "msp.msp.customer_quick_entry.custom_customer_info" -# } -# } +doc_events = { + "Location": { + "before_save": "msp.tools.hooks_methods.build_full_location_path" + } +} # Scheduled Tasks # --------------- @@ -133,3 +135,6 @@ jenv = { # "Task": "msp.task.get_dashboard_data" # } +override_doctype_class = { + "Location": "msp.overrides.location.CustomLocation.CustomLocation" +} diff --git a/msp/msp/custom/location.json b/msp/msp/custom/location.json new file mode 100644 index 0000000..231f59c --- /dev/null +++ b/msp/msp/custom/location.json @@ -0,0 +1,237 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-06 09:39:15.583037", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Location", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "full_path", + "fieldtype": "Data", + "hidden": 1, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 4, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "html_full_path", + "label": "Full Path", + "length": 1000, + "mandatory_depends_on": null, + "modified": "2022-09-06 09:39:15.583037", + "modified_by": "Administrator", + "name": "Location-full_path", + "no_copy": 0, + "non_negative": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": "", + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": "" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-06 15:02:44.835105", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Location", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "html_full_path", + "fieldtype": "Text Editor", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 3, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "parent_location", + "label": "HTML Full Path", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-06 15:02:44.835105", + "modified_by": "Administrator", + "name": "Location-html_full_path", + "no_copy": 0, + "non_negative": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-06 15:12:53.892684", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Location", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "type", + "fieldtype": "Select", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 5, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_preview": 0, + "in_standard_filter": 1, + "insert_after": "full_path", + "label": "Type", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-06 15:12:53.892684", + "modified_by": "Administrator", + "name": "Location-type", + "no_copy": 0, + "non_negative": 0, + "options": "\nCountry\nState\nCity\nStreet\nBuilding\nFloor\nRoom\nRack\nHU", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 1, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Location", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2022-09-06 13:12:35.858567", + "default_value": null, + "doc_type": "Location", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2022-09-06 13:12:35.858567", + "modified_by": "Administrator", + "name": "Location-main-search_fields", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "search_fields", + "property_type": "Data", + "row_name": null, + "value": "location_name, full_path" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2022-09-06 09:37:34.757324", + "default_value": null, + "doc_type": "Location", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2022-09-06 09:37:34.757324", + "modified_by": "Administrator", + "name": "Location-main-autoname", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "autoname", + "property_type": "Data", + "row_name": null, + "value": "LOC-.#####" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/msp/msp/custom/todo.json b/msp/msp/custom/todo.json new file mode 100644 index 0000000..80fe3f8 --- /dev/null +++ b/msp/msp/custom/todo.json @@ -0,0 +1,308 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-05 12:52:53.000762", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "ToDo", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "ip_network", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 19, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "assignment_rule", + "label": "IP Network", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-05 12:52:53.000762", + "modified_by": "Administrator", + "name": "ToDo-ip_network", + "no_copy": 0, + "non_negative": 0, + "options": "IP Network", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-05 12:56:53.645299", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "ToDo", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "it_landscape", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 20, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "ip_network", + "label": "IT Landscape", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-05 12:56:53.645299", + "modified_by": "Administrator", + "name": "ToDo-it_landscape", + "no_copy": 0, + "non_negative": 0, + "options": "IT Landscape", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-05 12:56:53.920916", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "ToDo", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "it_object", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 21, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "it_landscape", + "label": "IT Object", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-05 12:56:53.920916", + "modified_by": "Administrator", + "name": "ToDo-it_object", + "no_copy": 0, + "non_negative": 0, + "options": "IT Object", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-05 12:56:54.064975", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "ToDo", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "ip_address", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 22, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "it_object", + "label": "IP Address", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-05 12:56:54.064975", + "modified_by": "Administrator", + "name": "ToDo-ip_address", + "no_copy": 0, + "non_negative": 0, + "options": "IP Address", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2022-09-05 13:10:58.880444", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "ToDo", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "it_user_account", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "idx": 22, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "ip_address", + "label": "IT User Account", + "length": 0, + "mandatory_depends_on": null, + "modified": "2022-09-05 13:10:58.880444", + "modified_by": "Administrator", + "name": "ToDo-it_user_account", + "no_copy": 0, + "non_negative": 0, + "options": "IT User Account", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "ToDo", + "property_setters": [], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/msp/msp/doctype/ip_address/ip_address.json b/msp/msp/doctype/ip_address/ip_address.json index 4b1f6d1..a8692fd 100644 --- a/msp/msp/doctype/ip_address/ip_address.json +++ b/msp/msp/doctype/ip_address/ip_address.json @@ -10,6 +10,7 @@ "title", "ip_address", "protocol", + "it_object_name", "it_object", "ip_network", "it_landscape" @@ -37,7 +38,8 @@ "fieldname": "it_object", "fieldtype": "Link", "label": "IT Object", - "options": "IT Object" + "options": "IT Object", + "read_only": 1 }, { "fieldname": "it_landscape", @@ -52,10 +54,16 @@ "label": "IP Network", "options": "IP Network", "reqd": 1 + }, + { + "fieldname": "it_object_name", + "fieldtype": "Data", + "label": "IT Object Name", + "read_only": 1 } ], "links": [], - "modified": "2022-06-17 11:21:47.850521", + "modified": "2022-09-05 12:03:39.294521", "modified_by": "Administrator", "module": "MSP", "name": "IP Address", diff --git a/msp/msp/doctype/ip_address/ip_address_dashboard.py b/msp/msp/doctype/ip_address/ip_address_dashboard.py new file mode 100644 index 0000000..e2d4eb9 --- /dev/null +++ b/msp/msp/doctype/ip_address/ip_address_dashboard.py @@ -0,0 +1,14 @@ +from __future__ import unicode_literals +from frappe import _ + +def get_data(): + return { + 'heatmap': False, + 'fieldname': 'ip_address', + 'transactions': [ + { + 'label': _('Processes'), + 'items': ['ToDo'] + } + ] + } diff --git a/msp/msp/doctype/ip_network/ip_network.json b/msp/msp/doctype/ip_network/ip_network.json index 2cf5750..ae54fed 100644 --- a/msp/msp/doctype/ip_network/ip_network.json +++ b/msp/msp/doctype/ip_network/ip_network.json @@ -27,6 +27,7 @@ "it_landscape", "description", "customer", + "location_full_path", "location", "ip_network_reserved_ranges_section", "ip_network_reserved_ranges_table", @@ -172,10 +173,17 @@ "fieldtype": "HTML", "label": "Usage Overview Table", "options": "
Used IPs expected
" + }, + { + "fetch_from": "location.html_full_path", + "fieldname": "location_full_path", + "fieldtype": "Text Editor", + "label": "Location Full Path", + "read_only": 1 } ], "links": [], - "modified": "2022-08-18 10:28:34.233288", + "modified": "2022-09-06 16:39:46.172950", "modified_by": "Administrator", "module": "MSP", "name": "IP Network", diff --git a/msp/msp/doctype/ip_network/ip_network.py b/msp/msp/doctype/ip_network/ip_network.py index 9bff55c..e433fac 100644 --- a/msp/msp/doctype/ip_network/ip_network.py +++ b/msp/msp/doctype/ip_network/ip_network.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +import socket from ipaddress import IPv4Address, IPv4Network from frappe.model.document import Document @@ -16,6 +17,7 @@ class IPNetwork(Document): SELECT ipa.name as ip_address_name, ipa.ip_address, + ipa.protocol, ito.name as it_object_name, ito.title, ito.type, @@ -35,15 +37,19 @@ class IPNetwork(Document): used_ips.append({ 'ip_address': ip_network_reserved_range.start, 'title': ip_network_reserved_range.type, - 'type': 'DHCP Range Start' + 'type': 'DHCP Range Start', + 'protocol': ip_network_reserved_range.protocol }) used_ips.append({ 'ip_address': ip_network_reserved_range.end, 'title': ip_network_reserved_range.type, - 'type': 'DHCP Range End' + 'type': 'DHCP Range End', + 'protocol': ip_network_reserved_range.protocol }) - return used_ips + # Sorting method is using inet_pton built in function which is used to convert IPs from string format to a packed, binary format to be able to compare them. It supports IPv4 and IPv6 IPs + # @see https://docs.python.org/3/library/socket.html#socket.inet_pton and https://stackoverflow.com/a/6545090 for more information + return sorted(used_ips, key=lambda item: socket.inet_pton(socket.AF_INET if item['protocol'] == 'IPv4' or not item['protocol'] else socket.AF_INET6 , item['ip_address'])) @frappe.whitelist() def calculate_network_data(doc): diff --git a/msp/msp/doctype/ip_network/ip_network_dashboard.py b/msp/msp/doctype/ip_network/ip_network_dashboard.py index 9ccf345..71feceb 100644 --- a/msp/msp/doctype/ip_network/ip_network_dashboard.py +++ b/msp/msp/doctype/ip_network/ip_network_dashboard.py @@ -9,6 +9,10 @@ def get_data(): { 'label': _('Objects'), 'items': ['IP Address' ] + }, + { + 'label': _('Processes'), + 'items': ['ToDo' ] } ] } diff --git a/msp/msp/doctype/ip_network_reserved_range/ip_network_reserved_range.json b/msp/msp/doctype/ip_network_reserved_range/ip_network_reserved_range.json index 993669f..cc0f7f6 100644 --- a/msp/msp/doctype/ip_network_reserved_range/ip_network_reserved_range.json +++ b/msp/msp/doctype/ip_network_reserved_range/ip_network_reserved_range.json @@ -9,6 +9,7 @@ "start", "end", "type", + "protocol", "description" ], "fields": [ @@ -35,12 +36,19 @@ "fieldname": "description", "fieldtype": "Text Editor", "label": "Description" + }, + { + "default": "IPv4", + "fieldname": "protocol", + "fieldtype": "Select", + "label": "Protocol", + "options": "IPv4\nIPv6" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2022-08-17 13:44:07.476976", + "modified": "2022-09-05 09:57:47.527108", "modified_by": "Administrator", "module": "MSP", "name": "IP Network Reserved Range", diff --git a/msp/msp/doctype/it_landscape/it_landscape_dashboard.py b/msp/msp/doctype/it_landscape/it_landscape_dashboard.py index 3b57d2f..7f66ea2 100644 --- a/msp/msp/doctype/it_landscape/it_landscape_dashboard.py +++ b/msp/msp/doctype/it_landscape/it_landscape_dashboard.py @@ -13,7 +13,7 @@ def get_data(): }, { 'label': _('Processes'), - 'items': ['IT Contract'] + 'items': ['IT Contract', 'ToDo'] } ] } diff --git a/msp/msp/doctype/it_object/it_object.json b/msp/msp/doctype/it_object/it_object.json index 35d9320..d5c0771 100644 --- a/msp/msp/doctype/it_object/it_object.json +++ b/msp/msp/doctype/it_object/it_object.json @@ -16,6 +16,7 @@ "item", "customer", "it_landscape", + "location_full_path", "location", "monitoring_section", "oitc_output", @@ -156,11 +157,18 @@ "fieldtype": "HTML", "label": "OITC Output", "options": "
OITC output expected
" + }, + { + "fetch_from": "location.html_full_path", + "fieldname": "location_full_path", + "fieldtype": "Text Editor", + "label": "Location Full Path", + "read_only": 1 } ], "image_field": "image", "links": [], - "modified": "2022-07-18 15:05:40.504305", + "modified": "2022-09-06 16:18:52.084632", "modified_by": "Administrator", "module": "MSP", "name": "IT Object", diff --git a/msp/msp/doctype/it_object/it_object.py b/msp/msp/doctype/it_object/it_object.py index 7312138..48594f3 100644 --- a/msp/msp/doctype/it_object/it_object.py +++ b/msp/msp/doctype/it_object/it_object.py @@ -8,6 +8,26 @@ import requests from frappe.model.document import Document class ITObject(Document): + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + self.set_it_object_data_in_ip_address_doctype() + + def set_it_object_data_in_ip_address_doctype(self): + if not self.main_ip: + return + + ip_address_name_with_it_object = frappe.db.get_value("IP Address", {'it_object': self.name}, ['name']) + if ip_address_name_with_it_object: + current_ip_address_with_it_object_doctype = frappe.get_doc("IP Address", ip_address_name_with_it_object) + current_ip_address_with_it_object_doctype.it_object = None + current_ip_address_with_it_object_doctype.it_object_name = None + current_ip_address_with_it_object_doctype.save() + + ip_address_doctype = frappe.get_doc("IP Address", self.main_ip) + ip_address_doctype.it_object = self.name + ip_address_doctype.it_object_name = self.title + ip_address_doctype.save() + frappe.db.commit() def get_host_status_from_hosts_data(self, hosts_data, msp_settings_doc): @@ -75,3 +95,9 @@ class ITObject(Document): 'status': 500, 'response': f'Data could not be fetched from {msp_settings_doc.oitc_url}. Error -> {str(exception)}' } + +def set_it_object_data_in_ip_address_doctype_for_existing_it_objects(): + it_objects = frappe.db.get_all("IT Object", fields=['name']) + for it_object in it_objects: + it_object_doctype = frappe.get_doc("IT Object", it_object['name']) + it_object_doctype.set_it_object_data_in_ip_address_doctype() diff --git a/msp/msp/doctype/it_object/it_object_dashboard.py b/msp/msp/doctype/it_object/it_object_dashboard.py new file mode 100644 index 0000000..1721e13 --- /dev/null +++ b/msp/msp/doctype/it_object/it_object_dashboard.py @@ -0,0 +1,14 @@ +from __future__ import unicode_literals +from frappe import _ + +def get_data(): + return { + 'heatmap': False, + 'fieldname': 'it_object', + 'transactions': [ + { + 'label': _('Processes'), + 'items': ['ToDo'] + } + ] + } diff --git a/msp/msp/doctype/it_user_account/it_user_account_dashboard.py b/msp/msp/doctype/it_user_account/it_user_account_dashboard.py new file mode 100644 index 0000000..421ec63 --- /dev/null +++ b/msp/msp/doctype/it_user_account/it_user_account_dashboard.py @@ -0,0 +1,14 @@ +from __future__ import unicode_literals +from frappe import _ + +def get_data(): + return { + 'heatmap': False, + 'fieldname': 'it_user_account', + 'transactions': [ + { + 'label': _('Processes'), + 'items': ['ToDo'] + } + ] + } diff --git a/msp/overrides/location/CustomLocation.py b/msp/overrides/location/CustomLocation.py new file mode 100644 index 0000000..ea210b5 --- /dev/null +++ b/msp/overrides/location/CustomLocation.py @@ -0,0 +1,18 @@ +import frappe +from erpnext.assets.doctype.location.location import Location + +class CustomLocation(Location): + @frappe.whitelist() + def get_all_child_locations_from_location(self): + parent_location_name = self.name + locations_to_filter = [] + return self.search_child_locations(locations_to_filter, parent_location_name) + + def search_child_locations(self, locations_to_filter, parent_location_name): + locations_to_filter.append(parent_location_name) + child_locations = frappe.db.get_list('Location', {'parent_location': parent_location_name}, ['name']) + if child_locations: + for child_location in child_locations: + self.search_child_locations(locations_to_filter, child_location['name']) + + return locations_to_filter diff --git a/msp/overrides/location/__init__.py b/msp/overrides/location/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/msp/public/js/location.js b/msp/public/js/location.js new file mode 100644 index 0000000..6391515 --- /dev/null +++ b/msp/public/js/location.js @@ -0,0 +1,10 @@ +frappe.ui.form.on('Location', { + refresh(frm) { + frm.add_custom_button('Show IT Objects in Location', () => { + frm.call('get_all_child_locations_from_location',{}) + .then((response) => { + frappe.set_route('List', 'IT Object', { location: ['in', `${response.message.toString()}`] }) + }) + }) + } +}); diff --git a/msp/tools/hooks_methods.py b/msp/tools/hooks_methods.py new file mode 100644 index 0000000..962d83f --- /dev/null +++ b/msp/tools/hooks_methods.py @@ -0,0 +1,27 @@ +import frappe +from frappe.utils import cstr + +def build_full_location_path(doctype, method=None): + parent_location_name = doctype.parent_location + full_path = '' + html_full_path = '' + has_parent_location = True if parent_location_name else False + + while has_parent_location: + result = frappe.db.get_value('Location', {'name': parent_location_name}, ['name', 'location_name', 'parent_location'], as_dict=True) + if not result: + has_parent_location = False + continue + + full_path = f"{result['location_name']} --> {full_path}" + html_full_path = f"{result['location_name']} --> {html_full_path}" + parent_location_name = result['parent_location'] + + if not parent_location_name: + has_parent_location = False + + full_path = f"{full_path} {doctype.location_name}" if full_path != '' else doctype.location_name + html_full_path = f"{html_full_path} {doctype.location_name}" if html_full_path != '' else f"{doctype.location_name}" + + doctype.full_path = full_path + doctype.html_full_path = html_full_path