Subversion Repositories SmartDukaan

Rev

Rev 36733 | Rev 36784 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36733 Rev 36783
Line 53... Line 53...
53
            </div>
53
            </div>
54
            #set($completedCount = 0)
54
            #set($completedCount = 0)
55
            #set($pendingCount = 0)
55
            #set($pendingCount = 0)
56
            #set($deferredCount = 0)
56
            #set($deferredCount = 0)
57
            #foreach($v in $visits)
57
            #foreach($v in $visits)
58
                #if($v.getMarkType() == "CHECKIN-CHECKOUT" || $v.getMarkType() == "CHECKOUT")
58
                #if($v.getMarkType() == "CHECKIN-CHECKOUT" || $v.getMarkType() == "CHECKIN_CHECKOUT" || $v.getMarkType() == "CHECKOUT")
59
                    #set($completedCount = $completedCount + 1)
59
                    #set($completedCount = $completedCount + 1)
60
                #elseif($v.getMarkType() == "PENDING" || $v.getMarkType() == "CHECKIN")
60
                #elseif($v.getMarkType() == "PENDING" || $v.getMarkType() == "CHECKIN")
61
                    #set($pendingCount = $pendingCount + 1)
61
                    #set($pendingCount = $pendingCount + 1)
62
                #elseif($v.getMarkType() == "DEFERRED")
62
                #elseif($v.getMarkType() == "DEFERRED")
63
                    #set($deferredCount = $deferredCount + 1)
63
                    #set($deferredCount = $deferredCount + 1)
Line 123... Line 123...
123
                    <td>#if($v.getTaskDescription() && $v.getTaskDescription() != "")#if($v.getTaskDescription().length() > 50)<span class="desc-short">$v.getTaskDescription().substring(0, 50)... <a href="javascript:void(0);" class="read-more-link" style="color:#3498db;">read more</a></span><span class="desc-full" style="display:none;">$v.getTaskDescription() <a href="javascript:void(0);" class="read-less-link" style="color:#3498db;">read less</a></span>#else$v.getTaskDescription()#end#else--#end</td>
123
                    <td>#if($v.getTaskDescription() && $v.getTaskDescription() != "")#if($v.getTaskDescription().length() > 50)<span class="desc-short">$v.getTaskDescription().substring(0, 50)... <a href="javascript:void(0);" class="read-more-link" style="color:#3498db;">read more</a></span><span class="desc-full" style="display:none;">$v.getTaskDescription() <a href="javascript:void(0);" class="read-less-link" style="color:#3498db;">read less</a></span>#else$v.getTaskDescription()#end#else--#end</td>
124
                    <td>
124
                    <td>
125
                    #if($v.getAttachment() && $v.getAttachment() != "")
125
                    #if($v.getAttachment() && $v.getAttachment() != "")
126
                        <img src="/download-attachment?documentId=$v.getAttachment()" class="view-attachment-link" alt="IMAGE" width="50" data-attachment="$v.getAttachment()">
126
                        <img src="/download-attachment?documentId=$v.getAttachment()" class="view-attachment-link" alt="IMAGE" width="50" data-attachment="$v.getAttachment()">
127
                    #end
127
                    #end
128
                        #if($v.getMarkType() == "CHECKIN-CHECKOUT" || $v.getMarkType() == "CHECKOUT")
128
                        #if($v.getMarkType() == "CHECKIN-CHECKOUT" || $v.getMarkType() == "CHECKIN_CHECKOUT" || $v.getMarkType() == "CHECKOUT")
129
                            <span class="label label-success">$v.getMarkType()</span>
129
                            <span class="label label-success">$v.getMarkType()</span>
130
                        #elseif($v.getMarkType() == "PENDING" || $v.getMarkType() == "CHECKIN")
130
                        #elseif($v.getMarkType() == "PENDING" || $v.getMarkType() == "CHECKIN")
131
                            <span class="label label-warning">$v.getMarkType()</span>
131
                            <span class="label label-warning">$v.getMarkType()</span>
132
                        #elseif($v.getMarkType() == "DEFERRED")
132
                        #elseif($v.getMarkType() == "DEFERRED")
133
                            <span class="label label-danger">$v.getMarkType()</span>
133
                            <span class="label label-danger">$v.getMarkType()</span>
Line 327... Line 327...
327
    var liveTrackingMap = null;
327
    var liveTrackingMap = null;
328
    var liveTrackingUserId = null;
328
    var liveTrackingUserId = null;
329
    var liveTrackingInterval = null;
329
    var liveTrackingInterval = null;
330
 
330
 
