Export attachments for vehicle.

This commit is contained in:
DESKTOP-T0O5CDB\DESK-555BD 2024-01-29 13:24:30 -07:00
parent f5b9072cc6
commit 8a237bb7ec
5 changed files with 239 additions and 75 deletions

View File

@ -981,6 +981,84 @@ namespace CarCareTracker.Controllers
return PartialView("_ReminderMakeUpReport", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult GetVehicleAttachments(int vehicleId, List<ImportMode> exportTabs)
{
List<GenericReportModel> attachmentData = new List<GenericReportModel>();
if (exportTabs.Contains(ImportMode.ServiceRecord)){
var records = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId).Where(x=>x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.RepairRecord))
{
var records = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.UpgradeRecord))
{
var records = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.GasRecord))
{
var records = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.TaxRecord))
{
var records = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = 0,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.OdometerRecord))
{
var records = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (attachmentData.Any())
{
attachmentData = attachmentData.OrderBy(x => x.Date).ThenBy(x => x.Odometer).ToList();
var result = _fileHelper.MakeAttachmentsExport(attachmentData);
if (string.IsNullOrWhiteSpace(result))
{
return Json(new OperationResponse { Success = false, Message = StaticHelper.GenericErrorMessage });
}
return Json(new OperationResponse { Success = true, Message = result });
} else
{
return Json(new OperationResponse { Success = false, Message = "No Attachments Found" });
}
}
[TypeFilter(typeof(CollaboratorFilter))]
public IActionResult GetVehicleHistory(int vehicleId)
{
var vehicleHistory = new VehicleHistoryViewModel();

View File

@ -1,4 +1,5 @@
using System.IO.Compression;
using CarCareTracker.Models;
using System.IO.Compression;
namespace CarCareTracker.Helper
{
@ -9,6 +10,7 @@ namespace CarCareTracker.Helper
bool DeleteFile(string currentFilePath);
string MakeBackup();
bool RestoreBackup(string fileName, bool clearExisting = false);
string MakeAttachmentsExport(List<GenericReportModel> exportData);
}
public class FileHelper : IFileHelper
{
@ -123,6 +125,30 @@ namespace CarCareTracker.Helper
return false;
}
}
public string MakeAttachmentsExport(List<GenericReportModel> exportData)
{
var folderName = Guid.NewGuid();
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
if (!Directory.Exists(tempPath))
Directory.CreateDirectory(tempPath);
int fileIndex = 0;
foreach(GenericReportModel reportModel in exportData)
{
foreach(UploadedFiles file in reportModel.Files)
{
var fileToCopy = GetFullFilePath(file.Location);
var destFileName = $"{tempPath}/{fileIndex}{Path.GetExtension(file.Location)}";
File.Copy(fileToCopy, destFileName);
fileIndex++;
}
}
var destFilePath = $"{tempPath}.zip";
ZipFile.CreateFromDirectory(tempPath, destFilePath);
//delete temp directory
Directory.Delete(tempPath, true);
var zipFileName = $"/temp/{folderName}.zip";
return zipFileName;
}
public string MakeBackup()
{
var folderName = $"db_backup_{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}";

View File

@ -11,5 +11,6 @@
public string Description { get; set; }
public string Notes { get; set; }
public decimal Cost { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
}
}

View File

