added global parsefloat method which derives from C# culture.
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
var useDarkMode = userConfig.UseDarkMode;
|
var useDarkMode = userConfig.UseDarkMode;
|
||||||
var enableCsvImports = userConfig.EnableCsvImports;
|
var enableCsvImports = userConfig.EnableCsvImports;
|
||||||
var shortDatePattern = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
|
var shortDatePattern = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
|
||||||
|
var numberFormat = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
|
||||||
shortDatePattern = shortDatePattern.ToLower();
|
shortDatePattern = shortDatePattern.ToLower();
|
||||||
if (!shortDatePattern.Contains("dd"))
|
if (!shortDatePattern.Contains("dd"))
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,16 @@
|
|||||||
pattern: "@shortDatePattern"
|
pattern: "@shortDatePattern"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function globalParseFloat(input){
|
||||||
|
//remove thousands separator.
|
||||||
|
var thousandSeparator = "@numberFormat.NumberGroupSeparator";
|
||||||
|
var decimalSeparator = "@numberFormat.NumberDecimalSeparator";
|
||||||
|
//strip thousands from input.
|
||||||
|
input = input.replace(thousandSeparator, "");
|
||||||
|
//convert to JS format where decimal is only separated by .
|
||||||
|
input = input.replace(decimalSeparator, ".");
|
||||||
|
return parseFloat(input);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
@await RenderSectionAsync("Scripts", required: false)
|
@await RenderSectionAsync("Scripts", required: false)
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -153,6 +153,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" data-bs-focus="false" id="inputSuppliesModal" tabindex="-1" role="dialog" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content" id="inputSuppliesModalContent"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
function GetVehicleId() {
|
function GetVehicleId() {
|
||||||
return { vehicleId: @Model.Id};
|
return { vehicleId: @Model.Id};
|
||||||
|
|||||||
@@ -24,23 +24,23 @@
|
|||||||
<div class="col-md-1 d-sm-none d-md-block"></div>
|
<div class="col-md-1 d-sm-none d-md-block"></div>
|
||||||
<div class="col-12 col-md-10 reportsCheckBoxContainer">
|
<div class="col-12 col-md-10 reportsCheckBoxContainer">
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="serviceExpenseCheck" value="1" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="serviceExpenseCheck" value="1" checked>
|
||||||
<label class="form-check-label" for="serviceExpenseCheck">Service</label>
|
<label class="form-check-label" for="serviceExpenseCheck">Service</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="repairExpenseCheck" value="2" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="repairExpenseCheck" value="2" checked>
|
||||||
<label class="form-check-label" for="repairExpenseCheck">Repairs</label>
|
<label class="form-check-label" for="repairExpenseCheck">Repairs</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
|
||||||
<label class="form-check-label" for="upgradeExpenseCheck">Upgrades</label>
|
<label class="form-check-label" for="upgradeExpenseCheck">Upgrades</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="gasExpenseCheck" value="4" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="gasExpenseCheck" value="4" checked>
|
||||||
<label class="form-check-label" for="gasExpenseCheck">Gas</label>
|
<label class="form-check-label" for="gasExpenseCheck">Gas</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" onChange="updateCheck(this)" type="checkbox" id="taxExpenseCheck" value="5" checked>
|
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="taxExpenseCheck" value="5" checked>
|
||||||
<label class="form-check-label" for="taxExpenseCheck">Tax</label>
|
<label class="form-check-label" for="taxExpenseCheck">Tax</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<input type="text" id="serviceRecordDescription" class="form-control" placeholder="Description of item(s) serviced(i.e. Oil Change)" value="@Model.Description">
|
<input type="text" id="serviceRecordDescription" class="form-control" placeholder="Description of item(s) serviced(i.e. Oil Change)" value="@Model.Description">
|
||||||
<label for="serviceRecordCost">Cost</label>
|
<label for="serviceRecordCost">Cost</label>
|
||||||
<input type="text" id="serviceRecordCost" class="form-control" placeholder="Cost of the service" value="@(isNew ? "" : Model.Cost)">
|
<input type="text" id="serviceRecordCost" class="form-control" placeholder="Cost of the service" value="@(isNew ? "" : Model.Cost)">
|
||||||
@await Html.PartialAsync("_SupplyStore", "serviceRecordCost")
|
@await Html.PartialAsync("_SupplyStore", "ServiceRecord")
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-12">
|
<div class="col-md-6 col-12">
|
||||||
<label for="serviceRecordNotes">Notes(optional)</label>
|
<label for="serviceRecordNotes">Notes(optional)</label>
|
||||||
|
|||||||
@@ -1,20 +1,59 @@
|
|||||||
@model string
|
@model string
|
||||||
<a onclick="toggleSuppliesDiv()" class="btn btn-link">Available Supplies</a>
|
<a onclick="toggleSuppliesDiv()" class="btn btn-link">Available Supplies</a>
|
||||||
<div id="inputSupplies"v style="max-height:30vh; overflow-x:hidden;"></div>
|
|
||||||
<script>
|
<script>
|
||||||
|
resetSuppliesModal();
|
||||||
|
function GetCaller() {
|
||||||
|
return { tab: '@Model' };
|
||||||
|
}
|
||||||
|
function resetSuppliesModal() {
|
||||||
|
$("#inputSuppliesModalContent").html("");
|
||||||
|
}
|
||||||
|
function selectSupplies() {
|
||||||
|
var selectedSupplyResult = getSuppliesAndQuantity();
|
||||||
|
var caller = GetCaller().tab;
|
||||||
|
switch (caller) {
|
||||||
|
case "ServiceRecord":
|
||||||
|
$('#serviceRecordCost').val(selectedSupplyResult.totalSum);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hideSuppliesModal();
|
||||||
|
}
|
||||||
|
function hideParentModal(){
|
||||||
|
var caller = GetCaller().tab;
|
||||||
|
switch (caller) {
|
||||||
|
case "ServiceRecord":
|
||||||
|
$('#serviceRecordModal').modal('hide');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function showParentModal() {
|
||||||
|
var caller = GetCaller().tab;
|
||||||
|
switch (caller) {
|
||||||
|
case "ServiceRecord":
|
||||||
|
$('#serviceRecordModal').modal('show');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
function toggleSuppliesDiv(){
|
function toggleSuppliesDiv(){
|
||||||
if ($("#inputSupplies").html() != "") {
|
if ($("#inputSuppliesModalContent").html() == "") {
|
||||||
$("#inputSupplies").html("");
|
|
||||||
} else {
|
|
||||||
getSupplies();
|
getSupplies();
|
||||||
|
} else {
|
||||||
|
hideParentModal();
|
||||||
|
$('#inputSuppliesModal').modal('show');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getSupplies() {
|
function getSupplies() {
|
||||||
var vehicleId = GetVehicleId().vehicleId;
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
$.get(`/Vehicle/GetSupplyRecordsForRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
$.get(`/Vehicle/GetSupplyRecordsForRecordsByVehicleId?vehicleId=${vehicleId}`, function (data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
$("#inputSupplies").html(data);
|
hideParentModal();
|
||||||
|
$("#inputSuppliesModalContent").html(data);
|
||||||
|
$('#inputSuppliesModal').modal('show');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function hideSuppliesModal() {
|
||||||
|
$('#inputSuppliesModal').modal('hide');
|
||||||
|
showParentModal();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -1,40 +1,57 @@
|
|||||||
@model List<SupplyRecord>
|
@model List<SupplyRecord>
|
||||||
<div class="row">
|
<div class="modal-header">
|
||||||
<div class="col-12">
|
<h5 class="modal-title">Select Supplies</h5>
|
||||||
<table class="table table-hover">
|
<button type="button" class="btn-close" onclick="hideSuppliesModal()" aria-label="Close"></button>
|
||||||
<thead class="sticky-top">
|
</div>
|
||||||
<tr class="d-flex">
|
<div class="modal-body">
|
||||||
<th scope="col" class="col-1"></th>
|
<div class="row">
|
||||||
<th scope="col" class="col-3">Qty.</th>
|
<div class="col-12">
|
||||||
<th scope="col" class="col-2">In Stock</th>
|
<table class="table table-hover">
|
||||||
<th scope="col" class="col-4">Supply</th>
|
<thead class="sticky-top">
|
||||||
<th scope="col" class="col-2">Unit Cost</th>
|
<tr class="d-flex">
|
||||||
</tr>
|
<th scope="col" class="col-1"></th>
|
||||||
</thead>
|
<th scope="col" class="col-2">Quantity.</th>
|
||||||
<tbody>
|
<th scope="col" class="col-2">In Stock</th>
|
||||||
@foreach (SupplyRecord supplyRecord in Model)
|
<th scope="col" class="col-5">Description</th>
|
||||||
{
|
<th scope="col" class="col-2">Unit Cost</th>
|
||||||
<tr class="d-flex" id="supplyRows">
|
|
||||||
<td class="col-1"><input class="form-check-input" type="checkbox" onchange="toggleQuantityFieldDisabled(this)" value="@supplyRecord.Id"></td>
|
|
||||||
<td class="col-3"><input type="text" disabled class="form-control"></td>
|
|
||||||
<td class="col-2 supplyquantity">@supplyRecord.Quantity</td>
|
|
||||||
<td class="col-4">@supplyRecord.Description</td>
|
|
||||||
<td class="col-2 supplyprice">@((supplyRecord.Quantity > 0 ? supplyRecord.Cost / supplyRecord.Quantity : 0).ToString("F"))</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
@foreach (SupplyRecord supplyRecord in Model)
|
||||||
|
{
|
||||||
|
<tr class="d-flex" id="supplyRows">
|
||||||
|
<td class="col-1"><input class="form-check-input" type="checkbox" onchange="toggleQuantityFieldDisabled(this)" value="@supplyRecord.Id"></td>
|
||||||
|
<td class="col-2"><input type="text" disabled onchange="recalculateTotal()" class="form-control"></td>
|
||||||
|
<td class="col-2 supplyquantity">@supplyRecord.Quantity</td>
|
||||||
|
<td class="col-5">@supplyRecord.Description</td>
|
||||||
|
<td class="col-2 supplyprice">@((supplyRecord.Quantity > 0 ? supplyRecord.Cost / supplyRecord.Quantity : 0).ToString("F"))</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<span id="supplySumLabel" style="margin-right:auto;">Total: 0.00</span>
|
||||||
|
<button type="button" class="btn btn-secondary" onclick="hideSuppliesModal()">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" disabled id="selectSuppliesButton" onclick="selectSupplies()">Select</button>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
function toggleQuantityFieldDisabled(e){
|
function recalculateTotal() {
|
||||||
|
setDebounce(getSuppliesAndQuantity);
|
||||||
|
}
|
||||||
|
function toggleQuantityFieldDisabled(e) {
|
||||||
var textField = getTextFieldFromCheckBox(e);
|
var textField = getTextFieldFromCheckBox(e);
|
||||||
var isChecked = $(e).is(":checked");
|
var isChecked = $(e).is(":checked");
|
||||||
textField.attr('disabled', !isChecked);
|
textField.attr('disabled', !isChecked);
|
||||||
getSuppliesAndQuantity();
|
if (!isChecked){
|
||||||
|
textField.removeClass("is-invalid");
|
||||||
|
}
|
||||||
|
recalculateTotal();
|
||||||
}
|
}
|
||||||
function getTextFieldFromCheckBox(elem){
|
function getTextFieldFromCheckBox(elem) {
|
||||||
var textField = $(elem.parentElement.parentElement).find('.col-3 > input[type=text]')[0];
|
var textField = $(elem.parentElement.parentElement).find('.col-2 > input[type=text]')[0];
|
||||||
return $(textField);
|
return $(textField);
|
||||||
}
|
}
|
||||||
function getInStockFieldFromCheckBox(elem) {
|
function getInStockFieldFromCheckBox(elem) {
|
||||||
@@ -46,29 +63,47 @@
|
|||||||
return $(textField);
|
return $(textField);
|
||||||
}
|
}
|
||||||
function getSuppliesAndQuantity() {
|
function getSuppliesAndQuantity() {
|
||||||
|
var totalSum = 0;
|
||||||
|
var hasError = false;
|
||||||
var selectedSupplies = $("#supplyRows :checked").map(function () {
|
var selectedSupplies = $("#supplyRows :checked").map(function () {
|
||||||
var textField = getTextFieldFromCheckBox(this);
|
var textField = getTextFieldFromCheckBox(this);
|
||||||
var inStock = getInStockFieldFromCheckBox(this);
|
var inStock = getInStockFieldFromCheckBox(this);
|
||||||
var priceField = getPriceFieldFromCheckBox(this);
|
var priceField = getPriceFieldFromCheckBox(this);
|
||||||
var requestedQuantity = parseFloat(textField.val());
|
var requestedQuantity = globalParseFloat(textField.val());
|
||||||
var inStockQuantity = parseFloat(inStock.text());
|
var inStockQuantity = globalParseFloat(inStock.text());
|
||||||
var unitPrice = parseFloat(priceField.text());
|
var unitPrice = globalParseFloat(priceField.text());
|
||||||
//validation
|
//validation
|
||||||
if (isNaN(requestedQuantity) || requestedQuantity > inStockQuantity){
|
if (isNaN(requestedQuantity) || requestedQuantity > inStockQuantity) {
|
||||||
textField.addClass("is-invalid");
|
textField.addClass("is-invalid");
|
||||||
|
hasError = true;
|
||||||
} else {
|
} else {
|
||||||
textField.removeClass("is-invalid");
|
textField.removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
//calculate sum.
|
//calculate sum.
|
||||||
console.log(requestedQuantity);
|
|
||||||
console.log(unitPrice);
|
|
||||||
var sum = requestedQuantity * unitPrice;
|
var sum = requestedQuantity * unitPrice;
|
||||||
return {
|
totalSum += sum;
|
||||||
supplyId: this.value,
|
return {
|
||||||
quantity: textField.val(),
|
supplyId: this.value,
|
||||||
sum: sum
|
quantity: textField.val()
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return selectedSupplies.toArray();
|
if (isNaN(totalSum) || hasError) {
|
||||||
|
$("#supplySumLabel").text(`Total: 0.00`);
|
||||||
|
} else {
|
||||||
|
totalSum = totalSum.toFixed(2);
|
||||||
|
$("#supplySumLabel").text(`Total: ${totalSum}`);
|
||||||
|
}
|
||||||
|
$("#selectSuppliesButton").attr('disabled', (hasError || totalSum == 0));
|
||||||
|
if (!hasError) {
|
||||||
|
return {
|
||||||
|
totalSum: totalSum,
|
||||||
|
selectedSupplies: selectedSupplies.toArray()
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
totalSum: 0,
|
||||||
|
selectedSupplies: []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -91,14 +91,14 @@ function getAndValidateGasRecordValues() {
|
|||||||
} else {
|
} else {
|
||||||
$("#gasRecordMileage").removeClass("is-invalid");
|
$("#gasRecordMileage").removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
if (gasGallons.trim() == '' || parseFloat(gasGallons) <= 0) {
|
if (gasGallons.trim() == '' || globalParseFloat(gasGallons) <= 0) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
$("#gasRecordGallons").addClass("is-invalid");
|
$("#gasRecordGallons").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
$("#gasRecordGallons").removeClass("is-invalid");
|
$("#gasRecordGallons").removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
if (gasCostType != undefined && gasCostType == 'unit') {
|
if (gasCostType != undefined && gasCostType == 'unit') {
|
||||||
var convertedGasCost = parseFloat(gasCost) * parseFloat(gasGallons);
|
var convertedGasCost = globalParseFloat(gasCost) * globalParseFloat(gasGallons);
|
||||||
gasCost = convertedGasCost.toFixed(2).toString();
|
gasCost = convertedGasCost.toFixed(2).toString();
|
||||||
if (isNaN(gasCost))
|
if (isNaN(gasCost))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,12 +12,8 @@ function generateVehicleHistoryReport() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var debounce = null;
|
function updateCheck() {
|
||||||
function updateCheck(sender) {
|
setDebounce(refreshBarChart);
|
||||||
clearTimeout(debounce);
|
|
||||||
debounce = setTimeout(function () {
|
|
||||||
refreshBarChart();
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
function refreshMPGChart() {
|
function refreshMPGChart() {
|
||||||
var vehicleId = GetVehicleId().vehicleId;
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
@@ -26,7 +22,7 @@ function refreshMPGChart() {
|
|||||||
$("#monthFuelMileageReportContent").html(data);
|
$("#monthFuelMileageReportContent").html(data);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function refreshBarChart(callBack) {
|
function refreshBarChart() {
|
||||||
var selectedMetrics = [];
|
var selectedMetrics = [];
|
||||||
var vehicleId = GetVehicleId().vehicleId;
|
var vehicleId = GetVehicleId().vehicleId;
|
||||||
var year = getYear();
|
var year = getYear();
|
||||||
|
|||||||
@@ -147,4 +147,11 @@ function decodeHTMLEntities(text) {
|
|||||||
return $("<textarea/>")
|
return $("<textarea/>")
|
||||||
.html(text)
|
.html(text)
|
||||||
.text();
|
.text();
|
||||||
|
}
|
||||||
|
var debounce = null;
|
||||||
|
function setDebounce(callBack) {
|
||||||
|
clearTimeout(debounce);
|
||||||
|
debounce = setTimeout(function () {
|
||||||
|
callBack();
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ function getAndValidateSupplyRecordValues() {
|
|||||||
} else {
|
} else {
|
||||||
$("#supplyRecordDescription").removeClass("is-invalid");
|
$("#supplyRecordDescription").removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
if (supplyQuantity.trim() == '' || !isValidMoney(supplyQuantity) || parseFloat(supplyQuantity) < 0) {
|
if (supplyQuantity.trim() == '' || !isValidMoney(supplyQuantity) || globalParseFloat(supplyQuantity) < 0) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
$("#supplyRecordQuantity").addClass("is-invalid");
|
$("#supplyRecordQuantity").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user