331
    function getMarkerColor(markType) {
331
    function getMarkerColor(markType) {
332
        if (markType === 'CHECKIN-CHECKOUT' || markType === 'CHECKOUT') return '#0F9D58';
332
        if (markType === 'CHECKIN-CHECKOUT' || markType === 'CHECKIN_CHECKOUT' || markType === 'CHECKOUT') return '#0F9D58';
333
        if (markType === 'PENDING' || markType === 'CHECKIN') return '#4285F4';
333
        if (markType === 'PENDING' || markType === 'CHECKIN') return '#4285F4';
334
        if (markType === 'DEFERRED') return '#DB4437';
334
        if (markType === 'DEFERRED') return '#DB4437';
335
        if (markType === 'PUNCHIN') return '#1abc9c';
335
        if (markType === 'PUNCHIN') return '#1abc9c';
336
        if (markType === 'PUNCHOUT') return '#e74c3c';
336
        if (markType === 'PUNCHOUT') return '#e74c3c';
337
        return '#F4B400';
337
        return '#F4B400';
Line 472... Line 472...
472
        var bounds = new google.maps.LatLngBounds();
472
        var bounds = new google.maps.LatLngBounds();
473
        var hasPoints = false;
473
        var hasPoints = false;
474
        var visitIdx = 0;
474
        var visitIdx = 0;
475
        var visitCoords = [];
475
        var visitCoords = [];
476
 
476
 
-
 
477
        // Pre-compute first/last valid path point as fallback for punch records with no coordinates
-
 
478
        var firstPathLat = null, firstPathLng = null;
-
 
479
        var lastPathLat = null, lastPathLng = null;
-
 
480
        for (var pi = 0; pi < pathPoints.length; pi++) {
-
 
481
            var ppLat = parseFloat(pathPoints[pi].lat), ppLng = parseFloat(pathPoints[pi].lng);
-
 
482
            if (!isNaN(ppLat) && !isNaN(ppLng) && !(ppLat === 0 && ppLng === 0)) {
-
 
483
                if (firstPathLat === null) { firstPathLat = ppLat; firstPathLng = ppLng; }
-
 
484
                lastPathLat = ppLat; lastPathLng = ppLng;
-
 
485
            }
-
 
486
        }
-
 
487
 
477
        for (var i = 0; i < visits.length; i++) {
488
        for (var i = 0; i < visits.length; i++) {
478
            var v = visits[i];
489
            var v = visits[i];
479
            if (!v.lat || !v.lng) continue;
-
 
480
            var lat = parseFloat(v.lat);
490
            var lat = v.lat ? parseFloat(v.lat) : NaN;
481
            var lng = parseFloat(v.lng);
491
            var lng = v.lng ? parseFloat(v.lng) : NaN;
482
            if (isNaN(lat) || isNaN(lng) || (lat === 0 && lng === 0)) continue;
492
            if (isNaN(lat) || isNaN(lng) || (lat === 0 && lng === 0)) {
-
 
493
                if (v.markType === 'PUNCHIN' && firstPathLat !== null) {
-
 
494
                    lat = firstPathLat; lng = firstPathLng;
-
 
495
                } else if (v.markType === 'PUNCHOUT' && lastPathLat !== null) {
-
 
496
                    lat = lastPathLat; lng = lastPathLng;
-
 
497
                } else {
-
 
498
                    continue;
-
 
499
                }
-
 
500
            }
483
 
501
 
484
            hasPoints = true;
502
            hasPoints = true;
485
            var pos = { lat: lat, lng: lng };
503
            var pos = { lat: lat, lng: lng };
486
            bounds.extend(pos);
504
            bounds.extend(pos);
487
            visitCoords.push(pos);
505
            visitCoords.push(pos);
Line 701... Line 719...
701
            liveTrackingMap.fitBounds(bounds);
719
            liveTrackingMap.fitBounds(bounds);
702
        }
720
        }
703
 
721
 
704
        // Info bar
722
        // Info bar
705
        var totalVisits = visits.filter(function (v) { return v.markType !== 'PUNCHIN' && v.markType !== 'PUNCHOUT'; }).length;
723
        var totalVisits = visits.filter(function (v) { return v.markType !== 'PUNCHIN' && v.markType !== 'PUNCHOUT'; }).length;
706
        var completedVisits = visits.filter(function (v) { return v.markType === 'CHECKIN-CHECKOUT' || v.markType === 'CHECKOUT'; }).length;
724
        var completedVisits = visits.filter(function (v) { return v.markType === 'CHECKIN-CHECKOUT' || v.markType === 'CHECKIN_CHECKOUT' || v.markType === 'CHECKOUT'; }).length;
707
        var now = new Date();
725
        var now = new Date();
708
        var timeStr = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0') + ':' + now.getSeconds().toString().padStart(2, '0');
726
        var timeStr = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0') + ':' + now.getSeconds().toString().padStart(2, '0');
709
 
727
 
710
        var avgAccuracy = accuracyCount > 0 ? (accuracySum / accuracyCount).toFixed(0) : null;
728
        var avgAccuracy = accuracyCount > 0 ? (accuracySum / accuracyCount).toFixed(0) : null;
711
        var accuracyLabel = '';
729
        var accuracyLabel = '';
Line 717... Line 735...
717
            else { accuracyLabel = 'Low'; accuracyBadge = 'background:#e74c3c;'; }
735
            else { accuracyLabel = 'Low'; accuracyBadge = 'background:#e74c3c;'; }
718
        }
736
        }
