first commit
This commit is contained in:
156
wwwroot/js/collisionrecord.js
Normal file
156
wwwroot/js/collisionrecord.js
Normal file
@@ -0,0 +1,156 @@
|
||||
function showAddCollisionRecordModal() {
|
||||
$.get('/Vehicle/GetAddCollisionRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#collisionRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#collisionRecordDate'));
|
||||
initTagSelector($("#collisionRecordTag"));
|
||||
$('#collisionRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditCollisionRecordModal(collisionRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#collisionRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getCollisionRecordModelData().id;
|
||||
if (existingId == collisionRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#collisionRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetCollisionRecordForEditById?collisionRecordId=${collisionRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#collisionRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#collisionRecordDate'));
|
||||
initTagSelector($("#collisionRecordTag"));
|
||||
$('#collisionRecordModal').modal('show');
|
||||
bindModalInputChanges('collisionRecordModal');
|
||||
$('#collisionRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("collisionRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddCollisionRecordModal() {
|
||||
$('#collisionRecordModal').modal('hide');
|
||||
}
|
||||
function deleteCollisionRecord(collisionRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Repair Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteCollisionRecordById?collisionRecordId=${collisionRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddCollisionRecordModal();
|
||||
successToast("Repair Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleCollisionRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveCollisionRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateCollisionRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveCollisionRecordToVehicleId', { collisionRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Repair Record Updated" : "Repair Record Added.");
|
||||
hideAddCollisionRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleCollisionRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateCollisionRecordValues() {
|
||||
var collisionDate = $("#collisionRecordDate").val();
|
||||
var collisionMileage = parseInt(globalParseFloat($("#collisionRecordMileage").val())).toString();
|
||||
var collisionDescription = $("#collisionRecordDescription").val();
|
||||
var collisionCost = $("#collisionRecordCost").val();
|
||||
var collisionNotes = $("#collisionRecordNotes").val();
|
||||
var collisionTags = $("#collisionRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var collisionRecordId = getCollisionRecordModelData().id;
|
||||
var addReminderRecord = $("#addReminderCheck").is(":checked");
|
||||
//Odometer Adjustments
|
||||
if (isNaN(collisionMileage) && GetVehicleId().odometerOptional) {
|
||||
collisionMileage = '0';
|
||||
}
|
||||
collisionMileage = GetAdjustedOdometer(collisionRecordId, collisionMileage);
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (collisionDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#collisionRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#collisionRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (collisionMileage.trim() == '' || isNaN(collisionMileage) || parseInt(collisionMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#collisionRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#collisionRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (collisionDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#collisionRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#collisionRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (collisionCost.trim() == '' || !isValidMoney(collisionCost)) {
|
||||
hasError = true;
|
||||
$("#collisionRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#collisionRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: collisionRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: collisionDate,
|
||||
mileage: collisionMileage,
|
||||
description: collisionDescription,
|
||||
cost: collisionCost,
|
||||
notes: collisionNotes,
|
||||
files: uploadedFiles,
|
||||
supplies: selectedSupplies,
|
||||
tags: collisionTags,
|
||||
addReminderRecord: addReminderRecord,
|
||||
extraFields: extraFields.extraFields,
|
||||
requisitionHistory: supplyUsageHistory,
|
||||
deletedRequisitionHistory: deletedSupplyUsageHistory,
|
||||
reminderRecordId: recurringReminderRecordId,
|
||||
copySuppliesAttachment: copySuppliesAttachments
|
||||
}
|
||||
}
|
||||
451
wwwroot/js/garage.js
Normal file
451
wwwroot/js/garage.js
Normal file
@@ -0,0 +1,451 @@
|
||||
function showAddVehicleModal() {
|
||||
uploadedFile = "";
|
||||
$.get('/Vehicle/AddVehiclePartialView', function (data) {
|
||||
if (data) {
|
||||
$("#addVehicleModalContent").html(data);
|
||||
initTagSelector($("#inputTag"));
|
||||
initDatePicker($('#inputPurchaseDate'));
|
||||
initDatePicker($('#inputSoldDate'));
|
||||
$('#addVehicleModal').modal('show');
|
||||
}
|
||||
})
|
||||
}
|
||||
function hideAddVehicleModal() {
|
||||
$('#addVehicleModal').modal('hide');
|
||||
}
|
||||
//refreshable function to reload Garage PartialView
|
||||
function loadGarage() {
|
||||
$.get('/Home/Garage', function (data) {
|
||||
$("#garageContainer").html(data);
|
||||
loadSettings();
|
||||
bindTabEvent();
|
||||
});
|
||||
}
|
||||
function loadSettings() {
|
||||
$.get('/Home/Settings', function (data) {
|
||||
$("#settings-tab-pane").html(data);
|
||||
});
|
||||
}
|
||||
function getVehicleSupplyRecords() {
|
||||
$.get(`/Vehicle/GetSupplyRecordsByVehicleId?vehicleId=0`, function (data) {
|
||||
if (data) {
|
||||
$("#supply-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
}
|
||||
});
|
||||
}
|
||||
function GetVehicleId() {
|
||||
return { vehicleId: 0, hasOdometerAdjustment: false };
|
||||
}
|
||||
function bindTabEvent() {
|
||||
$('button[data-bs-toggle="tab"]').on('show.bs.tab', function (e) {
|
||||
switch (e.target.id) {
|
||||
case "supply-tab":
|
||||
getVehicleSupplyRecords();
|
||||
break;
|
||||
case "calendar-tab":
|
||||
getVehicleCalendarEvents();
|
||||
break;
|
||||
}
|
||||
switch (e.relatedTarget.id) { //clear out previous tabs with grids in them to help with performance
|
||||
case "supply-tab":
|
||||
$("#supply-tab-pane").html("");
|
||||
break;
|
||||
case "calendar-tab":
|
||||
$("#calendar-tab-pane").html("");
|
||||
break;
|
||||
}
|
||||
$(`.motovaultpro-tab #${e.target.id}`).addClass('active');
|
||||
$(`.motovaultpro-mobile-nav #${e.target.id}`).addClass('active');
|
||||
$(`.motovaultpro-tab #${e.relatedTarget.id}`).removeClass('active');
|
||||
$(`.motovaultpro-mobile-nav #${e.relatedTarget.id}`).removeClass('active');
|
||||
});
|
||||
}
|
||||
function getVehicleCalendarEvents() {
|
||||
$.get('/Home/Calendar', function (data) {
|
||||
if (data) {
|
||||
$("#calendar-tab-pane").html(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
function showCalendarReminderModal(id) {
|
||||
event.stopPropagation();
|
||||
$.get(`/Home/ViewCalendarReminder?reminderId=${id}`, function (data) {
|
||||
if (data) {
|
||||
$("#reminderRecordCalendarModalContent").html(data);
|
||||
$("#reminderRecordCalendarModal").modal('show');
|
||||
$('#reminderRecordCalendarModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("reminderNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
function hideCalendarReminderModal() {
|
||||
$("#reminderRecordCalendarModal").modal('hide');
|
||||
}
|
||||
function generateReminderItem(id, urgency, description) {
|
||||
if (description.trim() == '') {
|
||||
return;
|
||||
}
|
||||
switch (urgency) {
|
||||
case "VeryUrgent":
|
||||
return `<p class="badge text-wrap bg-danger reminder-calendar-item mb-2" onclick='showCalendarReminderModal(${id})'>${encodeHTMLInput(description)}</p>`;
|
||||
case "PastDue":
|
||||
return `<p class="badge text-wrap bg-secondary reminder-calendar-item mb-2" onclick='showCalendarReminderModal(${id})'>${encodeHTMLInput(description)}</p>`;
|
||||
case "Urgent":
|
||||
return `<p class="badge text-wrap text-bg-warning reminder-calendar-item mb-2" onclick='showCalendarReminderModal(${id})'>${encodeHTMLInput(description)}</p>`;
|
||||
case "NotUrgent":
|
||||
return `<p class="badge text-wrap bg-success reminder-calendar-item mb-2" onclick='showCalendarReminderModal(${id})'>${encodeHTMLInput(description)}</p>`;
|
||||
}
|
||||
}
|
||||
function markDoneCalendarReminderRecord(reminderRecordId, e) {
|
||||
event.stopPropagation();
|
||||
$.post(`/Vehicle/PushbackRecurringReminderRecord?reminderRecordId=${reminderRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideCalendarReminderModal();
|
||||
successToast("Reminder Updated");
|
||||
getVehicleCalendarEvents();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
function deleteCalendarReminderRecord(reminderRecordId, e) {
|
||||
if (e != undefined) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Reminders cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteReminderRecordById?reminderRecordId=${reminderRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideCalendarReminderModal();
|
||||
successToast("Reminder Deleted");
|
||||
getVehicleCalendarEvents();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function initCalendar() {
|
||||
if (groupedDates.length == 0) {
|
||||
//group dates
|
||||
eventDates.map(x => {
|
||||
var existingIndex = groupedDates.findIndex(y => y.date == x.date);
|
||||
if (existingIndex == -1) {
|
||||
groupedDates.push({ date: x.date, reminders: [`${generateReminderItem(x.id, x.urgency, x.description)}`] });
|
||||
} else if (existingIndex > -1) {
|
||||
groupedDates[existingIndex].reminders.push(`${generateReminderItem(x.id, x.urgency, x.description)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(".reminderCalendarViewContent").datepicker({
|
||||
startDate: "+0d",
|
||||
format: getShortDatePattern().pattern,
|
||||
todayHighlight: true,
|
||||
weekStart: getGlobalConfig().firstDayOfWeek,
|
||||
beforeShowDay: function (date) {
|
||||
var reminderDateIndex = groupedDates.findIndex(x => (x.date == date.getTime() || x.date == (date.getTime() - date.getTimezoneOffset() * 60000))); //take into account server timezone offset
|
||||
if (reminderDateIndex > -1) {
|
||||
return {
|
||||
enabled: true,
|
||||
classes: 'reminder-exist',
|
||||
content: `<div class='text-wrap' style='height:20px;'><p>${date.getDate()}</p>${groupedDates[reminderDateIndex].reminders.join('<br>')}</div>`
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function performLogOut() {
|
||||
$.post('/Login/LogOut', function (data) {
|
||||
if (data) {
|
||||
window.location.href = data;
|
||||
}
|
||||
})
|
||||
}
|
||||
function loadPinnedNotes(vehicleId) {
|
||||
var hoveredGrid = $(`#gridVehicle_${vehicleId}`);
|
||||
if (hoveredGrid.attr("data-bs-title") != '') {
|
||||
hoveredGrid.tooltip("show");
|
||||
}
|
||||
}
|
||||
function hidePinnedNotes(vehicleId) {
|
||||
if ($(`#gridVehicle_${vehicleId}`).attr('data-bs-title') != '') {
|
||||
$(`#gridVehicle_${vehicleId}`).tooltip("hide");
|
||||
}
|
||||
}
|
||||
|
||||
function filterGarage(sender) {
|
||||
var rowData = $(".garage-item");
|
||||
if (sender == undefined) {
|
||||
rowData.removeClass('override-hide');
|
||||
return;
|
||||
}
|
||||
var tagName = sender.textContent;
|
||||
if ($(sender).hasClass("bg-primary")) {
|
||||
rowData.removeClass('override-hide');
|
||||
$(sender).removeClass('bg-primary');
|
||||
$(sender).addClass('bg-secondary');
|
||||
} else {
|
||||
//hide table rows.
|
||||
rowData.addClass('override-hide');
|
||||
$(`[data-tags~='${tagName}']`).removeClass('override-hide');
|
||||
if ($(".tagfilter.bg-primary").length > 0) {
|
||||
//disabling other filters
|
||||
$(".tagfilter.bg-primary").addClass('bg-secondary');
|
||||
$(".tagfilter.bg-primary").removeClass('bg-primary');
|
||||
}
|
||||
$(sender).addClass('bg-primary');
|
||||
$(sender).removeClass('bg-secondary');
|
||||
}
|
||||
}
|
||||
function sortVehicles(desc) {
|
||||
//get row data
|
||||
var rowData = $('.garage-item');
|
||||
var sortedRow = rowData.toArray().sort((a, b) => {
|
||||
var currentVal = globalParseFloat($(a).find(".garage-item-year").attr('data-unit'));
|
||||
var nextVal = globalParseFloat($(b).find(".garage-item-year").attr('data-unit'));
|
||||
if (desc) {
|
||||
return nextVal - currentVal;
|
||||
} else {
|
||||
return currentVal - nextVal;
|
||||
}
|
||||
});
|
||||
sortedRow.push($('.garage-item-add'))
|
||||
$('.vehiclesContainer').html(sortedRow);
|
||||
}
|
||||
|
||||
var touchtimer;
|
||||
var touchduration = 800;
|
||||
function detectLongTouch(sender) {
|
||||
if ($(sender).hasClass("active")) {
|
||||
if (!touchtimer) {
|
||||
touchtimer = setTimeout(function () { sortGarage(sender, true); detectTouchEndPremature(sender); }, touchduration);
|
||||
}
|
||||
}
|
||||
}
|
||||
function detectTouchEndPremature(sender) {
|
||||
if (touchtimer) {
|
||||
clearTimeout(touchtimer);
|
||||
touchtimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function sortGarage(sender, isMobile) {
|
||||
if (event != undefined) {
|
||||
event.preventDefault();
|
||||
}
|
||||
sender = $(sender);
|
||||
if (sender.hasClass("active")) {
|
||||
//do sorting only if garage is the active tab.
|
||||
var sortColumn = sender.text();
|
||||
var garageIcon = '<i class="bi bi-car-front me-2"></i>';
|
||||
var sortAscIcon = '<i class="bi bi-sort-numeric-down ms-2"></i>';
|
||||
var sortDescIcon = '<i class="bi bi-sort-numeric-down-alt ms-2"></i>';
|
||||
if (sender.hasClass('sort-asc')) {
|
||||
sender.removeClass('sort-asc');
|
||||
sender.addClass('sort-desc');
|
||||
sender.html(isMobile ? `<span class="ms-2 display-3">${garageIcon}${sortColumn}${sortDescIcon}</span>` : `${garageIcon}${sortColumn}${sortDescIcon}`);
|
||||
sortVehicles(true);
|
||||
} else if (sender.hasClass('sort-desc')) {
|
||||
//restore table
|
||||
sender.removeClass('sort-desc');
|
||||
sender.html(isMobile ? `<span class="ms-2 display-3">${garageIcon}${sortColumn}</span>` : `${garageIcon}${sortColumn}`);
|
||||
resetSortGarage();
|
||||
} else {
|
||||
//first time sorting.
|
||||
//check if table was sorted before by a different column(only relevant to fuel tab)
|
||||
if ($("[default-sort]").length > 0 && ($(".sort-asc").length > 0 || $(".sort-desc").length > 0)) {
|
||||
//restore table state.
|
||||
resetSortGarage();
|
||||
//reset other sorted columns
|
||||
if ($(".sort-asc").length > 0) {
|
||||
$(".sort-asc").html($(".sort-asc").html().replace(sortAscIcon, ""));
|
||||
$(".sort-asc").removeClass("sort-asc");
|
||||
}
|
||||
if ($(".sort-desc").length > 0) {
|
||||
$(".sort-desc").html($(".sort-desc").html().replace(sortDescIcon, ""));
|
||||
$(".sort-desc").removeClass("sort-desc");
|
||||
}
|
||||
}
|
||||
sender.addClass('sort-asc');
|
||||
sender.html(isMobile ? `<span class="ms-2 display-3">${garageIcon}${sortColumn}${sortAscIcon}</span>` : `${garageIcon}${sortColumn}${sortAscIcon}`);
|
||||
//append sortRowId to the vehicle container
|
||||
if ($("[default-sort]").length == 0) {
|
||||
$(`.garage-item`).map((index, elem) => {
|
||||
$(elem).attr("default-sort", index);
|
||||
});
|
||||
}
|
||||
sortVehicles(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
function resetSortGarage() {
|
||||
var rowData = $(`.garage-item`);
|
||||
var sortedRow = rowData.toArray().sort((a, b) => {
|
||||
var currentVal = $(a).attr('default-sort');
|
||||
var nextVal = $(b).attr('default-sort');
|
||||
return currentVal - nextVal;
|
||||
});
|
||||
$(".garage-item-add").map((index, elem) => {
|
||||
sortedRow.push(elem);
|
||||
})
|
||||
$(`.vehiclesContainer`).html(sortedRow);
|
||||
}
|
||||
|
||||
let dragged = null;
|
||||
let draggedId = 0;
|
||||
function dragEnter(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
function dragStart(event, vehicleId) {
|
||||
dragged = event.target;
|
||||
draggedId = vehicleId;
|
||||
event.dataTransfer.setData('text/plain', draggedId);
|
||||
}
|
||||
function dragOver(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
function dropBox(event, targetVehicleId) {
|
||||
if (dragged.parentElement != event.target && event.target != dragged && draggedId != targetVehicleId) {
|
||||
copyContributors(draggedId, targetVehicleId);
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
function copyContributors(sourceVehicleId, destVehicleId) {
|
||||
var sourceVehicleName = $(`#gridVehicle_${sourceVehicleId} .card-body`).children('h5').map((index, elem) => { return elem.innerText }).toArray().join(" ");
|
||||
var destVehicleName = $(`#gridVehicle_${destVehicleId} .card-body`).children('h5').map((index, elem) => { return elem.innerText }).toArray().join(" ");
|
||||
Swal.fire({
|
||||
title: "Copy Collaborators?",
|
||||
text: `Copy collaborators over from ${sourceVehicleName} to ${destVehicleName}?`,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Copy",
|
||||
confirmButtonColor: "#0d6efd"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Vehicle/DuplicateVehicleCollaborators', { sourceVehicleId: sourceVehicleId, destVehicleId: destVehicleId }, function (data) {
|
||||
if (data.success) {
|
||||
successToast("Collaborators Copied");
|
||||
loadGarage();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showAccountInformationModal() {
|
||||
$.get('/Home/GetUserAccountInformationModal', function (data) {
|
||||
$('#accountInformationModalContent').html(data);
|
||||
$('#accountInformationModal').modal('show');
|
||||
})
|
||||
}
|
||||
|
||||
function showRootAccountInformationModal() {
|
||||
$.get('/Home/GetRootAccountInformationModal', function (data) {
|
||||
$('#accountInformationModalContent').html(data);
|
||||
$('#accountInformationModal').modal('show');
|
||||
})
|
||||
}
|
||||
function validateAndSaveRootUserAccount() {
|
||||
var hasError = false;
|
||||
if ($('#inputUsername').val().trim() == '') {
|
||||
$('#inputUsername').addClass("is-invalid");
|
||||
hasError = true;
|
||||
} else {
|
||||
$('#inputUsername').removeClass("is-invalid");
|
||||
}
|
||||
if ($('#inputPassword').val().trim() == '') {
|
||||
$('#inputPassword').addClass("is-invalid");
|
||||
hasError = true;
|
||||
} else {
|
||||
$('#inputPassword').removeClass("is-invalid");
|
||||
}
|
||||
if (hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var userAccountInfo = {
|
||||
userName: $('#inputUsername').val(),
|
||||
password: $('#inputPassword').val()
|
||||
}
|
||||
$.post('/Login/CreateLoginCreds', { credentials: userAccountInfo }, function (data) {
|
||||
if (data) {
|
||||
//hide modal
|
||||
hideAccountInformationModal();
|
||||
successToast('Root Account Updated');
|
||||
performLogOut();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hideAccountInformationModal() {
|
||||
$('#accountInformationModal').modal('hide');
|
||||
}
|
||||
function validateAndSaveUserAccount() {
|
||||
var hasError = false;
|
||||
if ($('#inputUsername').val().trim() == '') {
|
||||
$('#inputUsername').addClass("is-invalid");
|
||||
hasError = true;
|
||||
} else {
|
||||
$('#inputUsername').removeClass("is-invalid");
|
||||
}
|
||||
if ($('#inputEmail').val().trim() == '') {
|
||||
$('#inputEmail').addClass("is-invalid");
|
||||
hasError = true;
|
||||
} else {
|
||||
$('#inputEmail').removeClass("is-invalid");
|
||||
}
|
||||
if ($('#inputToken').val().trim() == '') {
|
||||
$('#inputToken').addClass("is-invalid");
|
||||
hasError = true;
|
||||
} else {
|
||||
$('#inputToken').removeClass("is-invalid");
|
||||
}
|
||||
if (hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var userAccountInfo = {
|
||||
userName: $('#inputUsername').val(),
|
||||
password: $('#inputPassword').val(),
|
||||
emailAddress: $('#inputEmail').val(),
|
||||
token: $('#inputToken').val()
|
||||
}
|
||||
$.post('/Home/UpdateUserAccount', { userAccount: userAccountInfo }, function (data) {
|
||||
if (data.success) {
|
||||
//hide modal
|
||||
hideAccountInformationModal();
|
||||
successToast('Profile Updated');
|
||||
performLogOut();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
function generateTokenForUser() {
|
||||
$.post('/Home/GenerateTokenForUser', function (data) {
|
||||
if (data) {
|
||||
successToast('Token sent');
|
||||
} else {
|
||||
errorToast(genericErrorMessage())
|
||||
}
|
||||
});
|
||||
}
|
||||
498
wwwroot/js/gasrecord.js
Normal file
498
wwwroot/js/gasrecord.js
Normal file
@@ -0,0 +1,498 @@
|
||||
function showAddGasRecordModal() {
|
||||
$.get(`/Vehicle/GetAddGasRecordPartialView?vehicleId=${GetVehicleId().vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#gasRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#gasRecordDate'));
|
||||
initTagSelector($("#gasRecordTag"));
|
||||
$('#gasRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditGasRecordModal(gasRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#gasRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getGasRecordModelData().id;
|
||||
if (existingId == gasRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#gasRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetGasRecordForEditById?gasRecordId=${gasRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#gasRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#gasRecordDate'));
|
||||
initTagSelector($("#gasRecordTag"));
|
||||
$('#gasRecordModal').modal('show');
|
||||
bindModalInputChanges('gasRecordModal');
|
||||
$('#gasRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("gasRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddGasRecordModal() {
|
||||
$('#gasRecordModal').modal('hide');
|
||||
}
|
||||
function deleteGasRecord(gasRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Gas Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteGasRecordById?gasRecordId=${gasRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddGasRecordModal();
|
||||
successToast("Gas Record deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleGasRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveGasRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateGasRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveGasRecordToVehicleId', { gasRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Gas Record Updated" : "Gas Record Added.");
|
||||
hideAddGasRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleGasRecords(formValues.vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateGasRecordValues() {
|
||||
var gasDate = $("#gasRecordDate").val();
|
||||
var gasMileage = parseInt(globalParseFloat($("#gasRecordMileage").val())).toString();
|
||||
var gasGallons = $("#gasRecordGallons").val();
|
||||
var gasCost = $("#gasRecordCost").val();
|
||||
var gasCostType = $("#gasCostType").val();
|
||||
var gasIsFillToFull = $("#gasIsFillToFull").is(":checked");
|
||||
var gasIsMissed = $("#gasIsMissed").is(":checked");
|
||||
var gasNotes = $("#gasRecordNotes").val();
|
||||
var gasTags = $("#gasRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var gasRecordId = getGasRecordModelData().id;
|
||||
//Odometer Adjustments
|
||||
if (isNaN(gasMileage) && GetVehicleId().odometerOptional) {
|
||||
gasMileage = '0';
|
||||
}
|
||||
gasMileage = GetAdjustedOdometer(gasRecordId, gasMileage);
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (gasDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#gasRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (gasMileage.trim() == '' || isNaN(gasMileage) || parseInt(gasMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#gasRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (gasGallons.trim() == '' || globalParseFloat(gasGallons) <= 0) {
|
||||
hasError = true;
|
||||
$("#gasRecordGallons").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordGallons").removeClass("is-invalid");
|
||||
}
|
||||
if (gasCostType != undefined && gasCostType == 'unit') {
|
||||
var convertedGasCost = globalParseFloat(gasCost) * globalParseFloat(gasGallons);
|
||||
if (isNaN(convertedGasCost))
|
||||
{
|
||||
hasError = true;
|
||||
$("#gasRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
gasCost = globalFloatToString(convertedGasCost.toFixed(2).toString());
|
||||
$("#gasRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
}
|
||||
if (gasCost.trim() == '' || !isValidMoney(gasCost)) {
|
||||
hasError = true;
|
||||
$("#gasRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: gasRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: gasDate,
|
||||
mileage: gasMileage,
|
||||
gallons: gasGallons,
|
||||
cost: gasCost,
|
||||
files: uploadedFiles,
|
||||
tags: gasTags,
|
||||
isFillToFull: gasIsFillToFull,
|
||||
missedFuelUp: gasIsMissed,
|
||||
notes: gasNotes,
|
||||
extraFields: extraFields.extraFields
|
||||
}
|
||||
}
|
||||
|
||||
function saveUserGasTabPreferences() {
|
||||
var gasUnit = $("[data-gas='consumption']").attr("data-unit");
|
||||
var fuelMileageUnit = $("[data-gas='fueleconomy']").attr("data-unit");
|
||||
$.post('/Vehicle/SaveUserGasTabPreferences', { gasUnit: gasUnit, fuelMileageUnit: fuelMileageUnit }, function (data) {
|
||||
if (!data) {
|
||||
errorToast("Error Saving User Preferences");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function convertGasConsumptionUnits(currentUnit, destinationUnit, save) {
|
||||
var sender = $("[data-gas='consumption']");
|
||||
if (currentUnit == "US gal") {
|
||||
switch (destinationUnit) {
|
||||
case "l":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 3.785;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "l"));
|
||||
sender.attr("data-unit", "l");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 3.785;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
case "imp gal":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 1.201;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "imp gal"));
|
||||
sender.attr("data-unit", "imp gal");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 1.201;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
}
|
||||
} else if (currentUnit == "l") {
|
||||
switch (destinationUnit) {
|
||||
case "US gal":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 3.785;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "US gal"));
|
||||
sender.attr("data-unit", "US gal");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 3.785;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
case "imp gal":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 4.546;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "imp gal"));
|
||||
sender.attr("data-unit", "imp gal");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 4.546;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
}
|
||||
} else if (currentUnit == "imp gal") {
|
||||
switch (destinationUnit) {
|
||||
case "US gal":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 1.201;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "US gal"));
|
||||
sender.attr("data-unit", "US gal");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 1.201;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
case "l":
|
||||
$("[data-gas-type='consumption']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) * 4.546;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "l"));
|
||||
sender.attr("data-unit", "l");
|
||||
});
|
||||
$("[data-gas-type='unitcost']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText) / 4.546;
|
||||
var decimalPoints = getGlobalConfig().useThreeDecimals ? 3 : 2;
|
||||
elem.innerText = `${globalAppendCurrency(globalFloatToString(convertedAmount.toFixed(decimalPoints)))}`;
|
||||
});
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateMPGLabels();
|
||||
}
|
||||
|
||||
function convertFuelMileageUnits(currentUnit, destinationUnit, save) {
|
||||
var sender = $("[data-gas='fueleconomy']");
|
||||
if (currentUnit == "l/100km") {
|
||||
switch (destinationUnit) {
|
||||
case "km/l":
|
||||
$("[data-gas-type='fueleconomy']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText);
|
||||
if (convertedAmount > 0) {
|
||||
convertedAmount = 100 / convertedAmount;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
}
|
||||
});
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "km/l"));
|
||||
sender.attr("data-unit", "km/l");
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
}
|
||||
} else if (currentUnit == "km/l") {
|
||||
switch (destinationUnit) {
|
||||
case "l/100km":
|
||||
$("[data-gas-type='fueleconomy']").map((index, elem) => {
|
||||
var convertedAmount = globalParseFloat(elem.innerText);
|
||||
if (convertedAmount > 0) {
|
||||
convertedAmount = 100 / convertedAmount;
|
||||
elem.innerText = globalFloatToString(convertedAmount.toFixed(2));
|
||||
}
|
||||
});
|
||||
sender.text(sender.text().replace(sender.attr("data-unit"), "l/100km"));
|
||||
sender.attr("data-unit", "l/100km");
|
||||
if (save) { setDebounce(saveUserGasTabPreferences); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateMPGLabels();
|
||||
}
|
||||
function toggleGasFilter(sender) {
|
||||
filterTable('gas-tab-pane', sender);
|
||||
updateMPGLabels();
|
||||
}
|
||||
function updateMPGLabels() {
|
||||
var averageLabel = $("#averageFuelMileageLabel");
|
||||
var minLabel = $("#minFuelMileageLabel");
|
||||
var maxLabel = $("#maxFuelMileageLabel");
|
||||
var totalConsumedLabel = $("#totalFuelConsumedLabel");
|
||||
var totalDistanceLabel = $("#totalDistanceLabel");
|
||||
if (averageLabel.length > 0 && minLabel.length > 0 && maxLabel.length > 0 && totalConsumedLabel.length > 0 && totalDistanceLabel.length > 0) {
|
||||
var rowsToAggregate = $("[data-aggregated='true']").parent(":not('.override-hide')");
|
||||
var rowsUnaggregated = $("[data-aggregated='false']").parent(":not('.override-hide')");
|
||||
var rowMPG = rowsToAggregate.children('[data-gas-type="fueleconomy"]').toArray().map(x => globalParseFloat(x.textContent));
|
||||
var rowNonZeroMPG = rowMPG.filter(x => x > 0);
|
||||
var maxMPG = rowMPG.length > 0 ? rowMPG.reduce((a, b) => a > b ? a : b) : 0;
|
||||
var minMPG = rowMPG.length > 0 && rowNonZeroMPG.length > 0 ? rowNonZeroMPG.reduce((a, b) => a < b ? a : b) : 0;
|
||||
var totalMilesTraveled = rowMPG.length > 0 ? rowsToAggregate.children('[data-gas-type="mileage"]').toArray().map(x => globalParseFloat($(x).attr("data-gas-aggregate"))).reduce((a, b) => a + b) : 0;
|
||||
var totalGasConsumed = rowMPG.length > 0 ? rowsToAggregate.children('[data-gas-type="consumption"]').toArray().map(x => globalParseFloat($(x).attr("data-gas-aggregate"))).reduce((a, b) => a + b) : 0;
|
||||
var totalGasConsumedFV = rowMPG.length > 0 ? rowsToAggregate.children('[data-gas-type="consumption"]').toArray().map(x => globalParseFloat(x.textContent)).reduce((a, b) => a + b) : 0;
|
||||
var totalUnaggregatedGasConsumedFV = rowsUnaggregated.length > 0 ? rowsUnaggregated.children('[data-gas-type="consumption"]').toArray().map(x => globalParseFloat(x.textContent)).reduce((a, b) => a + b) : 0;
|
||||
var totalMilesTraveledUnaggregated = rowsUnaggregated.length > 0 ? rowsUnaggregated.children('[data-gas-type="mileage"]').toArray().map(x => globalParseFloat($(x).attr("data-gas-aggregate"))).reduce((a, b) => a + b) : 0;
|
||||
var fullGasConsumed = totalGasConsumedFV + totalUnaggregatedGasConsumedFV;
|
||||
var fullDistanceTraveled = totalMilesTraveled + totalMilesTraveledUnaggregated;
|
||||
if (totalGasConsumed > 0 && rowNonZeroMPG.length > 0) {
|
||||
var averageMPG = totalMilesTraveled / totalGasConsumed;
|
||||
if (!getGlobalConfig().useMPG && $("[data-gas='fueleconomy']").attr("data-unit") != 'km/l' && averageMPG > 0) {
|
||||
averageMPG = 100 / averageMPG;
|
||||
}
|
||||
averageLabel.text(`${averageLabel.text().split(':')[0]}: ${globalFloatToString(averageMPG.toFixed(2))}`);
|
||||
} else {
|
||||
averageLabel.text(`${averageLabel.text().split(':')[0]}: ${globalFloatToString('0.00')}`);
|
||||
}
|
||||
if (fullDistanceTraveled > 0) {
|
||||
totalDistanceLabel.text(`${totalDistanceLabel.text().split(':')[0]}: ${fullDistanceTraveled} ${getGasModelData().distanceUnit}`);
|
||||
} else {
|
||||
totalDistanceLabel.text(`${totalDistanceLabel.text().split(':')[0]}: 0 ${getGasModelData().distanceUnit}`);
|
||||
}
|
||||
if (fullGasConsumed > 0) {
|
||||
totalConsumedLabel.text(`${totalConsumedLabel.text().split(':')[0]}: ${globalFloatToString(fullGasConsumed.toFixed(2))}`);
|
||||
} else {
|
||||
totalConsumedLabel.text(`${totalConsumedLabel.text().split(':')[0]}: ${globalFloatToString('0.00')}`);
|
||||
}
|
||||
if (!getGlobalConfig().useMPG && $("[data-gas='fueleconomy']").attr("data-unit") != 'km/l') {
|
||||
maxLabel.text(`${maxLabel.text().split(':')[0]}: ${globalFloatToString(minMPG.toFixed(2))}`);
|
||||
minLabel.text(`${minLabel.text().split(':')[0]}: ${globalFloatToString(maxMPG.toFixed(2))}`);
|
||||
}
|
||||
else {
|
||||
minLabel.text(`${minLabel.text().split(':')[0]}: ${globalFloatToString(minMPG.toFixed(2))}`);
|
||||
maxLabel.text(`${maxLabel.text().split(':')[0]}: ${globalFloatToString(maxMPG.toFixed(2))}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleUnits(sender) {
|
||||
event.preventDefault();
|
||||
//check which column to convert.
|
||||
sender = $(sender);
|
||||
if (sender.attr("data-gas") == "consumption") {
|
||||
switch (sender.attr("data-unit")) {
|
||||
case "US gal":
|
||||
convertGasConsumptionUnits("US gal", "l", true);
|
||||
break;
|
||||
case "l":
|
||||
convertGasConsumptionUnits("l", "imp gal", true);
|
||||
break;
|
||||
case "imp gal":
|
||||
convertGasConsumptionUnits("imp gal", "US gal", true);
|
||||
break;
|
||||
}
|
||||
} else if (sender.attr("data-gas") == "fueleconomy") {
|
||||
switch (sender.attr("data-unit")) {
|
||||
case "l/100km":
|
||||
convertFuelMileageUnits("l/100km", "km/l", true);
|
||||
break;
|
||||
case "km/l":
|
||||
convertFuelMileageUnits("km/l", "l/100km", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function searchGasTableRows() {
|
||||
var tabName = 'gas-tab-pane';
|
||||
Swal.fire({
|
||||
title: 'Search Records',
|
||||
html: `
|
||||
<input type="text" id="inputSearch" class="swal2-input" placeholder="Keyword(case sensitive)" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Search',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const searchString = $("#inputSearch").val();
|
||||
return { searchString }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
var rowData = $(`#${tabName} table tbody tr`);
|
||||
var filteredRows = $(`#${tabName} table tbody tr td:contains('${result.value.searchString}')`).parent();
|
||||
var splitSearchString = result.value.searchString.split('=');
|
||||
if (result.value.searchString.includes('=') && splitSearchString.length == 2) {
|
||||
//column specific search.
|
||||
//get column index
|
||||
var columns = $(`#${tabName} table th`).toArray().map(x => x.innerText);
|
||||
var columnName = splitSearchString[0];
|
||||
var colSearchString = splitSearchString[1];
|
||||
var colIndex = columns.findIndex(x => x == columnName) + 1;
|
||||
filteredRows = $(`#${tabName} table tbody tr td:nth-child(${colIndex}):contains('${colSearchString}')`).parent();
|
||||
}
|
||||
if (result.value.searchString.trim() == '') {
|
||||
rowData.removeClass('override-hide');
|
||||
} else {
|
||||
rowData.addClass('override-hide');
|
||||
filteredRows.removeClass('override-hide');
|
||||
}
|
||||
$(".tagfilter.bg-primary").addClass('bg-secondary').removeClass('bg-primary');
|
||||
updateAggregateLabels();
|
||||
updateMPGLabels();
|
||||
}
|
||||
});
|
||||
}
|
||||
function editMultipleGasRecords(ids) {
|
||||
if (ids.length < 2) {
|
||||
return;
|
||||
}
|
||||
$.post('/Vehicle/GetGasRecordsEditModal', { recordIds: ids }, function (data) {
|
||||
if (data) {
|
||||
$("#gasRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#gasRecordDate'));
|
||||
initTagSelector($("#gasRecordTag"));
|
||||
$('#gasRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveMultipleGasRecordsToVehicle() {
|
||||
var gasDate = $("#gasRecordDate").val();
|
||||
var gasMileage = $("#gasRecordMileage").val();
|
||||
var gasMileageToParse = parseInt(globalParseFloat($("#gasRecordMileage").val())).toString();
|
||||
var gasConsumption = $("#gasRecordConsumption").val();
|
||||
var gasCost = $("#gasRecordCost").val();
|
||||
var gasNotes = $("#gasRecordNotes").val();
|
||||
var gasTags = $("#gasRecordTag").val();
|
||||
var gasExtraFields = getAndValidateExtraFields();
|
||||
//validation
|
||||
var hasError = false;
|
||||
if (gasMileage.trim() != '' && (isNaN(gasMileageToParse) || parseInt(gasMileageToParse) < 0)) {
|
||||
hasError = true;
|
||||
$("#gasRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (gasConsumption.trim() != '' && !isValidMoney(gasConsumption)) {
|
||||
hasError = true;
|
||||
$("#gasRecordConsumption").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordConsumption").removeClass("is-invalid");
|
||||
}
|
||||
if (gasCost.trim() != '' && !isValidMoney(gasCost)) {
|
||||
hasError = true;
|
||||
$("#gasRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#gasRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
if (hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var formValues = {
|
||||
recordIds: recordsToEdit,
|
||||
editRecord: {
|
||||
date: gasDate,
|
||||
mileage: gasMileageToParse,
|
||||
gallons: gasConsumption,
|
||||
cost: gasCost,
|
||||
notes: gasNotes,
|
||||
tags: gasTags,
|
||||
extraFields: gasExtraFields.extraFields
|
||||
}
|
||||
}
|
||||
$.post('/Vehicle/SaveMultipleGasRecords', { editModel: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast("Gas Records Updated");
|
||||
hideAddGasRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleGasRecords(GetVehicleId().vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
10
wwwroot/js/loader.js
Normal file
10
wwwroot/js/loader.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const sloader = {
|
||||
show: function () {
|
||||
var sLoaderElement = `<div class='sloader'><div class='loader'></div></div>`
|
||||
$("body").append(sLoaderElement);
|
||||
},
|
||||
hide: function () {
|
||||
$(".sloader").remove();
|
||||
}
|
||||
|
||||
}
|
||||
91
wwwroot/js/login.js
Normal file
91
wwwroot/js/login.js
Normal file
@@ -0,0 +1,91 @@
|
||||
function performLogin() {
|
||||
var userName = $("#inputUserName").val();
|
||||
var userPassword = $("#inputUserPassword").val();
|
||||
var isPersistent = $("#inputPersistent").is(":checked");
|
||||
$.post('/Login/Login', {userName: userName, password: userPassword, isPersistent: isPersistent}, function (data) {
|
||||
if (data) {
|
||||
//check for redirectURL
|
||||
var redirectURL = getRedirectURL().url;
|
||||
if (redirectURL.trim() != "") {
|
||||
window.location.href = redirectURL;
|
||||
} else {
|
||||
window.location.href = '/Home';
|
||||
}
|
||||
} else {
|
||||
errorToast("Invalid Login Credentials, please try again.");
|
||||
}
|
||||
})
|
||||
}
|
||||
function performRegistration() {
|
||||
var token = $("#inputToken").val();
|
||||
var userName = $("#inputUserName").val();
|
||||
var userPassword = $("#inputUserPassword").val();
|
||||
var userEmail = $("#inputEmail").val();
|
||||
$.post('/Login/Register', { userName: userName, password: userPassword, token: token, emailAddress: userEmail }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
setTimeout(function () { window.location.href = '/Login/Index' }, 500);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
function requestPasswordReset() {
|
||||
var userName = $("#inputUserName").val();
|
||||
$.post('/Login/RequestResetPassword', { userName: userName }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
setTimeout(function () { window.location.href = '/Login/Index' }, 500);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
function performPasswordReset() {
|
||||
var token = $("#inputToken").val();
|
||||
var userPassword = $("#inputUserPassword").val();
|
||||
var userEmail = $("#inputEmail").val();
|
||||
$.post('/Login/PerformPasswordReset', { password: userPassword, token: token, emailAddress: userEmail }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
setTimeout(function () { window.location.href = '/Login/Index' }, 500);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function remoteLogin() {
|
||||
$.get('/Login/GetRemoteLoginLink', function (data) {
|
||||
if (data) {
|
||||
window.location.href = data;
|
||||
}
|
||||
})
|
||||
}
|
||||
function sendRegistrationToken() {
|
||||
Swal.fire({
|
||||
title: 'Please Provide an Email Address',
|
||||
html: `
|
||||
<input type="text" id="inputTokenEmail" class="swal2-input" placeholder="Email Address" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Send',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const tokenEmail = $("#inputTokenEmail").val();
|
||||
if (!tokenEmail || tokenEmail.trim() == '') {
|
||||
Swal.showValidationMessage(`Please enter a valid email address`);
|
||||
}
|
||||
return { tokenEmail }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Login/SendRegistrationToken', { emailAddress: result.value.tokenEmail }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
129
wwwroot/js/note.js
Normal file
129
wwwroot/js/note.js
Normal file
@@ -0,0 +1,129 @@
|
||||
function showAddNoteModal() {
|
||||
$.get('/Vehicle/GetAddNotePartialView', function (data) {
|
||||
if (data) {
|
||||
$("#noteModalContent").html(data);
|
||||
initTagSelector($("#noteRecordTag"));
|
||||
$('#noteModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditNoteModal(noteId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#noteModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getNoteModelData().id;
|
||||
if (existingId == noteId && $('[data-changed=true]').length > 0) {
|
||||
$('#noteModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetNoteForEditById?noteId=${noteId}`, function (data) {
|
||||
if (data) {
|
||||
$("#noteModalContent").html(data);
|
||||
initTagSelector($("#noteRecordTag"));
|
||||
$('#noteModal').modal('show');
|
||||
bindModalInputChanges('noteModal');
|
||||
$('#noteModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("noteTextArea");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddNoteModal() {
|
||||
$('#noteModal').modal('hide');
|
||||
}
|
||||
function deleteNote(noteId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Notes cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteNoteById?noteId=${noteId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddNoteModal();
|
||||
successToast("Note Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleNotes(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveNoteToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateNoteValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveNoteToVehicleId', { note: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Note Updated" : "Note Added.");
|
||||
hideAddNoteModal();
|
||||
saveScrollPosition();
|
||||
getVehicleNotes(formValues.vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateNoteValues() {
|
||||
var noteDescription = $("#noteDescription").val();
|
||||
var noteText = $("#noteTextArea").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var noteId = getNoteModelData().id;
|
||||
var noteIsPinned = $("#noteIsPinned").is(":checked");
|
||||
var noteTags = $("#noteRecordTag").val();
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (noteDescription.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#noteDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#noteDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (noteText.trim() == '') {
|
||||
hasError = true;
|
||||
$("#noteTextArea").addClass("is-invalid");
|
||||
} else {
|
||||
$("#noteTextArea").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: noteId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
description: noteDescription,
|
||||
noteText: noteText,
|
||||
files: uploadedFiles,
|
||||
pinned: noteIsPinned,
|
||||
tags: noteTags,
|
||||
extraFields: extraFields.extraFields
|
||||
}
|
||||
}
|
||||
function pinNotes(ids, toggle, pinStatus) {
|
||||
$.post('/Vehicle/PinNotes', { noteIds: ids, isToggle: toggle, pinStatus: pinStatus }, function (data) {
|
||||
if (data) {
|
||||
successToast(ids.length > 1 ? `${ids.length} Notes Updated` : "Note Updated.");
|
||||
getVehicleNotes(GetVehicleId().vehicleId);
|
||||
}
|
||||
})
|
||||
}
|
||||
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');
|
||||
}
|
||||
}
|
||||
460
wwwroot/js/planrecord.js
Normal file
460
wwwroot/js/planrecord.js
Normal file
@@ -0,0 +1,460 @@
|
||||
function showAddPlanRecordModal() {
|
||||
$.get('/Vehicle/GetAddPlanRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#planRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#planRecordDate'));
|
||||
$('#planRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditPlanRecordModal(planRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#planRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getPlanRecordModelData().id;
|
||||
var isNotTemplate = !getPlanRecordModelData().isTemplate;
|
||||
if (existingId == planRecordId && isNotTemplate && $('[data-changed=true]').length > 0) {
|
||||
$('#planRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetPlanRecordForEditById?planRecordId=${planRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#planRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#planRecordDate'));
|
||||
$('#planRecordModal').modal('show');
|
||||
bindModalInputChanges('planRecordModal');
|
||||
$('#planRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("planRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditPlanRecordTemplateModal(planRecordTemplateId, nocache) {
|
||||
hidePlanRecordTemplatesModal();
|
||||
if (!nocache) {
|
||||
var existingContent = $("#planRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getPlanRecordModelData().id;
|
||||
var isTemplate = getPlanRecordModelData().isTemplate;
|
||||
if (existingId == planRecordTemplateId && isTemplate && $('[data-changed=true]').length > 0) {
|
||||
$('#planRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetPlanRecordTemplateForEditById?planRecordTemplateId=${planRecordTemplateId}`, function (data) {
|
||||
if (data) {
|
||||
$("#planRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#planRecordDate'));
|
||||
$('#planRecordModal').modal('show');
|
||||
bindModalInputChanges('planRecordModal');
|
||||
$('#planRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("planRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddPlanRecordModal() {
|
||||
$('#planRecordModal').modal('hide');
|
||||
if (getPlanRecordModelData().createdFromReminder) {
|
||||
//show reminder Modal
|
||||
$("#reminderRecordModal").modal("show");
|
||||
}
|
||||
if (getPlanRecordModelData().isTemplate) {
|
||||
showPlanRecordTemplatesModal();
|
||||
}
|
||||
}
|
||||
function deletePlanRecord(planRecordId, noModal) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Plan Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeletePlanRecordById?planRecordId=${planRecordId}`, function (data) {
|
||||
if (data) {
|
||||
if (!noModal) {
|
||||
hideAddPlanRecordModal();
|
||||
}
|
||||
successToast("Plan Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function savePlanRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidatePlanRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SavePlanRecordToVehicleId', { planRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Plan Record Updated" : "Plan Record Added.");
|
||||
hideAddPlanRecordModal();
|
||||
if (!getPlanRecordModelData().createdFromReminder) {
|
||||
saveScrollPosition();
|
||||
getVehiclePlanRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function showPlanRecordTemplatesModal() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
$.get(`/Vehicle/GetPlanRecordTemplatesForVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#planRecordTemplateModalContent").html(data);
|
||||
$('#planRecordTemplateModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function hidePlanRecordTemplatesModal() {
|
||||
$('#planRecordTemplateModal').modal('hide');
|
||||
}
|
||||
function usePlannerRecordTemplate(planRecordTemplateId) {
|
||||
$.post(`/Vehicle/ConvertPlanRecordTemplateToPlanRecord?planRecordTemplateId=${planRecordTemplateId}`, function (data) {
|
||||
if (data.success) {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
successToast(data.message);
|
||||
hidePlanRecordTemplatesModal();
|
||||
saveScrollPosition();
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
} else {
|
||||
if (data.message == "Insufficient Supplies") {
|
||||
data.message += `<br /><br /><a class='text-link' style='cursor:pointer;' onclick='orderPlanSupplies(${planRecordTemplateId}, true)'>Order Required Supplies</a>`
|
||||
}
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deletePlannerRecordTemplate(planRecordTemplateId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Plan Templates cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeletePlanRecordTemplateById?planRecordTemplateId=${planRecordTemplateId}`, function (data) {
|
||||
$("#workAroundInput").hide();
|
||||
if (data) {
|
||||
successToast("Plan Template Deleted");
|
||||
hideAddPlanRecordModal();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function savePlanRecordTemplate(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidatePlanRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SavePlanRecordTemplateToVehicleId', { planRecord: formValues }, function (data) {
|
||||
if (data.success) {
|
||||
if (isEdit) {
|
||||
hideAddPlanRecordModal();
|
||||
showPlanRecordTemplatesModal();
|
||||
$('[data-changed=true]').attr('data-changed', false)
|
||||
successToast('Plan Template Updated');
|
||||
} else {
|
||||
successToast('Plan Template Added');
|
||||
}
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidatePlanRecordValues() {
|
||||
var planDescription = $("#planRecordDescription").val();
|
||||
var planCost = $("#planRecordCost").val();
|
||||
var planNotes = $("#planRecordNotes").val();
|
||||
var planType = $("#planRecordType").val();
|
||||
var planPriority = $("#planRecordPriority").val();
|
||||
var planProgress = $("#planRecordProgress").val();
|
||||
var planDateCreated = getPlanRecordModelData().dateCreated;
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var planRecordId = getPlanRecordModelData().id;
|
||||
var reminderRecordId = getPlanRecordModelData().reminderRecordId;
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (planDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#planRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#planRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (planCost.trim() == '' || !isValidMoney(planCost)) {
|
||||
hasError = true;
|
||||
$("#planRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#planRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: planRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
dateCreated: planDateCreated,
|
||||
description: planDescription,
|
||||
cost: planCost,
|
||||
notes: planNotes,
|
||||
files: uploadedFiles,
|
||||
supplies: selectedSupplies,
|
||||
priority: planPriority,
|
||||
progress: planProgress,
|
||||
importMode: planType,
|
||||
extraFields: extraFields.extraFields,
|
||||
requisitionHistory: supplyUsageHistory,
|
||||
deletedRequisitionHistory: deletedSupplyUsageHistory,
|
||||
reminderRecordId: reminderRecordId,
|
||||
copySuppliesAttachment: copySuppliesAttachments
|
||||
}
|
||||
}
|
||||
//drag and drop stuff.
|
||||
|
||||
let dragged = null;
|
||||
let draggedId = 0;
|
||||
function dragEnter(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
function dragStart(event, planRecordId) {
|
||||
dragged = event.target;
|
||||
draggedId = planRecordId;
|
||||
event.dataTransfer.setData('text/plain', draggedId);
|
||||
}
|
||||
function dragOver(event) {
|
||||
event.preventDefault();
|
||||
if (planTouchTimer) {
|
||||
clearTimeout(planTouchTimer);
|
||||
planTouchTimer = null;
|
||||
}
|
||||
}
|
||||
function dropBox(event, newProgress) {
|
||||
var targetSwimLane = $(event.target).hasClass("swimlane") ? event.target : $(event.target).parents(".swimlane")[0];
|
||||
var draggedSwimLane = $(dragged).parents(".swimlane")[0];
|
||||
if (targetSwimLane != draggedSwimLane) {
|
||||
updatePlanRecordProgress(newProgress);
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
function updatePlanRecordProgress(newProgress) {
|
||||
if (draggedId > 0) {
|
||||
if (newProgress == 'Done') {
|
||||
//if user is marking the task as done, we will want them to enter the mileage so that we can auto-convert it.
|
||||
Swal.fire({
|
||||
title: 'Mark Task as Done?',
|
||||
html: `<p>To confirm, please enter the current odometer reading on your vehicle, as we also need the current odometer to auto convert the task into the relevant record.</p>
|
||||
<input type="text" inputmode="numeric" id="inputOdometer" class="swal2-input" placeholder="Odometer Reading" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Confirm',
|
||||
showCancelButton: true,
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
var odometer = $("#inputOdometer").val();
|
||||
if (odometer.trim() == '' && GetVehicleId().odometerOptional) {
|
||||
odometer = '0';
|
||||
}
|
||||
if (!odometer || isNaN(odometer)) {
|
||||
Swal.showValidationMessage(`Please enter an odometer reading`)
|
||||
}
|
||||
return { odometer }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
//Odometer Adjustments
|
||||
var adjustedOdometer = GetAdjustedOdometer(0, result.value.odometer);
|
||||
$.post('/Vehicle/UpdatePlanRecordProgress', { planRecordId: draggedId, planProgress: newProgress, odometer: adjustedOdometer }, function (data) {
|
||||
if (data) {
|
||||
successToast("Plan Progress Updated");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
draggedId = 0;
|
||||
});
|
||||
} else {
|
||||
$.post('/Vehicle/UpdatePlanRecordProgress', { planRecordId: draggedId, planProgress: newProgress }, function (data) {
|
||||
if (data) {
|
||||
successToast("Plan Progress Updated");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
draggedId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
function orderPlanSupplies(planRecordTemplateId, closeSwal) {
|
||||
if (closeSwal) {
|
||||
Swal.close();
|
||||
}
|
||||
$.get(`/Vehicle/OrderPlanSupplies?planRecordTemplateId=${planRecordTemplateId}`, function (data) {
|
||||
if (data.success != undefined && !data.success) {
|
||||
//success is provided.
|
||||
errorToast(data.message);
|
||||
} else {
|
||||
//hide plan record template modal.
|
||||
hidePlanRecordTemplatesModal();
|
||||
$("#planRecordTemplateSupplyOrderModalContent").html(data);
|
||||
$("#planRecordTemplateSupplyOrderModal").modal('show');
|
||||
}
|
||||
})
|
||||
}
|
||||
function hideOrderSupplyModal() {
|
||||
$("#planRecordTemplateSupplyOrderModal").modal('hide');
|
||||
showPlanRecordTemplatesModal();
|
||||
}
|
||||
function configurePlanTableContextMenu(planRecordId, currentSwimLane) {
|
||||
//clear any bound actions
|
||||
$(".context-menu-move").off('click');
|
||||
//bind context menu actions
|
||||
$(".context-menu-delete").on('click', () => {
|
||||
deletePlanRecord(planRecordId, true);
|
||||
});
|
||||
let planRecordIdArray = [planRecordId];
|
||||
$(".context-menu-print-tab-sticker").on('click', () => {
|
||||
printTabStickers(planRecordIdArray, 'PlanRecord');
|
||||
});
|
||||
$(".context-menu-duplicate").on('click', () => {
|
||||
duplicateRecords(planRecordIdArray, 'PlanRecord');
|
||||
});
|
||||
$(".context-menu-duplicate-vehicle").on('click', () => {
|
||||
duplicateRecordsToOtherVehicles(planRecordIdArray, 'PlanRecord');
|
||||
});
|
||||
$(".context-menu-move.move-planned").on('click', () => {
|
||||
draggedId = planRecordId;
|
||||
updatePlanRecordProgress('Backlog');
|
||||
draggedId = 0;
|
||||
});
|
||||
$(".context-menu-move.move-doing").on('click', () => {
|
||||
draggedId = planRecordId;
|
||||
updatePlanRecordProgress('InProgress');
|
||||
});
|
||||
$(".context-menu-move.move-testing").on('click', () => {
|
||||
draggedId = planRecordId;
|
||||
updatePlanRecordProgress('Testing');
|
||||
});
|
||||
$(".context-menu-move.move-done").on('click', () => {
|
||||
draggedId = planRecordId;
|
||||
updatePlanRecordProgress('Done');
|
||||
});
|
||||
//hide all move buttons
|
||||
$(".context-menu-move").hide();
|
||||
$(".context-menu-delete").show(); //delete is always visible.
|
||||
switch (currentSwimLane) {
|
||||
case 'Backlog':
|
||||
$(".context-menu-move.move-header").show();
|
||||
$(".context-menu-move.move-doing").show();
|
||||
$(".context-menu-move.move-testing").show();
|
||||
$(".context-menu-move.move-done").show();
|
||||
break;
|
||||
case 'InProgress':
|
||||
$(".context-menu-move.move-header").show();
|
||||
$(".context-menu-move.move-planned").show();
|
||||
$(".context-menu-move.move-testing").show();
|
||||
$(".context-menu-move.move-done").show();
|
||||
break;
|
||||
case 'Testing':
|
||||
$(".context-menu-move.move-header").show();
|
||||
$(".context-menu-move.move-planned").show();
|
||||
$(".context-menu-move.move-doing").show();
|
||||
$(".context-menu-move.move-done").show();
|
||||
break;
|
||||
case 'Done':
|
||||
break;
|
||||
}
|
||||
}
|
||||
function showPlanTableContextMenu(e, planRecordId, currentSwimLane) {
|
||||
if (event != undefined) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (getDeviceIsTouchOnly()) {
|
||||
return;
|
||||
}
|
||||
if (planRecordId == 0) {
|
||||
return;
|
||||
}
|
||||
$(".table-context-menu").fadeIn("fast");
|
||||
$(".table-context-menu").css({
|
||||
left: getMenuPosition(event.clientX, 'width', 'scrollLeft'),
|
||||
top: getMenuPosition(event.clientY, 'height', 'scrollTop')
|
||||
});
|
||||
configurePlanTableContextMenu(planRecordId, currentSwimLane);
|
||||
}
|
||||
function showPlanTableContextMenuForMobile(e, xPosition, yPosition, planRecordId, currentSwimLane) {
|
||||
$(".table-context-menu").fadeIn("fast");
|
||||
$(".table-context-menu").css({
|
||||
left: getMenuPosition(xPosition, 'width', 'scrollLeft'),
|
||||
top: getMenuPosition(yPosition, 'height', 'scrollTop')
|
||||
});
|
||||
configurePlanTableContextMenu(planRecordId, currentSwimLane);
|
||||
if (planTouchTimer) {
|
||||
clearTimeout(planTouchTimer);
|
||||
planTouchTimer = null;
|
||||
}
|
||||
}
|
||||
var planTouchTimer;
|
||||
var planTouchDuration = 3000;
|
||||
function detectPlanItemLongTouch(sender, planRecordId, currentSwimLane) {
|
||||
var touchX = event.touches[0].clientX;
|
||||
var touchY = event.touches[0].clientY;
|
||||
if (!planTouchTimer) {
|
||||
planTouchTimer = setTimeout(function () { showPlanTableContextMenuForMobile(sender, touchX, touchY, planRecordId, currentSwimLane); detectPlanItemTouchEndPremature(sender); }, planTouchDuration);
|
||||
}
|
||||
}
|
||||
function detectPlanItemTouchEndPremature(sender) {
|
||||
if (planTouchTimer) {
|
||||
clearTimeout(planTouchTimer);
|
||||
planTouchTimer = null;
|
||||
}
|
||||
}
|
||||
361
wwwroot/js/reminderrecord.js
Normal file
361
wwwroot/js/reminderrecord.js
Normal file
@@ -0,0 +1,361 @@
|
||||
function showEditReminderRecordModal(reminderId) {
|
||||
$.get(`/Vehicle/GetReminderRecordForEditById?reminderRecordId=${reminderId}`, function (data) {
|
||||
if (data) {
|
||||
$("#reminderRecordModalContent").html(data);
|
||||
initDatePicker($('#reminderDate'), true);
|
||||
initTagSelector($("#reminderRecordTag"));
|
||||
$("#reminderRecordModal").modal("show");
|
||||
$('#reminderRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("reminderNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddReminderRecordModal() {
|
||||
$('#reminderRecordModal').modal('hide');
|
||||
}
|
||||
function checkCustomMonthInterval() {
|
||||
var selectedValue = $("#reminderRecurringMonth").val();
|
||||
if (selectedValue == "Other") {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: 'Specify Custom Time Interval',
|
||||
html: `
|
||||
<input type="text" inputmode="numeric" id="inputCustomMonth" class="swal2-input" placeholder="Time" onkeydown="handleSwalEnter(event)">
|
||||
<select class="swal2-select" id="inputCustomMonthUnit">
|
||||
<option value="Months">Months</option>
|
||||
<option value="Days">Days</option>
|
||||
</select>
|
||||
`,
|
||||
confirmButtonText: 'Set',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const customMonth = $("#inputCustomMonth").val();
|
||||
if (!customMonth || isNaN(parseInt(customMonth)) || parseInt(customMonth) <= 0) {
|
||||
Swal.showValidationMessage(`Please enter a valid number`);
|
||||
}
|
||||
const customMonthUnit = $("#inputCustomMonthUnit").val();
|
||||
return { customMonth, customMonthUnit }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
customMonthInterval = result.value.customMonth;
|
||||
customMonthIntervalUnit = result.value.customMonthUnit;
|
||||
$("#reminderRecurringMonth > option[value='Other']").text(`Other: ${result.value.customMonth} ${result.value.customMonthUnit}`);
|
||||
} else {
|
||||
$("#reminderRecurringMonth").val(getReminderRecordModelData().monthInterval);
|
||||
}
|
||||
$("#workAroundInput").hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkCustomMileageInterval() {
|
||||
var selectedValue = $("#reminderRecurringMileage").val();
|
||||
if (selectedValue == "Other") {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: 'Specify Custom Mileage Interval',
|
||||
html: `
|
||||
<input type="text" inputmode="numeric" id="inputCustomMileage" class="swal2-input" placeholder="Mileage" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Set',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const customMileage = $("#inputCustomMileage").val();
|
||||
if (!customMileage || isNaN(parseInt(customMileage)) || parseInt(customMileage) <= 0) {
|
||||
Swal.showValidationMessage(`Please enter a valid number`);
|
||||
}
|
||||
return { customMileage }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
customMileageInterval = result.value.customMileage;
|
||||
$("#reminderRecurringMileage > option[value='Other']").text(`Other: ${result.value.customMileage}`);
|
||||
} else {
|
||||
$("#reminderRecurringMileage").val(getReminderRecordModelData().mileageInterval);
|
||||
}
|
||||
$("#workAroundInput").hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
function deleteReminderRecord(reminderRecordId, e) {
|
||||
if (e != undefined) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Reminders cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteReminderRecordById?reminderRecordId=${reminderRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddReminderRecordModal();
|
||||
successToast("Reminder Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleReminders(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function toggleCustomThresholds() {
|
||||
var isChecked = $("#reminderUseCustomThresholds").is(':checked');
|
||||
if (isChecked) {
|
||||
$("#reminderCustomThresholds").collapse('show');
|
||||
} else {
|
||||
$("#reminderCustomThresholds").collapse('hide');
|
||||
}
|
||||
}
|
||||
function saveReminderRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateReminderRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveReminderRecordToVehicleId', { reminderRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Reminder Updated" : "Reminder Added.");
|
||||
hideAddReminderRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleReminders(formValues.vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function appendMileageToOdometer(increment) {
|
||||
var reminderMileage = $("#reminderMileage").val();
|
||||
var reminderMileageIsInvalid = reminderMileage.trim() == '' || parseInt(reminderMileage) < 0;
|
||||
if (reminderMileageIsInvalid) {
|
||||
reminderMileage = 0;
|
||||
} else {
|
||||
reminderMileage = parseInt(reminderMileage);
|
||||
}
|
||||
reminderMileage += increment;
|
||||
$("#reminderMileage").val(reminderMileage);
|
||||
}
|
||||
|
||||
function enableRecurring() {
|
||||
var reminderIsRecurring = $("#reminderIsRecurring").is(":checked");
|
||||
if (reminderIsRecurring) {
|
||||
//check selected metric
|
||||
var reminderMetric = $('#reminderOptions input:radio:checked').val();
|
||||
if (reminderMetric == "Date") {
|
||||
$("#reminderRecurringMonth").attr('disabled', false);
|
||||
$("#reminderRecurringMileage").attr('disabled', true);
|
||||
}
|
||||
else if (reminderMetric == "Odometer") {
|
||||
$("#reminderRecurringMileage").attr('disabled', false);
|
||||
$("#reminderRecurringMonth").attr('disabled', true);
|
||||
}
|
||||
else if (reminderMetric == "Both") {
|
||||
$("#reminderRecurringMonth").attr('disabled', false);
|
||||
$("#reminderRecurringMileage").attr('disabled', false);
|
||||
}
|
||||
} else {
|
||||
$("#reminderRecurringMileage").attr('disabled', true);
|
||||
$("#reminderRecurringMonth").attr('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
function markDoneReminderRecord(reminderRecordId, e) {
|
||||
event.stopPropagation();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
$.post(`/Vehicle/PushbackRecurringReminderRecord?reminderRecordId=${reminderRecordId}`, function (data) {
|
||||
if (data) {
|
||||
successToast("Reminder Updated");
|
||||
getVehicleReminders(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getAndValidateReminderRecordValues() {
|
||||
var reminderDate = $("#reminderDate").val();
|
||||
var reminderMileage = parseInt(globalParseFloat($("#reminderMileage").val())).toString();
|
||||
var reminderDescription = $("#reminderDescription").val();
|
||||
var reminderNotes = $("#reminderNotes").val();
|
||||
var reminderOption = $('#reminderOptions input:radio:checked').val();
|
||||
var reminderIsRecurring = $("#reminderIsRecurring").is(":checked");
|
||||
var reminderRecurringMonth = $("#reminderRecurringMonth").val();
|
||||
var reminderRecurringMileage = $("#reminderRecurringMileage").val();
|
||||
var reminderTags = $("#reminderRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var reminderId = getReminderRecordModelData().id;
|
||||
var reminderUseCustomThresholds = $("#reminderUseCustomThresholds").is(":checked");
|
||||
var reminderUrgentDays = $("#reminderUrgentDays").val();
|
||||
var reminderVeryUrgentDays = $("#reminderVeryUrgentDays").val();
|
||||
var reminderUrgentDistance = $("#reminderUrgentDistance").val();
|
||||
var reminderVeryUrgentDistance = $("#reminderVeryUrgentDistance").val();
|
||||
//validation
|
||||
var hasError = false;
|
||||
var reminderDateIsInvalid = reminderDate.trim() == ''; //eliminates whitespace.
|
||||
var reminderMileageIsInvalid = reminderMileage.trim() == '' || isNaN(reminderMileage) || parseInt(reminderMileage) < 0;
|
||||
if ((reminderOption == "Both" || reminderOption == "Date") && reminderDateIsInvalid) {
|
||||
hasError = true;
|
||||
$("#reminderDate").addClass("is-invalid");
|
||||
} else if (reminderOption == "Date") {
|
||||
$("#reminderDate").removeClass("is-invalid");
|
||||
}
|
||||
if ((reminderOption == "Both" || reminderOption == "Odometer") && reminderMileageIsInvalid) {
|
||||
hasError = true;
|
||||
$("#reminderMileage").addClass("is-invalid");
|
||||
} else if (reminderOption == "Odometer") {
|
||||
$("#reminderMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (reminderDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#reminderDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (reminderUseCustomThresholds) {
|
||||
//validate custom threshold values
|
||||
if (reminderUrgentDays.trim() == '' || isNaN(reminderUrgentDays) || parseInt(reminderUrgentDays) < 0) {
|
||||
hasError = true;
|
||||
$("#reminderUrgentDays").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderUrgentDays").removeClass("is-invalid");
|
||||
}
|
||||
if (reminderVeryUrgentDays.trim() == '' || isNaN(reminderVeryUrgentDays) || parseInt(reminderVeryUrgentDays) < 0) {
|
||||
hasError = true;
|
||||
$("#reminderVeryUrgentDays").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderVeryUrgentDays").removeClass("is-invalid");
|
||||
}
|
||||
if (reminderUrgentDistance.trim() == '' || isNaN(reminderUrgentDistance) || parseInt(reminderUrgentDistance) < 0) {
|
||||
hasError = true;
|
||||
$("#reminderUrgentDistance").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderUrgentDistance").removeClass("is-invalid");
|
||||
}
|
||||
if (reminderVeryUrgentDistance.trim() == '' || isNaN(reminderVeryUrgentDistance) || parseInt(reminderVeryUrgentDistance) < 0) {
|
||||
hasError = true;
|
||||
$("#reminderVeryUrgentDistance").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderVeryUrgentDistance").removeClass("is-invalid");
|
||||
}
|
||||
}
|
||||
if (reminderOption == undefined) {
|
||||
hasError = true;
|
||||
$("#reminderMetricDate").addClass("is-invalid");
|
||||
$("#reminderMetricOdometer").addClass("is-invalid");
|
||||
$("#reminderMetricBoth").addClass("is-invalid");
|
||||
} else {
|
||||
$("#reminderMetricDate").removeClass("is-invalid");
|
||||
$("#reminderMetricOdometer").removeClass("is-invalid");
|
||||
$("#reminderMetricBoth").removeClass("is-invalid");
|
||||
}
|
||||
|
||||
return {
|
||||
id: reminderId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: reminderDate,
|
||||
mileage: reminderMileage,
|
||||
description: reminderDescription,
|
||||
notes: reminderNotes,
|
||||
metric: reminderOption,
|
||||
isRecurring: reminderIsRecurring,
|
||||
useCustomThresholds: reminderUseCustomThresholds,
|
||||
customThresholds: {
|
||||
urgentDays: reminderUrgentDays,
|
||||
veryUrgentDays: reminderVeryUrgentDays,
|
||||
urgentDistance: reminderUrgentDistance,
|
||||
veryUrgentDistance: reminderVeryUrgentDistance
|
||||
},
|
||||
reminderMileageInterval: reminderRecurringMileage,
|
||||
reminderMonthInterval: reminderRecurringMonth,
|
||||
customMileageInterval: customMileageInterval,
|
||||
customMonthInterval: customMonthInterval,
|
||||
customMonthIntervalUnit: customMonthIntervalUnit,
|
||||
tags: reminderTags
|
||||
}
|
||||
}
|
||||
function createPlanRecordFromReminder(reminderRecordId) {
|
||||
//get values
|
||||
var formValues = getAndValidateReminderRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var planModelInput = {
|
||||
id: 0,
|
||||
createdFromReminder: true,
|
||||
vehicleId: formValues.vehicleId,
|
||||
reminderRecordId: reminderRecordId,
|
||||
description: formValues.description,
|
||||
notes: formValues.notes
|
||||
};
|
||||
$.post('/Vehicle/GetAddPlanRecordPartialView', { planModel: planModelInput }, function (data) {
|
||||
$("#reminderRecordModal").modal("hide");
|
||||
$("#planRecordModalContent").html(data);
|
||||
$("#planRecordModal").modal("show");
|
||||
});
|
||||
}
|
||||
|
||||
function filterReminderTable(sender) {
|
||||
var rowData = $(`#reminder-tab-pane table tbody tr`);
|
||||
if (sender == undefined) {
|
||||
rowData.removeClass('override-hide');
|
||||
return;
|
||||
}
|
||||
var tagName = sender.textContent;
|
||||
//check for other applied filters
|
||||
if ($(sender).hasClass("bg-primary")) {
|
||||
rowData.removeClass('override-hide');
|
||||
$(sender).removeClass('bg-primary');
|
||||
$(sender).addClass('bg-secondary');
|
||||
updateReminderAggregateLabels();
|
||||
} else {
|
||||
//hide table rows.
|
||||
rowData.addClass('override-hide');
|
||||
$(`[data-tags~='${tagName}']`).removeClass('override-hide');
|
||||
updateReminderAggregateLabels();
|
||||
if ($(".tagfilter.bg-primary").length > 0) {
|
||||
//disabling other filters
|
||||
$(".tagfilter.bg-primary").addClass('bg-secondary');
|
||||
$(".tagfilter.bg-primary").removeClass('bg-primary');
|
||||
}
|
||||
$(sender).addClass('bg-primary');
|
||||
$(sender).removeClass('bg-secondary');
|
||||
}
|
||||
}
|
||||
function updateReminderAggregateLabels() {
|
||||
//update main count
|
||||
var newCount = $("[data-record-type='cost']").parent(":not('.override-hide')").length;
|
||||
var countLabel = $("[data-aggregate-type='count']");
|
||||
countLabel.text(`${countLabel.text().split(':')[0]}: ${newCount}`);
|
||||
//update labels
|
||||
//paste due
|
||||
var pastDueCount = $("tr td span.badge.text-bg-secondary").parents("tr:not('.override-hide')").length;
|
||||
var pastDueLabel = $('[data-aggregate-type="pastdue-count"]');
|
||||
pastDueLabel.text(`${pastDueLabel.text().split(':')[0]}: ${pastDueCount}`);
|
||||
//very urgent
|
||||
var veryUrgentCount = $("tr td span.badge.text-bg-danger").parents("tr:not('.override-hide')").length;
|
||||
var veryUrgentLabel = $('[data-aggregate-type="veryurgent-count"]');
|
||||
veryUrgentLabel.text(`${veryUrgentLabel.text().split(':')[0]}: ${veryUrgentCount}`);
|
||||
//urgent
|
||||
var urgentCount = $("tr td span.badge.text-bg-warning").parents("tr:not('.override-hide')").length;
|
||||
var urgentLabel = $('[data-aggregate-type="urgent-count"]');
|
||||
urgentLabel.text(`${urgentLabel.text().split(':')[0]}: ${urgentCount}`);
|
||||
//not urgent
|
||||
var notUrgentCount = $("tr td span.badge.text-bg-success").parents("tr:not('.override-hide')").length;
|
||||
var notUrgentLabel = $('[data-aggregate-type="noturgent-count"]');
|
||||
notUrgentLabel.text(`${notUrgentLabel.text().split(':')[0]}: ${notUrgentCount}`);
|
||||
}
|
||||
414
wwwroot/js/reports.js
Normal file
414
wwwroot/js/reports.js
Normal file
@@ -0,0 +1,414 @@
|
||||
function getYear() {
|
||||
return $("#yearOption").val() ?? '0';
|
||||
}
|
||||
function getAndValidateSelectedColumns() {
|
||||
var reportVisibleColumns = [];
|
||||
var reportExtraFields = [];
|
||||
var tagFilterMode = $("#tagSelector").val();
|
||||
var tagsToFilter = $("#tagSelectorInput").val();
|
||||
var filterByDateRange = $("#dateRangeSelector").is(":checked");
|
||||
var printIndividualRecords = $("#printIndividualRecordsCheck").is(":checked");
|
||||
var startDate = $("#dateRangeStartDate").val();
|
||||
var endDate = $("#dateRangeEndDate").val();
|
||||
$("#columnSelector :checked").map(function () {
|
||||
if ($(this).hasClass('column-default')) {
|
||||
reportVisibleColumns.push(this.value);
|
||||
} else {
|
||||
reportExtraFields.push(this.value);
|
||||
}
|
||||
});
|
||||
var hasValidationError = false;
|
||||
var validationErrorMessage = "";
|
||||
if (reportVisibleColumns.length + reportExtraFields.length == 0) {
|
||||
hasValidationError = true;
|
||||
validationErrorMessage = "You must select at least one column";
|
||||
}
|
||||
if (filterByDateRange) {
|
||||
//validate date range
|
||||
let startDateTicks = $("#dateRangeStartDate").datepicker('getDate')?.getTime();
|
||||
let endDateTicks = $("#dateRangeEndDate").datepicker('getDate')?.getTime();
|
||||
if (!startDateTicks || !endDateTicks || startDateTicks > endDateTicks) {
|
||||
hasValidationError = true;
|
||||
validationErrorMessage = "Invalid date range";
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValidationError) {
|
||||
return {
|
||||
hasError: true,
|
||||
errorMessage: validationErrorMessage,
|
||||
visibleColumns: [],
|
||||
extraFields: [],
|
||||
tagFilter: tagFilterMode,
|
||||
tags: [],
|
||||
filterByDateRange: filterByDateRange,
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
printIndividualRecords: printIndividualRecords
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
hasError: false,
|
||||
errorMessage: '',
|
||||
visibleColumns: reportVisibleColumns,
|
||||
extraFields: reportExtraFields,
|
||||
tagFilter: tagFilterMode,
|
||||
tags: tagsToFilter,
|
||||
filterByDateRange: filterByDateRange,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
printIndividualRecords: printIndividualRecords
|
||||
}
|
||||
}
|
||||
}
|
||||
function getSavedReportParameters() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var selectedReportColumns = sessionStorage.getItem(`${vehicleId}_selectedReportColumns`);
|
||||
if (selectedReportColumns != null) {
|
||||
selectedReportColumns = JSON.parse(selectedReportColumns);
|
||||
//unselected everything
|
||||
$(".column-extrafield").prop('checked', false);
|
||||
$(".column-default").prop('checked', false);
|
||||
//load selected checkboxes
|
||||
selectedReportColumns.extraFields.map(x => {
|
||||
$(`[value='${x}'].column-extrafield`).prop('checked', true);
|
||||
});
|
||||
selectedReportColumns.visibleColumns.map(x => {
|
||||
$(`[value='${x}'].column-default`).prop('checked', true);
|
||||
});
|
||||
$("#tagSelector").val(selectedReportColumns.tagFilter);
|
||||
selectedReportColumns.tags.map(x => {
|
||||
$("#tagSelectorInput").append(`<option value='${x}'>${x}</option>`)
|
||||
});
|
||||
$("#dateRangeSelector").prop('checked', selectedReportColumns.filterByDateRange);
|
||||
$("#dateRangeStartDate").val(selectedReportColumns.startDate);
|
||||
$("#dateRangeEndDate").val(selectedReportColumns.endDate);
|
||||
$("#printIndividualRecordsCheck").prop('checked', selectedReportColumns.printIndividualRecords);
|
||||
}
|
||||
}
|
||||
function generateVehicleHistoryReport() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
$.get(`/Vehicle/GetReportParameters`, function (data) {
|
||||
if (data) {
|
||||
//prompt user to select columns
|
||||
Swal.fire({
|
||||
html: data,
|
||||
confirmButtonText: 'Generate Report',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
//validate
|
||||
var selectedColumnsData = getAndValidateSelectedColumns();
|
||||
if (selectedColumnsData.hasError) {
|
||||
Swal.showValidationMessage(selectedColumnsData.errorMessage);
|
||||
}
|
||||
return { selectedColumnsData }
|
||||
},
|
||||
didOpen: () => {
|
||||
getSavedReportParameters();
|
||||
initTagSelector($("#tagSelectorInput"));
|
||||
initDatePicker($('#dateRangeStartDate'));
|
||||
initDatePicker($('#dateRangeEndDate'));
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
//save params in sessionStorage
|
||||
sessionStorage.setItem(`${vehicleId}_selectedReportColumns`, JSON.stringify(result.value.selectedColumnsData));
|
||||
//post params
|
||||
$.post(`/Vehicle/GetVehicleHistory?vehicleId=${vehicleId}`, {
|
||||
reportParameter: result.value.selectedColumnsData
|
||||
}, function (data) {
|
||||
if (data) {
|
||||
printContainer(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function updateCheckAll() {
|
||||
var isChecked = $("#selectAllExpenseCheck").is(":checked");
|
||||
$(".reportCheckBox").prop('checked', isChecked);
|
||||
setDebounce(refreshBarChart);
|
||||
}
|
||||
function updateCheck() {
|
||||
setDebounce(refreshBarChart);
|
||||
var allIsChecked = $(".reportCheckBox:checked").length == 6;
|
||||
$("#selectAllExpenseCheck").prop("checked", allIsChecked);
|
||||
}
|
||||
function refreshMPGChart() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
$.post('/Vehicle/GetMonthMPGByVehicle', {vehicleId: vehicleId, year: year}, function (data) {
|
||||
$("#monthFuelMileageReportContent").html(data);
|
||||
refreshReportHeader();
|
||||
})
|
||||
}
|
||||
function refreshReportHeader() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
$.post('/Vehicle/GetSummaryForVehicle', { vehicleId: vehicleId, year: year }, function (data) {
|
||||
$("#reportHeaderContent").html(data);
|
||||
})
|
||||
}
|
||||
function setSelectedMetrics() {
|
||||
var selectedMetricCheckBoxes = [];
|
||||
$(".reportCheckBox:checked").map((index, elem) => {
|
||||
selectedMetricCheckBoxes.push(elem.id);
|
||||
});
|
||||
var yearMetric = $('#yearOption').val();
|
||||
var reminderMetric = $("#reminderOption").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
sessionStorage.setItem(`${vehicleId}_selectedMetricCheckBoxes`, JSON.stringify(selectedMetricCheckBoxes));
|
||||
sessionStorage.setItem(`${vehicleId}_yearMetric`, yearMetric);
|
||||
sessionStorage.setItem(`${vehicleId}_reminderMetric`, reminderMetric);
|
||||
}
|
||||
function getSelectedMetrics() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var selectedMetricCheckBoxes = sessionStorage.getItem(`${vehicleId}_selectedMetricCheckBoxes`);
|
||||
var yearMetric = sessionStorage.getItem(`${vehicleId}_yearMetric`);
|
||||
var reminderMetric = sessionStorage.getItem(`${vehicleId}_reminderMetric`);
|
||||
if (selectedMetricCheckBoxes != null && yearMetric != null && reminderMetric != null) {
|
||||
selectedMetricCheckBoxes = JSON.parse(selectedMetricCheckBoxes);
|
||||
$(".reportCheckBox").prop('checked', false);
|
||||
$("#selectAllExpenseCheck").prop("checked", false);
|
||||
selectedMetricCheckBoxes.map(x => {
|
||||
$(`#${x}`).prop('checked', true);
|
||||
});
|
||||
if (selectedMetricCheckBoxes.length == 6) {
|
||||
$("#selectAllExpenseCheck").prop("checked", true);
|
||||
}
|
||||
//check if option is available
|
||||
if ($("#yearOption").has(`option[value=${yearMetric}]`).length > 0) {
|
||||
$('#yearOption').val(yearMetric);
|
||||
}
|
||||
$("#reminderOption").val(reminderMetric);
|
||||
//retrieve data.
|
||||
yearUpdated();
|
||||
updateReminderPie();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function refreshBarChart() {
|
||||
var selectedMetrics = [];
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
|
||||
if ($("#serviceExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('ServiceRecord');
|
||||
}
|
||||
if ($("#repairExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('RepairRecord');
|
||||
}
|
||||
if ($("#upgradeExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('UpgradeRecord');
|
||||
}
|
||||
if ($("#gasExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('GasRecord');
|
||||
}
|
||||
if ($("#taxExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('TaxRecord');
|
||||
}
|
||||
if ($("#odometerExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('OdometerRecord');
|
||||
}
|
||||
|
||||
$.post('/Vehicle/GetCostByMonthByVehicle',
|
||||
{
|
||||
vehicleId: vehicleId,
|
||||
selectedMetrics: selectedMetrics,
|
||||
year: year
|
||||
}, function (data) {
|
||||
$("#gasCostByMonthReportContent").html(data);
|
||||
refreshMPGChart();
|
||||
});
|
||||
setSelectedMetrics();
|
||||
}
|
||||
function showBarChartTable(elemClicked) {
|
||||
var selectedMetrics = [];
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
|
||||
if ($("#serviceExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('ServiceRecord');
|
||||
}
|
||||
if ($("#repairExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('RepairRecord');
|
||||
}
|
||||
if ($("#upgradeExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('UpgradeRecord');
|
||||
}
|
||||
if ($("#gasExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('GasRecord');
|
||||
}
|
||||
if ($("#taxExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('TaxRecord');
|
||||
}
|
||||
if ($("#odometerExpenseCheck").is(":checked")) {
|
||||
selectedMetrics.push('OdometerRecord');
|
||||
}
|
||||
|
||||
$.post('/Vehicle/GetCostByMonthAndYearByVehicle',
|
||||
{
|
||||
vehicleId: vehicleId,
|
||||
selectedMetrics: selectedMetrics,
|
||||
year: year
|
||||
}, function (data) {
|
||||
$("#vehicleDataTableModalContent").html(data);
|
||||
$("#vehicleDataTableModal").modal('show');
|
||||
//highlight clicked row.
|
||||
if (elemClicked.length > 0) {
|
||||
var rowClickedIndex = elemClicked[0].index + 1;
|
||||
var rowToHighlight = $("#vehicleDataTableModalContent").find(`tbody > tr:nth-child(${rowClickedIndex})`);
|
||||
if (rowToHighlight.length > 0) {
|
||||
rowToHighlight.addClass('table-info');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function toggleBarChartTableData() {
|
||||
//find out which column data type is shown
|
||||
if (!$('[report-data="cost"]').hasClass('d-none')) {
|
||||
//currently cost is shown.
|
||||
$('[report-data="cost"]').addClass('d-none');
|
||||
$('[report-data="distance"]').removeClass('d-none');
|
||||
}
|
||||
else if (!$('[report-data="distance"]').hasClass('d-none')) {
|
||||
//currently distance is shown.
|
||||
$('[report-data="distance"]').addClass('d-none');
|
||||
$('[report-data="costperdistance"]').removeClass('d-none');
|
||||
}
|
||||
else if (!$('[report-data="costperdistance"]').hasClass('d-none')) {
|
||||
//currently cost per distance is shown.
|
||||
$('[report-data="costperdistance"]').addClass('d-none');
|
||||
$('[report-data="cost"]').removeClass('d-none');
|
||||
}
|
||||
}
|
||||
function toggleCostTableHint() {
|
||||
if ($(".cost-table-hint").hasClass("d-none")) {
|
||||
$(".cost-table-hint").removeClass("d-none");
|
||||
} else {
|
||||
$(".cost-table-hint").addClass("d-none");
|
||||
}
|
||||
}
|
||||
function updateReminderPie() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var daysToAdd = $("#reminderOption").val();
|
||||
setSelectedMetrics();
|
||||
$.get(`/Vehicle/GetReminderMakeUpByVehicle?vehicleId=${vehicleId}`, { daysToAdd: daysToAdd }, function (data) {
|
||||
$("#reminderMakeUpReportContent").html(data);
|
||||
});
|
||||
}
|
||||
//called when year selected is changed.
|
||||
function yearUpdated() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
$.get(`/Vehicle/GetCostMakeUpForVehicle?vehicleId=${vehicleId}`, { year: year }, function (data) {
|
||||
$("#costMakeUpReportContent").html(data);
|
||||
refreshBarChart();
|
||||
})
|
||||
}
|
||||
function refreshCollaborators() {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
$.get(`/Vehicle/GetCollaboratorsForVehicle?vehicleId=${vehicleId}`, function (data) {
|
||||
$("#collaboratorContent").html(data);
|
||||
});
|
||||
}
|
||||
function exportAttachments() {
|
||||
Swal.fire({
|
||||
title: 'Export Attachments',
|
||||
html: `
|
||||
<div id='attachmentTabs'>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportServiceRecord" class="form-check-input me-1" value='ServiceRecord'>
|
||||
<label for="exportServiceRecord" class='form-check-label'>Service Record</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportRepairRecord" class="form-check-input me-1" value='RepairRecord'>
|
||||
<label for="exportRepairRecord" class='form-check-label'>Repairs</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportUpgradeRecord" class="form-check-input me-1" value='UpgradeRecord'>
|
||||
<label for="exportUpgradeRecord" class='form-check-label'>Upgrades</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportGasRecord" class="form-check-input me-1" value='GasRecord'>
|
||||
<label for="exportGasRecord" class='form-check-label'>Fuel</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportTaxRecord" class="form-check-input me-1" value='TaxRecord'>
|
||||
<label for="exportTaxRecord" class='form-check-label'>Taxes</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportOdometerRecord" class="form-check-input me-1" value='OdometerRecord'>
|
||||
<label for="exportOdometerRecord" class='form-check-label'>Odometer</label>
|
||||
</div>
|
||||
<div class='form-check form-check-inline'>
|
||||
<input type="checkbox" id="exportNoteRecord" class="form-check-input me-1" value='NoteRecord'>
|
||||
<label for="exportNoteRecord" class='form-check-label'>Notes</label>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
confirmButtonText: 'Export',
|
||||
showCancelButton: true,
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
var selectedExportTabs = $("#attachmentTabs :checked").map(function () {
|
||||
return this.value;
|
||||
});
|
||||
if (selectedExportTabs.toArray().length == 0) {
|
||||
Swal.showValidationMessage(`Please make at least one selection`)
|
||||
}
|
||||
return { selectedTabs: selectedExportTabs.toArray() }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
$.post('/Vehicle/GetVehicleAttachments', { vehicleId: vehicleId, exportTabs: result.value.selectedTabs }, function (data) {
|
||||
if (data.success) {
|
||||
window.location.href = data.message;
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
function showDataTable(elemClicked) {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
$.get(`/Vehicle/GetCostTableForVehicle?vehicleId=${vehicleId}`, { year: year }, function (data) {
|
||||
$("#vehicleDataTableModalContent").html(data);
|
||||
$("#vehicleDataTableModal").modal('show');
|
||||
if (elemClicked.length > 0) {
|
||||
var rowClickedIndex = elemClicked[0].index + 1;
|
||||
var rowToHighlight = $("#vehicleDataTableModalContent").find(`tbody > tr:nth-child(${rowClickedIndex})`);
|
||||
if (rowToHighlight.length > 0) {
|
||||
rowToHighlight.addClass('table-info');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideDataTable() {
|
||||
$("#vehicleDataTableModal").modal('hide');
|
||||
}
|
||||
function loadCustomWidgets() {
|
||||
$.get('/Vehicle/GetAdditionalWidgets', function (data) {
|
||||
$("#vehicleCustomWidgetsModalContent").html(data);
|
||||
$("#vehicleCustomWidgetsModal").modal('show');
|
||||
})
|
||||
}
|
||||
function hideCustomWidgetsModal() {
|
||||
$("#vehicleCustomWidgetsModal").modal('hide');
|
||||
}
|
||||
|
||||
function showReportAdvancedParameters() {
|
||||
if ($(".report-advanced-parameters").hasClass("d-none")) {
|
||||
$(".report-advanced-parameters").removeClass("d-none");
|
||||
} else {
|
||||
$(".report-advanced-parameters").addClass("d-none");
|
||||
}
|
||||
}
|
||||
160
wwwroot/js/serversettings.js
Normal file
160
wwwroot/js/serversettings.js
Normal file
@@ -0,0 +1,160 @@
|
||||
function loadSetupPage(pageNumber) {
|
||||
let pageElem = $(`.setup-wizard-content[data-page="${pageNumber}"]`);
|
||||
if (pageElem.length > 0) {
|
||||
$('.setup-wizard-content').hide();
|
||||
pageElem.show();
|
||||
}
|
||||
determineSetupButtons();
|
||||
}
|
||||
function determineSetupButtons() {
|
||||
let currentVisiblePage = $(".setup-wizard-content:visible").attr('data-page');
|
||||
switch (currentVisiblePage) {
|
||||
case '0':
|
||||
case '5':
|
||||
$(".setup-wizard-nav").hide();
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
$(".setup-wizard-nav").show();
|
||||
$(".btn-prev").show();
|
||||
$(".btn-next").show();
|
||||
$(".btn-save").hide();
|
||||
break;
|
||||
case '4':
|
||||
$(".setup-wizard-nav").show();
|
||||
$(".btn-prev").show();
|
||||
$(".btn-next").hide();
|
||||
$(".btn-save").show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
function nextSetupPage() {
|
||||
let currentVisiblePage = $(".setup-wizard-content:visible").attr('data-page');
|
||||
let nextPage = parseInt(currentVisiblePage) + 1;
|
||||
loadSetupPage(nextPage);
|
||||
}
|
||||
function previousSetupPage() {
|
||||
let currentVisiblePage = $(".setup-wizard-content:visible").attr('data-page');
|
||||
let prevPage = parseInt(currentVisiblePage) - 1;
|
||||
loadSetupPage(prevPage);
|
||||
}
|
||||
function saveSetup() {
|
||||
let setupData = {
|
||||
PostgresConnection: $("#inputPostgres").val(),
|
||||
AllowedFileExtensions: $("#inputFileExt").val(),
|
||||
CustomLogoURL: $("#inputLogoURL").val(),
|
||||
CustomSmallLogoURL: $("#inputSmallLogoURL").val(),
|
||||
MessageOfTheDay: $("#inputMOTD").val(),
|
||||
WebHookURL: $("#inputWebHook").val(),
|
||||
ServerURL: $("#inputDomain").val(),
|
||||
CustomWidgetsEnabled: $("#inputCustomWidget").val(),
|
||||
InvariantAPIEnabled: $("#inputInvariantAPI").val(),
|
||||
SMTPConfig: {
|
||||
EmailServer: $("#inputSMTPServer").val(),
|
||||
EmailFrom: $("#inputSMTPFrom").val(),
|
||||
Port: $("#inputSMTPPort").val(),
|
||||
Username: $("#inputSMTPUsername").val(),
|
||||
Password: $("#inputSMTPPassword").val()
|
||||
},
|
||||
OIDCConfig: {
|
||||
Name: $("#inputOIDCProvider").val(),
|
||||
ClientId: $("#inputOIDCClient").val(),
|
||||
ClientSecret: $("#inputOIDCSecret").val(),
|
||||
AuthURL: $("#inputOIDCAuth").val(),
|
||||
TokenURL: $("#inputOIDCToken").val(),
|
||||
RedirectURL: $("#inputOIDCRedirect").val(),
|
||||
Scope: $("#inputOIDCScope").val(),
|
||||
ValidateState: $("#inputOIDCState").val(),
|
||||
DisableRegularLogin: $("#inputOIDCDisable").val(),
|
||||
UsePKCE: $("#inputOIDCPKCE").val(),
|
||||
LogOutURL: $("#inputOIDCLogout").val(),
|
||||
UserInfoURL: $("#inputOIDCUserInfo").val()
|
||||
},
|
||||
ReminderUrgencyConfig: {
|
||||
UrgentDays: $("#inputUrgentDays").val(),
|
||||
VeryUrgentDays: $("#inputVeryUrgentDays").val(),
|
||||
UrgentDistance: $("#inputUrgentDistance").val(),
|
||||
VeryUrgentDistance: $("#inputVeryUrgentDistance").val()
|
||||
},
|
||||
DefaultReminderEmail: $("#inputDefaultReminderEmail").val(),
|
||||
EnableRootUserOIDC: $("#inputOIDCRootUser").val()
|
||||
};
|
||||
let registrationMode = $("#inputRegistrationMode");
|
||||
if (registrationMode.length > 0) {
|
||||
switch (registrationMode.val()) {
|
||||
case '0':
|
||||
setupData["DisableRegistration"] = 'false';
|
||||
setupData["OpenRegistration"] = 'false'
|
||||
break;
|
||||
case '1':
|
||||
setupData["DisableRegistration"] = 'true';
|
||||
setupData["OpenRegistration"] = 'false'
|
||||
break;
|
||||
case '2':
|
||||
setupData["DisableRegistration"] = 'false';
|
||||
setupData["OpenRegistration"] = 'true'
|
||||
break;
|
||||
}
|
||||
}
|
||||
//nullify skipped settings
|
||||
if ($("#skipSMTP").is(":checked")) {
|
||||
setupData["SMTPConfig"] = null;
|
||||
}
|
||||
if ($("#skipOIDC").is(":checked")) {
|
||||
setupData["OIDCConfig"] = null;
|
||||
}
|
||||
if ($("#skipPostgres").is(":checked")) {
|
||||
setupData["PostgresConnection"] = null;
|
||||
}
|
||||
let rootUserOIDC = $("#inputOIDCRootUser");
|
||||
if (rootUserOIDC.length > 0) {
|
||||
setupData["EnableRootUserOIDC"] = $("#inputOIDCRootUser").val();
|
||||
}
|
||||
$.post('/Home/WriteServerConfiguration', { serverConfig: setupData }, function (data) {
|
||||
if (data) {
|
||||
nextSetupPage();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function sendTestEmail() {
|
||||
let mailConfig = {
|
||||
EmailServer: $("#inputSMTPServer").val(),
|
||||
EmailFrom: $("#inputSMTPFrom").val(),
|
||||
Port: $("#inputSMTPPort").val(),
|
||||
Username: $("#inputSMTPUsername").val(),
|
||||
Password: $("#inputSMTPPassword").val()
|
||||
}
|
||||
Swal.fire({
|
||||
title: 'Send Test Email',
|
||||
html: `
|
||||
<input type="text" id="testEmailRecipient" class="swal2-input" placeholder="Email Address" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Send',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const emailRecipient = $("#testEmailRecipient").val();
|
||||
if (!emailRecipient || emailRecipient.trim() == '') {
|
||||
Swal.showValidationMessage(`Please enter a valid email address`);
|
||||
}
|
||||
return { emailRecipient }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Home/SendTestEmail', { emailAddress: result.value.emailRecipient, mailConfig: mailConfig }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function nextOnSkip(sender) {
|
||||
if ($(sender).is(":checked")) {
|
||||
nextSetupPage();
|
||||
}
|
||||
}
|
||||
156
wwwroot/js/servicerecord.js
Normal file
156
wwwroot/js/servicerecord.js
Normal file
@@ -0,0 +1,156 @@
|
||||
function showAddServiceRecordModal() {
|
||||
$.get('/Vehicle/GetAddServiceRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#serviceRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#serviceRecordDate'));
|
||||
initTagSelector($("#serviceRecordTag"));
|
||||
$('#serviceRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditServiceRecordModal(serviceRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#serviceRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getServiceRecordModelData().id;
|
||||
if (existingId == serviceRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#serviceRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetServiceRecordForEditById?serviceRecordId=${serviceRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#serviceRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#serviceRecordDate'));
|
||||
initTagSelector($("#serviceRecordTag"));
|
||||
$('#serviceRecordModal').modal('show');
|
||||
bindModalInputChanges('serviceRecordModal');
|
||||
$('#serviceRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("serviceRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddServiceRecordModal() {
|
||||
$('#serviceRecordModal').modal('hide');
|
||||
}
|
||||
function deleteServiceRecord(serviceRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Service Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteServiceRecordById?serviceRecordId=${serviceRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddServiceRecordModal();
|
||||
successToast("Service Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleServiceRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveServiceRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateServiceRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveServiceRecordToVehicleId', { serviceRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Service Record Updated" : "Service Record Added.");
|
||||
hideAddServiceRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleServiceRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateServiceRecordValues() {
|
||||
var serviceDate = $("#serviceRecordDate").val();
|
||||
var serviceMileage = parseInt(globalParseFloat($("#serviceRecordMileage").val())).toString();
|
||||
var serviceDescription = $("#serviceRecordDescription").val();
|
||||
var serviceCost = $("#serviceRecordCost").val();
|
||||
var serviceNotes = $("#serviceRecordNotes").val();
|
||||
var serviceTags = $("#serviceRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var serviceRecordId = getServiceRecordModelData().id;
|
||||
var addReminderRecord = $("#addReminderCheck").is(":checked");
|
||||
//Odometer Adjustments
|
||||
if (isNaN(serviceMileage) && GetVehicleId().odometerOptional) {
|
||||
serviceMileage = '0';
|
||||
}
|
||||
serviceMileage = GetAdjustedOdometer(serviceRecordId, serviceMileage);
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (serviceDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#serviceRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#serviceRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (serviceMileage.trim() == '' || isNaN(serviceMileage) || parseInt(serviceMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#serviceRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#serviceRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (serviceDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#serviceRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#serviceRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (serviceCost.trim() == '' || !isValidMoney(serviceCost)) {
|
||||
hasError = true;
|
||||
$("#serviceRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#serviceRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: serviceRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: serviceDate,
|
||||
mileage: serviceMileage,
|
||||
description: serviceDescription,
|
||||
cost: serviceCost,
|
||||
notes: serviceNotes,
|
||||
files: uploadedFiles,
|
||||
supplies: selectedSupplies,
|
||||
tags: serviceTags,
|
||||
addReminderRecord: addReminderRecord,
|
||||
extraFields: extraFields.extraFields,
|
||||
requisitionHistory: supplyUsageHistory,
|
||||
deletedRequisitionHistory: deletedSupplyUsageHistory,
|
||||
reminderRecordId: recurringReminderRecordId,
|
||||
copySuppliesAttachment: copySuppliesAttachments
|
||||
}
|
||||
}
|
||||
408
wwwroot/js/settings.js
Normal file
408
wwwroot/js/settings.js
Normal file
@@ -0,0 +1,408 @@
|
||||
function showExtraFieldModal() {
|
||||
$.get(`/Home/GetExtraFieldsModal?importMode=0`, function (data) {
|
||||
$("#extraFieldModalContent").html(data);
|
||||
$("#extraFieldModal").modal('show');
|
||||
});
|
||||
}
|
||||
function hideExtraFieldModal() {
|
||||
$("#extraFieldModal").modal('hide');
|
||||
}
|
||||
function getCheckedTabs() {
|
||||
var visibleTabs = $("#visibleTabs :checked").map(function () {
|
||||
return this.value;
|
||||
});
|
||||
return visibleTabs.toArray();
|
||||
}
|
||||
function deleteLanguage() {
|
||||
var languageFileLocation = `/translations/${$("#defaultLanguage").val()}.json`;
|
||||
$.post('/Files/DeleteFiles', { fileLocation: languageFileLocation }, function (data) {
|
||||
//reset user language back to en_US
|
||||
$("#defaultLanguage").val('en_US');
|
||||
updateSettings();
|
||||
});
|
||||
}
|
||||
function updateColorModeSettings(e) {
|
||||
var colorMode = $(e).prop("id");
|
||||
switch (colorMode) {
|
||||
case "enableDarkMode":
|
||||
//uncheck system prefernce
|
||||
$("#useSystemColorMode").prop('checked', false);
|
||||
updateSettings();
|
||||
break;
|
||||
case "useSystemColorMode":
|
||||
$("#enableDarkMode").prop('checked', false);
|
||||
updateSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
function updateSettings() {
|
||||
var visibleTabs = getCheckedTabs();
|
||||
var defaultTab = $("#defaultTab").val();
|
||||
if (!visibleTabs.includes(defaultTab)) {
|
||||
defaultTab = "Dashboard"; //default to dashboard.
|
||||
}
|
||||
var tabOrder = getTabOrder();
|
||||
|
||||
var userConfigObject = {
|
||||
useDarkMode: $("#enableDarkMode").is(':checked'),
|
||||
useSystemColorMode: $("#useSystemColorMode").is(':checked'),
|
||||
enableCsvImports: $("#enableCsvImports").is(':checked'),
|
||||
useMPG: $("#useMPG").is(':checked'),
|
||||
useDescending: $("#useDescending").is(':checked'),
|
||||
hideZero: $("#hideZero").is(":checked"),
|
||||
automaticDecimalFormat: $("#automaticDecimalFormat").is(":checked"),
|
||||
useUKMpg: $("#useUKMPG").is(":checked"),
|
||||
useThreeDecimalGasCost: $("#useThreeDecimal").is(":checked"),
|
||||
useThreeDecimalGasConsumption: $("#useThreeDecimalGasConsumption").is(":checked"),
|
||||
useMarkDownOnSavedNotes: $("#useMarkDownOnSavedNotes").is(":checked"),
|
||||
enableAutoReminderRefresh: $("#enableAutoReminderRefresh").is(":checked"),
|
||||
enableAutoOdometerInsert: $("#enableAutoOdometerInsert").is(":checked"),
|
||||
enableShopSupplies: $("#enableShopSupplies").is(":checked"),
|
||||
showCalendar: $("#showCalendar").is(":checked"),
|
||||
showVehicleThumbnail: $("#showVehicleThumbnail").is(":checked"),
|
||||
enableExtraFieldColumns: $("#enableExtraFieldColumns").is(":checked"),
|
||||
hideSoldVehicles: $("#hideSoldVehicles").is(":checked"),
|
||||
preferredGasUnit: $("#preferredGasUnit").val(),
|
||||
preferredGasMileageUnit: $("#preferredFuelMileageUnit").val(),
|
||||
userLanguage: $("#defaultLanguage").val(),
|
||||
useUnitForFuelCost: $("#useUnitForFuelCost").is(":checked"),
|
||||
visibleTabs: visibleTabs,
|
||||
defaultTab: defaultTab,
|
||||
tabOrder: tabOrder
|
||||
}
|
||||
sloader.show();
|
||||
$.post('/Home/WriteToSettings', { userConfig: userConfigObject }, function (data) {
|
||||
sloader.hide();
|
||||
if (data) {
|
||||
setTimeout(function () { window.location.href = '/Home/Index?tab=settings' }, 500);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function makeBackup() {
|
||||
$.get('/Files/MakeBackup', function (data) {
|
||||
window.location.href = data;
|
||||
});
|
||||
}
|
||||
function openUploadLanguage() {
|
||||
$("#inputLanguage").trigger('click');
|
||||
}
|
||||
function openRestoreBackup() {
|
||||
$("#inputBackup").trigger('click');
|
||||
}
|
||||
function uploadLanguage(event) {
|
||||
let formData = new FormData();
|
||||
formData.append("file", event.files[0]);
|
||||
sloader.show();
|
||||
$.ajax({
|
||||
url: "/Files/HandleTranslationFileUpload",
|
||||
data: formData,
|
||||
cache: false,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
success: function (response) {
|
||||
sloader.hide();
|
||||
if (response.success) {
|
||||
setTimeout(function () { window.location.href = '/Home/Index?tab=settings' }, 500);
|
||||
} else {
|
||||
errorToast(response.message);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
sloader.hide();
|
||||
errorToast("An error has occurred, please check the file size and try again later.");
|
||||
}
|
||||
});
|
||||
}
|
||||
function restoreBackup(event) {
|
||||
let formData = new FormData();
|
||||
formData.append("file", event.files[0]);
|
||||
console.log('MotoVaultPro - DB Restoration Started');
|
||||
sloader.show();
|
||||
$.ajax({
|
||||
url: "/Files/HandleFileUpload",
|
||||
data: formData,
|
||||
cache: false,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
success: function (response) {
|
||||
if (response.trim() != '') {
|
||||
$.post('/Files/RestoreBackup', { fileName: response }, function (data) {
|
||||
sloader.hide();
|
||||
if (data) {
|
||||
console.log('MotoVaultPro - DB Restoration Completed');
|
||||
successToast("Backup Restored");
|
||||
setTimeout(function () { window.location.href = '/Home/Index' }, 500);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
console.log('MotoVaultPro - DB Restoration Failed - Failed to process backup file.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('MotoVaultPro - DB Restoration Failed - Failed to upload backup file.');
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
sloader.hide();
|
||||
console.log('MotoVaultPro - DB Restoration Failed - Request failed to reach backend, please check file size.');
|
||||
errorToast("An error has occurred, please check the file size and try again later.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadSponsors() {
|
||||
$.get('/Home/Sponsors', function (data) {
|
||||
$("#sponsorsContainer").html(data);
|
||||
})
|
||||
}
|
||||
|
||||
function showTranslationEditor() {
|
||||
$.get(`/Home/GetTranslatorEditor?userLanguage=${$("#defaultLanguage").val()}`, function (data) {
|
||||
$('#translationEditorModalContent').html(data);
|
||||
$('#translationEditorModal').modal('show');
|
||||
})
|
||||
}
|
||||
function hideTranslationEditor() {
|
||||
$('#translationEditorModal').modal('hide');
|
||||
}
|
||||
function saveTranslation() {
|
||||
var currentLanguage = $("#defaultLanguage").val();
|
||||
var translationData = [];
|
||||
$(".translation-keyvalue").map((index, elem) => {
|
||||
var translationKey = $(elem).find('.translation-key');
|
||||
var translationValue = $(elem).find('.translation-value textarea');
|
||||
translationData.push({ key: translationKey.text().replaceAll(' ', '_').trim(), value: translationValue.val().trim() });
|
||||
});
|
||||
if (translationData.length == 0) {
|
||||
errorToast(genericErrorMessage());
|
||||
return;
|
||||
}
|
||||
var userCanDelete = $(".translation-delete").length > 0;
|
||||
Swal.fire({
|
||||
title: 'Save Translation',
|
||||
html: `
|
||||
<input type="text" id="translationFileName" class="swal2-input" placeholder="Translation Name" value="${currentLanguage}" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Save',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const translationFileName = $("#translationFileName").val();
|
||||
if (!translationFileName || translationFileName.trim() == '') {
|
||||
Swal.showValidationMessage(`Please enter a valid file name`);
|
||||
} else if (translationFileName.trim() == 'en_US' && !userCanDelete) {
|
||||
Swal.showValidationMessage(`en_US is reserved, please enter a different name`);
|
||||
}
|
||||
return { translationFileName }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Home/SaveTranslation', { userLanguage: result.value.translationFileName, translationData: translationData }, function (data) {
|
||||
if (data.success) {
|
||||
successToast("Translation Updated");
|
||||
updateSettings();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function exportTranslation(){
|
||||
var translationData = [];
|
||||
$(".translation-keyvalue").map((index, elem) => {
|
||||
var translationKey = $(elem).find('.translation-key');
|
||||
var translationValue = $(elem).find('.translation-value textarea');
|
||||
translationData.push({ key: translationKey.text().replaceAll(' ', '_').trim(), value: translationValue.val().trim() });
|
||||
});
|
||||
if (translationData.length == 0) {
|
||||
errorToast(genericErrorMessage());
|
||||
return;
|
||||
}
|
||||
$.post('/Home/ExportTranslation', { translationData: translationData }, function (data) {
|
||||
if (!data) {
|
||||
errorToast(genericErrorMessage());
|
||||
} else {
|
||||
window.location.href = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
function showTranslationDownloader() {
|
||||
$.get('/Home/GetAvailableTranslations', function(data){
|
||||
$('#translationDownloadModalContent').html(data);
|
||||
$('#translationDownloadModal').modal('show');
|
||||
})
|
||||
}
|
||||
function hideTranslationDownloader() {
|
||||
$('#translationDownloadModal').modal('hide');
|
||||
}
|
||||
function downloadTranslation(continent, name) {
|
||||
sloader.show();
|
||||
$.get(`/Home/DownloadTranslation?continent=${continent}&name=${name}`, function (data) {
|
||||
sloader.hide();
|
||||
if (data) {
|
||||
successToast("Translation Downloaded");
|
||||
updateSettings();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function downloadAllTranslations() {
|
||||
sloader.show();
|
||||
$.get('/Home/DownloadAllTranslations', function (data) {
|
||||
sloader.hide();
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
updateSettings();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
function deleteTranslationKey(e) {
|
||||
$(e).parent().parent().remove();
|
||||
}
|
||||
//tabs reorder
|
||||
function showTabReorderModal() {
|
||||
//reorder the list items based on the CSS attribute
|
||||
var sortedOrderedTabs = $(".motovaultpro-tab-groups > li").toArray().sort((a, b) => {
|
||||
var currentVal = $(a).css("order");
|
||||
var nextVal = $(b).css("order");
|
||||
return currentVal - nextVal;
|
||||
});
|
||||
$(".motovaultpro-tab-groups").html(sortedOrderedTabs);
|
||||
$("#tabReorderModal").modal('show');
|
||||
bindTabReorderEvents();
|
||||
}
|
||||
function hideTabReorderModal() {
|
||||
$("#tabReorderModal").modal('hide');
|
||||
}
|
||||
var tabDraggedToReorder = undefined;
|
||||
function handleTabDragStart(e) {
|
||||
tabDraggedToReorder = $(e.target).closest('.list-group-item');
|
||||
//clear out order attribute.
|
||||
$(".motovaultpro-tab-groups > li").map((index, elem) => {
|
||||
$(elem).css('order', 0);
|
||||
})
|
||||
}
|
||||
function handleTabDragOver(e) {
|
||||
if (tabDraggedToReorder == undefined || tabDraggedToReorder == "") {
|
||||
return;
|
||||
}
|
||||
var potentialDropTarget = $(e.target).closest('.list-group-item').attr("data-tab");
|
||||
var draggedTarget = tabDraggedToReorder.closest('.list-group-item').attr("data-tab");
|
||||
if (draggedTarget != potentialDropTarget) {
|
||||
var targetObj = $(e.target).closest('.list-group-item');
|
||||
var draggedOrder = tabDraggedToReorder.index();
|
||||
var targetOrder = targetObj.index();
|
||||
if (draggedOrder < targetOrder) {
|
||||
tabDraggedToReorder.insertAfter(targetObj);
|
||||
} else {
|
||||
tabDraggedToReorder.insertBefore(targetObj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
function bindTabReorderEvents() {
|
||||
$(".motovaultpro-tab-groups > li").on('dragstart', event => {
|
||||
handleTabDragStart(event);
|
||||
});
|
||||
$(".motovaultpro-tab-groups > li").on('dragover', event => {
|
||||
handleTabDragOver(event);
|
||||
});
|
||||
$(".motovaultpro-tab-groups > li").on('dragend', event => {
|
||||
//reset order attribute
|
||||
$(".motovaultpro-tab-groups > li").map((index, elem) => {
|
||||
$(elem).css('order', $(elem).index());
|
||||
})
|
||||
});
|
||||
}
|
||||
function getTabOrder() {
|
||||
var tabOrderArray = [];
|
||||
//check if any tabs have -1 order
|
||||
var resetTabs = $(".motovaultpro-tab-groups > li").filter((index, elem) => $(elem).css('order') == -1).length > 0;
|
||||
if (resetTabs) {
|
||||
return tabOrderArray; //return empty array.
|
||||
}
|
||||
var sortedOrderedTabs = $(".motovaultpro-tab-groups > li").toArray().sort((a, b) => {
|
||||
var currentVal = $(a).css("order");
|
||||
var nextVal = $(b).css("order");
|
||||
return currentVal - nextVal;
|
||||
});
|
||||
sortedOrderedTabs.map(elem => {
|
||||
var elemName = $(elem).attr("data-tab");
|
||||
tabOrderArray.push(elemName);
|
||||
});
|
||||
return tabOrderArray;
|
||||
}
|
||||
function resetTabOrder() {
|
||||
//set all orders to -1
|
||||
$(".motovaultpro-tab-groups > li").map((index, elem) => {
|
||||
$(elem).css('order', -1);
|
||||
})
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
function hideCustomWidgets() {
|
||||
$("#customWidgetModal").modal('hide');
|
||||
}
|
||||
function saveCustomWidgets() {
|
||||
$.post('/Home/SaveCustomWidgets', { widgetsData: $("#widgetEditor").val() }, function (data) {
|
||||
if (data) {
|
||||
successToast("Custom Widgets Saved!");
|
||||
updateSettings();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function deleteCustomWidgets() {
|
||||
$.post('/Home/DeleteCustomWidgets', function (data) {
|
||||
if (data) {
|
||||
successToast("Custom Widgets Deleted!");
|
||||
updateSettings();
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function showCustomWidgets() {
|
||||
Swal.fire({
|
||||
title: 'Warning',
|
||||
icon: "warning",
|
||||
html: `
|
||||
<span>
|
||||
You are about to use the Custom Widgets Editor, this is a developer-focused feature that can lead to security vulnerabilities if you don't understand what you're doing.
|
||||
<br />Zero support will be provided from the developer(s) of MotoVaultPro regarding Custom Widgets, Read the Documentation.
|
||||
<br />By proceeding, you acknowledge that you are solely responsible for all consequences from utilizing the Custom Widgets Editor.
|
||||
<br />To proceed, enter 'acknowledge' into the text field below.
|
||||
</span>
|
||||
<input type="text" id="inputAcknowledge" class="swal2-input" placeholder="acknowledge" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Proceed',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const userAcknowledge = $("#inputAcknowledge").val();
|
||||
if (!userAcknowledge || userAcknowledge != 'acknowledge') {
|
||||
Swal.showValidationMessage(`Please acknowledge before proceeding.`)
|
||||
}
|
||||
return { userAcknowledge }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$.get('/Home/GetCustomWidgetEditor', function (data) {
|
||||
if (data.trim() != '') {
|
||||
$("#customWidgetModalContent").html(data);
|
||||
$("#customWidgetModal").modal('show');
|
||||
} else {
|
||||
errorToast("Custom Widgets Not Enabled");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
1705
wwwroot/js/shared.js
Normal file
1705
wwwroot/js/shared.js
Normal file
File diff suppressed because it is too large
Load Diff
149
wwwroot/js/supplyrecord.js
Normal file
149
wwwroot/js/supplyrecord.js
Normal file
@@ -0,0 +1,149 @@
|
||||
function showAddSupplyRecordModal() {
|
||||
$.get('/Vehicle/GetAddSupplyRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#supplyRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#supplyRecordDate'));
|
||||
initTagSelector($("#supplyRecordTag"));
|
||||
$('#supplyRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditSupplyRecordModal(supplyRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#supplyRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getSupplyRecordModelData().id;
|
||||
if (existingId == supplyRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#supplyRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetSupplyRecordForEditById?supplyRecordId=${supplyRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#supplyRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#supplyRecordDate'));
|
||||
initTagSelector($("#supplyRecordTag"));
|
||||
$('#supplyRecordModal').modal('show');
|
||||
bindModalInputChanges('supplyRecordModal');
|
||||
$('#supplyRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("supplyRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddSupplyRecordModal() {
|
||||
$('#supplyRecordModal').modal('hide');
|
||||
}
|
||||
function deleteSupplyRecord(supplyRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Supply Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteSupplyRecordById?supplyRecordId=${supplyRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddSupplyRecordModal();
|
||||
successToast("Supply Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleSupplyRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveSupplyRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateSupplyRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveSupplyRecordToVehicleId', { supplyRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Supply Record Updated" : "Supply Record Added.");
|
||||
hideAddSupplyRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleSupplyRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateSupplyRecordValues() {
|
||||
var supplyDate = $("#supplyRecordDate").val();
|
||||
var supplyPartNumber = $("#supplyRecordPartNumber").val();
|
||||
var supplyDescription = $("#supplyRecordDescription").val();
|
||||
var supplySupplier = $("#supplyRecordSupplier").val();
|
||||
var supplyQuantity = $("#supplyRecordQuantity").val();
|
||||
var supplyCost = $("#supplyRecordCost").val();
|
||||
var supplyNotes = $("#supplyRecordNotes").val();
|
||||
var supplyTags = $("#supplyRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var supplyRecordId = getSupplyRecordModelData().id;
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (supplyDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#supplyRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#supplyRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (supplyDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#supplyRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#supplyRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (supplyQuantity.trim() == '' || !isValidMoney(supplyQuantity) || globalParseFloat(supplyQuantity) < 0) {
|
||||
hasError = true;
|
||||
$("#supplyRecordQuantity").addClass("is-invalid");
|
||||
} else {
|
||||
$("#supplyRecordQuantity").removeClass("is-invalid");
|
||||
}
|
||||
if (supplyCost.trim() == '' || !isValidMoney(supplyCost)) {
|
||||
hasError = true;
|
||||
$("#supplyRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#supplyRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: supplyRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: supplyDate,
|
||||
partNumber: supplyPartNumber,
|
||||
partSupplier: supplySupplier,
|
||||
description: supplyDescription,
|
||||
cost: supplyCost,
|
||||
notes: supplyNotes,
|
||||
quantity: supplyQuantity,
|
||||
files: uploadedFiles,
|
||||
tags: supplyTags,
|
||||
extraFields: extraFields.extraFields,
|
||||
requisitionHistory: supplyUsageHistory
|
||||
}
|
||||
}
|
||||
198
wwwroot/js/taxrecord.js
Normal file
198
wwwroot/js/taxrecord.js
Normal file
@@ -0,0 +1,198 @@
|
||||
function showAddTaxRecordModal() {
|
||||
$.get('/Vehicle/GetAddTaxRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#taxRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#taxRecordDate'));
|
||||
initTagSelector($("#taxRecordTag"));
|
||||
$('#taxRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditTaxRecordModal(taxRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#taxRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getTaxRecordModelData().id;
|
||||
if (existingId == taxRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#taxRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetTaxRecordForEditById?taxRecordId=${taxRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#taxRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#taxRecordDate'));
|
||||
initTagSelector($("#taxRecordTag"));
|
||||
$('#taxRecordModal').modal('show');
|
||||
bindModalInputChanges('taxRecordModal');
|
||||
$('#taxRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("taxRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function enableTaxRecurring() {
|
||||
var taxIsRecurring = $("#taxIsRecurring").is(":checked");
|
||||
if (taxIsRecurring) {
|
||||
$("#taxRecurringMonth").attr('disabled', false);
|
||||
} else {
|
||||
$("#taxRecurringMonth").attr('disabled', true);
|
||||
}
|
||||
}
|
||||
function hideAddTaxRecordModal() {
|
||||
$('#taxRecordModal').modal('hide');
|
||||
}
|
||||
function deleteTaxRecord(taxRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Tax Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteTaxRecordById?taxRecordId=${taxRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddTaxRecordModal();
|
||||
successToast("Tax Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleTaxRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveTaxRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateTaxRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveTaxRecordToVehicleId', { taxRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Tax Record Updated" : "Tax Record Added.");
|
||||
hideAddTaxRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleTaxRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function checkCustomMonthIntervalForTax() {
|
||||
var selectedValue = $("#taxRecurringMonth").val();
|
||||
if (selectedValue == "Other") {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: 'Specify Custom Time Interval',
|
||||
html: `
|
||||
<input type="text" inputmode="numeric" id="inputCustomMonth" class="swal2-input" placeholder="Months" onkeydown="handleSwalEnter(event)">
|
||||
<select class="swal2-select" id="inputCustomMonthUnit">
|
||||
<option value="Months">Months</option>
|
||||
<option value="Days">Days</option>
|
||||
</select>
|
||||
`,
|
||||
confirmButtonText: 'Set',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const customMonth = $("#inputCustomMonth").val();
|
||||
if (!customMonth || isNaN(parseInt(customMonth)) || parseInt(customMonth) <= 0) {
|
||||
Swal.showValidationMessage(`Please enter a valid number`);
|
||||
}
|
||||
const customMonthUnit = $("#inputCustomMonthUnit").val();
|
||||
return { customMonth, customMonthUnit }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
customMonthInterval = result.value.customMonth;
|
||||
customMonthIntervalUnit = result.value.customMonthUnit;
|
||||
$("#taxRecurringMonth > option[value='Other']").text(`Other: ${result.value.customMonth} ${result.value.customMonthUnit}`);
|
||||
} else {
|
||||
$("#taxRecurringMonth").val(getTaxRecordModelData().monthInterval);
|
||||
}
|
||||
$("#workAroundInput").hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
function getAndValidateTaxRecordValues() {
|
||||
var taxDate = $("#taxRecordDate").val();
|
||||
var taxDescription = $("#taxRecordDescription").val();
|
||||
var taxCost = $("#taxRecordCost").val();
|
||||
var taxNotes = $("#taxRecordNotes").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var taxRecordId = getTaxRecordModelData().id;
|
||||
var taxIsRecurring = $("#taxIsRecurring").is(":checked");
|
||||
var taxRecurringMonth = $("#taxRecurringMonth").val();
|
||||
var taxTags = $("#taxRecordTag").val();
|
||||
var addReminderRecord = $("#addReminderCheck").is(":checked");
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (taxDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#taxRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#taxRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (taxDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#taxRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#taxRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (taxCost.trim() == '' || !isValidMoney(taxCost)) {
|
||||
hasError = true;
|
||||
$("#taxRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#taxRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: taxRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: taxDate,
|
||||
description: taxDescription,
|
||||
cost: taxCost,
|
||||
notes: taxNotes,
|
||||
isRecurring: taxIsRecurring,
|
||||
recurringInterval: taxRecurringMonth,
|
||||
customMonthInterval: customMonthInterval,
|
||||
customMonthIntervalUnit: customMonthIntervalUnit,
|
||||
tags: taxTags,
|
||||
files: uploadedFiles,
|
||||
addReminderRecord: addReminderRecord,
|
||||
extraFields: extraFields.extraFields,
|
||||
reminderRecordId: recurringReminderRecordId
|
||||
}
|
||||
}
|
||||
|
||||
function checkRecurringTaxes() {
|
||||
let vehicleId = GetVehicleId().vehicleId
|
||||
$.post('/Vehicle/CheckRecurringTaxRecords', { vehicleId: vehicleId }, function (data) {
|
||||
if (data) {
|
||||
//notify users that recurring tax records were updated and they should refresh the page to see the new changes.
|
||||
infoToast(`Recurring Tax Records Updated!<br /><br /><a class='text-link' style='cursor:pointer;' onclick='viewVehicle(${vehicleId})'>Refresh to see new records</a>`);
|
||||
}
|
||||
})
|
||||
}
|
||||
156
wwwroot/js/upgraderecord.js
Normal file
156
wwwroot/js/upgraderecord.js
Normal file
@@ -0,0 +1,156 @@
|
||||
function showAddUpgradeRecordModal() {
|
||||
$.get('/Vehicle/GetAddUpgradeRecordPartialView', function (data) {
|
||||
if (data) {
|
||||
$("#upgradeRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#upgradeRecordDate'));
|
||||
initTagSelector($("#upgradeRecordTag"));
|
||||
$('#upgradeRecordModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function showEditUpgradeRecordModal(upgradeRecordId, nocache) {
|
||||
if (!nocache) {
|
||||
var existingContent = $("#upgradeRecordModalContent").html();
|
||||
if (existingContent.trim() != '') {
|
||||
//check if id is same.
|
||||
var existingId = getUpgradeRecordModelData().id;
|
||||
if (existingId == upgradeRecordId && $('[data-changed=true]').length > 0) {
|
||||
$('#upgradeRecordModal').modal('show');
|
||||
$('.cached-banner').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.get(`/Vehicle/GetUpgradeRecordForEditById?upgradeRecordId=${upgradeRecordId}`, function (data) {
|
||||
if (data) {
|
||||
$("#upgradeRecordModalContent").html(data);
|
||||
//initiate datepicker
|
||||
initDatePicker($('#upgradeRecordDate'));
|
||||
initTagSelector($("#upgradeRecordTag"));
|
||||
$('#upgradeRecordModal').modal('show');
|
||||
bindModalInputChanges('upgradeRecordModal');
|
||||
$('#upgradeRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
|
||||
if (getGlobalConfig().useMarkDown) {
|
||||
toggleMarkDownOverlay("upgradeRecordNotes");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideAddUpgradeRecordModal() {
|
||||
$('#upgradeRecordModal').modal('hide');
|
||||
}
|
||||
function deleteUpgradeRecord(upgradeRecordId) {
|
||||
$("#workAroundInput").show();
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "Deleted Upgrade Records cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post(`/Vehicle/DeleteUpgradeRecordById?upgradeRecordId=${upgradeRecordId}`, function (data) {
|
||||
if (data) {
|
||||
hideAddUpgradeRecordModal();
|
||||
successToast("Upgrade Record Deleted");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
getVehicleUpgradeRecords(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveUpgradeRecordToVehicle(isEdit) {
|
||||
//get values
|
||||
var formValues = getAndValidateUpgradeRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/SaveUpgradeRecordToVehicleId', { upgradeRecord: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(isEdit ? "Upgrade Record Updated" : "Upgrade Record Added.");
|
||||
hideAddUpgradeRecordModal();
|
||||
saveScrollPosition();
|
||||
getVehicleUpgradeRecords(formValues.vehicleId);
|
||||
if (formValues.addReminderRecord) {
|
||||
setTimeout(function () { showAddReminderModal(formValues); }, 500);
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateUpgradeRecordValues() {
|
||||
var upgradeDate = $("#upgradeRecordDate").val();
|
||||
var upgradeMileage = parseInt(globalParseFloat($("#upgradeRecordMileage").val())).toString();
|
||||
var upgradeDescription = $("#upgradeRecordDescription").val();
|
||||
var upgradeCost = $("#upgradeRecordCost").val();
|
||||
var upgradeNotes = $("#upgradeRecordNotes").val();
|
||||
var upgradeTags = $("#upgradeRecordTag").val();
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var upgradeRecordId = getUpgradeRecordModelData().id;
|
||||
var addReminderRecord = $("#addReminderCheck").is(":checked");
|
||||
//Odometer Adjustments
|
||||
if (isNaN(upgradeMileage) && GetVehicleId().odometerOptional) {
|
||||
upgradeMileage = '0';
|
||||
}
|
||||
upgradeMileage = GetAdjustedOdometer(upgradeRecordId, upgradeMileage);
|
||||
//validation
|
||||
var hasError = false;
|
||||
var extraFields = getAndValidateExtraFields();
|
||||
if (extraFields.hasError) {
|
||||
hasError = true;
|
||||
}
|
||||
if (upgradeDate.trim() == '') { //eliminates whitespace.
|
||||
hasError = true;
|
||||
$("#upgradeRecordDate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#upgradeRecordDate").removeClass("is-invalid");
|
||||
}
|
||||
if (upgradeMileage.trim() == '' || isNaN(upgradeMileage) || parseInt(upgradeMileage) < 0) {
|
||||
hasError = true;
|
||||
$("#upgradeRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#upgradeRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (upgradeDescription.trim() == '') {
|
||||
hasError = true;
|
||||
$("#upgradeRecordDescription").addClass("is-invalid");
|
||||
} else {
|
||||
$("#upgradeRecordDescription").removeClass("is-invalid");
|
||||
}
|
||||
if (upgradeCost.trim() == '' || !isValidMoney(upgradeCost)) {
|
||||
hasError = true;
|
||||
$("#upgradeRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#upgradeRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
id: upgradeRecordId,
|
||||
hasError: hasError,
|
||||
vehicleId: vehicleId,
|
||||
date: upgradeDate,
|
||||
mileage: upgradeMileage,
|
||||
description: upgradeDescription,
|
||||
cost: upgradeCost,
|
||||
notes: upgradeNotes,
|
||||
files: uploadedFiles,
|
||||
supplies: selectedSupplies,
|
||||
tags: upgradeTags,
|
||||
addReminderRecord: addReminderRecord,
|
||||
extraFields: extraFields.extraFields,
|
||||
requisitionHistory: supplyUsageHistory,
|
||||
deletedRequisitionHistory: deletedSupplyUsageHistory,
|
||||
reminderRecordId: recurringReminderRecordId,
|
||||
copySuppliesAttachment: copySuppliesAttachments
|
||||
}
|
||||
}
|
||||
731
wwwroot/js/vehicle.js
Normal file
731
wwwroot/js/vehicle.js
Normal file
@@ -0,0 +1,731 @@
|
||||
$(document).ready(function () {
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
//bind tabs
|
||||
$('button[data-bs-toggle="tab"]').on('show.bs.tab', function (e) {
|
||||
switch (e.target.id) {
|
||||
case "servicerecord-tab":
|
||||
getVehicleServiceRecords(vehicleId);
|
||||
break;
|
||||
case "notes-tab":
|
||||
getVehicleNotes(vehicleId);
|
||||
break;
|
||||
case "gas-tab":
|
||||
getVehicleGasRecords(vehicleId);
|
||||
break;
|
||||
case "accident-tab":
|
||||
getVehicleCollisionRecords(vehicleId);
|
||||
break;
|
||||
case "tax-tab":
|
||||
getVehicleTaxRecords(vehicleId);
|
||||
break;
|
||||
case "report-tab":
|
||||
getVehicleReport(vehicleId);
|
||||
break;
|
||||
case "reminder-tab":
|
||||
getVehicleReminders(vehicleId);
|
||||
break;
|
||||
case "upgrade-tab":
|
||||
getVehicleUpgradeRecords(vehicleId);
|
||||
break;
|
||||
case "supply-tab":
|
||||
getVehicleSupplyRecords(vehicleId);
|
||||
break;
|
||||
case "plan-tab":
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
break;
|
||||
case "odometer-tab":
|
||||
getVehicleOdometerRecords(vehicleId);
|
||||
break;
|
||||
}
|
||||
switch (e.relatedTarget.id) { //clear out previous tabs with grids in them to help with performance
|
||||
case "servicerecord-tab":
|
||||
$("#servicerecord-tab-pane").html("");
|
||||
break;
|
||||
case "gas-tab":
|
||||
$("#gas-tab-pane").html("");
|
||||
break;
|
||||
case "accident-tab":
|
||||
$("#accident-tab-pane").html("");
|
||||
break;
|
||||
case "tax-tab":
|
||||
$("#tax-tab-pane").html("");
|
||||
break;
|
||||
case "report-tab":
|
||||
$("#report-tab-pane").html("");
|
||||
break;
|
||||
case "reminder-tab":
|
||||
$("#reminder-tab-pane").html("");
|
||||
break;
|
||||
case "upgrade-tab":
|
||||
$("#upgrade-tab-pane").html("");
|
||||
break;
|
||||
case "notes-tab":
|
||||
$("#notes-tab-pane").html("");
|
||||
break;
|
||||
case "supply-tab":
|
||||
$("#supply-tab-pane").html("");
|
||||
break;
|
||||
case "plan-tab":
|
||||
$("#plan-tab-pane").html("");
|
||||
break;
|
||||
case "odometer-tab":
|
||||
$("#odometer-tab-pane").html("");
|
||||
break;
|
||||
}
|
||||
$(`.motovaultpro-tab #${e.target.id}`).addClass('active');
|
||||
$(`.motovaultpro-mobile-nav #${e.target.id}`).addClass('active');
|
||||
$(`.motovaultpro-tab #${e.relatedTarget.id}`).removeClass('active');
|
||||
$(`.motovaultpro-mobile-nav #${e.relatedTarget.id}`).removeClass('active');
|
||||
});
|
||||
var defaultTab = GetDefaultTab().tab;
|
||||
switch (defaultTab) {
|
||||
case "ServiceRecord":
|
||||
getVehicleServiceRecords(vehicleId);
|
||||
break;
|
||||
case "NoteRecord":
|
||||
getVehicleNotes(vehicleId);
|
||||
break;
|
||||
case "GasRecord":
|
||||
getVehicleGasRecords(vehicleId);
|
||||
break;
|
||||
case "RepairRecord":
|
||||
getVehicleCollisionRecords(vehicleId);
|
||||
break;
|
||||
case "TaxRecord":
|
||||
getVehicleTaxRecords(vehicleId);
|
||||
break;
|
||||
case "Dashboard":
|
||||
getVehicleReport(vehicleId);
|
||||
break;
|
||||
case "ReminderRecord":
|
||||
getVehicleReminders(vehicleId);
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
getVehicleUpgradeRecords(vehicleId);
|
||||
break;
|
||||
case "SupplyRecord":
|
||||
getVehicleSupplyRecords(vehicleId);
|
||||
break;
|
||||
case "PlanRecord":
|
||||
getVehiclePlanRecords(vehicleId);
|
||||
break;
|
||||
case "OdometerRecord":
|
||||
getVehicleOdometerRecords(vehicleId);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function getVehicleNotes(vehicleId) {
|
||||
$.get(`/Vehicle/GetNotesByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#notes-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleServiceRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetServiceRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#servicerecord-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehiclePlanRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetPlanRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#plan-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleOdometerRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetOdometerRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#odometer-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleSupplyRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetSupplyRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#supply-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleUpgradeRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetUpgradeRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#upgrade-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleGasRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetGasRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#gas-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleCollisionRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetCollisionRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#accident-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleTaxRecords(vehicleId) {
|
||||
$.get(`/Vehicle/GetTaxRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#tax-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleReminders(vehicleId) {
|
||||
$.get(`/Vehicle/GetReminderRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#reminder-tab-pane").html(data);
|
||||
restoreScrollPosition();
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
function getVehicleReport(vehicleId) {
|
||||
$.get(`/Vehicle/GetReportPartialView?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#report-tab-pane").html(data);
|
||||
getVehicleHaveImportantReminders(vehicleId);
|
||||
}
|
||||
})
|
||||
}
|
||||
function editVehicle(vehicleId) {
|
||||
$.get(`/Vehicle/GetEditVehiclePartialViewById?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$("#editVehicleModalContent").html(data);
|
||||
initTagSelector($("#inputTag"), true);
|
||||
initDatePicker($('#inputPurchaseDate'));
|
||||
initDatePicker($('#inputSoldDate'));
|
||||
$('#editVehicleModal').modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideEditVehicleModal() {
|
||||
$('#editVehicleModal').modal('hide');
|
||||
}
|
||||
function deleteVehicle(vehicleId) {
|
||||
Swal.fire({
|
||||
title: "Confirm Deletion?",
|
||||
text: "This will also delete all data tied to this vehicle. Deleted Vehicles and their associated data cannot be restored.",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Vehicle/DeleteVehicle', { vehicleId: vehicleId }, function (data) {
|
||||
if (data) {
|
||||
window.location.href = '/Home';
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
function showAddReminderModal(reminderModalInput) {
|
||||
if (reminderModalInput != undefined) {
|
||||
$.post('/Vehicle/GetAddReminderRecordPartialView', { reminderModel: reminderModalInput }, function (data) {
|
||||
$("#reminderRecordModalContent").html(data);
|
||||
initDatePicker($('#reminderDate'), true);
|
||||
initTagSelector($("#reminderRecordTag"));
|
||||
$("#reminderRecordModal").modal("show");
|
||||
});
|
||||
} else {
|
||||
$.post('/Vehicle/GetAddReminderRecordPartialView', function (data) {
|
||||
$("#reminderRecordModalContent").html(data);
|
||||
initDatePicker($('#reminderDate'), true);
|
||||
initTagSelector($("#reminderRecordTag"));
|
||||
$("#reminderRecordModal").modal("show");
|
||||
});
|
||||
}
|
||||
}
|
||||
function getVehicleHaveImportantReminders(vehicleId) {
|
||||
setTimeout(function () {
|
||||
$.get(`/Vehicle/GetVehicleHaveUrgentOrPastDueReminders?vehicleId=${vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
$(".reminderBell").removeClass("bi-bell");
|
||||
$(".reminderBell").addClass("bi-bell-fill");
|
||||
$(".reminderBell").addClass("text-warning");
|
||||
$(".reminderBellDiv").addClass("bell-shake");
|
||||
} else {
|
||||
$(".reminderBellDiv").removeClass("bell-shake");
|
||||
$(".reminderBell").removeClass("bi-bell-fill");
|
||||
$(".reminderBell").addClass("bi-bell");
|
||||
$(".reminderBell").removeClass("text-warning");
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
function moveRecord(recordId, source, dest) {
|
||||
$("#workAroundInput").show();
|
||||
var friendlySource = "";
|
||||
var friendlyDest = "";
|
||||
var hideModalCallBack;
|
||||
var refreshDataCallBack;
|
||||
switch (source) {
|
||||
case "ServiceRecord":
|
||||
friendlySource = "Service Records";
|
||||
hideModalCallBack = hideAddServiceRecordModal;
|
||||
refreshDataCallBack = getVehicleServiceRecords;
|
||||
break;
|
||||
case "RepairRecord":
|
||||
friendlySource = "Repairs";
|
||||
hideModalCallBack = hideAddCollisionRecordModal;
|
||||
refreshDataCallBack = getVehicleCollisionRecords;
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
friendlySource = "Upgrades";
|
||||
hideModalCallBack = hideAddUpgradeRecordModal;
|
||||
refreshDataCallBack = getVehicleUpgradeRecords;
|
||||
break;
|
||||
}
|
||||
switch (dest) {
|
||||
case "ServiceRecord":
|
||||
friendlyDest = "Service Records";
|
||||
break;
|
||||
case "RepairRecord":
|
||||
friendlyDest = "Repairs";
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
friendlyDest = "Upgrades";
|
||||
break;
|
||||
}
|
||||
Swal.fire({
|
||||
title: "Confirm Move?",
|
||||
text: `Move this record from ${friendlySource} to ${friendlyDest}?`,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Move",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Vehicle/MoveRecord', { recordId: recordId, source: source, destination: dest }, function (data) {
|
||||
if (data) {
|
||||
hideModalCallBack();
|
||||
successToast("Record Moved");
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
refreshDataCallBack(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function showRecurringReminderSelector(descriptionFieldName, noteFieldName) {
|
||||
$.get(`/Vehicle/GetRecurringReminderRecordsByVehicleId?vehicleId=${GetVehicleId().vehicleId}`, function (data) {
|
||||
if (data) {
|
||||
//prompt user to select a recurring reminder
|
||||
Swal.fire({
|
||||
title: 'Select Recurring Reminder',
|
||||
html: data,
|
||||
confirmButtonText: 'Select',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
//validate
|
||||
var selectedRecurringReminderData = getAndValidateSelectedRecurringReminder();
|
||||
if (selectedRecurringReminderData.hasError) {
|
||||
Swal.showValidationMessage(`You must select a recurring reminder`);
|
||||
}
|
||||
return { selectedRecurringReminderData }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
recurringReminderRecordId = result.value.selectedRecurringReminderData.ids;
|
||||
let descriptionField = $(`#${descriptionFieldName}`);
|
||||
let noteField = $(`#${noteFieldName}`);
|
||||
if (descriptionField.length > 0) {
|
||||
let descriptionFieldText = result.value.selectedRecurringReminderData.text.join(', ');
|
||||
descriptionField.val(descriptionFieldText);
|
||||
}
|
||||
if (noteField.length > 0 && result.value.selectedRecurringReminderData.text.length > 1) {
|
||||
result.value.selectedRecurringReminderData.text.map(x => {
|
||||
noteField.append(`- ${x}\r\n`);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function editMultipleRecords(ids, dataType) {
|
||||
if (ids.length < 2) {
|
||||
return;
|
||||
}
|
||||
$.post('/Vehicle/GetGenericRecordModal', { recordIds: ids, dataType: dataType }, function (data) {
|
||||
if (data) {
|
||||
$("#genericRecordEditModalContent").html(data);
|
||||
initDatePicker($('#genericRecordDate'));
|
||||
initTagSelector($("#genericRecordTag"));
|
||||
$("#genericRecordEditModal").modal('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
function hideGenericRecordModal() {
|
||||
$("#genericRecordEditModal").modal('hide');
|
||||
}
|
||||
function saveGenericRecord() {
|
||||
//get values
|
||||
var formValues = getAndValidateGenericRecordValues();
|
||||
//validate
|
||||
if (formValues.hasError) {
|
||||
errorToast("Please check the form data");
|
||||
return;
|
||||
}
|
||||
var refreshDataCallBack;
|
||||
switch (formValues.dataType) {
|
||||
case "ServiceRecord":
|
||||
refreshDataCallBack = getVehicleServiceRecords;
|
||||
break;
|
||||
case "RepairRecord":
|
||||
refreshDataCallBack = getVehicleCollisionRecords;
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
refreshDataCallBack = getVehicleUpgradeRecords;
|
||||
break;
|
||||
}
|
||||
//save to db.
|
||||
$.post('/Vehicle/EditMultipleRecords', { genericRecordEditModel: formValues }, function (data) {
|
||||
if (data) {
|
||||
successToast(formValues.recordIds.length > 1 ? "Records Updated" : "Record Updated.");
|
||||
hideGenericRecordModal();
|
||||
refreshDataCallBack(GetVehicleId().vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
})
|
||||
}
|
||||
function getAndValidateGenericRecordValues() {
|
||||
var genericDate = $("#genericRecordDate").val();
|
||||
var genericMileage = $("#genericRecordMileage").val();
|
||||
var genericMileageToParse = parseInt(globalParseFloat($("#genericRecordMileage").val())).toString();
|
||||
var genericDescription = $("#genericRecordDescription").val();
|
||||
var genericCost = $("#genericRecordCost").val();
|
||||
var genericNotes = $("#genericRecordNotes").val();
|
||||
var genericTags = $("#genericRecordTag").val();
|
||||
var genericExtraFields = getAndValidateExtraFields();
|
||||
//validation
|
||||
var hasError = false;
|
||||
if (genericMileage.trim() != '' && (isNaN(genericMileageToParse) || parseInt(genericMileageToParse) < 0)) {
|
||||
hasError = true;
|
||||
$("#genericRecordMileage").addClass("is-invalid");
|
||||
} else {
|
||||
$("#genericRecordMileage").removeClass("is-invalid");
|
||||
}
|
||||
if (genericCost.trim() != '' && !isValidMoney(genericCost)) {
|
||||
hasError = true;
|
||||
$("#genericRecordCost").addClass("is-invalid");
|
||||
} else {
|
||||
$("#genericRecordCost").removeClass("is-invalid");
|
||||
}
|
||||
return {
|
||||
hasError: hasError,
|
||||
dataType: getGenericRecordEditModelData().dataType,
|
||||
recordIds: recordsToEdit,
|
||||
editRecord: {
|
||||
date: genericDate,
|
||||
mileage: genericMileageToParse,
|
||||
description: genericDescription,
|
||||
cost: genericCost,
|
||||
notes: genericNotes,
|
||||
tags: genericTags,
|
||||
extraFields: genericExtraFields.extraFields
|
||||
}
|
||||
}
|
||||
}
|
||||
function getRecordsDeltaStats(recordIds) {
|
||||
if (recordIds.length < 2) {
|
||||
return;
|
||||
}
|
||||
var odometerReadings = [];
|
||||
var dateReadings = [];
|
||||
var costReadings = [];
|
||||
//get all of the odometer readings
|
||||
recordIds.map(x => {
|
||||
var odometerReading = parseInt($(`tr[data-rowId='${x}'] td[data-column='odometer']`).text());
|
||||
if (!isNaN(odometerReading)) {
|
||||
odometerReadings.push(odometerReading);
|
||||
}
|
||||
var dateReading = parseInt($(`tr[data-rowId=${x}] td[data-column='date']`).attr('data-date'));
|
||||
if (!isNaN(dateReading)) {
|
||||
dateReadings.push(dateReading);
|
||||
}
|
||||
var costReading = globalParseFloat($(`tr[data-rowId='${x}'] td[data-column='cost']`).text());
|
||||
if (costReading > 0) {
|
||||
costReadings.push(costReading);
|
||||
}
|
||||
});
|
||||
//get max stats
|
||||
var maxOdo = odometerReadings.length > 0 ? odometerReadings.reduce((a, b) => a > b ? a : b) : 0;
|
||||
var maxDate = dateReadings.length > 0 ? dateReadings.reduce((a, b) => a > b ? a : b) : 0;
|
||||
//get min stats
|
||||
var minOdo = odometerReadings.length > 0 ? odometerReadings.reduce((a, b) => a < b ? a : b) : 0;
|
||||
var minDate = dateReadings.length > 0 ? dateReadings.reduce((a, b) => a < b ? a : b) : 0;
|
||||
//get sum of costs
|
||||
var costSum = costReadings.length > 0 ? costReadings.reduce((a, b) => a + b) : 0;
|
||||
var diffOdo = maxOdo - minOdo;
|
||||
var diffDate = maxDate - minDate;
|
||||
var divisibleCount = recordIds.length - 1;
|
||||
var averageOdo = diffOdo > 0 ? (diffOdo / divisibleCount).toFixed(2) : '0';
|
||||
var averageDays = diffDate > 0 ? Math.floor((diffDate / divisibleCount) / 8.64e7) : '0';
|
||||
var averageSum = costSum > 0 ? (costSum / recordIds.length).toFixed(2) : '0';
|
||||
costSum = costSum.toFixed(2);
|
||||
Swal.fire({
|
||||
title: "Record Statistics",
|
||||
html: `<p>Average Distance Traveled between Records: ${globalFloatToString(averageOdo)}</p>
|
||||
<br />
|
||||
<p>Average Days between Records: ${averageDays}</p>
|
||||
<br />
|
||||
<p>Total Cost: ${globalAppendCurrency(globalFloatToString(costSum))}</p>
|
||||
<br />
|
||||
<p>Average Cost: ${globalAppendCurrency(globalFloatToString(averageSum))}</p>`
|
||||
,
|
||||
icon: "info"
|
||||
});
|
||||
}
|
||||
function GetAdjustedOdometer(id, odometerInput) {
|
||||
//if editing an existing record or vehicle does not have odometer adjustment or input is NaN then just return the original input.
|
||||
if (id > 0 || !GetVehicleId().hasOdometerAdjustment || isNaN(odometerInput)) {
|
||||
return odometerInput;
|
||||
}
|
||||
//apply odometer adjustments first.
|
||||
var adjustedOdometer = parseInt(odometerInput) + parseInt(GetVehicleId().odometerDifference);
|
||||
//apply odometer multiplier.
|
||||
adjustedOdometer *= globalParseFloat(GetVehicleId().odometerMultiplier);
|
||||
return adjustedOdometer.toFixed(0);
|
||||
}
|
||||
function adjustRecordsOdometer(ids, source) {
|
||||
if (ids.length == 0) {
|
||||
return;
|
||||
}
|
||||
$("#workAroundInput").show();
|
||||
var friendlySource = "";
|
||||
var refreshDataCallBack;
|
||||
var recordVerbiage = ids.length > 1 ? `these ${ids.length} records` : "this record";
|
||||
switch (source) {
|
||||
case "ServiceRecord":
|
||||
friendlySource = "Service Records";
|
||||
refreshDataCallBack = getVehicleServiceRecords;
|
||||
break;
|
||||
case "RepairRecord":
|
||||
friendlySource = "Repairs";
|
||||
refreshDataCallBack = getVehicleCollisionRecords;
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
friendlySource = "Upgrades";
|
||||
refreshDataCallBack = getVehicleUpgradeRecords;
|
||||
break;
|
||||
case "OdometerRecord":
|
||||
friendlySource = "Odometer Records";
|
||||
refreshDataCallBack = getVehicleOdometerRecords;
|
||||
break;
|
||||
case "GasRecord":
|
||||
friendlySource = "Fuel Records";
|
||||
refreshDataCallBack = getVehicleGasRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: "Adjust Odometer?",
|
||||
text: `Apply Odometer Adjustments to ${recordVerbiage}?`,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Adjust",
|
||||
confirmButtonColor: "#dc3545"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
saveScrollPosition();
|
||||
$.post('/Vehicle/AdjustRecordsOdometer', { recordIds: ids, vehicleId: GetVehicleId().vehicleId, importMode: source }, function (data) {
|
||||
if (data) {
|
||||
successToast(`${ids.length} Record(s) Updated`);
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
refreshDataCallBack(vehicleId);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#workAroundInput").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
function showMultipleRemindersSelector() {
|
||||
if ($("#multipleRemindersCheck").is(":checked")) {
|
||||
$("#recurringMultipleReminders").show();
|
||||
$("#recurringReminderInput").hide();
|
||||
} else {
|
||||
$("#recurringMultipleReminders").hide();
|
||||
$("#recurringReminderInput").show();
|
||||
}
|
||||
}
|
||||
function getAndValidateSelectedRecurringReminder() {
|
||||
if ($("#multipleRemindersCheck").is(":checked")) {
|
||||
//validate multiple reminders
|
||||
var selectedRecurringRemindersArray = [];
|
||||
$("#recurringMultipleReminders :checked").map(function () {
|
||||
selectedRecurringRemindersArray.push({
|
||||
value: this.value,
|
||||
text: $(this).attr("data-description")
|
||||
});
|
||||
});
|
||||
if (selectedRecurringRemindersArray.length == 0) {
|
||||
return {
|
||||
hasError: true,
|
||||
ids: [],
|
||||
text: ''
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
hasError: false,
|
||||
ids: selectedRecurringRemindersArray.map(x=>x.value),
|
||||
text: selectedRecurringRemindersArray.map(x=>x.text)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//validate single reminder
|
||||
var selectedRecurringReminder = $("#recurringReminderInput").val();
|
||||
var selectedRecurringReminderText = $("#recurringReminderInput option:selected").attr("data-description");
|
||||
if (!selectedRecurringReminder || parseInt(selectedRecurringReminder) == 0) {
|
||||
return {
|
||||
hasError: true,
|
||||
ids: [],
|
||||
text: ''
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
hasError: false,
|
||||
ids: [selectedRecurringReminder],
|
||||
text: [selectedRecurringReminderText]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function getLastOdometerReadingAndIncrement(odometerFieldName) {
|
||||
$.get(`/Vehicle/GetMaxMileage?vehicleId=${GetVehicleId().vehicleId}`, function (currentOdometer) {
|
||||
let additionalHtml = isNaN(currentOdometer) || currentOdometer == 0 ? '' : `<span>Current Odometer: ${currentOdometer}</span><br/>`;
|
||||
Swal.fire({
|
||||
title: 'Increment Last Reported Odometer Reading',
|
||||
html: `${additionalHtml}
|
||||
<input type="text" inputmode="decimal" id="inputOdometerIncrement" class="swal2-input" placeholder="Increment" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Add',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const odometerIncrement = parseInt(globalParseFloat($("#inputOdometerIncrement").val()));
|
||||
if (isNaN(odometerIncrement) || odometerIncrement < 0) {
|
||||
Swal.showValidationMessage(`Please enter a positive amount to increment or 0 to use current odometer`);
|
||||
}
|
||||
return { odometerIncrement }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
var amountToIncrement = result.value.odometerIncrement;
|
||||
var newAmount = currentOdometer + amountToIncrement;
|
||||
if (!isNaN(newAmount)) {
|
||||
var odometerField = $(`#${odometerFieldName}`);
|
||||
if (odometerField.length > 0) {
|
||||
odometerField.val(newAmount);
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
} else {
|
||||
errorToast(genericErrorMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showGlobalSearch() {
|
||||
$('#globalSearchModal').modal('show');
|
||||
}
|
||||
function hideGlobalSearch() {
|
||||
$('#globalSearchModal').modal('hide');
|
||||
}
|
||||
function performGlobalSearch() {
|
||||
var searchQuery = $('#globalSearchInput').val();
|
||||
if (searchQuery.trim() == '') {
|
||||
$('#globalSearchInput').addClass('is-invalid');
|
||||
} else {
|
||||
$('#globalSearchInput').removeClass('is-invalid');
|
||||
}
|
||||
let caseSensitiveSearch = $("#globalSearchCaseSensitiveCheck").is(':checked');
|
||||
$.post('/Vehicle/SearchRecords', { vehicleId: GetVehicleId().vehicleId, searchQuery: searchQuery, caseSensitive: caseSensitiveSearch }, function (data) {
|
||||
$('#globalSearchModalResults').html(data);
|
||||
});
|
||||
}
|
||||
function handleGlobalSearchKeyPress(event) {
|
||||
if ($('#globalSearchAutoSearchCheck').is(':checked')) {
|
||||
setDebounce(performGlobalSearch);
|
||||
} else if (event.keyCode == 13) {
|
||||
performGlobalSearch();
|
||||
}
|
||||
}
|
||||
|
||||
function loadGlobalSearchResult(recordId, recordType) {
|
||||
hideGlobalSearch();
|
||||
switch (recordType) {
|
||||
case "ServiceRecord":
|
||||
$('#servicerecord-tab').tab('show');
|
||||
waitForElement('#serviceRecordModalContent', showEditServiceRecordModal, recordId);
|
||||
break;
|
||||
case "RepairRecord":
|
||||
$('#accident-tab').tab('show');
|
||||
waitForElement('#collisionRecordModalContent', showEditCollisionRecordModal, recordId);
|
||||
break;
|
||||
case "UpgradeRecord":
|
||||
$('#upgrade-tab').tab('show');
|
||||
waitForElement('#upgradeRecordModalContent', showEditUpgradeRecordModal, recordId);
|
||||
break;
|
||||
case "TaxRecord":
|
||||
$('#tax-tab').tab('show');
|
||||
waitForElement('#taxRecordModalContent', showEditTaxRecordModal, recordId);
|
||||
break;
|
||||
case "SupplyRecord":
|
||||
$('#supply-tab').tab('show');
|
||||
waitForElement('#supplyRecordModalContent', showEditSupplyRecordModal, recordId);
|
||||
break;
|
||||
case "NoteRecord":
|
||||
$('#notes-tab').tab('show');
|
||||
waitForElement('#noteModalContent', showEditNoteModal, recordId);
|
||||
break;
|
||||
case "OdometerRecord":
|
||||
$('#odometer-tab').tab('show');
|
||||
waitForElement('#odometerRecordModalContent', showEditOdometerRecordModal, recordId);
|
||||
break;
|
||||
case "ReminderRecord":
|
||||
$('#reminder-tab').tab('show');
|
||||
waitForElement('#reminderRecordModalContent', showEditReminderRecordModal, recordId);
|
||||
break;
|
||||
case "GasRecord":
|
||||
$('#gas-tab').tab('show');
|
||||
waitForElement('#gasRecordModalContent', showEditGasRecordModal, recordId);
|
||||
break;
|
||||
case "PlanRecord":
|
||||
$('#plan-tab').tab('show');
|
||||
waitForElement('#planRecordModalContent', showEditPlanRecordModal, recordId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user