first commit
This commit is contained in:
394
wwwroot/js/odometerrecord.js
Normal file
394
wwwroot/js/odometerrecord.js
Normal file
@@ -0,0 +1,394 @@
|
||||
function showAddOdometerRecordModal() {
|
||||
$.get(`/Vehicle/GetAddOdometerRecordPartialView?vehicleId=${GetVehicleId().vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#odometerRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#odometerRecordDate'));
|
||||
initTagSelector($("#odometerRecordTag"));
|
||||
$('#odometerRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditOdometerRecordModal(odometerRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#odometerRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getOdometerRecordModelData().id;
|
||||
if (existingId == odometerRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#odometerRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetOdometerRecordForEditById?odometerRecordId=${odometerRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#odometerRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#odometerRecordDate'));
|
||||
initTagSelector($("#odometerRecordTag"));
|
||||
$('#odometerRecordModal').modal('show');
|
||||
bindModalInputChanges('odometerRecordModal');
|
||||
$('#odometerRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("odometerRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddOdometerRecordModal() {
|
||||
$('#odometerRecordModal').modal('hide');
|
||||
}
|
||||
function deleteOdometerRecord(odometerRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Odometer Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteOdometerRecordById?odometerRecordId=${odometerRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddOdometerRecordModal();
|
||||
successToast("Odometer Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleOdometerRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveOdometerRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateOdometerRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveOdometerRecordToVehicleId', { odometerRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Odometer Record Updated" : "Odometer Record Added.");
|
||||
hideAddOdometerRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleOdometerRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateOdometerRecordValues() {
|
||||
var serviceDate = $("#odometerRecordDate").val();
|
||||
var initialOdometerMileage = parseInt(globalParseFloat($("#initialOdometerRecordMileage").val())).toString();
|
||||
var serviceMileage = parseInt(globalParseFloat($("#odometerRecordMileage").val())).toString();
|
||||
var serviceNotes = $("#odometerRecordNotes").val();
|
||||
var serviceTags = $("#odometerRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var odometerRecordId = getOdometerRecordModelData().id;
|
||||
//Odometer Adjustments
|
||||
serviceMileage = GetAdjustedOdometer(odometerRecordId, serviceMileage);
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (serviceDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#odometerRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#odometerRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (serviceMileage.trim() == '' || isNaN(serviceMileage) || parseInt(serviceMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#odometerRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#odometerRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (isNaN(initialOdometerMileage) || parseInt(initialOdometerMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#initialOdometerRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#initialOdometerRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: odometerRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: serviceDate,
|
||||
initialMileage: initialOdometerMileage,
|
||||
mileage: serviceMileage,
|
||||
notes: serviceNotes,
|
||||
tags: serviceTags,
|
||||
files: uploadedFiles,
|
||||
extraFields: extraFields.extraFields
|
||||
}
|
||||
}
|
||||
|
||||
function recalculateDistance() {
|
||||
//force distance recalculation
|
||||
//reserved for when data is incoherent with negative distances due to non-chronological order of odometer records.
|
||||
var vehicleId = GetVehicleId().vehicleId
|
||||
$.post(`/Vehicle/ForceRecalculateDistanceByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
successToast("Odometer Records Updated")
|
||||
getVehicleOdometerRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function editMultipleOdometerRecords(ids) {
|
||||
if (ids.length < 2) {
|
||||
return;
|
||||
}
|
||||
$.post('/Vehicle/GetOdometerRecordsEditModal', { recordIds: ids }, function (data) {
|
||||
if (data) {
|
||||
$("#odometerRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#odometerRecordDate'));
|
||||
initTagSelector($("#odometerRecordTag"));
|
||||
$('#odometerRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveMultipleOdometerRecordsToVehicle() {
|
||||
var odometerDate = $("#odometerRecordDate").val();
|
||||
var initialOdometerMileage = $("#initialOdometerRecordMileage").val();
|
||||
var odometerMileage = $("#odometerRecordMileage").val();
|
||||
var initialOdometerMileageToParse = parseInt(globalParseFloat($("#initialOdometerRecordMileage").val())).toString();
|
||||
var odometerMileageToParse = parseInt(globalParseFloat($("#odometerRecordMileage").val())).toString();
|
||||
var odometerNotes = $("#odometerRecordNotes").val();
|
||||
var odometerTags = $("#odometerRecordTag").val();
|
||||
var odometerExtraFields = getAndValidateExtraFields();
|
||||
//validation
|
||||
var hasError = false;
|
||||
if (odometerMileage.trim() != '' && (isNaN(odometerMileageToParse) || parseInt(odometerMileageToParse) < 0)) {
|
||||
hasError = true;
|
||||
$("#odometerRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#odometerRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (initialOdometerMileage.trim() != '' && (isNaN(initialOdometerMileageToParse) || parseInt(initialOdometerMileageToParse) < 0)) {
|
||||
hasError = true;
|
||||
$("#odometerRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#odometerRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var formValues = {
|
||||
recordIds: recordsToEdit,
|
||||
editRecord: {
|
||||
date: odometerDate,
|
||||
initialMileage: initialOdometerMileageToParse,
|
||||
mileage: odometerMileageToParse,
|
||||
notes: odometerNotes,
|
||||
tags: odometerTags,
|
||||
extraFields: odometerExtraFields.extraFields
|
||||
}
|
||||
}
|
||||
$.post('/Vehicle/SaveMultipleOdometerRecords', { editModel: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast("Odometer Records Updated");
|
||||
hideAddOdometerRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleOdometerRecords(GetVehicleId().vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function toggleInitialOdometerEnabled() {
|
||||
if ($("#initialOdometerRecordMileage").prop("disabled")) {
|
||||
$("#initialOdometerRecordMileage").prop("disabled", false);
|
||||
} else {
|
||||
$("#initialOdometerRecordMileage").prop("disabled", true);
|
||||
}
|
||||
|
||||
}
|
||||
function showTripModal() {
|
||||
$(".odometer-modal").addClass('d-none');
|
||||
$(".trip-modal").removeClass('d-none');
|
||||
//set current odometer
|
||||
$(".trip-odometer").text($("#initialOdometerRecordMileage").val());
|
||||
}
|
||||
function hideTripModal() {
|
||||
//check if recording is in progress
|
||||
if (tripTimer != undefined || tripWakeLock != undefined) {
|
||||
Swal.fire({
|
||||
title: "Confirm Exit?",
|
||||
text: "Recording in Progress, Exit?",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Exit",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
stopRecording();
|
||||
$(".odometer-modal").removeClass('d-none');
|
||||
$(".trip-modal").addClass('d-none');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$(".odometer-modal").removeClass('d-none');
|
||||
$(".trip-modal").addClass('d-none');
|
||||
}
|
||||
}
|
||||
function startRecording() {
|
||||
if (navigator.geolocation && navigator.wakeLock) {
|
||||
try {
|
||||
navigator.wakeLock.request('screen').then((wl) => {
|
||||
tripWakeLock = wl;
|
||||
tripTimer = setInterval(() => {
|
||||
navigator.geolocation.getCurrentPosition(recordPosition, stopRecording, { maximumAge: 1000, timeout: 4000, enableHighAccuracy: true });
|
||||
}, 5000);
|
||||
$(".trip-start").addClass('d-none');
|
||||
$(".trip-stop").removeClass('d-none');
|
||||
//modify modal to prevent closing
|
||||
$("#odometerRecordModal").on("hide.bs.modal", function (event) {
|
||||
event.preventDefault();
|
||||
hideTripModal();
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
errorToast('Location Services not Enabled');
|
||||
}
|
||||
} else {
|
||||
errorToast('Browser does not support GeoLocation and/or WakeLock API');
|
||||
}
|
||||
}
|
||||
function recordPosition(position) {
|
||||
var currentLat = position.coords.latitude;
|
||||
var currentLong = position.coords.longitude;
|
||||
if (tripLastPosition == undefined) {
|
||||
tripLastPosition = {
|
||||
latitude: currentLat,
|
||||
longitude: currentLong
|
||||
}
|
||||
tripCoordinates.push(`${currentLat},${currentLong}`);
|
||||
} else {
|
||||
//calculate distance
|
||||
var distanceTraveled = calculateDistance(tripLastPosition.latitude, tripLastPosition.longitude, currentLat, currentLong);
|
||||
var recordedTotalOdometer = getRecordedOdometer();
|
||||
if (distanceTraveled >= 0.1) { //if greater than 0.1 mile or KM then it's significant
|
||||
recordedTotalOdometer += distanceTraveled;
|
||||
var recordedOdometerString = recordedTotalOdometer.toString().split('.');
|
||||
$(".trip-odometer").html(recordedOdometerString[0]);
|
||||
if (recordedOdometerString.length == 2) {
|
||||
if (recordedOdometerString[1].toString().length > 3) {
|
||||
$(".trip-odometer-sub").html(recordedOdometerString[1].toString().substring(0, 3));
|
||||
} else {
|
||||
$(".trip-odometer-sub").html(recordedOdometerString[1].toString());
|
||||
}
|
||||
$(".trip-odometer-sub").attr("data-value", recordedOdometerString[1]);
|
||||
}
|
||||
//update last position
|
||||
tripLastPosition = {
|
||||
latitude: currentLat,
|
||||
longitude: currentLong
|
||||
}
|
||||
tripCoordinates.push(`${currentLat},${currentLong}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
function stopRecording(errMsg) {
|
||||
if (errMsg && errMsg.code) {
|
||||
switch (errMsg.code) {
|
||||
case 1:
|
||||
errorToast(errMsg.message);
|
||||
break;
|
||||
case 2:
|
||||
errorToast("Location Unavailable");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tripTimer != undefined) {
|
||||
clearInterval(tripTimer);
|
||||
tripTimer = undefined;
|
||||
}
|
||||
if (tripWakeLock != undefined) {
|
||||
tripWakeLock.release();
|
||||
tripWakeLock = undefined;
|
||||
}
|
||||
if (tripLastPosition != undefined) {
|
||||
tripLastPosition = undefined;
|
||||
}
|
||||
$(".trip-start").removeClass('d-none');
|
||||
$(".trip-stop").addClass('d-none');
|
||||
$("#odometerRecordModal").off("hide.bs.modal");
|
||||
if (parseInt(getRecordedOdometer()) != $("#initialOdometerRecordMileage").val()) {
|
||||
$(".trip-save").removeClass('d-none');
|
||||
}
|
||||
}
|
||||
// Converts numeric degrees to radians
|
||||
function toRad(Value) {
|
||||
return Value * Math.PI / 180;
|
||||
}
|
||||
//haversine
|
||||
function calculateDistance(lat1, lon1, lat2, lon2) {
|
||||
var earthRadius = 6371; // km radius of the earth
|
||||
var dLat = toRad(lat2 - lat1);
|
||||
var dLon = toRad(lon2 - lon1);
|
||||
var lat1 = toRad(lat1);
|
||||
var lat2 = toRad(lat2);
|
||||
|
||||
var sinOne = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
||||
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
|
||||
var tanOne = 2 * Math.atan2(Math.sqrt(sinOne), Math.sqrt(1 - sinOne));
|
||||
var calculatedDistance = earthRadius * tanOne;
|
||||
if (getGlobalConfig().useMPG) {
|
||||
calculatedDistance *= 0.621; //convert to mile if needed.
|
||||
}
|
||||
return Math.abs(calculatedDistance);
|
||||
}
|
||||
function getRecordedOdometer() {
|
||||
var recordedOdometer = $(".trip-odometer").html();
|
||||
var recordedSubOdometer = $(".trip-odometer-sub").attr("data-value");
|
||||
return parseFloat(`${recordedOdometer}.${recordedSubOdometer}`);
|
||||
}
|
||||
function saveRecordedOdometer() {
|
||||
//save coordinates into a CSV file and upload
|
||||
if (tripCoordinates.length > 1) {
|
||||
//update current odometer value
|
||||
$("#odometerRecordMileage").val(parseInt(getRecordedOdometer()).toString());
|
||||
//generate attachment
|
||||
$.post('/Files/UploadCoordinates', { coordinates: tripCoordinates }, function (response) {
|
||||
uploadedFiles.push(response);
|
||||
$.post('/Vehicle/GetFilesPendingUpload', { uploadedFiles: uploadedFiles }, function (viewData) {
|
||||
$("#filesPendingUpload").html(viewData);
|
||||
tripCoordinates = ["Latitude,Longitude"];
|
||||
});
|
||||
});
|
||||
}
|
||||
hideTripModal();
|
||||
}
|
||||
function toggleSubOdometer() {
|
||||
if ($(".trip-odometer-sub").hasClass("d-none")) {
|
||||
$(".trip-odometer-sub").removeClass("d-none");
|
||||
} else {
|
||||
$(".trip-odometer-sub").addClass("d-none");
|
||||
}
|
||||
}
|
||||
function checkTripRecorder() {
|
||||
//check if connection is https, browser supports required API, and that vehicle does not use engine hours
|
||||
if (location.protocol != 'https:' || !navigator.geolocation || !navigator.wakeLock || GetVehicleId().useEngineHours) {
|
||||
$(".trip-show").remove();
|
||||
} else {
|
||||
$(".trip-show").removeClass('d-none');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user