719
 
737
 
720
        var totalGpsKm = (totalGpsDistanceM / 1000).toFixed(2);
738
        var totalGpsKm = (totalGpsDistanceM / 1000).toFixed(2);
721
 
739
 
-
 
740
        var punchInRecord = visits.filter(function (v) { return v.markType === 'PUNCHIN'; })[0];
-
 
741
        var punchOutRecord = visits.filter(function (v) { return v.markType === 'PUNCHOUT'; })[0];
-
 
742
 
722
        var infoHtml = '<strong>' + username + '</strong> | ' +
743
        var infoHtml = '<strong>' + username + '</strong> | ';
-
 
744
        if (punchInRecord && punchInRecord.checkInTime) {
-
 
745
            infoHtml += '<i class="fa fa-sign-in" style="color:#1abc9c;"></i> In: <strong>' + punchInRecord.checkInTime + '</strong> | ';
-
 
746
        }
-
 
747
        if (punchOutRecord && punchOutRecord.checkInTime) {
-
 
748
            infoHtml += '<i class="fa fa-sign-out" style="color:#e74c3c;"></i> Out: <strong>' + punchOutRecord.checkInTime + '</strong> | ';
-
 
749
        }
723
            'Visits: <strong>' + totalVisits + '</strong> | ' +
750
        infoHtml += 'Visits: <strong>' + totalVisits + '</strong> | ' +
724
            'Completed: <strong>' + completedVisits + '</strong>';
751
            'Completed: <strong>' + completedVisits + '</strong>';
725
 
752
 
726
        if (pathPoints.length > 0) {
753
        if (pathPoints.length > 0) {
727
            infoHtml += ' | GPS Distance: <strong>' + totalGpsKm + ' km</strong>';
754
            infoHtml += ' | GPS Distance: <strong>' + totalGpsKm + ' km</strong>';
728
            infoHtml += ' | Points: <strong>' + pathPoints.length + '</strong>';
755
            infoHtml += ' | Points: <strong>' + pathPoints.length + '</strong>';
Line 739... Line 766...
739
 
766
 
740
        infoHtml += ' | <span style="color:#e74c3c;"><i class="fa fa-arrow-right" style="font-size:10px;"></i></span> GPS Trail';
767
        infoHtml += ' | <span style="color:#e74c3c;"><i class="fa fa-arrow-right" style="font-size:10px;"></i></span> GPS Trail';
741
        if (visitCoords.length > 1) {
768
        if (visitCoords.length > 1) {
742
            infoHtml += ' | <span style="background:#8e44ad; display:inline-block; width:14px; height:3px; vertical-align:middle; margin:0 2px;"></span> Route';
769
            infoHtml += ' | <span style="background:#8e44ad; display:inline-block; width:14px; height:3px; vertical-align:middle; margin:0 2px;"></span> Route';
743
        }
770
        }
-
 
771
        var battery = data.batteryLevel;
-
 
772
        if (battery !== null && battery !== undefined) {
-
 
773
            var batteryColor = battery > 50 ? '#27ae60' : (battery > 20 ? '#f39c12' : '#e74c3c');
-
 
774
            var batteryIcon = battery > 50 ? 'fa-battery-full' : (battery > 20 ? 'fa-battery-half' : 'fa-battery-quarter');
-
 
775
            infoHtml += ' | <span style="color:' + batteryColor + ';"><i class="fa ' + batteryIcon + '"></i> Battery: <strong>' + battery + '%</strong></span>';
-
 
776
        }
-
 
777
 
744
        var locToggle = data.locationToggleCount || 0;
778
        var locToggle = data.locationToggleCount || 0;
745
        if (locToggle > 0) {
779
        if (locToggle > 0) {
746
            infoHtml += ' | <span class="label" style="background:#e74c3c; color:white; padding:2px 8px; border-radius:3px; font-size:11px;"><i class="fa fa-power-off"></i> Loc Off: ' + locToggle + '</span>';
780
            infoHtml += ' | <span class="label" style="background:#e74c3c; color:white; padding:2px 8px; border-radius:3px; font-size:11px;"><i class="fa fa-power-off"></i> Loc Off: ' + locToggle + '</span>';
747
        }
781
        }
748
 
782
 
Line 799... Line 833...
799
 
833
 
800
        setTimeout(function () {
834
        setTimeout(function () {
801
            liveTrackingMap = null;
835
            liveTrackingMap = null;
802
            ensureGoogleMaps(function () {
836
            ensureGoogleMaps(function () {
803
                loadLiveTracking(liveTrackingUserId, liveTrackingUsername);
837
                loadLiveTracking(liveTrackingUserId, liveTrackingUsername);
804
                startAutoRefresh();
-
 
805
            });
838
            });
806
        }, 300);
839
        }, 300);
807
    });
840
    });
808
 
841
 
809
    $(document).on('click.livetrack', '#refreshTrackingBtn', function () {
842
    $(document).on('click.livetrack', '#refreshTrackingBtn', function () {