@ -1,90 +1,93 @@
@model ReportViewModel
<div class="container reportTabContainer">
<div class="row hideOnPrint">
<div class="col-md-3 col-12 mt-2">
<div class="row">
<div class="col-12">
<select class="form-select" id="yearOption" onchange="yearUpdated()">
<option value="0">All Time</option>
@foreach (int year in Model.Years)
{
<option value="@year">@year</option>
}
</select>
<div class="row hideOnPrint">
<div class="col-md-3 col-12 mt-2">
<div class="row">
<div class="col-12">
<select class="form-select" id="yearOption" onchange="yearUpdated()">
<option value="0">All Time</option>
@foreach (int year in Model.Years)
{
<option value="@year">@year</option>
}
</select>
</div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="costMakeUpReportContent">
@await Html.PartialAsync("_CostMakeUpReport", Model.CostMakeUpForVehicle)
</div>
</div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="costMakeUpReportContent">
@await Html.PartialAsync("_CostMakeUpReport", Model.CostMakeUpForVehicle)
</div>
</div>
</div>
<div class="col-md-6 col-12 mt-2">
<div class="row">
<div class="col-md-1 d-sm-none d-md-block"></div>
<div class="col-12 col-md-10 reportsCheckBoxContainer">
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="serviceExpenseCheck" value="1" checked>
<label class="form-check-label" for="serviceExpenseCheck">Service</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="repairExpenseCheck" value="2" checked>
<label class="form-check-label" for="repairExpenseCheck">Repairs</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
<label class="form-check-label" for="upgradeExpenseCheck">Upgrades</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="gasExpenseCheck" value="4" checked>
<label class="form-check-label" for="gasExpenseCheck">Gas</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="taxExpenseCheck" value="5" checked>
<label class="form-check-label" for="taxExpenseCheck">Tax</label>
</div>
</div>
<div class="col-md-6 col-12 mt-2">
<div class="row">
<div class="col-md-1 d-sm-none d-md-block"></div>
<div class="col-12 col-md-10 reportsCheckBoxContainer">
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="serviceExpenseCheck" value="1" checked>
<label class="form-check-label" for="serviceExpenseCheck">Service</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="repairExpenseCheck" value="2" checked>
<label class="form-check-label" for="repairExpenseCheck">Repairs</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="upgradeExpenseCheck" value="3" checked>
<label class="form-check-label" for="upgradeExpenseCheck">Upgrades</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="gasExpenseCheck" value="4" checked>
<label class="form-check-label" for="gasExpenseCheck">Fuel</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" onChange="updateCheck()" type="checkbox" id="taxExpenseCheck" value="5" checked>
<label class="form-check-label" for="taxExpenseCheck">Taxes</label>
</div>
</div>
<div class="col-md-1 d-sm-none d-md-block"></div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="gasCostByMonthReportContent">
@await Html.PartialAsync("_GasCostByMonthReport", Model.CostForVehicleByMonth)
</div>
</div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="gasCostByMonthReportContent">
@await Html.PartialAsync("_GasCostByMonthReport", Model.CostForVehicleByMonth)
<div class="col-md-3 col-12 mt-2">
<div class="row">
<div class="col-12">
<select class="form-select" onchange="updateReminderPie()" id="reminderOption">
<option value="0">As of Today</option>
<option value="30">+30 Days</option>
<option value="60">+60 Days</option>
<option value="90">+90 Days</option>
</select>
</div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="reminderMakeUpReportContent">
@await Html.PartialAsync("_ReminderMakeUpReport", Model.ReminderMakeUpForVehicle)
</div>
</div>
</div>
</div>
<div class="col-md-3 col-12 mt-2">
<div class="row">
<div class="col-12">
<select class="form-select" onchange="updateReminderPie()" id="reminderOption">
<option value="0">As of Today</option>
<option value="30">+30 Days</option>
<option value="60">+60 Days</option>
<option value="90">+90 Days</option>
</select>
<hr />
<div class="row hideOnPrint">
<div class="col-md-3 col-12 chartContainer" id="collaboratorContent">
@await Html.PartialAsync("_Collaborators", Model.Collaborators)
</div>
<div class="col-md-6 col-12 chartContainer">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="monthFuelMileageReportContent">
@await Html.PartialAsync("_MPGByMonthReport", Model.FuelMileageForVehicleByMonth)
</div>
</div>
<div class="row">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="reminderMakeUpReportContent">
@await Html.PartialAsync("_ReminderMakeUpReport", Model.ReminderMakeUpForVehicle)
<div class="col-md-3 col-12 chartContainer">
<div class="d-grid">
<button onclick="generateVehicleHistoryReport()" class="btn btn-secondary btn-md mt-1 mb-1">Vehicle Maintenance Report<i class="bi ms-2 bi-box-arrow-in-up-right"></i></button>
</div>
<div class="d-grid">
<button onclick="exportAttachments()" class="btn btn-secondary btn-md mt-1 mb-1">Export Attachments<i class="bi ms-2 bi-box-arrow-in-up-right"></i></button>
</div>
</div>
</div>
</div>
<hr />
<div class="row hideOnPrint">
<div class="col-md-3 col-12 chartContainer" id="collaboratorContent">
@await Html.PartialAsync("_Collaborators", Model.Collaborators)
</div>
<div class="col-md-6 col-12 chartContainer">
<div class="d-flex justify-content-center align-items-center col-12 chartContainer" id="monthFuelMileageReportContent">
@await Html.PartialAsync("_MPGByMonthReport", Model.FuelMileageForVehicleByMonth)
</div>
</div>
<div class="col-md-3 col-12 chartContainer">
<div class="d-flex justify-content-center">
<button onclick="generateVehicleHistoryReport()" class="btn btn-secondary btn-md mt-1 mb-1">Vehicle Maintenance Report<i class="bi ms-2 bi-box-arrow-in-up-right"></i></button>
</div>
</div>
</div>
</div>
<div id="vehicleHistoryReport" class="showOnPrint"></div>

View File

@ -74,4 +74,60 @@ function refreshCollaborators() {
$.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>
`,
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);
}
})
}
});
}