revert and enhance.
This commit is contained in:
@@ -1140,11 +1140,7 @@ namespace CarCareTracker.Controllers
|
||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords);
|
||||
var minMileage = _vehicleLogic.GetMinMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords);
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
var totalDistanceTraveled = maxMileage - minMileage;
|
||||
var viewModel = new ReportViewModel();
|
||||
//get totalCostMakeUp
|
||||
viewModel.CostMakeUpForVehicle = new CostMakeUpForVehicle
|
||||
@@ -1153,9 +1149,7 @@ namespace CarCareTracker.Controllers
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost),
|
||||
TotalDistance = totalDistanceTraveled,
|
||||
DistanceUnit = vehicleData.UseHours ? "Per Hour" : userConfig.UseMPG ? "Per Mile" : "Per Kilometer"
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost)
|
||||
};
|
||||
//get costbymonth
|
||||
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
|
||||
@@ -1253,6 +1247,33 @@ namespace CarCareTracker.Controllers
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
var collisionRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
|
||||
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||
if (year != default)
|
||||
{
|
||||
serviceRecords.RemoveAll(x => x.Date.Year != year);
|
||||
gasRecords.RemoveAll(x => x.Date.Year != year);
|
||||
collisionRecords.RemoveAll(x => x.Date.Year != year);
|
||||
taxRecords.RemoveAll(x => x.Date.Year != year);
|
||||
upgradeRecords.RemoveAll(x => x.Date.Year != year);
|
||||
}
|
||||
var viewModel = new CostMakeUpForVehicle
|
||||
{
|
||||
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
CollisionRecordSum = collisionRecords.Sum(x => x.Cost),
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost)
|
||||
};
|
||||
return PartialView("_CostMakeUpReport", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
[HttpGet]
|
||||
public IActionResult GetCostTableForVehicle(int vehicleId, int year = 0)
|
||||
{
|
||||
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||
@@ -1271,10 +1292,11 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
var maxMileage = _vehicleLogic.GetMaxMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords);
|
||||
var minMileage = _vehicleLogic.GetMinMileage(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords);
|
||||
var totalDistanceTraveled = maxMileage - minMileage;
|
||||
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
var viewModel = new CostMakeUpForVehicle
|
||||
var totalDistanceTraveled = maxMileage - minMileage;
|
||||
var totalMonths = _vehicleLogic.GetNumberOfMonths(serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords, taxRecords);
|
||||
var viewModel = new CostTableForVehicle
|
||||
{
|
||||
ServiceRecordSum = serviceRecords.Sum(x => x.Cost),
|
||||
GasRecordSum = gasRecords.Sum(x => x.Cost),
|
||||
@@ -1282,9 +1304,10 @@ namespace CarCareTracker.Controllers
|
||||
TaxRecordSum = taxRecords.Sum(x => x.Cost),
|
||||
UpgradeRecordSum = upgradeRecords.Sum(x => x.Cost),
|
||||
TotalDistance = totalDistanceTraveled,
|
||||
DistanceUnit = vehicleData.UseHours ? "Per Hour" : userConfig.UseMPG ? "Per Mile" : "Per Kilometer"
|
||||
DistanceUnit = vehicleData.UseHours ? "Per Hour" : userConfig.UseMPG ? "Per Mile" : "Per Kilometer",
|
||||
NumberOfMonths = totalMonths
|
||||
};
|
||||
return PartialView("_CostMakeUpReport", viewModel);
|
||||
return PartialView("_CostTableReport", viewModel);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd)
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace CarCareTracker.Logic
|
||||
int GetMaxMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords);
|
||||
int GetMinMileage(int vehicleId);
|
||||
int GetMinMileage(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords);
|
||||
int GetNumberOfMonths(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords, List<TaxRecord> taxRecords);
|
||||
bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId);
|
||||
}
|
||||
public class VehicleLogic: IVehicleLogic
|
||||
@@ -153,6 +154,18 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
return numbersArray.Any() ? numbersArray.Min() : 0;
|
||||
}
|
||||
public int GetNumberOfMonths(List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords, List<TaxRecord> taxRecords)
|
||||
{
|
||||
var dateArray = new List<string>();
|
||||
dateArray.AddRange(serviceRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
dateArray.AddRange(repairRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
dateArray.AddRange(gasRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
dateArray.AddRange(upgradeRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
dateArray.AddRange(odometerRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
dateArray.AddRange(taxRecords.Select(x => x.Date.ToString("MM/yyyy")));
|
||||
var uniqueMonths = dateArray.Distinct();
|
||||
return uniqueMonths.Count();
|
||||
}
|
||||
public bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId)
|
||||
{
|
||||
var currentMileage = GetMaxMileage(vehicleId);
|
||||
|
||||
@@ -2,24 +2,10 @@
|
||||
{
|
||||
public class CostMakeUpForVehicle
|
||||
{
|
||||
public string DistanceUnit { get; set; } = "Per Mile";
|
||||
public int TotalDistance { get; set; }
|
||||
public decimal ServiceRecordSum { get; set; }
|
||||
public decimal GasRecordSum { get; set; }
|
||||
public decimal TaxRecordSum { get; set; }
|
||||
public decimal CollisionRecordSum { get; set; }
|
||||
public decimal UpgradeRecordSum { get; set; }
|
||||
public decimal ServiceRecordPerMile { get { return TotalDistance != default ? ServiceRecordSum / TotalDistance : 0; } }
|
||||
public decimal GasRecordPerMile { get { return TotalDistance != default ? GasRecordSum / TotalDistance : 0; } }
|
||||
public decimal CollisionRecordPerMile { get { return TotalDistance != default ? CollisionRecordSum / TotalDistance : 0; } }
|
||||
public decimal UpgradeRecordPerMile { get { return TotalDistance != default ? UpgradeRecordSum / TotalDistance : 0; } }
|
||||
public decimal ServiceRecordPerMonth { get { return ServiceRecordSum / 12; } }
|
||||
public decimal GasRecordPerMonth { get { return GasRecordSum / 12; } }
|
||||
public decimal CollisionRecordPerMonth { get { return CollisionRecordSum / 12; } }
|
||||
public decimal UpgradeRecordPerMonth { get { return UpgradeRecordSum / 12; } }
|
||||
public decimal TaxRecordPerMonth { get { return TaxRecordSum / 12; } }
|
||||
public decimal TotalPerMonth { get { return ServiceRecordPerMonth + CollisionRecordPerMonth + UpgradeRecordPerMonth + GasRecordPerMonth + TaxRecordPerMonth; } }
|
||||
public decimal TotalPerMile { get { return ServiceRecordPerMile + CollisionRecordPerMile + UpgradeRecordPerMile + GasRecordPerMile; } }
|
||||
public decimal TotalCost { get { return ServiceRecordSum + CollisionRecordSum + UpgradeRecordSum + GasRecordSum + TaxRecordSum; } }
|
||||
}
|
||||
}
|
||||
|
||||
26
Models/Report/CostTableForVehicle.cs
Normal file
26
Models/Report/CostTableForVehicle.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class CostTableForVehicle
|
||||
{
|
||||
public string DistanceUnit { get; set; } = "Per Mile";
|
||||
public int TotalDistance { get; set; }
|
||||
public int NumberOfMonths { get; set; }
|
||||
public decimal ServiceRecordSum { get; set; }
|
||||
public decimal GasRecordSum { get; set; }
|
||||
public decimal TaxRecordSum { get; set; }
|
||||
public decimal CollisionRecordSum { get; set; }
|
||||
public decimal UpgradeRecordSum { get; set; }
|
||||
public decimal ServiceRecordPerMile { get { return TotalDistance != default ? ServiceRecordSum / TotalDistance : 0; } }
|
||||
public decimal GasRecordPerMile { get { return TotalDistance != default ? GasRecordSum / TotalDistance : 0; } }
|
||||
public decimal CollisionRecordPerMile { get { return TotalDistance != default ? CollisionRecordSum / TotalDistance : 0; } }
|
||||
public decimal UpgradeRecordPerMile { get { return TotalDistance != default ? UpgradeRecordSum / TotalDistance : 0; } }
|
||||
public decimal ServiceRecordPerMonth { get { return NumberOfMonths != default ? ServiceRecordSum / NumberOfMonths : 0; } }
|
||||
public decimal GasRecordPerMonth { get { return NumberOfMonths != default ? GasRecordSum / NumberOfMonths : 0; } }
|
||||
public decimal CollisionRecordPerMonth { get { return NumberOfMonths != default ? CollisionRecordSum / NumberOfMonths : 0; } }
|
||||
public decimal UpgradeRecordPerMonth { get { return NumberOfMonths != default ? UpgradeRecordSum / NumberOfMonths : 0; } }
|
||||
public decimal TaxRecordPerMonth { get { return NumberOfMonths != default ? TaxRecordSum / NumberOfMonths : 0; } }
|
||||
public decimal TotalPerMonth { get { return ServiceRecordPerMonth + CollisionRecordPerMonth + UpgradeRecordPerMonth + GasRecordPerMonth + TaxRecordPerMonth; } }
|
||||
public decimal TotalPerMile { get { return ServiceRecordPerMile + CollisionRecordPerMile + UpgradeRecordPerMile + GasRecordPerMile; } }
|
||||
public decimal TotalCost { get { return ServiceRecordSum + CollisionRecordSum + UpgradeRecordSum + GasRecordSum + TaxRecordSum; } }
|
||||
}
|
||||
}
|
||||
@@ -8,66 +8,6 @@
|
||||
@model CostMakeUpForVehicle
|
||||
@if (Model.CollisionRecordSum + Model.ServiceRecordSum + Model.GasRecordSum + Model.TaxRecordSum + Model.UpgradeRecordSum > 0)
|
||||
{
|
||||
<div class="d-none" id="vehicleDataTableModalContentClone">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@(translator.Translate(userLanguage, "Vehicle Cost Breakdown"))</h5>
|
||||
<button type="button" class="btn-close" onclick="hideDataTable()" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Type")</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Monthly Average")</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, Model.DistanceUnit)</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Service Records")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Repairs")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Upgrades")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Fuel")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Taxes")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TaxRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">---</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TaxRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalCost.ToString("C2")</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="pie-chart"></canvas>
|
||||
<script>
|
||||
renderChart();
|
||||
|
||||
77
Views/Vehicle/_CostTableReport.cshtml
Normal file
77
Views/Vehicle/_CostTableReport.cshtml
Normal file
@@ -0,0 +1,77 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
@model CostTableForVehicle
|
||||
@if (Model.CollisionRecordSum + Model.ServiceRecordSum + Model.GasRecordSum + Model.TaxRecordSum + Model.UpgradeRecordSum > 0)
|
||||
{
|
||||
<div>
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@(translator.Translate(userLanguage, "Vehicle Cost Breakdown"))</h5>
|
||||
<button type="button" class="btn-close" onclick="hideDataTable()" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Type")</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Monthly Average")</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, Model.DistanceUnit)</th>
|
||||
<th scope="col" class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Service Records")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.ServiceRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Repairs")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.CollisionRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Upgrades")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.UpgradeRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Fuel")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.GasRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Taxes")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TaxRecordPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">---</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TaxRecordSum.ToString("C2")</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<td class="col-3 flex-grow-1">@translator.Translate(userLanguage, "Total")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalPerMonth.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalPerMile.ToString("C2")</td>
|
||||
<td class="col-3 flex-grow-1">@Model.TotalCost.ToString("C2")</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-center">
|
||||
<h4>@translator.Translate(userLanguage, "No data found or all records have zero sums, insert records with non-zero sums to see visualizations here.")</h4>
|
||||
</div>
|
||||
}
|
||||
@@ -181,8 +181,12 @@ function exportAttachments() {
|
||||
});
|
||||
}
|
||||
function showDataTable() {
|
||||
$("#vehicleDataTableModalContent").html($("#vehicleDataTableModalContentClone").html());
|
||||
$("#vehicleDataTableModal").modal('show');
|
||||
var vehicleId = GetVehicleId().vehicleId;
|
||||
var year = getYear();
|
||||
$.get(`/Vehicle/GetCostTableForVehicle?vehicleId=${vehicleId}`, { year: year }, function (data) {
|
||||
$("#vehicleDataTableModalContent").html(data);
|
||||
$("#vehicleDataTableModal").modal('show');
|
||||
});
|
||||
}
|
||||
function hideDataTable() {
|
||||
$("#vehicleDataTableModal").modal('hide');
|
||||
|
||||
Reference in New Issue
Block a user