Files
lubelog/Views/Vehicle/_SupplyUsage.cshtml
DESKTOP-T0O5CDB\DESK-555BD fb169d5054 automatic decimal formatting.
2024-11-02 15:46:21 -06:00

147 lines
7.4 KiB
Plaintext

@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
var recordTags = Model.Supplies.SelectMany(x => x.Tags).Distinct();
}
@model SupplyUsageViewModel
<div class="modal-header">
<h5 class="modal-title">@translator.Translate(userLanguage,"Select Supplies")</h5>
<button type="button" class="btn-close" onclick="hideSuppliesModal()" aria-label="Close"></button>
</div>
<div class="modal-body">
@if (Model.Supplies.Any())
{
<div class="row">
<div class="col-12" style="max-height:50vh; overflow-y:auto;" id="supplies-table">
<div class="alert alert-warning" role="alert">
@translator.Translate(userLanguage,"Supplies are requisitioned immediately after the record is created and cannot be modified. If you have incorrectly entered the amount you needed you will need to correct it in the Supplies tab.")
</div>
<div class="d-flex align-items-center flex-wrap">
@foreach (string recordTag in recordTags)
{
<span onclick="filterTable('supplies-table', this)" class="user-select-none ms-2 rounded-pill badge bg-secondary tagfilter" style="cursor:pointer;">@recordTag</span>
}
</div>
<table class="table table-hover">
<thead class="sticky-top">
<tr class="d-flex">
<th scope="col" class="col-1"></th>
<th scope="col" class="col-2">@translator.Translate(userLanguage,"Quantity")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "In Stock")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Part Number")</th>
<th scope="col" class="col-3">@translator.Translate(userLanguage, "Description")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Unit Cost")</th>
</tr>
</thead>
<tbody>
@foreach (SupplyRecord supplyRecord in Model.Supplies)
{
var supplyUsage = Model.Usage.Where(x => x.SupplyId == supplyRecord.Id).SingleOrDefault();
<tr class="d-flex" id="supplyRows" data-tags='@string.Join(" ", supplyRecord.Tags)'>
<td class="col-1"><input class="form-check-input" type="checkbox" onchange="toggleQuantityFieldDisabled(this)" value="@supplyRecord.Id" @(supplyUsage == default ? "" : "checked")></td>
<td class="col-2"><input type="text" inputmode="decimal" onkeydown="interceptDecimalKeys(event)" onkeyup="fixDecimalInput(this, 2)" @(supplyUsage == default ? "disabled" : "") value="@(supplyUsage == default ? "" : supplyUsage.Quantity)" onchange="recalculateTotal()" class="form-control"></td>
<td class="col-2 supplyquantity">@supplyRecord.Quantity</td>
<td class="col-2 text-truncate">@StaticHelper.TruncateStrings(supplyRecord.PartNumber)</td>
<td class="col-3 text-truncate">@StaticHelper.TruncateStrings(supplyRecord.Description)</td>
<td class="col-2 supplyprice">@((supplyRecord.Quantity > 0 ? supplyRecord.Cost / supplyRecord.Quantity : 0).ToString("F"))</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
else
{
<div class="row">
<div class="col-12">
<div class="text-center">
<h4>@translator.Translate(userLanguage, "No supplies with quantities greater than 0 is found.")</h4>
</div>
</div>
</div>
}
</div>
<div class="modal-footer">
<span id="supplySumLabel" style="margin-right:auto;">Total: 0.00</span>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="inputCopySuppliesAttachments">
<label class="form-check-label" for="inputCopySuppliesAttachments">@translator.Translate(userLanguage, "Copy Attachments")</label>
</div>
<button type="button" class="btn btn-secondary" onclick="hideSuppliesModal()">@translator.Translate(userLanguage, "Cancel")</button>
<button type="button" class="btn btn-primary" disabled id="selectSuppliesButton" onclick="selectSupplies()">@translator.Translate(userLanguage, "Select")</button>
</div>
<script>
function recalculateTotal() {
setDebounce(getSuppliesAndQuantity);
}
function toggleQuantityFieldDisabled(e) {
var textField = getTextFieldFromCheckBox(e);
var isChecked = $(e).is(":checked");
textField.attr('disabled', !isChecked);
if (!isChecked) {
textField.removeClass("is-invalid");
}
recalculateTotal();
}
function getTextFieldFromCheckBox(elem) {
var textField = $(elem.parentElement.parentElement).find('.col-2 > input[type=text]')[0];
return $(textField);
}
function getInStockFieldFromCheckBox(elem) {
var textField = $(elem.parentElement.parentElement).find('.col-2.supplyquantity')[0];
return $(textField);
}
function getPriceFieldFromCheckBox(elem) {
var textField = $(elem.parentElement.parentElement).find('.col-2.supplyprice')[0];
return $(textField);
}
function getSuppliesAndQuantity() {
var totalSum = 0;
var hasError = false;
var selectedSupplies = $("#supplyRows :checked").map(function () {
var textField = getTextFieldFromCheckBox(this);
var inStock = getInStockFieldFromCheckBox(this);
var priceField = getPriceFieldFromCheckBox(this);
var requestedQuantity = globalParseFloat(textField.val());
var inStockQuantity = globalParseFloat(inStock.text());
var unitPrice = globalParseFloat(priceField.text());
//validation
if (isNaN(requestedQuantity) || requestedQuantity > inStockQuantity || requestedQuantity <= 0) {
textField.addClass("is-invalid");
hasError = true;
} else {
textField.removeClass("is-invalid");
}
//calculate sum.
var sum = requestedQuantity * unitPrice;
totalSum += sum;
return {
supplyId: this.value,
quantity: textField.val()
};
});
if (isNaN(totalSum) || hasError) {
$("#supplySumLabel").text(`Total: 0.00`);
} else {
totalSum = totalSum.toFixed(2);
var parsedFloat = globalFloatToString(totalSum);
$("#supplySumLabel").text(`Total: ${parsedFloat}`);
}
$("#selectSuppliesButton").attr('disabled', (hasError || selectedSupplies.toArray().length == 0));
if (!hasError) {
return {
totalSum: globalFloatToString(totalSum),
selectedSupplies: selectedSupplies.toArray()
};
} else {
return {
totalSum: 0,
selectedSupplies: []
}
}
}
</script>