mirror of
https://github.com/itsdave-de/msp.git
synced 2025-05-06 15:35:12 +02:00
Merge branch 'main' of https://github.com/itsdave-de/msp into main
This commit is contained in:
commit
a0a6759c65
29
msp/fixtures/print_format.json
Normal file
29
msp/fixtures/print_format.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"absolute_value": 0,
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"css": null,
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": null,
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "MSP Documentation",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"row clearfix main\\\">\\r\\n\\t<div class=\\\"col-xs-5 center\\\">\\r\\n\\t\\t<div style=\\\"height: 75px;\\\">\\r\\n\\t\\t\\t<img src=\\\"/files/logo-1024x300.svg\\\" height=\\\"100%\\\">\\r\\n\\t\\t</div>\\r\\n\\t</div>\\r\\n\\t<div class=\\\"col-xs-5 center\\\" style=\\\"height: 75px; display: table;\\\">\\r\\n\\t\\t<p style=\\\"display: table-cell; vertical-align: middle; text-align: right; color: #333A3F; text-transform: uppercase; font-size: 22px;\\\">\\r\\nIT Documentation\\r\\n\\t\\t<br>{{ doc.name }}</p>\\r\\n\\t</div>\\r\\n\\t<div class=\\\"col-xs-2 center\\\">\\r\\n\\t\\t<img class=\\\"vcenter\\\" style=\\\"height: 75px;\\\" src=\\\"https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=https://erpnext.itsdave.de/app/msp-documentation/{{ doc.name }}&format=svg&color=333A3F\\\">\\r\\n\\t</div>\\r\\n</div>\\r\\n<div class=\\\"row\\\">\\r\\n\\t<div class=\\\"col-xs-12\\\">\\r\\n\\t\\t<hr style=\\\"border-color: #333A3F;\\\">\\r\\n\\t</div>\\r\\n</div>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"customer\", \"print_hide\": 0, \"label\": \"Customer\"}, {\"fieldname\": \"customer_name\", \"print_hide\": 0, \"label\": \"Customer Name\"}, {\"fieldname\": \"generation_date\", \"print_hide\": 0, \"label\": \"Generation Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"landscape\", \"print_hide\": 0, \"label\": \"Landscape\"}, {\"fieldname\": \"tactical_rmm_tenant_caption\", \"print_hide\": 0, \"label\": \"Tactical RMM Tenant Caption\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"<h3>Introduction</h3>\\n{{ frappe.utils.md_to_html(doc.introduction) }}\\n<hr>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Systems from RMM\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"<h3>Server Systems</h3>\\n{{ frappe.utils.md_to_html(doc.server_list) }}\\n<hr>\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"<h3>Workstation Systems</h3>\\n{{ frappe.utils.md_to_html(doc.workstation_list) }}\\n<hr>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Backups\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"backup\", \"print_hide\": 0, \"label\": \"Backup\"}, {\"fieldname\": \"aditional_data\", \"print_hide\": 0, \"label\": \"Aditional Data\"}]",
|
||||||
|
"html": null,
|
||||||
|
"line_breaks": 0,
|
||||||
|
"modified": "2023-06-09 07:34:10.957905",
|
||||||
|
"module": "MSP",
|
||||||
|
"name": "Standard IT Landscape Documentation",
|
||||||
|
"parent": null,
|
||||||
|
"parentfield": null,
|
||||||
|
"parenttype": null,
|
||||||
|
"print_format_builder": 1,
|
||||||
|
"print_format_type": "Jinja",
|
||||||
|
"raw_commands": null,
|
||||||
|
"raw_printing": 0,
|
||||||
|
"show_section_headings": 1,
|
||||||
|
"standard": "No"
|
||||||
|
}
|
||||||
|
]
|
27
msp/hooked_methods.py
Normal file
27
msp/hooked_methods.py
Normal file
@ -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"<a href='http://{cstr(frappe.local.site)}/app/location/{result['name']}' target='_blank'>{result['location_name']}</a> --> {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} <a href='http://{cstr(frappe.local.site)}/app/location/{doctype.name}' target='_blank'>{doctype.location_name}</a>" if html_full_path != '' else f"<a href='{doctype.name}'>{doctype.location_name}</a>"
|
||||||
|
|
||||||
|
doctype.full_path = full_path
|
||||||
|
doctype.html_full_path = html_full_path
|
@ -91,7 +91,7 @@ doctype_js = {"Location" : "public/js/location.js"}
|
|||||||
|
|
||||||
doc_events = {
|
doc_events = {
|
||||||
"Location": {
|
"Location": {
|
||||||
"before_save": "msp.tools.hooks_methods.build_full_location_path"
|
"before_save": "msp.hooked_methods.build_full_location_path"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,3 +138,7 @@ doc_events = {
|
|||||||
override_doctype_class = {
|
override_doctype_class = {
|
||||||
"Location": "msp.overrides.location.CustomLocation.CustomLocation"
|
"Location": "msp.overrides.location.CustomLocation.CustomLocation"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixtures = [
|
||||||
|
{"doctype": "Print Format", "filters": {"name": "Standard IT Landscape Documentation"}}
|
||||||
|
]
|
||||||
|
@ -9,6 +9,9 @@ frappe.ui.form.on('IT Landscape', {
|
|||||||
};
|
};
|
||||||
if (frm.doc.monitoring_link) {
|
if (frm.doc.monitoring_link) {
|
||||||
frm.add_custom_button('Open Monitoring', () => frm.trigger('open_monitoring'), 'Actions');
|
frm.add_custom_button('Open Monitoring', () => frm.trigger('open_monitoring'), 'Actions');
|
||||||
|
};
|
||||||
|
if (frm.doc.rmm_instance) {
|
||||||
|
frm.add_custom_button('Get Agents From RMM', () => frm.trigger('rmm_get_agents'), 'RMM');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
open_ticket_system: function(frm) {
|
open_ticket_system: function(frm) {
|
||||||
@ -17,6 +20,21 @@ frappe.ui.form.on('IT Landscape', {
|
|||||||
open_monitoring: function(frm) {
|
open_monitoring: function(frm) {
|
||||||
window.open(frm.doc.monitoring_link, '_blank').focus();
|
window.open(frm.doc.monitoring_link, '_blank').focus();
|
||||||
},
|
},
|
||||||
|
rmm_get_agents: function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
"method": "msp.tactical-rmm.get_agents",
|
||||||
|
args: {
|
||||||
|
"it_landscape": frm.doc.name,
|
||||||
|
"rmm_instance": frm.doc.rmm_instance,
|
||||||
|
"tactical_rmm_tenant_caption": frm.doc.tactical_rmm_tenant_caption
|
||||||
|
},
|
||||||
|
callback: (response) => {
|
||||||
|
frappe.msgprint(__(response.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
copy_ssh_keys: function(frm) {
|
copy_ssh_keys: function(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
"landscape_image",
|
"landscape_image",
|
||||||
"monitoring_link",
|
"monitoring_link",
|
||||||
"ticket_system_link",
|
"ticket_system_link",
|
||||||
"tactical_rmm_tenant_caption"
|
"tactical_rmm_tenant_caption",
|
||||||
|
"rmm_instance"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -112,11 +113,17 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "IT Contract",
|
"label": "IT Contract",
|
||||||
"options": "IT Contract"
|
"options": "IT Contract"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rmm_instance",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "RMM Instance",
|
||||||
|
"options": "RMM Instance"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"image_field": "landscape_image",
|
"image_field": "landscape_image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-02-22 20:02:46.515700",
|
"modified": "2023-06-08 23:20:35.777651",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "MSP",
|
"module": "MSP",
|
||||||
"name": "IT Landscape",
|
"name": "IT Landscape",
|
||||||
|
@ -28,10 +28,15 @@
|
|||||||
"linked_objects",
|
"linked_objects",
|
||||||
"network_config_section",
|
"network_config_section",
|
||||||
"ip_adresses",
|
"ip_adresses",
|
||||||
|
"rmm_data_section",
|
||||||
|
"rmm_specs",
|
||||||
|
"rmm_software",
|
||||||
"external_links_section",
|
"external_links_section",
|
||||||
"admin_interface_link",
|
"admin_interface_link",
|
||||||
"monitoring_link",
|
"monitoring_link",
|
||||||
"oitc_host_uuid"
|
"oitc_host_uuid",
|
||||||
|
"rmm_agent_id",
|
||||||
|
"rmm_instance"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -183,11 +188,38 @@
|
|||||||
"fieldname": "serial_number",
|
"fieldname": "serial_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Serial Number"
|
"label": "Serial Number"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rmm_agent_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "RMM Agent ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rmm_instance",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "RMM Instance",
|
||||||
|
"options": "RMM Instance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "rmm_data_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "RMM Data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rmm_specs",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"label": "RMM Specs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "rmm_software",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"label": "RMM Software"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-03-02 10:10:07.173113",
|
"modified": "2023-06-08 23:00:31.338542",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "MSP",
|
"module": "MSP",
|
||||||
"name": "IT Object",
|
"name": "IT Object",
|
||||||
|
0
msp/msp/doctype/it_software_matching/__init__.py
Normal file
0
msp/msp/doctype/it_software_matching/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('IT Software Matching', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "ITSWMATCH-.#####",
|
||||||
|
"creation": "2023-06-08 22:10:40.703139",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"search_regex",
|
||||||
|
"software_name",
|
||||||
|
"category",
|
||||||
|
"active"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "search_regex",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Search Regex"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "software_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Software Name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "category",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Category",
|
||||||
|
"options": "\nSoftware\nMS Office"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "active",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Active"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2023-06-08 22:10:59.456228",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "MSP",
|
||||||
|
"name": "IT Software Matching",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class ITSoftwareMatching(Document):
|
||||||
|
pass
|
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestITSoftwareMatching(unittest.TestCase):
|
||||||
|
pass
|
@ -14,6 +14,16 @@ frappe.ui.form.on('MSP Documentation', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 'Workflow');
|
}, 'Workflow');
|
||||||
|
frm.add_custom_button('2. office suche', function(){
|
||||||
|
frappe.call({
|
||||||
|
method: 'msp.tactical-rmm.search_office',
|
||||||
|
args: { documentation: frm.doc.name },
|
||||||
|
callback:function(r){
|
||||||
|
console.log(r.message)
|
||||||
|
frm.reload_doc()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 'Workflow');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"landscape",
|
"landscape",
|
||||||
"customer",
|
"customer",
|
||||||
|
"customer_name",
|
||||||
"tactical_rmm_tenant_caption",
|
"tactical_rmm_tenant_caption",
|
||||||
"generation_date",
|
"generation_date",
|
||||||
"introduction",
|
"introduction",
|
||||||
|
"server_list",
|
||||||
|
"workstation_list",
|
||||||
"system_list",
|
"system_list",
|
||||||
"backup",
|
"backup",
|
||||||
"aditional_data"
|
"aditional_data"
|
||||||
@ -24,10 +27,12 @@
|
|||||||
"options": "IT Landscape"
|
"options": "IT Landscape"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fetch_from": "landscape.customer",
|
||||||
"fieldname": "customer",
|
"fieldname": "customer",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Customer",
|
"label": "Customer",
|
||||||
"options": "Customer"
|
"options": "Customer",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "introduction",
|
"fieldname": "introduction",
|
||||||
@ -59,11 +64,28 @@
|
|||||||
"fieldname": "generation_date",
|
"fieldname": "generation_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Generation Date"
|
"label": "Generation Date"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "server_list",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"label": "Server List"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "workstation_list",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"label": "Workstation List"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "customer.customer_name",
|
||||||
|
"fieldname": "customer_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Customer Name",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-02-02 01:08:47.664035",
|
"modified": "2023-06-09 07:14:25.256192",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "MSP",
|
"module": "MSP",
|
||||||
"name": "MSP Documentation",
|
"name": "MSP Documentation",
|
||||||
|
0
msp/msp/doctype/msp_functions/__init__.py
Normal file
0
msp/msp/doctype/msp_functions/__init__.py
Normal file
8
msp/msp/doctype/msp_functions/msp_functions.js
Normal file
8
msp/msp/doctype/msp_functions/msp_functions.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('MSP Functions', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
41
msp/msp/doctype/msp_functions/msp_functions.json
Normal file
41
msp/msp/doctype/msp_functions/msp_functions.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2023-06-08 21:34:09.516160",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"get_office_versions"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "get_office_versions",
|
||||||
|
"fieldtype": "Button",
|
||||||
|
"label": "Get Office Versions",
|
||||||
|
"options": "msp.tactical-rmm.search_office"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"issingle": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2023-06-08 21:34:09.516160",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "MSP",
|
||||||
|
"name": "MSP Functions",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
8
msp/msp/doctype/msp_functions/msp_functions.py
Normal file
8
msp/msp/doctype/msp_functions/msp_functions.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class MSPFunctions(Document):
|
||||||
|
pass
|
8
msp/msp/doctype/msp_functions/test_msp_functions.py
Normal file
8
msp/msp/doctype/msp_functions/test_msp_functions.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestMSPFunctions(unittest.TestCase):
|
||||||
|
pass
|
0
msp/msp/doctype/rmm_instance/__init__.py
Normal file
0
msp/msp/doctype/rmm_instance/__init__.py
Normal file
8
msp/msp/doctype/rmm_instance/rmm_instance.js
Normal file
8
msp/msp/doctype/rmm_instance/rmm_instance.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('RMM Instance', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
76
msp/msp/doctype/rmm_instance/rmm_instance.json
Normal file
76
msp/msp/doctype/rmm_instance/rmm_instance.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "format:RMMINST-{caption}",
|
||||||
|
"creation": "2023-06-08 22:46:28.727092",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"caption",
|
||||||
|
"type",
|
||||||
|
"api_url",
|
||||||
|
"user",
|
||||||
|
"key"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "type",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Type",
|
||||||
|
"options": "Tactical RMM",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "api_url",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "API URL",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "caption",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Caption",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "user",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "key",
|
||||||
|
"fieldtype": "Password",
|
||||||
|
"label": "Key"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2023-06-08 22:48:17.914520",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "MSP",
|
||||||
|
"name": "RMM Instance",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
8
msp/msp/doctype/rmm_instance/rmm_instance.py
Normal file
8
msp/msp/doctype/rmm_instance/rmm_instance.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class RMMInstance(Document):
|
||||||
|
pass
|
8
msp/msp/doctype/rmm_instance/test_rmm_instance.py
Normal file
8
msp/msp/doctype/rmm_instance/test_rmm_instance.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2023, itsdave GmbH and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestRMMInstance(unittest.TestCase):
|
||||||
|
pass
|
59
msp/quotation_tools.py
Normal file
59
msp/quotation_tools.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def copy_attachments(source_doctype, source_docname, target_doctype, target_docname):
|
||||||
|
attachments = frappe.get_all("File", filters={"attached_to_doctype": source_doctype, "attached_to_name": source_docname})
|
||||||
|
|
||||||
|
for attachment in attachments:
|
||||||
|
# Überprüfen Sie den Datei-URL-Wert
|
||||||
|
file_url = frappe.db.get_value("File", attachment.name, "file_url")
|
||||||
|
|
||||||
|
# Überprüfen, ob ein Anhang mit derselben URL bereits für das Ziel-Dokument existiert
|
||||||
|
exists = frappe.db.exists({
|
||||||
|
"doctype": "File",
|
||||||
|
"file_url": file_url,
|
||||||
|
"attached_to_doctype": target_doctype,
|
||||||
|
"attached_to_name": target_docname
|
||||||
|
})
|
||||||
|
|
||||||
|
if not exists:
|
||||||
|
# Wenn nicht existiert, dann Anhang zum Ziel-Dokument kopieren
|
||||||
|
attach = frappe.get_doc({
|
||||||
|
"doctype": "File",
|
||||||
|
"file_url": file_url,
|
||||||
|
"attached_to_doctype": target_doctype,
|
||||||
|
"attached_to_name": target_docname
|
||||||
|
})
|
||||||
|
attach.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
""" Benötigt das folgende Client Script für Quotation Form
|
||||||
|
|
||||||
|
frappe.ui.form.on('Quotation', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.add_custom_button(__('Anhänge hinzufügen'), function() {
|
||||||
|
attach_item_attachments_to_quotation(frm);
|
||||||
|
}, "Aktionen");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function attach_item_attachments_to_quotation(frm) {
|
||||||
|
frm.doc.items.forEach(item_row => {
|
||||||
|
frappe.call({
|
||||||
|
method: 'msp.quotation_tools.copy_attachments',
|
||||||
|
args: {
|
||||||
|
'source_doctype': 'Item',
|
||||||
|
'source_docname': item_row.item_code, // Verwenden Sie item_code, um den Anhang vom Artikel zu kopieren
|
||||||
|
'target_doctype': 'Quotation',
|
||||||
|
'target_docname': frm.doc.name
|
||||||
|
},
|
||||||
|
callback: function(response) {
|
||||||
|
if (!response.exc) {
|
||||||
|
frm.reload_doc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
frappe.msgprint(__('Anhänge wurden hinzugefügt.'));
|
||||||
|
}
|
||||||
|
"""
|
@ -4,6 +4,84 @@ from frappe.utils.password import get_decrypted_password
|
|||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
import re
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_agents(it_landscape, rmm_instance = None, tactical_rmm_tenant_caption = None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_relevant_software_for_agent(agent_id):
|
||||||
|
found_software = []
|
||||||
|
software_for_agent = get_software_for_agent(agent_id)
|
||||||
|
if "software" in software_for_agent:
|
||||||
|
for s in software_for_agent["software"]:
|
||||||
|
result = _match_software(s)
|
||||||
|
if result:
|
||||||
|
found_software.append(result)
|
||||||
|
|
||||||
|
return(found_software)
|
||||||
|
|
||||||
|
def _match_software(rmm_software_elememt):
|
||||||
|
sw_match_list = frappe.get_all("IT Software Matching", fields=["search_regex", "software_name", "category"], filters={"active": 1})
|
||||||
|
for el in sw_match_list:
|
||||||
|
result = re.match(el["search_regex"])
|
||||||
|
if result:
|
||||||
|
return {el["software_name"], el["category"]}
|
||||||
|
return None
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def search_office(agents = None):
|
||||||
|
points_for_found_strings = {}
|
||||||
|
agents_with_office = []
|
||||||
|
|
||||||
|
if not agents:
|
||||||
|
agents = get_all_agents()
|
||||||
|
todo = len(agents)
|
||||||
|
count = 0
|
||||||
|
for agent in agents:
|
||||||
|
found_office = False
|
||||||
|
count = count + 1
|
||||||
|
print("verarbeite agent " + str(count) + " von " + str(todo))
|
||||||
|
software_for_agent = get_software_for_agent(agent["agent_id"])
|
||||||
|
if "software" in software_for_agent:
|
||||||
|
for s in software_for_agent["software"]:
|
||||||
|
if (s["name"].lower().startswith("Microsoft Office".lower())):
|
||||||
|
found_string = s["name"]
|
||||||
|
found_office = True
|
||||||
|
|
||||||
|
if found_string in points_for_found_strings.keys():
|
||||||
|
points_for_found_strings[found_string] = points_for_found_strings[found_string] + 1
|
||||||
|
else:
|
||||||
|
points_for_found_strings[found_string] = 1
|
||||||
|
if found_office:
|
||||||
|
agents_with_office.append(agent)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(points_for_found_strings)
|
||||||
|
#print(len(agents_with_office))
|
||||||
|
search_for_office_patches(agents_with_office)
|
||||||
|
print(points_for_found_strings)
|
||||||
|
|
||||||
|
def search_for_office_patches(agents_with_office):
|
||||||
|
count = 0
|
||||||
|
for agent in agents_with_office:
|
||||||
|
found_patches_for_office = False
|
||||||
|
patches = get_patches_for_agent(agent["agent_id"])
|
||||||
|
for patch in patches:
|
||||||
|
if "office".lower() in patch["title"].lower():
|
||||||
|
found_patches_for_office = True
|
||||||
|
if found_patches_for_office == False:
|
||||||
|
print("kein patch für agent mit office gefunden: " + agent["hostname"] + " | " + agent["client_name"])
|
||||||
|
count = count + 1
|
||||||
|
print("Anzahl Clients: " + str(count))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_agents_pretty(documentation):
|
def get_agents_pretty(documentation):
|
||||||
@ -15,15 +93,30 @@ def get_agents_pretty(documentation):
|
|||||||
client_name = documentation_doc.tactical_rmm_tenant_caption
|
client_name = documentation_doc.tactical_rmm_tenant_caption
|
||||||
|
|
||||||
agents = get_all_agents()
|
agents = get_all_agents()
|
||||||
|
print(agents)
|
||||||
agent_list = []
|
agent_list = []
|
||||||
|
workstation_list = []
|
||||||
|
server_list = []
|
||||||
|
#if not agent_list:
|
||||||
|
# frappe.throw("API Abfrage hat keine Agents geliefert.")
|
||||||
|
|
||||||
|
|
||||||
for agent in agents:
|
for agent in agents:
|
||||||
if agent["client_name"] == client_name:
|
if agent["client_name"] == client_name:
|
||||||
agent_list.append(agent)
|
agent_list.append(agent)
|
||||||
|
if agent["monitoring_type"] == "workstation":
|
||||||
|
workstation_list.append(agent)
|
||||||
|
if agent["monitoring_type"] == "server":
|
||||||
|
server_list.append(agent)
|
||||||
|
pprint(agent)
|
||||||
|
|
||||||
output = make_agent_md_output(agent_list)
|
output = make_agent_md_output(agent_list)
|
||||||
|
output_workstation = make_agent_md_output(workstation_list)
|
||||||
|
output_server = make_agent_md_output(server_list)
|
||||||
|
|
||||||
documentation_doc.system_list = output
|
documentation_doc.system_list = output
|
||||||
|
documentation_doc.workstation_list = output_workstation
|
||||||
|
documentation_doc.server_list = output_server
|
||||||
documentation_doc.save()
|
documentation_doc.save()
|
||||||
return agent_list
|
return agent_list
|
||||||
|
|
||||||
@ -42,9 +135,48 @@ def get_all_agents():
|
|||||||
}
|
}
|
||||||
|
|
||||||
agents = requests.get(f"{API}/agents/?detail=true", headers=HEADERS)
|
agents = requests.get(f"{API}/agents/?detail=true", headers=HEADERS)
|
||||||
|
|
||||||
return agents.json()
|
return agents.json()
|
||||||
|
|
||||||
|
def get_software_for_agent(agent_id=None):
|
||||||
|
settings = frappe.get_single("MSP Settings")
|
||||||
|
if not settings.api_key:
|
||||||
|
frappe.throw("API Key is missing")
|
||||||
|
if not settings.api_url:
|
||||||
|
frappe.throw("API URL is missing")
|
||||||
|
|
||||||
|
API = settings.api_url
|
||||||
|
HEADERS = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-API-KEY": get_decrypted_password("MSP Settings", "MSP Settings", "api_key", raise_exception=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
if not agent_id:
|
||||||
|
frappe.throw("Agent ID fehlt")
|
||||||
|
|
||||||
|
software_for_agent = requests.get(f"{API}/software/{agent_id}/", headers=HEADERS)
|
||||||
|
return software_for_agent.json()
|
||||||
|
|
||||||
|
def get_patches_for_agent(agent_id=None):
|
||||||
|
settings = frappe.get_single("MSP Settings")
|
||||||
|
if not settings.api_key:
|
||||||
|
frappe.throw("API Key is missing")
|
||||||
|
if not settings.api_url:
|
||||||
|
frappe.throw("API URL is missing")
|
||||||
|
|
||||||
|
API = settings.api_url
|
||||||
|
HEADERS = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-API-KEY": get_decrypted_password("MSP Settings", "MSP Settings", "api_key", raise_exception=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
if not agent_id:
|
||||||
|
frappe.throw("Agent ID fehlt")
|
||||||
|
|
||||||
|
patches_for_agent = requests.get(f"{API}/winupdate/{agent_id}/", headers=HEADERS)
|
||||||
|
return patches_for_agent.json()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_agent_md_output(agents):
|
def make_agent_md_output(agents):
|
||||||
md_output = ""
|
md_output = ""
|
||||||
@ -56,8 +188,12 @@ def make_agent_md_output(agents):
|
|||||||
- GPU: {agent["graphics"]}
|
- GPU: {agent["graphics"]}
|
||||||
- Disks: {agent["physical_disks"]}
|
- Disks: {agent["physical_disks"]}
|
||||||
- Model: {render_model(agent["make_model"])}
|
- Model: {render_model(agent["make_model"])}
|
||||||
|
- Serial Number: {agent["serial_number"]}
|
||||||
- Type: {agent["monitoring_type"]}
|
- Type: {agent["monitoring_type"]}
|
||||||
- Site: {agent["site_name"]}
|
- Site: {agent["site_name"]}
|
||||||
|
- Local IPs: {agent["local_ips"]}
|
||||||
|
- Public IP: {agent["public_ip"]}
|
||||||
|
- Last Seen: {agent["last_seen"]}
|
||||||
- Last User: {agent["logged_username"]}
|
- Last User: {agent["logged_username"]}
|
||||||
'''
|
'''
|
||||||
if agent["description"]:
|
if agent["description"]:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user