diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index c7ac57d..f3904e2 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ .DS_Store -.vs/ *.pyc *.egg-info *.swp tags fleet_management/docs/current node_modules/ +.vs/ \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100755 index 0d4654a..0000000 Binary files a/.vs/slnx.sqlite and /dev/null differ diff --git a/MANIFEST.in b/MANIFEST.in old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/fleet_management/__init__.py b/fleet_management/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/config/__init__.py b/fleet_management/config/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/config/desktop.py b/fleet_management/config/desktop.py old mode 100755 new mode 100644 diff --git a/fleet_management/config/docs.py b/fleet_management/config/docs.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/__init__.py b/fleet_management/fleet_management/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/__init__.py b/fleet_management/fleet_management/doctype/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/fleet_vehicle/__init__.py b/fleet_management/fleet_management/doctype/fleet_vehicle/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.js b/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.js old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.json b/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.json old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.py b/fleet_management/fleet_management/doctype/fleet_vehicle/fleet_vehicle.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/fleet_vehicle/test_fleet_vehicle.py b/fleet_management/fleet_management/doctype/fleet_vehicle/test_fleet_vehicle.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/traccar_settings/__init__.py b/fleet_management/fleet_management/doctype/traccar_settings/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/traccar_settings/test_traccar_settings.py b/fleet_management/fleet_management/doctype/traccar_settings/test_traccar_settings.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.js b/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.js old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.json b/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.json old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.py b/fleet_management/fleet_management/doctype/traccar_settings/traccar_settings.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/tracker/__init__.py b/fleet_management/fleet_management/doctype/tracker/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/tracker/test_tracker.py b/fleet_management/fleet_management/doctype/tracker/test_tracker.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/tracker/tracker.js b/fleet_management/fleet_management/doctype/tracker/tracker.js old mode 100755 new mode 100644 index 5ea8e16..7d997fe --- a/fleet_management/fleet_management/doctype/tracker/tracker.js +++ b/fleet_management/fleet_management/doctype/tracker/tracker.js @@ -1,8 +1,136 @@ -// Copyright (c) 2024, itsdave GmbH and contributors +// Copyright (c) 2024, itsdave GmbH and contributors // For license information, please see license.txt -frappe.ui.form.on('Tracker', { - // refresh: function(frm) { +frappe.listview_settings.Tracker = { + button: { + show: function (doc) { + return true; + }, + get_label: function () { + return __('🗺️ Show Trips'); + }, + get_description: function (doc) { + return __('Show trip for {0}', [doc.name]); + }, + action: function (doc) { + // Função para abrir um modal de filtros + const openDateFilterModal = () => { + const options = [ + { label: __('Today'), value: 'today' }, + { label: __('Yesterday'), value: 'yesterday' }, + { label: __('Last Week'), value: 'last_week' }, + { label: __('Current Month'), value: 'current_month' }, + { label: __('Custom'), value: 'custom' } + ]; + const defaultOption = 'today'; - // } -}); + const fields = [ + { + label: __('Select Date Range'), + fieldtype: 'Select', + fieldname: 'date_range', + options: options.map(option => option.label), + onchange: function () { + const selectedOption = options.find( + option => option.label === this.value + ); + toggleCustomDateFields(selectedOption.value === 'custom', dialog); + } + }, + // Fields hidden for custom date selection that will be shown when 'Custom' is selected + { + label: __('Start Date'), + fieldtype: 'Date', + fieldname: 'start_date', + depends_on: 'eval:doc.date_range=="Custom"' + }, + { + label: __('End Date'), + fieldtype: 'Date', + fieldname: 'end_date', + depends_on: 'eval:doc.date_range=="Custom"' + }, + ]; + + const dialog = new frappe.ui.Dialog({ + title: __('Select Date Range'), + fields: fields, + primary_action_label: __('Apply Filter'), + primary_action: function (values) { + if (values.date_range === 'Custom' && values.start_date && values.end_date) { + applyDateFilter('custom', values.start_date, values.end_date); + } else { + const selectedOption = options.find( + option => option.label === values.date_range + ); + applyDateFilter(selectedOption.value); + } + dialog.hide(); + } + }); + dialog.show(); + + function toggleCustomDateFields(show, dialog) { + const startField = dialog.fields_dict.start_date.$wrapper; + const endField = dialog.fields_dict.end_date.$wrapper; + if (show) { + startField.show(); + endField.show(); + } else { + startField.hide(); + endField.hide(); + } + } + + const applyDateFilter = (filterValue, startDate, endDate) => { + // Logica para definir startDate e endDate com base no filterValue + switch (filterValue) { + case 'today': + startDate = moment().subtract(1, 'days').format('YYYY-MM-DD 23:00:00'); + endDate = moment().format('YYYY-MM-DD 23:59:59'); + break; + case 'yesterday': + startDate = moment().subtract(2, 'days').format('YYYY-MM-DD 23:00:00'); + endDate = moment().subtract(1, 'days').format('YYYY-MM-DD 23:59:59'); + break; + case 'last_week': + startDate = moment().subtract(7, 'days').format('YYYY-MM-DD 23:00:00'); + endDate = moment().format('YYYY-MM-DD 23:59:59'); + break; + case 'current_month': + startDate = moment().subtract(30, 'days').format('YYYY-MM-DD 23:00:00'); + endDate = moment().format('YYYY-MM-DD 23:59:59'); + break; + case 'custom': + startDate = moment(startDate).format('YYYY-MM-DD 23:00:00'); + endDate = moment(endDate).format('YYYY-MM-DD 23:59:59'); + break; + } + + // Let's redirect to the Trip list view with the selected filters + frappe.set_route('List', 'Trip', { + 'device_id': doc.portal_id, + 'start': ['>=', startDate], + 'end': ['<=', endDate] + }); + }; + }; + + // Chamada para abrir o modal de filtros + openDateFilterModal(); + } + }, + + onload(listview) { + listview.page.add_inner_button('Sync devices', function () { + frappe.call({ + method: 'fleet_management.traccar_api.get_devices', + callback: function (r) { + if (!r.exc) { + location.reload(); + } + } + }); + }); + } +}; diff --git a/fleet_management/fleet_management/doctype/tracker/tracker.json b/fleet_management/fleet_management/doctype/tracker/tracker.json old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/tracker/tracker.py b/fleet_management/fleet_management/doctype/tracker/tracker.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/trip/__init__.py b/fleet_management/fleet_management/doctype/trip/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/trip/test_trip.py b/fleet_management/fleet_management/doctype/trip/test_trip.py old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/trip/trip.js b/fleet_management/fleet_management/doctype/trip/trip.js old mode 100755 new mode 100644 index 89e0b08..9ddfd17 --- a/fleet_management/fleet_management/doctype/trip/trip.js +++ b/fleet_management/fleet_management/doctype/trip/trip.js @@ -1,8 +1,170 @@ -// Copyright (c) 2024, itsdave GmbH and contributors +// Copyright (c) 2024, itsdave GmbH and contributors // For license information, please see license.txt -frappe.ui.form.on('Trip', { - // refresh: function(frm) { +function loadLeafletAndInitMap(frm, callback) { + if (typeof callback === "function") callback(frm); // Leaftlet is already loaded, just run the callback +} - // } -}); +function create_dialog_and_init_map(frm) { + const dialog = new frappe.ui.Dialog({ + title: 'Show Route', + fields: [{ fieldtype: 'HTML', fieldname: 'map_html', label: 'Map', options: '
' }], + primary_action_label: 'Close', + primary_action() { + if (currentMap) { + currentMap.remove(); // Remove the map when closing the dialog + currentMap = null; // unset the reference + } + dialog.hide(); + } + }); + + // Add hide event to reload the page when the dialog is closed + dialog.onhide = function () { + window.location.reload(); + }; + + dialog.show(); + setTimeout(() => init_map(frm), 500); // Add a delay to ensure the map loads correctly +} + +var currentMap = null; + +function init_map(frm) { + console.table(window.L); + console.log("Initializing map with MyLeaflet..."); + if (currentMap !== null) { + currentMap.remove(); // Remove the previous map if it exists + } + var map = window.L.map('map').setView([52.998919, 10.0654483], 13); + window.L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap' + }).addTo(map); + currentMap = map; + + // Create a layer group for checkpoint markers + var checkpointMarkers = window.L.layerGroup().addTo(map); + + // Control to toggle checkpoint markers + var control = window.L.control({ position: 'topleft' }); + control.onAdd = function (map) { + var div = window.L.DomUtil.create('div', 'leaflet-control leaflet-bar'); + var button = window.L.DomUtil.create('a', '', div); + button.innerHTML = '📍'; + button.href = '#'; + + window.L.DomEvent.on(button, 'click', function (e) { + window.L.DomEvent.stop(e); // Alterado para parar totalmente o evento + + if (map.hasLayer(checkpointMarkers)) { + map.removeLayer(checkpointMarkers); // Desligar + } else { + map.addLayer(checkpointMarkers); // Ligar + } + }); + + return div; + }; + control.addTo(map); + + // call data from api + frappe.call({ + method: "fleet_management.traccar_api.getroutes", + args: { + "name": frm.name, + "start": frm.start, + "end": frm.end + }, + callback: function (r) { + if (r.message) { + console.table(r.message); + const data = r.message; + const routeCoordinates = data.map(entry => [entry.latitude, entry.longitude]); + const polyline = window.L.polyline(routeCoordinates, { color: 'red' }).addTo(map); + map.fitBounds(polyline.getBounds()); + + // Add differentiated markers + data.forEach((point, index) => { + let markerColor, layerToAdd = map; + let popupMessage = `Time: ${moment(point.deviceTime).tz("Europe/Berlin").format('DD/MM/YYYY HH:mm:ss')}
Speed: ${parseFloat(point.speed).toFixed(2)} km/h`; + + if (index === 0) { // Point of start + markerColor = 'green'; + } else if (index === data.length - 1) { // Point of end + markerColor = 'blue'; + } else { // Points in between + markerColor = 'yellow'; + layerToAdd = checkpointMarkers; // Add these markers to the checkpoint layer + } + + const icon = new window.L.Icon({ + iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${markerColor}.png`, + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + iconSize: [20, 32], + iconAnchor: [10, 32], + popupAnchor: [1, -32], + shadowSize: [32, 32] + }); + + window.L.marker([point.latitude, point.longitude], { icon: icon }).addTo(layerToAdd) + .bindPopup(popupMessage); + }); + } + }, + error: function (error) { + console.error('Error loading the route data:', error); + frappe.msgprint('Error loading the route data'); + } + }); +} + +function show_map(frm) { + console.log("Loading map..."); + loadLeafletAndInitMap(frm, create_dialog_and_init_map); +} + +frappe.listview_settings.Trip = { + button: { + show: function (doc) { + return true; + }, + get_label: function () { + return __('🗺️ Map route'); + }, + get_description: function (doc) { + return __('Show map route'); + }, + action: function (doc) { + show_map(doc); + } + }, + formatters: { + average_speed(val) { + return (parseFloat(val) * 1.852).toFixed(2) + " km/h"; // Convert knots to km/h + //return parseFloat(val) + " km/h"; // Convert knots to km/h + }, + distance(val) { + return (parseFloat(val) / 1000).toFixed(2) + " km"; // Convert meters to km + //return parseFloat(val) + " km"; // Convert meters to km + } + }, + onload(listview) { + listview.page.add_inner_button('Force Route Synchronization', function () { + frappe.show_alert({ indicator: 'blue', message: __("🔄 Synchronizing data...") }); + frappe.call({ + method: 'fleet_management.tasks.get_trips_for_device', + freeze: true, // Option to freeze the user interface with a transparent overlay + freeze_message: __("🔄 Synchronizing data..."), // Message to show when the user interface is frozen + callback: function (r) { + if (!r.exc) { + frappe.hide_msgprint(); // Hide the synchronization message / spinner + location.reload(); // Reload the page after completion + } else { + frappe.show_alert({ message: __("Synchronization failed"), indicator: 'red' }); + } + } + }); + }); + } +}; diff --git a/fleet_management/fleet_management/doctype/trip/trip.json b/fleet_management/fleet_management/doctype/trip/trip.json old mode 100755 new mode 100644 diff --git a/fleet_management/fleet_management/doctype/trip/trip.py b/fleet_management/fleet_management/doctype/trip/trip.py old mode 100755 new mode 100644 diff --git a/fleet_management/hooks.py b/fleet_management/hooks.py old mode 100755 new mode 100644 diff --git a/fleet_management/modules.txt b/fleet_management/modules.txt old mode 100755 new mode 100644 diff --git a/fleet_management/patches.txt b/fleet_management/patches.txt old mode 100755 new mode 100644 diff --git a/fleet_management/public/.gitkeep b/fleet_management/public/.gitkeep old mode 100755 new mode 100644 diff --git a/fleet_management/tasks.py b/fleet_management/tasks.py old mode 100755 new mode 100644 diff --git a/fleet_management/templates/__init__.py b/fleet_management/templates/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/templates/pages/__init__.py b/fleet_management/templates/pages/__init__.py old mode 100755 new mode 100644 diff --git a/fleet_management/traccar_api.py b/fleet_management/traccar_api.py old mode 100755 new mode 100644 diff --git a/license.txt b/license.txt old mode 100755 new mode 100644 diff --git a/requirements.txt b/requirements.txt old mode 100755 new mode 100644 diff --git a/setup.py b/setup.py old mode 100755 new mode 100644