GPS Tracking With Scheduler Event

Good day Everyone

I created a new Client Script to fetch the GPS Coordinates for the (Employee Checkin) Doctype, and it’s working well. Now, I need to keep track of all the Employees who Check-in all day long.

How can I keep track of the Employees’ GPS Coordinates?

I tried creating a Scheduler Event in Server Script in order to register the GPS Data of the Employees on an hourly basis, but it doesn’t seem to be working or rather I don’t know how to make it work.

Here is the code (JavaScript - Client Script)

frappe.ui.form.on('Employee Checkin', {
	onload(frm) {
	    function onPositionRecieved(position){
	        var longitude= position.coords.longitude;
	        var latitude= position.coords.latitude;
	        frm.set_value('longitude',longitude);
	        frm.set_value('latitude',latitude);
	        console.log(longitude);
	        console.log(latitude);
	        fetch('https://api.opencagedata.com/geocode/v1/json?q='+latitude+'+'+longitude+'&key=813661b481fe4ee8b2f7fcf770c06a30')
	         .then(response => response.json())
            .then(data => {
                var city=data['results'][0].components.city;
                var state=data['results'][0].components.state;
                var area=data['results'][0].components.residential;
                frm.set_value('city',city);
                frm.set_value('state',state);
                frm.set_value('area',area);
                console.log(data);
            })
            .catch(err => console.log(err));
	        frm.set_df_property('my_location','options','<div class="mapouter"><div class="gmap_canvas"><iframe width=100% height="300" id="gmap_canvas" src="https://maps.google.com/maps?q='+latitude+','+longitude+'&t=&z=17&ie=UTF8&iwloc=&output=embed" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe><a href="https://yt2.org/youtube-to-mp3-ALeKk00qEW0sxByTDSpzaRvl8WxdMAeMytQ1611842368056QMMlSYKLwAsWUsAfLipqwCA2ahUKEwiikKDe5L7uAhVFCuwKHUuFBoYQ8tMDegUAQCSAQCYAQCqAQdnd3Mtd2l6"></a><br><style>.mapouter{position:relative;text-align:right;height:300px;width:100%;}</style><style>.gmap_canvas {overflow:hidden;background:none!important;height:300px;width:100%;}</style></div></div>');
            frm.refresh_field('my_location');
	    }
	    
	    function locationNotRecieved(positionError){
	        console.log(positionError);
	    }
	    
	    if(frm.doc.longitude && frm.doc.latitude){
	        frm.set_df_property('my_location','options','<div class="mapouter"><div class="gmap_canvas"><iframe width=100% height="300" id="gmap_canvas" src="https://maps.google.com/maps?q='+frm.doc.latitude+','+frm.doc.longitude+'&t=&z=17&ie=UTF8&iwloc=&output=embed" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe><a href="https://yt2.org/youtube-to-mp3-ALeKk00qEW0sxByTDSpzaRvl8WxdMAeMytQ1611842368056QMMlSYKLwAsWUsAfLipqwCA2ahUKEwiikKDe5L7uAhVFCuwKHUuFBoYQ8tMDegUAQCSAQCYAQCqAQdnd3Mtd2l6"></a><br><style>.mapouter{position:relative;text-align:right;height:300px;width:100%;}</style><style>.gmap_canvas {overflow:hidden;background:none!important;height:300px;width:100%;}</style></div></div>');
            frm.refresh_field('my_location');
	    } else {
	        if(navigator.geolocation){
	            navigator.geolocation.getCurrentPosition(onPositionRecieved,locationNotRecieved,{ enableHighAccuracy: true});
	        }
	    }
    }
    ,
	validate(frm){
        const R = 6371e3; // metres
        var curLong = frm.doc.longitude;
        var curLat = frm.doc.latitude;

        var brnLong = frm.doc.branch_longitude;
        var brnLat = frm.doc.branch_latitude;

        const radLong = curLat * Math.PI/180; // φ, λ in radians
        const radLat = brnLat * Math.PI/180;
        const radBrLong = (brnLat-curLat) * Math.PI/180;
        const radBrLat = (brnLong-curLong) * Math.PI/180;

        const a = Math.sin(radBrLong/2) * Math.sin(radBrLong/2) +
            Math.cos(radLong) * Math.cos(radLat) *
            Math.sin(radBrLat/2) * Math.sin(radBrLat/2);
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

        var dist = R * c; // in metres
        frm.set_value("distance_in_meters", dist);
        refresh_field("distance_in_meters");

        if (frm.doc.distance_in_meters > 300.0000000 && !frm.doc.reason){
            frm.set_value('skip_auto_attendance', 1);
        }
    }
})

The code is copied from ERPNext Forum Topic:
[Geolocation based Employee Attendance check-in system - Frappe Framework / Customization - Frappe Forum](Geolocation based Employee Attendance check-in system)

And here is the Scheduler Event Code (Python - Server Script)

check = frappe.get_doc({
'doctype': 'Employee Checkin',
'employee': 'EMP/00091',
'log_type': 'IN'
})
check. Insert()
# check.run_method('onload')
# check.queue_action('onload')
# meta = frappe.get_meta('Employee Checkin')
# meta.has_field('employee') # True
# meta.get_custom_fields()

As can be seen, I’ve tried many different codes from the Frappe Framework instructions but no luck so far. However, the rest of the docfields are being fetch automatically, such as, Shift Type, but not the GPS Coordinates.

Can someone please provide a solution for this issue?
Thank you :slight_smile:

The Final Draft for the Scheduler Event Code (Python - Server Script)

curr_t = frappe.utils.now()
c_t = frappe.utils.cint(frappe.utils.get_time(curr_t).hour)
if c_t < 18:
    emp = frappe.db.get_list('Employee',
    filters={
        'default_shift': ['is', 'set'],
        'status': 'Active'
    }, fields=['name'])
    for row in emp:
        name = row.name
        first_checkin = frappe.db.get_value('Employee Checkin',
        {
            'employee': row.name,
            'log_type': 'IN',
            'creation': ['between', [
                frappe.utils.today(),
                frappe.utils.now()
            ]]
        },
        ['time'],
        order_by='time asc'
        )
        if first_checkin:
            check = frappe.get_doc({
            'doctype': 'Employee Checkin',
            'employee': row.name,
            'log_type': 'IN'
            })
            check. Insert()

The goal is to keep track of the Employees who checked-in for the day, keep track of their GPS Coordinates