Compare commits

..

1 Commits

Author SHA1 Message Date
DESKTOP-T0O5CDB\DESK-555BD
7bc47363fd backend for torque integration. 2024-01-24 14:15:40 -07:00
302 changed files with 15009 additions and 25341 deletions

8
.env
View File

@@ -2,11 +2,7 @@ LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
MailConfig__EmailServer=""
MailConfig__EmailFrom=""
MailConfig__UseSSL="false"
MailConfig__Port=587
MailConfig__Username=""
MailConfig__Password=""
LOGGING__LOGLEVEL__DEFAULT=Error
# This file is provided as a GUIDELINE ONLY
# Use the LubeLogger Configurator to configure your environment variables
# https://lubelogger.com/configure
MailConfig__Password=""

View File

@@ -1,48 +0,0 @@
# Contributing Guidelines
## Asking Questions
Before submitting a question, please check the [Troubleshooting Guide](https://docs.lubelogger.com/Installation/Troubleshooting) and search through existing issues.
Ideally, the Issues tab should only consist of bug reports and feature requests instead of debugging your LubeLogger installation.
## Feature Requests
Feature Requests are cool, but we do want to avoid bloat and scope/feature creep.
LubeLogger is a Vehicle Maintenance and Fuel Mileage Tracker.
It is not and should not be used for the following:
- Project Management Software(e.g.: Jira)
- Budget Management(e.g: YNAB/Actual)
- Inventory Management
Before submitting a feature request, please consider the following:
- Will this feature benefit more than just a niche subset of users
- Will this feature result in scope creep
- Has this feature already been requested/exist
## Bug Reports
Please fill out the issue template for bug reports.
## Security Vulnerabilities
Contact us via [Email](mailto:hargatasoftworks@gmail.com)
## Submitting Pull Requests
Pull Requests are welcome, but please consider the following:
CI/CD, Bugs, Tech-Debt Related PRs:
- Make sure changes are not breaking.
- If any dependencies are added, they must be cross-platform compatible.
- Please test changes thoroughly.
Feature Related PRs:
- Have you requested this feature in the Issues tab
- Will this feature benefit more than just a niche subset of users
- Will this feature result in scope creep
- Do these changes fix a root cause or is it simply a workaround
Ideally, you should first submit a feature request in the Issues tab before submitting a PR just in case it's something we are already working on.
Note the following:
We(the maintainers) are not responsible for cleaning up, testing, or fixing your changes.
If your changes doesn't have a wide-ranging use-case, has not been thoroughly tested, or cannot be easily maintained, we won't merge your PR.

14
.github/FUNDING.yml vendored
View File

@@ -1,14 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: lubelogger
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -1,30 +0,0 @@
---
name: Bug report
about: Report a bug
title: ''
labels: ''
assignees: ''
---
**Checklist**
Please make sure you have performed the following steps before opening a new bug ticket, change `[ ]` to `[x]` to mark it as done
- [ ] I have read and tried the steps outlined in the [Troubleshooting Guide](https://docs.lubelogger.com/Installation/Troubleshooting)
- [ ] I have searched through existing issues.
**Description**
<!-- Describe the bug below this line -->
**Platform**
- [ ] Docker Image
- [ ] Windows Standalone Executable
**Browser Console Errors(F12)**
<!-- Attach a screenshot or codeblock containing the browser console error -->
**App/Container Console Error**
<!-- Attach a screenshot or codeblock containing the app/container console error -->
**Screenshots(optional)**
<!-- Attach a screenshot describing the bug -->

View File

@@ -1,51 +0,0 @@
name: Build and Push Image to Dockerhub and GHCR
on:
push:
branches: ["main"]
release:
types: ["published"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: "${{ secrets.DH_USER }}"
password: "${{ secrets.DH_PASS }}"
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "hargata"
password: "${{ secrets.GHCR_PAT }}"
- name: Docker Metadata
id: meta
uses: docker/metadata-action@v5
with:
context: workflow
images: |
hargata/lubelogger
ghcr.io/hargata/lubelogger
tags: |
type=edge,branch=main
type=ref,event=tag
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -0,0 +1,30 @@
name: Docker Image To Docker Hub
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: "${{ secrets.DH_USER }}"
password: "${{ secrets.DH_PASS }}"
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
hargata/lubelogger:latest

31
.github/workflows/ghcr-docker-image.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Docker Image To GHCR
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "hargata"
password: "${{ secrets.GHCR_PAT }}"
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/hargata/lubelogger:latest

6
.gitignore vendored
View File

@@ -7,9 +7,3 @@ data/cartracker.db
wwwroot/documents/
wwwroot/temp/
wwwroot/imports/
wwwroot/translations/
config/userConfig.json
CarCareTracker.csproj.user
Properties/launchSettings.json
data/cartracker-log.db
data/widgets.html

View File

@@ -13,9 +13,6 @@
<ItemGroup>
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="LiteDB" Version="5.0.17" />
<PackageReference Include="MailKit" Version="4.8.0" />
<PackageReference Include="Npgsql" Version="8.0.5" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<View_SelectedScaffolderID>RazorViewEmptyScaffolder</View_SelectedScaffolderID>
<View_SelectedScaffolderCategoryPath>root/Common/MVC/View</View_SelectedScaffolderCategoryPath>
</PropertyGroup>
</Project>

View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarCareTracker", "CarCareTracker.csproj", "{0DB85611-6555-4127-A66E-DADD25A16526}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CarCareTracker", "CarCareTracker.csproj", "{0DB85611-6555-4127-A66E-DADD25A16526}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,8 @@ using CarCareTracker.Logic;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using System.Net.Mail;
namespace CarCareTracker.Controllers
{
@@ -22,46 +24,15 @@ namespace CarCareTracker.Controllers
{
var viewModel = new AdminViewModel
{
Users = _loginLogic.GetAllUsers().OrderBy(x=>x.Id).ToList(),
Users = _loginLogic.GetAllUsers(),
Tokens = _loginLogic.GetAllTokens()
};
return View(viewModel);
}
public IActionResult GetTokenPartialView()
{
var viewModel = _loginLogic.GetAllTokens();
return PartialView("_Tokens", viewModel);
}
public IActionResult GetUserPartialView()
{
var viewModel = _loginLogic.GetAllUsers().OrderBy(x => x.Id).ToList();
return PartialView("_Users", viewModel);
}
public IActionResult GenerateNewToken(string emailAddress, bool autoNotify)
{
if (emailAddress.Contains(","))
{
string[] emailAddresses = emailAddress.Split(',');
foreach(string emailAdd in emailAddresses)
{
var trimmedEmail = emailAdd.Trim();
if (!string.IsNullOrWhiteSpace(trimmedEmail))
{
var result = _loginLogic.GenerateUserToken(emailAdd.Trim(), autoNotify);
if (!result.Success)
{
//if fail, return prematurely
return Json(result);
}
}
}
var successResponse = OperationResponse.Succeed("Token Generated!");
return Json(successResponse);
} else
{
var result = _loginLogic.GenerateUserToken(emailAddress, autoNotify);
return Json(result);
}
var result = _loginLogic.GenerateUserToken(emailAddress, autoNotify);
return Json(result);
}
[HttpPost]
public IActionResult DeleteToken(int tokenId)

View File

@@ -1,5 +1,12 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using LiteDB;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
using System.Drawing;
using System.Linq.Expressions;
using Microsoft.Extensions.Logging;
using CarCareTracker.Helper;
using Microsoft.AspNetCore.Authorization;
@@ -26,26 +33,6 @@ namespace CarCareTracker.Controllers
return Json(fileName);
}
[HttpPost]
public IActionResult HandleTranslationFileUpload(IFormFile file)
{
var originalFileName = Path.GetFileNameWithoutExtension(file.FileName);
if (originalFileName == "en_US")
{
return Json(OperationResponse.Failed("The translation file name en_US is reserved."));
}
var fileName = UploadFile(file);
//move file from temp to translation folder.
var uploadedFilePath = _fileHelper.MoveFileFromTemp(fileName, "translations/");
//rename uploaded file so that it preserves original name.
if (!string.IsNullOrWhiteSpace(uploadedFilePath))
{
var result = _fileHelper.RenameFile(uploadedFilePath, originalFileName);
return Json(OperationResponse.Conditional(result));
}
return Json(OperationResponse.Failed());
}
[HttpPost]
public IActionResult HandleMultipleFileUpload(List<IFormFile> file)
{
@@ -57,7 +44,7 @@ namespace CarCareTracker.Controllers
}
return Json(uploadedFiles);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult DeleteFiles(string fileLocation)
{
@@ -92,18 +79,5 @@ namespace CarCareTracker.Controllers
}
return Path.Combine("/", uploadDirectory, fileName);
}
public IActionResult UploadCoordinates(List<string> coordinates)
{
string uploadDirectory = "temp/";
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
string fileName = Guid.NewGuid() + ".csv";
string filePath = Path.Combine(uploadPath, fileName);
string fileData = string.Join("\r\n", coordinates);
System.IO.File.WriteAllText(filePath, fileData);
var uploadedFile = new UploadedFiles { Name = "coordinates.csv", Location = Path.Combine("/", uploadDirectory, fileName) };
return Json(uploadedFile);
}
}
}

View File

@@ -15,37 +15,17 @@ namespace CarCareTracker.Controllers
private readonly ILogger<HomeController> _logger;
private readonly IVehicleDataAccess _dataAccess;
private readonly IUserLogic _userLogic;
private readonly ILoginLogic _loginLogic;
private readonly IVehicleLogic _vehicleLogic;
private readonly IFileHelper _fileHelper;
private readonly IConfigHelper _config;
private readonly IExtraFieldDataAccess _extraFieldDataAccess;
private readonly IReminderRecordDataAccess _reminderRecordDataAccess;
private readonly IReminderHelper _reminderHelper;
private readonly ITranslationHelper _translationHelper;
public HomeController(ILogger<HomeController> logger,
public HomeController(ILogger<HomeController> logger,
IVehicleDataAccess dataAccess,
IUserLogic userLogic,
ILoginLogic loginLogic,
IVehicleLogic vehicleLogic,
IConfigHelper configuration,
IFileHelper fileHelper,
IExtraFieldDataAccess extraFieldDataAccess,
IReminderRecordDataAccess reminderRecordDataAccess,
IReminderHelper reminderHelper,
ITranslationHelper translationHelper)
IConfigHelper configuration)
{
_logger = logger;
_dataAccess = dataAccess;
_config = configuration;
_userLogic = userLogic;
_fileHelper = fileHelper;
_extraFieldDataAccess = extraFieldDataAccess;
_reminderRecordDataAccess = reminderRecordDataAccess;
_reminderHelper = reminderHelper;
_loginLogic = loginLogic;
_vehicleLogic = vehicleLogic;
_translationHelper = translationHelper;
}
private int GetUserID()
{
@@ -55,59 +35,6 @@ namespace CarCareTracker.Controllers
{
return View(model: tab);
}
[Route("/kiosk")]
public IActionResult Kiosk(string exclusions, KioskMode kioskMode = KioskMode.Vehicle)
{
try {
var viewModel = new KioskViewModel
{
Exclusions = string.IsNullOrWhiteSpace(exclusions) ? new List<int>() : exclusions.Split(',').Select(x => int.Parse(x)).ToList(),
KioskMode = kioskMode
};
return View(viewModel);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return View(new KioskViewModel());
}
}
[HttpPost]
public IActionResult KioskContent(KioskViewModel kioskParameters)
{
var vehiclesStored = _dataAccess.GetVehicles();
if (!User.IsInRole(nameof(UserData.IsRootUser)))
{
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
}
vehiclesStored.RemoveAll(x => kioskParameters.Exclusions.Contains(x.Id));
var userConfig = _config.GetUserConfig(User);
if (userConfig.HideSoldVehicles)
{
vehiclesStored.RemoveAll(x => !string.IsNullOrWhiteSpace(x.SoldDate));
}
switch (kioskParameters.KioskMode)
{
case KioskMode.Vehicle:
{
var kioskResult = _vehicleLogic.GetVehicleInfo(vehiclesStored);
return PartialView("_Kiosk", kioskResult);
}
case KioskMode.Plan:
{
var kioskResult = _vehicleLogic.GetPlans(vehiclesStored, true);
return PartialView("_KioskPlan", kioskResult);
}
break;
case KioskMode.Reminder:
{
var kioskResult = _vehicleLogic.GetReminders(vehiclesStored, false);
return PartialView("_KioskReminder", kioskResult);
}
}
var result = _vehicleLogic.GetVehicleInfo(vehiclesStored);
return PartialView("_Kiosk", result);
}
public IActionResult Garage()
{
var vehiclesStored = _dataAccess.GetVehicles();
@@ -115,447 +42,24 @@ namespace CarCareTracker.Controllers
{
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
}
var vehicleViewModels = vehiclesStored.Select(x =>
{
var vehicleVM = new VehicleViewModel
{
Id = x.Id,
ImageLocation = x.ImageLocation,
Year = x.Year,
Make = x.Make,
Model = x.Model,
LicensePlate = x.LicensePlate,
SoldDate = x.SoldDate,
IsElectric = x.IsElectric,
IsDiesel = x.IsDiesel,
UseHours = x.UseHours,
OdometerOptional = x.OdometerOptional,
ExtraFields = x.ExtraFields,
Tags = x.Tags,
DashboardMetrics = x.DashboardMetrics,
VehicleIdentifier = x.VehicleIdentifier
};
//dashboard metrics
if (x.DashboardMetrics.Any())
{
var vehicleRecords = _vehicleLogic.GetVehicleRecords(x.Id);
var userConfig = _config.GetUserConfig(User);
var distanceUnit = x.UseHours ? "h" : userConfig.UseMPG ? "mi." : "km";
if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.Default))
{
vehicleVM.LastReportedMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
vehicleVM.HasReminders = _vehicleLogic.GetVehicleHasUrgentOrPastDueReminders(x.Id, vehicleVM.LastReportedMileage);
}
if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.CostPerMile))
{
var vehicleTotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords);
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
var totalDistance = maxMileage - minMileage;
vehicleVM.CostPerMile = totalDistance != default ? vehicleTotalCost / totalDistance : 0.00M;
vehicleVM.DistanceUnit = distanceUnit;
}
if (vehicleVM.DashboardMetrics.Contains(DashboardMetric.TotalCost))
{
vehicleVM.TotalCost = _vehicleLogic.GetVehicleTotalCost(vehicleRecords);
}
}
return vehicleVM;
}).ToList();
return PartialView("_GarageDisplay", vehicleViewModels);
return PartialView("_GarageDisplay", vehiclesStored);
}
public IActionResult Calendar()
{
var vehiclesStored = _dataAccess.GetVehicles();
if (!User.IsInRole(nameof(UserData.IsRootUser)))
{
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
}
var reminders = _vehicleLogic.GetReminders(vehiclesStored, true);
return PartialView("_Calendar", reminders);
}
public IActionResult ViewCalendarReminder(int reminderId)
{
var reminder = _reminderRecordDataAccess.GetReminderRecordById(reminderId);
var reminderUrgency = _reminderHelper.GetReminderRecordViewModels(new List<ReminderRecord> { reminder }, 0, DateTime.Now).FirstOrDefault();
return PartialView("_ReminderRecordCalendarModal", reminderUrgency);
}
public async Task<IActionResult> Settings()
public IActionResult Settings()
{
var userConfig = _config.GetUserConfig(User);
var languages = _fileHelper.GetLanguages();
var viewModel = new SettingsViewModel
{
UserConfig = userConfig,
UILanguages = languages
};
return PartialView("_Settings", viewModel);
}
public async Task<IActionResult> Sponsors()
{
try
{
var httpClient = new HttpClient();
var sponsorsData = await httpClient.GetFromJsonAsync<Sponsors>(StaticHelper.SponsorsPath) ?? new Sponsors();
return PartialView("_Sponsors", sponsorsData);
}
catch (Exception ex)
{
_logger.LogError($"Unable to retrieve sponsors: {ex.Message}");
return PartialView("_Sponsors", new Sponsors());
}
return PartialView("_Settings", userConfig);
}
[HttpPost]
public IActionResult WriteToSettings(UserConfig userConfig)
{
//retrieve existing userConfig.
var existingConfig = _config.GetUserConfig(User);
//copy over stuff that persists
userConfig.UserColumnPreferences = existingConfig.UserColumnPreferences;
userConfig.ReminderUrgencyConfig = existingConfig.ReminderUrgencyConfig;
var result = _config.SaveUserConfig(User, userConfig);
return Json(result);
}
[HttpPost]
public IActionResult SaveReminderUrgencyThreshold(ReminderUrgencyConfig reminderUrgencyConfig)
public IActionResult Privacy()
{
//retrieve existing userConfig.
var existingConfig = _config.GetUserConfig(User);
existingConfig.ReminderUrgencyConfig = reminderUrgencyConfig;
var result = _config.SaveUserConfig(User, existingConfig);
return Json(result);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
public IActionResult GetExtraFieldsModal(int importMode = 0)
{
var recordExtraFields = _extraFieldDataAccess.GetExtraFieldsById(importMode);
if (recordExtraFields.Id != importMode)
{
recordExtraFields.Id = importMode;
}
return PartialView("_ExtraFields", recordExtraFields);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
public IActionResult UpdateExtraFields(RecordExtraField record)
{
try
{
var result = _extraFieldDataAccess.SaveExtraFields(record);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
var recordExtraFields = _extraFieldDataAccess.GetExtraFieldsById(record.Id);
return PartialView("_ExtraFields", recordExtraFields);
}
[HttpPost]
public IActionResult GenerateTokenForUser()
{
try
{
//get current user email address.
var emailAddress = User.FindFirstValue(ClaimTypes.Email);
if (!string.IsNullOrWhiteSpace(emailAddress))
{
var result = _loginLogic.GenerateTokenForEmailAddress(emailAddress, false);
return Json(result);
}
return Json(false);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(false);
}
}
[HttpPost]
public IActionResult UpdateUserAccount(LoginModel userAccount)
{
try
{
var userId = GetUserID();
if (userId > 0)
{
var result = _loginLogic.UpdateUserDetails(userId, userAccount);
return Json(result);
}
return Json(OperationResponse.Failed());
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(OperationResponse.Failed());
}
}
[HttpGet]
public IActionResult GetUserAccountInformationModal()
{
var emailAddress = User.FindFirstValue(ClaimTypes.Email);
var userName = User.Identity.Name;
return PartialView("_AccountModal", new UserData() { EmailAddress = emailAddress, UserName = userName });
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public IActionResult GetRootAccountInformationModal()
{
var userName = User.Identity.Name;
return PartialView("_RootAccountModal", new UserData() { UserName = userName });
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public IActionResult GetTranslatorEditor(string userLanguage)
{
var translationData = _translationHelper.GetTranslations(userLanguage);
return PartialView("_TranslationEditor", translationData);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult SaveTranslation(string userLanguage, Dictionary<string, string> translationData)
{
var result = _translationHelper.SaveTranslation(userLanguage, translationData);
return Json(result);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult ExportTranslation(Dictionary<string, string> translationData)
{
var result = _translationHelper.ExportTranslation(translationData);
return Json(result);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public async Task<IActionResult> GetAvailableTranslations()
{
try
{
var httpClient = new HttpClient();
var translations = await httpClient.GetFromJsonAsync<Translations>(StaticHelper.TranslationDirectoryPath) ?? new Translations();
return PartialView("_Translations", translations);
}
catch (Exception ex)
{
_logger.LogError($"Unable to retrieve translations: {ex.Message}");
return PartialView("_Translations", new Translations());
}
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public async Task<IActionResult> DownloadTranslation(string continent, string name)
{
try
{
var httpClient = new HttpClient();
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath(continent, name)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(name, translationData);
if (!result.Success)
{
return Json(false);
}
}
else
{
_logger.LogError($"Unable to download translation: {name}");
return Json(false);
}
return Json(true);
}
catch (Exception ex)
{
_logger.LogError($"Unable to download translation: {ex.Message}");
return Json(false);
}
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public async Task<IActionResult> DownloadAllTranslations()
{
try
{
var httpClient = new HttpClient();
var translations = await httpClient.GetFromJsonAsync<Translations>(StaticHelper.TranslationDirectoryPath) ?? new Translations();
int translationsDownloaded = 0;
foreach (string translation in translations.Asia)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("Asia", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
foreach (string translation in translations.Africa)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("Africa", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
foreach (string translation in translations.Europe)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("Europe", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
foreach (string translation in translations.NorthAmerica)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("NorthAmerica", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
foreach (string translation in translations.SouthAmerica)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("SouthAmerica", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
foreach (string translation in translations.Oceania)
{
try
{
var translationData = await httpClient.GetFromJsonAsync<Dictionary<string, string>>(StaticHelper.GetTranslationDownloadPath("Oceania", translation)) ?? new Dictionary<string, string>();
if (translationData.Any())
{
var result = _translationHelper.SaveTranslation(translation, translationData);
if (result.Success)
{
translationsDownloaded++;
};
}
}
catch (Exception ex)
{
_logger.LogError($"Error Downloading Translation {translation}: {ex.Message} ");
}
}
if (translationsDownloaded > 0)
{
return Json(OperationResponse.Succeed($"{translationsDownloaded} Translations Downloaded"));
} else
{
return Json(OperationResponse.Failed("No Translations Downloaded"));
}
}
catch (Exception ex)
{
_logger.LogError($"Unable to retrieve translations: {ex.Message}");
return Json(OperationResponse.Failed());
}
}
public ActionResult GetVehicleSelector(int vehicleId)
{
var vehiclesStored = _dataAccess.GetVehicles();
if (!User.IsInRole(nameof(UserData.IsRootUser)))
{
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
}
if (vehicleId != default)
{
vehiclesStored.RemoveAll(x => x.Id == vehicleId);
}
var userConfig = _config.GetUserConfig(User);
if (userConfig.HideSoldVehicles)
{
vehiclesStored.RemoveAll(x => !string.IsNullOrWhiteSpace(x.SoldDate));
}
return PartialView("_VehicleSelector", vehiclesStored);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public IActionResult GetCustomWidgetEditor()
{
if (_config.GetCustomWidgetsEnabled())
{
var customWidgetData = _fileHelper.GetWidgets();
return PartialView("_WidgetEditor", customWidgetData);
}
return Json(string.Empty);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult SaveCustomWidgets(string widgetsData)
{
if (_config.GetCustomWidgetsEnabled())
{
var saveResult = _fileHelper.SaveWidgets(widgetsData);
return Json(saveResult);
}
return Json(false);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult DeleteCustomWidgets()
{
if (_config.GetCustomWidgetsEnabled())
{
var deleteResult = _fileHelper.DeleteWidgets();
return Json(deleteResult);
}
return Json(false);
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{

View File

@@ -4,7 +4,9 @@ using CarCareTracker.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace CarCareTracker.Controllers
@@ -13,48 +15,23 @@ namespace CarCareTracker.Controllers
{
private IDataProtector _dataProtector;
private ILoginLogic _loginLogic;
private IConfigHelper _config;
private readonly ILogger<LoginController> _logger;
public LoginController(
ILogger<LoginController> logger,
IDataProtectionProvider securityProvider,
ILoginLogic loginLogic,
IConfigHelper config
)
ILoginLogic loginLogic
)
{
_dataProtector = securityProvider.CreateProtector("login");
_logger = logger;
_loginLogic = loginLogic;
_config = config;
}
public IActionResult Index(string redirectURL = "")
public IActionResult Index()
{
var remoteAuthConfig = _config.GetOpenIDConfig();
if (remoteAuthConfig.DisableRegularLogin && !string.IsNullOrWhiteSpace(remoteAuthConfig.LogOutURL))
{
var generatedState = Guid.NewGuid().ToString().Substring(0, 8);
remoteAuthConfig.State = generatedState;
var pkceKeyPair = _loginLogic.GetPKCEChallengeCode();
remoteAuthConfig.CodeChallenge = pkceKeyPair.Value;
if (remoteAuthConfig.ValidateState)
{
Response.Cookies.Append("OIDC_STATE", remoteAuthConfig.State, new CookieOptions { Expires = new DateTimeOffset(DateTime.Now.AddMinutes(5)) });
}
if (remoteAuthConfig.UsePKCE)
{
Response.Cookies.Append("OIDC_VERIFIER", pkceKeyPair.Key, new CookieOptions { Expires = new DateTimeOffset(DateTime.Now.AddMinutes(5)) });
}
var remoteAuthURL = remoteAuthConfig.RemoteAuthURL;
return Redirect(remoteAuthURL);
}
return View(model: redirectURL);
return View();
}
public IActionResult Registration()
{
if (_config.GetServerDisabledRegistration())
{
return RedirectToAction("Index");
}
return View();
}
public IActionResult ForgotPassword()
@@ -65,121 +42,6 @@ namespace CarCareTracker.Controllers
{
return View();
}
public IActionResult GetRemoteLoginLink()
{
var remoteAuthConfig = _config.GetOpenIDConfig();
var generatedState = Guid.NewGuid().ToString().Substring(0, 8);
remoteAuthConfig.State = generatedState;
var pkceKeyPair = _loginLogic.GetPKCEChallengeCode();
remoteAuthConfig.CodeChallenge = pkceKeyPair.Value;
if (remoteAuthConfig.ValidateState)
{
Response.Cookies.Append("OIDC_STATE", remoteAuthConfig.State, new CookieOptions { Expires = new DateTimeOffset(DateTime.Now.AddMinutes(5)) });
}
if (remoteAuthConfig.UsePKCE)
{
Response.Cookies.Append("OIDC_VERIFIER", pkceKeyPair.Key, new CookieOptions { Expires = new DateTimeOffset(DateTime.Now.AddMinutes(5)) });
}
var remoteAuthURL = remoteAuthConfig.RemoteAuthURL;
return Json(remoteAuthURL);
}
public async Task<IActionResult> RemoteAuth(string code, string state = "")
{
try
{
if (!string.IsNullOrWhiteSpace(code))
{
//received code from OIDC provider
//create http client to retrieve user token from OIDC
var httpClient = new HttpClient();
var openIdConfig = _config.GetOpenIDConfig();
//check if validate state is enabled.
if (openIdConfig.ValidateState)
{
var storedStateValue = Request.Cookies["OIDC_STATE"];
if (!string.IsNullOrWhiteSpace(storedStateValue))
{
Response.Cookies.Delete("OIDC_STATE");
}
if (string.IsNullOrWhiteSpace(storedStateValue) || string.IsNullOrWhiteSpace(state) || storedStateValue != state)
{
_logger.LogInformation("Failed OIDC State Validation - Try disabling state validation if you are confident this is not a malicious attempt.");
return new RedirectResult("/Login");
}
}
var httpParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("client_id", openIdConfig.ClientId),
new KeyValuePair<string, string>("client_secret", openIdConfig.ClientSecret),
new KeyValuePair<string, string>("redirect_uri", openIdConfig.RedirectURL)
};
if (openIdConfig.UsePKCE)
{
//retrieve stored challenge verifier
var storedVerifier = Request.Cookies["OIDC_VERIFIER"];
if (!string.IsNullOrWhiteSpace(storedVerifier))
{
httpParams.Add(new KeyValuePair<string, string>("code_verifier", storedVerifier));
Response.Cookies.Delete("OIDC_VERIFIER");
}
}
var httpRequest = new HttpRequestMessage(HttpMethod.Post, openIdConfig.TokenURL)
{
Content = new FormUrlEncodedContent(httpParams)
};
var tokenResult = await httpClient.SendAsync(httpRequest).Result.Content.ReadAsStringAsync();
var userJwt = JsonSerializer.Deserialize<OpenIDResult>(tokenResult)?.id_token ?? string.Empty;
if (!string.IsNullOrWhiteSpace(userJwt))
{
//validate JWT token
var tokenParser = new JwtSecurityTokenHandler();
var parsedToken = tokenParser.ReadJwtToken(userJwt);
var userEmailAddress = parsedToken.Claims.First(x => x.Type == "email").Value;
if (!string.IsNullOrWhiteSpace(userEmailAddress))
{
var userData = _loginLogic.ValidateOpenIDUser(new LoginModel() { EmailAddress = userEmailAddress });
if (userData.Id != default)
{
AuthCookie authCookie = new AuthCookie
{
UserData = userData,
ExpiresOn = DateTime.Now.AddDays(1)
};
var serializedCookie = JsonSerializer.Serialize(authCookie);
var encryptedCookie = _dataProtector.Protect(serializedCookie);
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
return new RedirectResult("/Home");
} else
{
_logger.LogInformation($"User {userEmailAddress} tried to login via OpenID but is not a registered user in LubeLogger.");
return View("OpenIDRegistration", model: userEmailAddress);
}
} else
{
_logger.LogInformation("OpenID Provider did not provide a valid email address for the user");
}
} else
{
_logger.LogInformation("OpenID Provider did not provide a valid id_token");
if (!string.IsNullOrWhiteSpace(tokenResult))
{
//if something was returned from the IdP but it's invalid, we want to log it as an error.
_logger.LogError($"Expected id_token, received {tokenResult}");
}
}
} else
{
_logger.LogInformation("OpenID Provider did not provide a code.");
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new RedirectResult("/Login");
}
return new RedirectResult("/Login");
}
[HttpPost]
public IActionResult Login(LoginModel credentials)
{
@@ -219,27 +81,6 @@ namespace CarCareTracker.Controllers
return Json(result);
}
[HttpPost]
public IActionResult RegisterOpenIdUser(LoginModel credentials)
{
var result = _loginLogic.RegisterOpenIdUser(credentials);
if (result.Success)
{
var userData = _loginLogic.ValidateOpenIDUser(new LoginModel() { EmailAddress = credentials.EmailAddress });
if (userData.Id != default)
{
AuthCookie authCookie = new AuthCookie
{
UserData = userData,
ExpiresOn = DateTime.Now.AddDays(1)
};
var serializedCookie = JsonSerializer.Serialize(authCookie);
var encryptedCookie = _dataProtector.Protect(serializedCookie);
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
}
}
return Json(result);
}
[HttpPost]
public IActionResult RequestResetPassword(LoginModel credentials)
{
var result = _loginLogic.RequestResetPassword(credentials);
@@ -251,7 +92,7 @@ namespace CarCareTracker.Controllers
var result = _loginLogic.ResetPasswordByUser(credentials);
return Json(result);
}
[Authorize(Roles = nameof(UserData.IsRootUser))] //User must already be logged in as root user to do this.
[Authorize] //User must already be logged in to do this.
[HttpPost]
public IActionResult CreateLoginCreds(LoginModel credentials)
{
@@ -266,7 +107,7 @@ namespace CarCareTracker.Controllers
}
return Json(false);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[Authorize]
[HttpPost]
public IActionResult DestroyLoginCreds()
{
@@ -291,12 +132,7 @@ namespace CarCareTracker.Controllers
public IActionResult LogOut()
{
Response.Cookies.Delete("ACCESS_TOKEN");
var remoteAuthConfig = _config.GetOpenIDConfig();
if (remoteAuthConfig.DisableRegularLogin && !string.IsNullOrWhiteSpace(remoteAuthConfig.LogOutURL))
{
return Json(remoteAuthConfig.LogOutURL);
}
return Json("/Login");
return Json(true);
}
}
}

View File

@@ -1,756 +0,0 @@
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Npgsql;
using System.IO.Compression;
using JsonSerializer=System.Text.Json.JsonSerializer;
namespace CarCareTracker.Controllers
{
[Authorize(Roles = nameof(UserData.IsRootUser))]
public class MigrationController : Controller
{
private IConfigHelper _configHelper;
private IFileHelper _fileHelper;
private readonly ILogger<MigrationController> _logger;
public MigrationController(IConfigHelper configHelper, IFileHelper fileHelper, ILogger<MigrationController> logger)
{
_configHelper = configHelper;
_fileHelper = fileHelper;
_logger = logger;
}
public IActionResult Index()
{
if (!string.IsNullOrWhiteSpace(_configHelper.GetServerPostgresConnection()))
{
return View();
} else
{
return new RedirectResult("/Error/Unauthorized");
}
}
private void InitializeTables(NpgsqlDataSource conn)
{
var cmds = new List<string>
{
"CREATE SCHEMA IF NOT EXISTS app",
"CREATE TABLE IF NOT EXISTS app.vehicles (id INT GENERATED BY DEFAULT AS IDENTITY primary key, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.collisionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.upgraderecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.servicerecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.gasrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.notes (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.odometerrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.reminderrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.planrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.planrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.supplyrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.taxrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.userrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, username TEXT not null, emailaddress TEXT not null, password TEXT not null, isadmin BOOLEAN)",
"CREATE TABLE IF NOT EXISTS app.tokenrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, body TEXT not null, emailaddress TEXT not null)",
"CREATE TABLE IF NOT EXISTS app.userconfigrecords (id INT primary key, data jsonb not null)",
"CREATE TABLE IF NOT EXISTS app.useraccessrecords (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))",
"CREATE TABLE IF NOT EXISTS app.extrafields (id INT primary key, data jsonb not null)"
};
foreach(string cmd in cmds)
{
using (var ctext = conn.CreateCommand(cmd))
{
ctext.ExecuteNonQuery();
}
}
}
public IActionResult Export()
{
if (string.IsNullOrWhiteSpace(_configHelper.GetServerPostgresConnection()))
{
return Json(OperationResponse.Failed("Postgres connection not set up"));
}
var tempFolder = $"temp/{Guid.NewGuid()}";
var tempPath = $"{tempFolder}/cartracker.db";
var fullFolderPath = _fileHelper.GetFullFilePath(tempFolder, false);
Directory.CreateDirectory(fullFolderPath);
var fullFileName = _fileHelper.GetFullFilePath(tempPath, false);
try
{
var pgDataSource = NpgsqlDataSource.Create(_configHelper.GetServerPostgresConnection());
InitializeTables(pgDataSource);
//pull records
var vehicles = new List<Vehicle>();
var repairrecords = new List<CollisionRecord>();
var upgraderecords = new List<UpgradeRecord>();
var servicerecords = new List<ServiceRecord>();
var gasrecords = new List<GasRecord>();
var noterecords = new List<Note>();
var odometerrecords = new List<OdometerRecord>();
var reminderrecords = new List<ReminderRecord>();
var planrecords = new List<PlanRecord>();
var planrecordtemplates = new List<PlanRecordInput>();
var supplyrecords = new List<SupplyRecord>();
var taxrecords = new List<TaxRecord>();
var userrecords = new List<UserData>();
var tokenrecords = new List<Token>();
var userconfigrecords = new List<UserConfigData>();
var useraccessrecords = new List<UserAccess>();
var extrafields = new List<RecordExtraField>();
#region "Part1"
string cmd = $"SELECT data FROM app.vehicles";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Vehicle vehicle = JsonSerializer.Deserialize<Vehicle>(reader["data"] as string);
vehicles.Add(vehicle);
}
}
foreach (var vehicle in vehicles)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Vehicle>("vehicles");
table.Upsert(vehicle);
};
}
cmd = $"SELECT data FROM app.collisionrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
repairrecords.Add(JsonSerializer.Deserialize<CollisionRecord>(reader["data"] as string));
}
}
foreach (var record in repairrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<CollisionRecord>("collisionrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.upgraderecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
upgraderecords.Add(JsonSerializer.Deserialize<UpgradeRecord>(reader["data"] as string));
}
}
foreach (var record in upgraderecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UpgradeRecord>("upgraderecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.servicerecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
servicerecords.Add(JsonSerializer.Deserialize<ServiceRecord>(reader["data"] as string));
}
}
foreach (var record in servicerecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<ServiceRecord>("servicerecords");
table.Upsert(record);
};
}
#endregion
#region "Part2"
cmd = $"SELECT data FROM app.gasrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
gasrecords.Add(JsonSerializer.Deserialize<GasRecord>(reader["data"] as string));
}
}
foreach (var record in gasrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<GasRecord>("gasrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.notes";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
noterecords.Add(JsonSerializer.Deserialize<Note>(reader["data"] as string));
}
}
foreach (var record in noterecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Note>("notes");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.odometerrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
odometerrecords.Add(JsonSerializer.Deserialize<OdometerRecord>(reader["data"] as string));
}
}
foreach (var record in odometerrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<OdometerRecord>("odometerrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.reminderrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
reminderrecords.Add(JsonSerializer.Deserialize<ReminderRecord>(reader["data"] as string));
}
}
foreach (var record in reminderrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<ReminderRecord>("reminderrecords");
table.Upsert(record);
};
}
#endregion
#region "Part3"
cmd = $"SELECT data FROM app.planrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
planrecords.Add(JsonSerializer.Deserialize<PlanRecord>(reader["data"] as string));
}
}
foreach (var record in planrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<PlanRecord>("planrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.planrecordtemplates";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
planrecordtemplates.Add(JsonSerializer.Deserialize<PlanRecordInput>(reader["data"] as string));
}
}
foreach (var record in planrecordtemplates)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<PlanRecordInput>("planrecordtemplates");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.supplyrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
supplyrecords.Add(JsonSerializer.Deserialize<SupplyRecord>(reader["data"] as string));
}
}
foreach (var record in supplyrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<SupplyRecord>("supplyrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.taxrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
taxrecords.Add(JsonSerializer.Deserialize<TaxRecord>(reader["data"] as string));
}
}
foreach (var record in taxrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<TaxRecord>("taxrecords");
table.Upsert(record);
};
}
#endregion
#region "Part4"
cmd = $"SELECT id, username, emailaddress, password, isadmin FROM app.userrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserData result = new UserData();
result.Id = int.Parse(reader["id"].ToString());
result.UserName = reader["username"].ToString();
result.EmailAddress = reader["emailaddress"].ToString();
result.Password = reader["password"].ToString();
result.IsAdmin = bool.Parse(reader["isadmin"].ToString());
userrecords.Add(result);
}
}
foreach (var record in userrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserData>("userrecords");
table.Upsert(record);
};
}
cmd = $"SELECT id, emailaddress, body FROM app.tokenrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Token result = new Token();
result.Id = int.Parse(reader["id"].ToString());
result.EmailAddress = reader["emailaddress"].ToString();
result.Body = reader["body"].ToString();
tokenrecords.Add(result);
}
}
foreach (var record in tokenrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Token>("tokenrecords");
table.Upsert(record);
};
}
cmd = $"SELECT data FROM app.userconfigrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
userconfigrecords.Add(JsonSerializer.Deserialize<UserConfigData>(reader["data"] as string));
}
}
foreach (var record in userconfigrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserConfigData>("userconfigrecords");
table.Upsert(record);
};
}
cmd = $"SELECT userId, vehicleId FROM app.useraccessrecords";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserAccess result = new UserAccess()
{
Id = new UserVehicle
{
UserId = int.Parse(reader["userId"].ToString()),
VehicleId = int.Parse(reader["vehicleId"].ToString())
}
};
useraccessrecords.Add(result);
}
}
foreach (var record in useraccessrecords)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserAccess>("useraccessrecords");
table.Upsert(record);
};
}
#endregion
#region "Part5"
cmd = $"SELECT data FROM app.extrafields";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
extrafields.Add(JsonSerializer.Deserialize<RecordExtraField>(reader["data"] as string));
}
}
foreach (var record in extrafields)
{
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<RecordExtraField>("extrafields");
table.Upsert(record);
};
}
#endregion
var destFilePath = $"{fullFolderPath}.zip";
ZipFile.CreateFromDirectory(fullFolderPath, destFilePath);
return Json(OperationResponse.Succeed($"/{tempFolder}.zip"));
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(OperationResponse.Failed());
}
}
public IActionResult Import(string fileName)
{
if (string.IsNullOrWhiteSpace(_configHelper.GetServerPostgresConnection()))
{
return Json(OperationResponse.Failed("Postgres connection not set up"));
}
var fullFileName = _fileHelper.GetFullFilePath(fileName);
if (string.IsNullOrWhiteSpace(fullFileName))
{
return Json(OperationResponse.Failed());
}
try
{
var pgDataSource = NpgsqlDataSource.Create(_configHelper.GetServerPostgresConnection());
InitializeTables(pgDataSource);
//pull records
var vehicles = new List<Vehicle>();
var repairrecords = new List<CollisionRecord>();
var upgraderecords = new List<UpgradeRecord>();
var servicerecords = new List<ServiceRecord>();
var gasrecords = new List<GasRecord>();
var noterecords = new List<Note>();
var odometerrecords = new List<OdometerRecord>();
var reminderrecords = new List<ReminderRecord>();
var planrecords = new List<PlanRecord>();
var planrecordtemplates = new List<PlanRecordInput>();
var supplyrecords = new List<SupplyRecord>();
var taxrecords = new List<TaxRecord>();
var userrecords = new List<UserData>();
var tokenrecords = new List<Token>();
var userconfigrecords = new List<UserConfigData>();
var useraccessrecords = new List<UserAccess>();
var extrafields = new List<RecordExtraField>();
#region "Part1"
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Vehicle>("vehicles");
vehicles = table.FindAll().ToList();
};
foreach(var vehicle in vehicles)
{
string cmd = $"INSERT INTO app.vehicles (id, data) VALUES(@id, CAST(@data AS jsonb)); SELECT setval('app.vehicles_id_seq', (SELECT MAX(id) from app.vehicles));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicle.Id);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(vehicle));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<CollisionRecord>("collisionrecords");
repairrecords = table.FindAll().ToList();
};
foreach (var record in repairrecords)
{
string cmd = $"INSERT INTO app.collisionrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.collisionrecords_id_seq', (SELECT MAX(id) from app.collisionrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<ServiceRecord>("servicerecords");
servicerecords = table.FindAll().ToList();
};
foreach (var record in servicerecords)
{
string cmd = $"INSERT INTO app.servicerecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.servicerecords_id_seq', (SELECT MAX(id) from app.servicerecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UpgradeRecord>("upgraderecords");
upgraderecords = table.FindAll().ToList();
};
foreach (var record in upgraderecords)
{
string cmd = $"INSERT INTO app.upgraderecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.upgraderecords_id_seq', (SELECT MAX(id) from app.upgraderecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
#endregion
#region "Part2"
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<GasRecord>("gasrecords");
gasrecords = table.FindAll().ToList();
};
foreach (var record in gasrecords)
{
string cmd = $"INSERT INTO app.gasrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.gasrecords_id_seq', (SELECT MAX(id) from app.gasrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Note>("notes");
noterecords = table.FindAll().ToList();
};
foreach (var record in noterecords)
{
string cmd = $"INSERT INTO app.notes (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.notes_id_seq', (SELECT MAX(id) from app.notes));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<OdometerRecord>("odometerrecords");
odometerrecords = table.FindAll().ToList();
};
foreach (var record in odometerrecords)
{
string cmd = $"INSERT INTO app.odometerrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.odometerrecords_id_seq', (SELECT MAX(id) from app.odometerrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<ReminderRecord>("reminderrecords");
reminderrecords = table.FindAll().ToList();
};
foreach (var record in reminderrecords)
{
string cmd = $"INSERT INTO app.reminderrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.reminderrecords_id_seq', (SELECT MAX(id) from app.reminderrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
#endregion
#region "Part3"
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<PlanRecord>("planrecords");
planrecords = table.FindAll().ToList();
};
foreach (var record in planrecords)
{
string cmd = $"INSERT INTO app.planrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.planrecords_id_seq', (SELECT MAX(id) from app.planrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<PlanRecordInput>("planrecordtemplates");
planrecordtemplates = table.FindAll().ToList();
};
foreach (var record in planrecordtemplates)
{
string cmd = $"INSERT INTO app.planrecordtemplates (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.planrecordtemplates_id_seq', (SELECT MAX(id) from app.planrecordtemplates));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<SupplyRecord>("supplyrecords");
supplyrecords = table.FindAll().ToList();
};
foreach (var record in supplyrecords)
{
string cmd = $"INSERT INTO app.supplyrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.supplyrecords_id_seq', (SELECT MAX(id) from app.supplyrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<TaxRecord>("taxrecords");
taxrecords = table.FindAll().ToList();
};
foreach (var record in taxrecords)
{
string cmd = $"INSERT INTO app.taxrecords (id, vehicleId, data) VALUES(@id, @vehicleId, CAST(@data AS jsonb)); SELECT setval('app.taxrecords_id_seq', (SELECT MAX(id) from app.taxrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("vehicleId", record.VehicleId);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
#endregion
#region "Part4"
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserData>("userrecords");
userrecords = table.FindAll().ToList();
};
foreach (var record in userrecords)
{
string cmd = $"INSERT INTO app.userrecords (id, username, emailaddress, password, isadmin) VALUES(@id, @username, @emailaddress, @password, @isadmin); SELECT setval('app.userrecords_id_seq', (SELECT MAX(id) from app.userrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("username", record.UserName);
ctext.Parameters.AddWithValue("emailaddress", record.EmailAddress);
ctext.Parameters.AddWithValue("password", record.Password);
ctext.Parameters.AddWithValue("isadmin", record.IsAdmin);
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<Token>("tokenrecords");
tokenrecords = table.FindAll().ToList();
};
foreach (var record in tokenrecords)
{
string cmd = $"INSERT INTO app.tokenrecords (id, emailaddress, body) VALUES(@id, @emailaddress, @body); SELECT setval('app.tokenrecords_id_seq', (SELECT MAX(id) from app.tokenrecords));";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("emailaddress", record.EmailAddress);
ctext.Parameters.AddWithValue("body", record.Body);
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserConfigData>("userconfigrecords");
userconfigrecords = table.FindAll().ToList();
};
foreach (var record in userconfigrecords)
{
string cmd = $"INSERT INTO app.userconfigrecords (id, data) VALUES(@id, CAST(@data AS jsonb))";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<UserAccess>("useraccessrecords");
useraccessrecords = table.FindAll().ToList();
};
foreach (var record in useraccessrecords)
{
string cmd = $"INSERT INTO app.useraccessrecords (userId, vehicleId) VALUES(@userId, @vehicleId)";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", record.Id.UserId);
ctext.Parameters.AddWithValue("vehicleId", record.Id.VehicleId);
ctext.ExecuteNonQuery();
}
}
#endregion
#region "Part5"
using (var db = new LiteDatabase(fullFileName))
{
var table = db.GetCollection<RecordExtraField>("extrafields");
extrafields = table.FindAll().ToList();
};
foreach (var record in extrafields)
{
string cmd = $"INSERT INTO app.extrafields (id, data) VALUES(@id, CAST(@data AS jsonb))";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
#endregion
return Json(OperationResponse.Succeed("Data Imported Successfully"));
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(OperationResponse.Failed());
}
}
}
}

View File

@@ -1,209 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetGasRecordsByVehicleId(int vehicleId)
{
var result = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
//check if the user uses MPG or Liters per 100km.
var userConfig = _config.GetUserConfig(User);
bool useMPG = userConfig.UseMPG;
bool useUKMPG = userConfig.UseUKMPG;
var computedResults = _gasHelper.GetGasRecordViewModels(result, useMPG, useUKMPG);
if (userConfig.UseDescending)
{
computedResults = computedResults.OrderByDescending(x => DateTime.Parse(x.Date)).ThenByDescending(x => x.Mileage).ToList();
}
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
var vehicleIsElectric = vehicleData.IsElectric;
var vehicleUseHours = vehicleData.UseHours;
var viewModel = new GasRecordViewModelContainer()
{
UseKwh = vehicleIsElectric,
UseHours = vehicleUseHours,
GasRecords = computedResults
};
return PartialView("_Gas", viewModel);
}
[HttpPost]
public IActionResult SaveGasRecordToVehicleId(GasRecordInput gasRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), gasRecord.VehicleId))
{
return Json(false);
}
if (gasRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = DateTime.Parse(gasRecord.Date),
VehicleId = gasRecord.VehicleId,
Mileage = gasRecord.Mileage,
Notes = $"Auto Insert From Gas Record. {gasRecord.Notes}"
});
}
gasRecord.Files = gasRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
var result = _gasRecordDataAccess.SaveGasRecordToVehicle(gasRecord.ToGasRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(gasRecord.ToGasRecord(), gasRecord.Id == default ? "gasrecord.add" : "gasrecord.update", User.Identity.Name));
}
return Json(result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetAddGasRecordPartialView(int vehicleId)
{
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
var vehicleIsElectric = vehicleData.IsElectric;
var vehicleUseHours = vehicleData.UseHours;
return PartialView("_GasModal", new GasRecordInputContainer() { UseKwh = vehicleIsElectric, UseHours = vehicleUseHours, GasRecord = new GasRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields } });
}
[HttpGet]
public IActionResult GetGasRecordForEditById(int gasRecordId)
{
var result = _gasRecordDataAccess.GetGasRecordById(gasRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
var convertedResult = new GasRecordInput
{
Id = result.Id,
Mileage = result.Mileage,
VehicleId = result.VehicleId,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Files = result.Files,
Gallons = result.Gallons,
IsFillToFull = result.IsFillToFull,
MissedFuelUp = result.MissedFuelUp,
Notes = result.Notes,
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields)
};
var vehicleData = _dataAccess.GetVehicleById(convertedResult.VehicleId);
var vehicleIsElectric = vehicleData.IsElectric;
var vehicleUseHours = vehicleData.UseHours;
var viewModel = new GasRecordInputContainer()
{
UseKwh = vehicleIsElectric,
UseHours = vehicleUseHours,
GasRecord = convertedResult
};
return PartialView("_GasModal", viewModel);
}
private bool DeleteGasRecordWithChecks(int gasRecordId)
{
var existingRecord = _gasRecordDataAccess.GetGasRecordById(gasRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
var result = _gasRecordDataAccess.DeleteGasRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGasRecord(existingRecord, "gasrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteGasRecordById(int gasRecordId)
{
var result = DeleteGasRecordWithChecks(gasRecordId);
return Json(result);
}
[HttpPost]
public IActionResult SaveUserGasTabPreferences(string gasUnit, string fuelMileageUnit)
{
var currentConfig = _config.GetUserConfig(User);
currentConfig.PreferredGasUnit = gasUnit;
currentConfig.PreferredGasMileageUnit = fuelMileageUnit;
var result = _config.SaveUserConfig(User, currentConfig);
return Json(result);
}
[HttpPost]
public IActionResult GetGasRecordsEditModal(List<int> recordIds)
{
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields;
return PartialView("_GasRecordsModal", new GasRecordEditModel { RecordIds = recordIds, EditRecord = new GasRecord { ExtraFields = extraFields } });
}
[HttpPost]
public IActionResult SaveMultipleGasRecords(GasRecordEditModel editModel)
{
var dateIsEdited = editModel.EditRecord.Date != default;
var mileageIsEdited = editModel.EditRecord.Mileage != default;
var consumptionIsEdited = editModel.EditRecord.Gallons != default;
var costIsEdited = editModel.EditRecord.Cost != default;
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
var tagsIsEdited = editModel.EditRecord.Tags.Any();
var extraFieldIsEdited = editModel.EditRecord.ExtraFields.Any();
//handle clear overrides
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
{
editModel.EditRecord.Tags = new List<string>();
}
if (noteIsEdited && editModel.EditRecord.Notes == "---")
{
editModel.EditRecord.Notes = "";
}
bool result = false;
foreach (int recordId in editModel.RecordIds)
{
var existingRecord = _gasRecordDataAccess.GetGasRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = editModel.EditRecord.Date;
}
if (consumptionIsEdited)
{
existingRecord.Gallons = editModel.EditRecord.Gallons;
}
if (costIsEdited)
{
existingRecord.Cost = editModel.EditRecord.Cost;
}
if (mileageIsEdited)
{
existingRecord.Mileage = editModel.EditRecord.Mileage;
}
if (noteIsEdited)
{
existingRecord.Notes = editModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = editModel.EditRecord.Tags;
}
if (extraFieldIsEdited)
{
foreach (ExtraField extraField in editModel.EditRecord.ExtraFields)
{
if (existingRecord.ExtraFields.Any(x => x.Name == extraField.Name))
{
var insertIndex = existingRecord.ExtraFields.FindIndex(x => x.Name == extraField.Name);
existingRecord.ExtraFields.RemoveAll(x => x.Name == extraField.Name);
existingRecord.ExtraFields.Insert(insertIndex, extraField);
}
else
{
existingRecord.ExtraFields.Add(extraField);
}
}
}
result = _gasRecordDataAccess.SaveGasRecordToVehicle(existingRecord);
}
return Json(result);
}
}
}

View File

@@ -1,495 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.MapProfile;
using CarCareTracker.Models;
using CsvHelper;
using CsvHelper.Configuration;
using Microsoft.AspNetCore.Mvc;
using System.Globalization;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[HttpGet]
public IActionResult GetBulkImportModalPartialView(ImportMode mode)
{
return PartialView("_BulkDataImporter", mode);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult ExportFromVehicleToCsv(int vehicleId, ImportMode mode)
{
if (vehicleId == default && mode != ImportMode.SupplyRecord)
{
return Json(false);
}
string uploadDirectory = "temp/";
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
var fileNameToExport = $"temp/{Guid.NewGuid()}.csv";
var fullExportFilePath = _fileHelper.GetFullFilePath(fileNameToExport, false);
if (mode == ImportMode.ServiceRecord)
{
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
{
Date = x.Date.ToShortDateString(),
Description = x.Description,
Cost = x.Cost.ToString("C"),
Notes = x.Notes,
Odometer = x.Mileage.ToString(),
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
//custom writer
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
}
writer.Dispose();
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.RepairRecord)
{
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
{
Date = x.Date.ToShortDateString(),
Description = x.Description,
Cost = x.Cost.ToString("C"),
Notes = x.Notes,
Odometer = x.Mileage.ToString(),
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.UpgradeRecord)
{
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new GenericRecordExportModel
{
Date = x.Date.ToShortDateString(),
Description = x.Description,
Cost = x.Cost.ToString("C"),
Notes = x.Notes,
Odometer = x.Mileage.ToString(),
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteGenericRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.OdometerRecord)
{
var vehicleRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new OdometerRecordExportModel
{
Date = x.Date.ToShortDateString(),
Notes = x.Notes,
InitialOdometer = x.InitialMileage.ToString(),
Odometer = x.Mileage.ToString(),
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteOdometerRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.SupplyRecord)
{
var vehicleRecords = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new SupplyRecordExportModel
{
Date = x.Date.ToShortDateString(),
Description = x.Description,
Cost = x.Cost.ToString("C"),
PartNumber = x.PartNumber,
PartQuantity = x.Quantity.ToString(),
PartSupplier = x.PartSupplier,
Notes = x.Notes,
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteSupplyRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.TaxRecord)
{
var vehicleRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new TaxRecordExportModel
{
Date = x.Date.ToShortDateString(),
Description = x.Description,
Cost = x.Cost.ToString("C"),
Notes = x.Notes,
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteTaxRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.PlanRecord)
{
var vehicleRecords = _planRecordDataAccess.GetPlanRecordsByVehicleId(vehicleId);
if (vehicleRecords.Any())
{
var exportData = vehicleRecords.Select(x => new PlanRecordExportModel
{
DateCreated = x.DateCreated.ToString("G"),
DateModified = x.DateModified.ToString("G"),
Description = x.Description,
Cost = x.Cost.ToString("C"),
Type = x.ImportMode.ToString(),
Priority = x.Priority.ToString(),
Progress = x.Progress.ToString(),
Notes = x.Notes,
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WritePlanRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
}
else if (mode == ImportMode.GasRecord)
{
var vehicleRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
bool useMPG = _config.GetUserConfig(User).UseMPG;
bool useUKMPG = _config.GetUserConfig(User).UseUKMPG;
var convertedRecords = _gasHelper.GetGasRecordViewModels(vehicleRecords, useMPG, useUKMPG);
var exportData = convertedRecords.Select(x => new GasRecordExportModel
{
Date = x.Date.ToString(),
Cost = x.Cost.ToString(),
FuelConsumed = x.Gallons.ToString(),
FuelEconomy = x.MilesPerGallon.ToString(),
Odometer = x.Mileage.ToString(),
IsFillToFull = x.IsFillToFull.ToString(),
MissedFuelUp = x.MissedFuelUp.ToString(),
Notes = x.Notes,
Tags = string.Join(" ", x.Tags),
ExtraFields = x.ExtraFields
});
using (var writer = new StreamWriter(fullExportFilePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
StaticHelper.WriteGasRecordExportModel(csv, exportData);
}
}
return Json($"/{fileNameToExport}");
}
return Json(false);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult ImportToVehicleIdFromCsv(int vehicleId, ImportMode mode, string fileName)
{
if (vehicleId == default && mode != ImportMode.SupplyRecord)
{
return Json(false);
}
if (string.IsNullOrWhiteSpace(fileName))
{
return Json(false);
}
var fullFileName = _fileHelper.GetFullFilePath(fileName);
if (string.IsNullOrWhiteSpace(fullFileName))
{
return Json(false);
}
try
{
using (var reader = new StreamReader(fullFileName))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.MissingFieldFound = null;
config.HeaderValidated = null;
config.PrepareHeaderForMatch = args => { return args.Header.Trim().ToLower(); };
using (var csv = new CsvReader(reader, config))
{
csv.Context.RegisterClassMap<ImportMapper>();
var records = csv.GetRecords<ImportModel>().ToList();
if (records.Any())
{
var requiredExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)mode).ExtraFields.Where(x => x.IsRequired).Select(y => y.Name);
foreach (ImportModel importModel in records)
{
var parsedDate = DateTime.Now.Date;
if (!string.IsNullOrWhiteSpace(importModel.Date))
{
parsedDate = DateTime.Parse(importModel.Date);
}
else if (!string.IsNullOrWhiteSpace(importModel.Day) && !string.IsNullOrWhiteSpace(importModel.Month) && !string.IsNullOrWhiteSpace(importModel.Year))
{
parsedDate = new DateTime(int.Parse(importModel.Year), int.Parse(importModel.Month), int.Parse(importModel.Day));
}
if (mode == ImportMode.GasRecord)
{
//convert to gas model.
var convertedRecord = new GasRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
Gallons = decimal.Parse(importModel.FuelConsumed, NumberStyles.Any),
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
if (string.IsNullOrWhiteSpace(importModel.Cost) && !string.IsNullOrWhiteSpace(importModel.Price))
{
//cost was not given but price is.
//fuelly sometimes exports CSVs without total cost.
var parsedPrice = decimal.Parse(importModel.Price, NumberStyles.Any);
convertedRecord.Cost = convertedRecord.Gallons * parsedPrice;
}
else
{
convertedRecord.Cost = decimal.Parse(importModel.Cost, NumberStyles.Any);
}
if (string.IsNullOrWhiteSpace(importModel.IsFillToFull) && !string.IsNullOrWhiteSpace(importModel.PartialFuelUp))
{
var parsedBool = importModel.PartialFuelUp.Trim() == "1";
convertedRecord.IsFillToFull = !parsedBool;
}
else if (!string.IsNullOrWhiteSpace(importModel.IsFillToFull))
{
var possibleFillToFullValues = new List<string> { "1", "true", "full" };
var parsedBool = possibleFillToFullValues.Contains(importModel.IsFillToFull.Trim().ToLower());
convertedRecord.IsFillToFull = parsedBool;
}
if (!string.IsNullOrWhiteSpace(importModel.MissedFuelUp))
{
var possibleMissedFuelUpValues = new List<string> { "1", "true" };
var parsedBool = possibleMissedFuelUpValues.Contains(importModel.MissedFuelUp.Trim().ToLower());
convertedRecord.MissedFuelUp = parsedBool;
}
//insert record into db, check to make sure fuelconsumed is not zero so we don't get a divide by zero error.
if (convertedRecord.Gallons > 0)
{
_gasRecordDataAccess.SaveGasRecordToVehicle(convertedRecord);
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = convertedRecord.Date,
VehicleId = convertedRecord.VehicleId,
Mileage = convertedRecord.Mileage,
Notes = $"Auto Insert From Gas Record via CSV Import. {convertedRecord.Notes}"
});
}
}
}
else if (mode == ImportMode.ServiceRecord)
{
var convertedRecord = new ServiceRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Service Record on {parsedDate.ToShortDateString()}" : importModel.Description,
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_serviceRecordDataAccess.SaveServiceRecordToVehicle(convertedRecord);
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = convertedRecord.Date,
VehicleId = convertedRecord.VehicleId,
Mileage = convertedRecord.Mileage,
Notes = $"Auto Insert From Service Record via CSV Import. {convertedRecord.Notes}"
});
}
}
else if (mode == ImportMode.OdometerRecord)
{
var convertedRecord = new OdometerRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
InitialMileage = string.IsNullOrWhiteSpace(importModel.InitialOdometer) ? 0 : decimal.ToInt32(decimal.Parse(importModel.InitialOdometer, NumberStyles.Any)),
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_odometerRecordDataAccess.SaveOdometerRecordToVehicle(convertedRecord);
}
else if (mode == ImportMode.PlanRecord)
{
var progressIsEnum = Enum.TryParse(importModel.Progress, out PlanProgress parsedProgress);
var typeIsEnum = Enum.TryParse(importModel.Type, out ImportMode parsedType);
var priorityIsEnum = Enum.TryParse(importModel.Priority, out PlanPriority parsedPriority);
var convertedRecord = new PlanRecord()
{
VehicleId = vehicleId,
DateCreated = DateTime.Parse(importModel.DateCreated),
DateModified = DateTime.Parse(importModel.DateModified),
Progress = parsedProgress,
ImportMode = parsedType,
Priority = parsedPriority,
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Plan Record on {importModel.DateCreated}" : importModel.Description,
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_planRecordDataAccess.SavePlanRecordToVehicle(convertedRecord);
}
else if (mode == ImportMode.RepairRecord)
{
var convertedRecord = new CollisionRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Repair Record on {parsedDate.ToShortDateString()}" : importModel.Description,
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(convertedRecord);
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = convertedRecord.Date,
VehicleId = convertedRecord.VehicleId,
Mileage = convertedRecord.Mileage,
Notes = $"Auto Insert From Repair Record via CSV Import. {convertedRecord.Notes}"
});
}
}
else if (mode == ImportMode.UpgradeRecord)
{
var convertedRecord = new UpgradeRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
Mileage = decimal.ToInt32(decimal.Parse(importModel.Odometer, NumberStyles.Any)),
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Upgrade Record on {parsedDate.ToShortDateString()}" : importModel.Description,
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(convertedRecord);
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = convertedRecord.Date,
VehicleId = convertedRecord.VehicleId,
Mileage = convertedRecord.Mileage,
Notes = $"Auto Insert From Upgrade Record via CSV Import. {convertedRecord.Notes}"
});
}
}
else if (mode == ImportMode.SupplyRecord)
{
var convertedRecord = new SupplyRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
PartNumber = importModel.PartNumber,
PartSupplier = importModel.PartSupplier,
Quantity = decimal.Parse(importModel.PartQuantity, NumberStyles.Any),
Description = importModel.Description,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
Notes = importModel.Notes,
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_supplyRecordDataAccess.SaveSupplyRecordToVehicle(convertedRecord);
}
else if (mode == ImportMode.TaxRecord)
{
var convertedRecord = new TaxRecord()
{
VehicleId = vehicleId,
Date = parsedDate,
Description = string.IsNullOrWhiteSpace(importModel.Description) ? $"Tax Record on {parsedDate.ToShortDateString()}" : importModel.Description,
Notes = string.IsNullOrWhiteSpace(importModel.Notes) ? "" : importModel.Notes,
Cost = decimal.Parse(importModel.Cost, NumberStyles.Any),
Tags = string.IsNullOrWhiteSpace(importModel.Tags) ? [] : importModel.Tags.Split(" ").ToList(),
ExtraFields = importModel.ExtraFields.Any() ? importModel.ExtraFields.Select(x => new ExtraField { Name = x.Key, Value = x.Value, IsRequired = requiredExtraFields.Contains(x.Key) }).ToList() : new List<ExtraField>()
};
_taxRecordDataAccess.SaveTaxRecordToVehicle(convertedRecord);
}
}
}
}
}
return Json(true);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error Occurred While Bulk Inserting");
return Json(false);
}
}
}
}

View File

@@ -1,100 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetNotesByVehicleId(int vehicleId)
{
var result = _noteDataAccess.GetNotesByVehicleId(vehicleId);
result = result.OrderByDescending(x => x.Pinned).ThenBy(x => x.Description).ToList();
return PartialView("_Notes", result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetPinnedNotesByVehicleId(int vehicleId)
{
var result = _noteDataAccess.GetNotesByVehicleId(vehicleId);
result = result.Where(x => x.Pinned).ToList();
return Json(result);
}
[HttpPost]
public IActionResult SaveNoteToVehicleId(Note note)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), note.VehicleId))
{
return Json(false);
}
note.Files = note.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
bool isCreate = note.Id == default; //needed here since Notes don't use an input object.
var result = _noteDataAccess.SaveNoteToVehicle(note);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromNoteRecord(note, isCreate ? "noterecord.add" : "noterecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddNotePartialView()
{
return PartialView("_NoteModal", new Note());
}
[HttpGet]
public IActionResult GetNoteForEditById(int noteId)
{
var result = _noteDataAccess.GetNoteById(noteId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
return PartialView("_NoteModal", result);
}
private bool DeleteNoteWithChecks(int noteId)
{
var existingRecord = _noteDataAccess.GetNoteById(noteId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
var result = _noteDataAccess.DeleteNoteById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromNoteRecord(existingRecord, "noterecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteNoteById(int noteId)
{
var result = DeleteNoteWithChecks(noteId);
return Json(result);
}
[HttpPost]
public IActionResult PinNotes(List<int> noteIds, bool isToggle = false, bool pinStatus = false)
{
var result = false;
foreach (int noteId in noteIds)
{
var existingNote = _noteDataAccess.GetNoteById(noteId);
if (isToggle)
{
existingNote.Pinned = !existingNote.Pinned;
}
else
{
existingNote.Pinned = pinStatus;
}
result = _noteDataAccess.SaveNoteToVehicle(existingNote);
}
return Json(result);
}
}
}

View File

@@ -1,176 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult ForceRecalculateDistanceByVehicleId(int vehicleId)
{
var result = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
result = _odometerLogic.AutoConvertOdometerRecord(result);
return Json(result.Any());
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetOdometerRecordsByVehicleId(int vehicleId)
{
var result = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
//determine if conversion is needed.
if (result.All(x => x.InitialMileage == default))
{
result = _odometerLogic.AutoConvertOdometerRecord(result);
}
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
}
return PartialView("_OdometerRecords", result);
}
[HttpPost]
public IActionResult SaveOdometerRecordToVehicleId(OdometerRecordInput odometerRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), odometerRecord.VehicleId))
{
return Json(false);
}
//move files from temp.
odometerRecord.Files = odometerRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
var result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(odometerRecord.ToOdometerRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(odometerRecord.ToOdometerRecord(), odometerRecord.Id == default ? "odometerrecord.add" : "odometerrecord.update", User.Identity.Name));
}
return Json(result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetAddOdometerRecordPartialView(int vehicleId)
{
return PartialView("_OdometerRecordModal", new OdometerRecordInput() { InitialMileage = _odometerLogic.GetLastOdometerRecordMileage(vehicleId, new List<OdometerRecord>()), ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields });
}
[HttpPost]
public IActionResult GetOdometerRecordsEditModal(List<int> recordIds)
{
var extraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields;
return PartialView("_OdometerRecordsModal", new OdometerRecordEditModel { RecordIds = recordIds, EditRecord = new OdometerRecord { ExtraFields = extraFields } });
}
[HttpPost]
public IActionResult SaveMultipleOdometerRecords(OdometerRecordEditModel editModel)
{
var dateIsEdited = editModel.EditRecord.Date != default;
var initialMileageIsEdited = editModel.EditRecord.InitialMileage != default;
var mileageIsEdited = editModel.EditRecord.Mileage != default;
var noteIsEdited = !string.IsNullOrWhiteSpace(editModel.EditRecord.Notes);
var tagsIsEdited = editModel.EditRecord.Tags.Any();
var extraFieldIsEdited = editModel.EditRecord.ExtraFields.Any();
//handle clear overrides
if (tagsIsEdited && editModel.EditRecord.Tags.Contains("---"))
{
editModel.EditRecord.Tags = new List<string>();
}
if (noteIsEdited && editModel.EditRecord.Notes == "---")
{
editModel.EditRecord.Notes = "";
}
bool result = false;
foreach (int recordId in editModel.RecordIds)
{
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = editModel.EditRecord.Date;
}
if (initialMileageIsEdited)
{
existingRecord.InitialMileage = editModel.EditRecord.InitialMileage;
}
if (mileageIsEdited)
{
existingRecord.Mileage = editModel.EditRecord.Mileage;
}
if (noteIsEdited)
{
existingRecord.Notes = editModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = editModel.EditRecord.Tags;
}
if (extraFieldIsEdited)
{
foreach (ExtraField extraField in editModel.EditRecord.ExtraFields)
{
if (existingRecord.ExtraFields.Any(x => x.Name == extraField.Name))
{
var insertIndex = existingRecord.ExtraFields.FindIndex(x => x.Name == extraField.Name);
existingRecord.ExtraFields.RemoveAll(x => x.Name == extraField.Name);
existingRecord.ExtraFields.Insert(insertIndex, extraField);
}
else
{
existingRecord.ExtraFields.Add(extraField);
}
}
}
result = _odometerRecordDataAccess.SaveOdometerRecordToVehicle(existingRecord);
}
return Json(result);
}
[HttpGet]
public IActionResult GetOdometerRecordForEditById(int odometerRecordId)
{
var result = _odometerRecordDataAccess.GetOdometerRecordById(odometerRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new OdometerRecordInput
{
Id = result.Id,
Date = result.Date.ToShortDateString(),
InitialMileage = result.InitialMileage,
Mileage = result.Mileage,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields)
};
return PartialView("_OdometerRecordModal", convertedResult);
}
private bool DeleteOdometerRecordWithChecks(int odometerRecordId)
{
var existingRecord = _odometerRecordDataAccess.GetOdometerRecordById(odometerRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
var result = _odometerRecordDataAccess.DeleteOdometerRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromOdometerRecord(existingRecord, "odometerrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteOdometerRecordById(int odometerRecordId)
{
var result = DeleteOdometerRecordWithChecks(odometerRecordId);
return Json(result);
}
}
}

View File

@@ -1,324 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetPlanRecordsByVehicleId(int vehicleId)
{
var result = _planRecordDataAccess.GetPlanRecordsByVehicleId(vehicleId);
return PartialView("_PlanRecords", result);
}
[HttpPost]
public IActionResult SavePlanRecordToVehicleId(PlanRecordInput planRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), planRecord.VehicleId))
{
return Json(false);
}
//populate createdDate
if (planRecord.Id == default)
{
planRecord.DateCreated = DateTime.Now.ToString("G");
}
planRecord.DateModified = DateTime.Now.ToString("G");
//move files from temp.
planRecord.Files = planRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
if (planRecord.Supplies.Any())
{
planRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(planRecord.Supplies, DateTime.Parse(planRecord.DateCreated), planRecord.Description));
if (planRecord.CopySuppliesAttachment)
{
planRecord.Files.AddRange(GetSuppliesAttachments(planRecord.Supplies));
}
}
if (planRecord.DeletedRequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(planRecord.DeletedRequisitionHistory, planRecord.Description);
}
var result = _planRecordDataAccess.SavePlanRecordToVehicle(planRecord.ToPlanRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromPlanRecord(planRecord.ToPlanRecord(), planRecord.Id == default ? "planrecord.add" : "planrecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpPost]
public IActionResult SavePlanRecordTemplateToVehicleId(PlanRecordInput planRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), planRecord.VehicleId))
{
return Json(OperationResponse.Failed("Access Denied"));
}
//check if template name already taken.
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(planRecord.VehicleId).Where(x => x.Description == planRecord.Description).Any();
if (planRecord.Id == default && existingRecord)
{
return Json(OperationResponse.Failed("A template with that description already exists for this vehicle"));
}
planRecord.Files = planRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
var result = _planRecordTemplateDataAccess.SavePlanRecordTemplateToVehicle(planRecord);
return Json(OperationResponse.Conditional(result, "Template Added", string.Empty));
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetPlanRecordTemplatesForVehicleId(int vehicleId)
{
var result = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(vehicleId);
return PartialView("_PlanRecordTemplateModal", result);
}
[HttpPost]
public IActionResult DeletePlanRecordTemplateById(int planRecordTemplateId)
{
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
if (existingRecord.Id == default)
{
return Json(false);
}
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return Json(false);
}
var result = _planRecordTemplateDataAccess.DeletePlanRecordTemplateById(planRecordTemplateId);
return Json(result);
}
[HttpGet]
public IActionResult OrderPlanSupplies(int planRecordTemplateId)
{
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
if (existingRecord.Id == default)
{
return Json(OperationResponse.Failed("Unable to find template"));
}
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return Json(OperationResponse.Failed("Access Denied"));
}
if (existingRecord.Supplies.Any())
{
var suppliesToOrder = CheckSupplyRecordsAvailability(existingRecord.Supplies);
return PartialView("_PlanOrderSupplies", suppliesToOrder);
}
else
{
return Json(OperationResponse.Failed("Template has No Supplies"));
}
}
[HttpPost]
public IActionResult ConvertPlanRecordTemplateToPlanRecord(int planRecordTemplateId)
{
var existingRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
if (existingRecord.Id == default)
{
return Json(OperationResponse.Failed("Unable to find template"));
}
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return Json(OperationResponse.Failed("Access Denied"));
}
if (existingRecord.Supplies.Any())
{
//check if all supplies are available
var supplyAvailability = CheckSupplyRecordsAvailability(existingRecord.Supplies);
if (supplyAvailability.Any(x => x.Missing))
{
return Json(OperationResponse.Failed("Missing Supplies, Please Delete This Template and Recreate It."));
}
else if (supplyAvailability.Any(x => x.Insufficient))
{
return Json(OperationResponse.Failed("Insufficient Supplies"));
}
}
if (existingRecord.ReminderRecordId != default)
{
//check if reminder still exists and is still recurring.
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(existingRecord.ReminderRecordId);
if (existingReminder is null || existingReminder.Id == default || !existingReminder.IsRecurring)
{
return Json(OperationResponse.Failed("Missing or Non-recurring Reminder, Please Delete This Template and Recreate It."));
}
}
//populate createdDate
existingRecord.DateCreated = DateTime.Now.ToString("G");
existingRecord.DateModified = DateTime.Now.ToString("G");
existingRecord.Id = default;
if (existingRecord.Supplies.Any())
{
existingRecord.RequisitionHistory = RequisitionSupplyRecordsByUsage(existingRecord.Supplies, DateTime.Parse(existingRecord.DateCreated), existingRecord.Description);
if (existingRecord.CopySuppliesAttachment)
{
existingRecord.Files.AddRange(GetSuppliesAttachments(existingRecord.Supplies));
}
}
var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord.ToPlanRecord());
return Json(OperationResponse.Conditional(result, "Plan Record Added", string.Empty));
}
[HttpGet]
public IActionResult GetAddPlanRecordPartialView()
{
return PartialView("_PlanRecordModal", new PlanRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields });
}
[HttpPost]
public IActionResult GetAddPlanRecordPartialView(PlanRecordInput? planModel)
{
if (planModel is not null)
{
planModel.ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields;
return PartialView("_PlanRecordModal", planModel);
}
return PartialView("_PlanRecordModal", new PlanRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields });
}
[HttpPost]
public IActionResult UpdatePlanRecordProgress(int planRecordId, PlanProgress planProgress, int odometer = 0)
{
if (planRecordId == default)
{
return Json(false);
}
var existingRecord = _planRecordDataAccess.GetPlanRecordById(planRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return Json(false);
}
existingRecord.Progress = planProgress;
existingRecord.DateModified = DateTime.Now;
var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord);
if (planProgress == PlanProgress.Done)
{
if (_config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = DateTime.Now.Date,
VehicleId = existingRecord.VehicleId,
Mileage = odometer,
Notes = $"Auto Insert From Plan Record: {existingRecord.Description}",
ExtraFields = existingRecord.ExtraFields
});
}
//convert plan record to service/upgrade/repair record.
if (existingRecord.ImportMode == ImportMode.ServiceRecord)
{
var newRecord = new ServiceRecord()
{
VehicleId = existingRecord.VehicleId,
Date = DateTime.Now.Date,
Mileage = odometer,
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files,
RequisitionHistory = existingRecord.RequisitionHistory,
ExtraFields = existingRecord.ExtraFields
};
_serviceRecordDataAccess.SaveServiceRecordToVehicle(newRecord);
}
else if (existingRecord.ImportMode == ImportMode.RepairRecord)
{
var newRecord = new CollisionRecord()
{
VehicleId = existingRecord.VehicleId,
Date = DateTime.Now.Date,
Mileage = odometer,
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files,
RequisitionHistory = existingRecord.RequisitionHistory,
ExtraFields = existingRecord.ExtraFields
};
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(newRecord);
}
else if (existingRecord.ImportMode == ImportMode.UpgradeRecord)
{
var newRecord = new UpgradeRecord()
{
VehicleId = existingRecord.VehicleId,
Date = DateTime.Now.Date,
Mileage = odometer,
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files,
RequisitionHistory = existingRecord.RequisitionHistory,
ExtraFields = existingRecord.ExtraFields
};
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(newRecord);
}
//push back any reminders
if (existingRecord.ReminderRecordId != default)
{
PushbackRecurringReminderRecordWithChecks(existingRecord.ReminderRecordId, DateTime.Now, odometer);
}
}
return Json(result);
}
[HttpGet]
public IActionResult GetPlanRecordTemplateForEditById(int planRecordTemplateId)
{
var result = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
return PartialView("_PlanRecordTemplateEditModal", result);
}
[HttpGet]
public IActionResult GetPlanRecordForEditById(int planRecordId)
{
var result = _planRecordDataAccess.GetPlanRecordById(planRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new PlanRecordInput
{
Id = result.Id,
Description = result.Description,
DateCreated = result.DateCreated.ToString("G"),
DateModified = result.DateModified.ToString("G"),
ImportMode = result.ImportMode,
Priority = result.Priority,
Progress = result.Progress,
Cost = result.Cost,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
RequisitionHistory = result.RequisitionHistory,
ReminderRecordId = result.ReminderRecordId,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields)
};
return PartialView("_PlanRecordModal", convertedResult);
}
[HttpPost]
public IActionResult DeletePlanRecordById(int planRecordId)
{
var existingRecord = _planRecordDataAccess.GetPlanRecordById(planRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return Json(false);
}
//restore any requisitioned supplies if it has not been converted to other record types.
if (existingRecord.RequisitionHistory.Any() && existingRecord.Progress != PlanProgress.Done)
{
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
}
var result = _planRecordDataAccess.DeletePlanRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromPlanRecord(existingRecord, "planrecord.delete", User.Identity.Name));
}
return Json(result);
}
}
}

View File

@@ -1,185 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
private List<ReminderRecordViewModel> GetRemindersAndUrgency(int vehicleId, DateTime dateCompare)
{
var currentMileage = _vehicleLogic.GetMaxMileage(vehicleId);
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
List<ReminderRecordViewModel> results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, dateCompare);
return results;
}
private bool GetAndUpdateVehicleUrgentOrPastDueReminders(int vehicleId)
{
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
//check if user wants auto-refresh past-due reminders
if (_config.GetUserConfig(User).EnableAutoReminderRefresh)
{
//check for past due reminders that are eligible for recurring.
var pastDueAndRecurring = result.Where(x => x.Urgency == ReminderUrgency.PastDue && x.IsRecurring);
if (pastDueAndRecurring.Any())
{
foreach (ReminderRecordViewModel reminderRecord in pastDueAndRecurring)
{
//update based on recurring intervals.
//pull reminderRecord based on ID
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(reminderRecord.Id);
existingReminder = _reminderHelper.GetUpdatedRecurringReminderRecord(existingReminder, null, null);
//save to db.
_reminderRecordDataAccess.SaveReminderRecordToVehicle(existingReminder);
//set urgency to not urgent so it gets excluded in count.
reminderRecord.Urgency = ReminderUrgency.NotUrgent;
}
}
}
//check for very urgent or past due reminders that were not eligible for recurring.
var pastDueAndUrgentReminders = result.Where(x => x.Urgency == ReminderUrgency.VeryUrgent || x.Urgency == ReminderUrgency.PastDue);
if (pastDueAndUrgentReminders.Any())
{
return true;
}
return false;
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
{
var result = GetAndUpdateVehicleUrgentOrPastDueReminders(vehicleId);
return Json(result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetReminderRecordsByVehicleId(int vehicleId)
{
var result = GetRemindersAndUrgency(vehicleId, DateTime.Now);
result = result.OrderByDescending(x => x.Urgency).ToList();
return PartialView("_ReminderRecords", result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetRecurringReminderRecordsByVehicleId(int vehicleId)
{
var result = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
result.RemoveAll(x => !x.IsRecurring);
return PartialView("_RecurringReminderSelector", result);
}
[HttpPost]
public IActionResult PushbackRecurringReminderRecord(int reminderRecordId)
{
var result = PushbackRecurringReminderRecordWithChecks(reminderRecordId, null, null);
return Json(result);
}
private bool PushbackRecurringReminderRecordWithChecks(int reminderRecordId, DateTime? currentDate, int? currentMileage)
{
try
{
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
if (existingReminder is not null && existingReminder.Id != default && existingReminder.IsRecurring)
{
existingReminder = _reminderHelper.GetUpdatedRecurringReminderRecord(existingReminder, currentDate, currentMileage);
//save to db.
var reminderUpdateResult = _reminderRecordDataAccess.SaveReminderRecordToVehicle(existingReminder);
if (!reminderUpdateResult)
{
_logger.LogError("Unable to update reminder either because the reminder no longer exists or is no longer recurring");
return false;
}
return true;
}
else
{
_logger.LogError("Unable to update reminder because it no longer exists.");
return false;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
[HttpPost]
public IActionResult SaveReminderRecordToVehicleId(ReminderRecordInput reminderRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), reminderRecord.VehicleId))
{
return Json(false);
}
var result = _reminderRecordDataAccess.SaveReminderRecordToVehicle(reminderRecord.ToReminderRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromReminderRecord(reminderRecord.ToReminderRecord(), reminderRecord.Id == default ? "reminderrecord.add" : "reminderrecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpPost]
public IActionResult GetAddReminderRecordPartialView(ReminderRecordInput? reminderModel)
{
if (reminderModel is not null)
{
return PartialView("_ReminderRecordModal", reminderModel);
}
else
{
return PartialView("_ReminderRecordModal", new ReminderRecordInput());
}
}
[HttpGet]
public IActionResult GetReminderRecordForEditById(int reminderRecordId)
{
var result = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new ReminderRecordInput
{
Id = result.Id,
Date = result.Date.ToShortDateString(),
Description = result.Description,
Notes = result.Notes,
VehicleId = result.VehicleId,
Mileage = result.Mileage,
Metric = result.Metric,
IsRecurring = result.IsRecurring,
UseCustomThresholds = result.UseCustomThresholds,
CustomThresholds = result.CustomThresholds,
ReminderMileageInterval = result.ReminderMileageInterval,
ReminderMonthInterval = result.ReminderMonthInterval,
CustomMileageInterval = result.CustomMileageInterval,
CustomMonthInterval = result.CustomMonthInterval,
Tags = result.Tags
};
return PartialView("_ReminderRecordModal", convertedResult);
}
private bool DeleteReminderRecordWithChecks(int reminderRecordId)
{
var existingRecord = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
var result = _reminderRecordDataAccess.DeleteReminderRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromReminderRecord(existingRecord, "reminderrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteReminderRecordById(int reminderRecordId)
{
var result = DeleteReminderRecordWithChecks(reminderRecordId);
return Json(result);
}
}
}

View File

@@ -1,131 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetCollisionRecordsByVehicleId(int vehicleId)
{
var result = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
}
return PartialView("_CollisionRecords", result);
}
[HttpPost]
public IActionResult SaveCollisionRecordToVehicleId(CollisionRecordInput collisionRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), collisionRecord.VehicleId))
{
return Json(false);
}
if (collisionRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = DateTime.Parse(collisionRecord.Date),
VehicleId = collisionRecord.VehicleId,
Mileage = collisionRecord.Mileage,
Notes = $"Auto Insert From Repair Record: {collisionRecord.Description}"
});
}
//move files from temp.
collisionRecord.Files = collisionRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
if (collisionRecord.Supplies.Any())
{
collisionRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(collisionRecord.Supplies, DateTime.Parse(collisionRecord.Date), collisionRecord.Description));
if (collisionRecord.CopySuppliesAttachment)
{
collisionRecord.Files.AddRange(GetSuppliesAttachments(collisionRecord.Supplies));
}
}
if (collisionRecord.DeletedRequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(collisionRecord.DeletedRequisitionHistory, collisionRecord.Description);
}
//push back any reminders
if (collisionRecord.ReminderRecordId.Any())
{
foreach (int reminderRecordId in collisionRecord.ReminderRecordId)
{
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(collisionRecord.Date), collisionRecord.Mileage);
}
}
var result = _collisionRecordDataAccess.SaveCollisionRecordToVehicle(collisionRecord.ToCollisionRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(collisionRecord.ToCollisionRecord(), collisionRecord.Id == default ? "repairrecord.add" : "repairrecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddCollisionRecordPartialView()
{
return PartialView("_CollisionRecordModal", new CollisionRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetCollisionRecordForEditById(int collisionRecordId)
{
var result = _collisionRecordDataAccess.GetCollisionRecordById(collisionRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new CollisionRecordInput
{
Id = result.Id,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Description = result.Description,
Mileage = result.Mileage,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags,
RequisitionHistory = result.RequisitionHistory,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields)
};
return PartialView("_CollisionRecordModal", convertedResult);
}
private bool DeleteCollisionRecordWithChecks(int collisionRecordId)
{
var existingRecord = _collisionRecordDataAccess.GetCollisionRecordById(collisionRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
//restore any requisitioned supplies.
if (existingRecord.RequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
}
var result = _collisionRecordDataAccess.DeleteCollisionRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "repairrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteCollisionRecordById(int collisionRecordId)
{
var result = DeleteCollisionRecordWithChecks(collisionRecordId);
return Json(result);
}
}
}

View File

@@ -1,657 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
using System.Globalization;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetReportPartialView(int vehicleId)
{
//get records
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
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);
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
var userConfig = _config.GetUserConfig(User);
var viewModel = new ReportViewModel();
//check if custom widgets are configured
viewModel.CustomWidgetsConfigured = _fileHelper.WidgetsExist();
//get totalCostMakeUp
viewModel.CostMakeUpForVehicle = 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)
};
//get costbymonth
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, 0));
allCosts.AddRange(_reportHelper.GetRepairRecordSum(collisionRecords, 0));
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, 0));
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, 0));
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, 0));
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, 0));
viewModel.CostForVehicleByMonth = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
{
MonthName = x.Key.MonthName,
Cost = x.Sum(y => y.Cost),
DistanceTraveled = x.Max(y => y.DistanceTraveled)
}).ToList();
//get reminders
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now);
viewModel.ReminderMakeUpForVehicle = new ReminderMakeUpForVehicle
{
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
};
//populate year dropdown.
var numbersArray = new List<int>();
if (serviceRecords.Any())
{
numbersArray.Add(serviceRecords.Min(x => x.Date.Year));
}
if (collisionRecords.Any())
{
numbersArray.Add(collisionRecords.Min(x => x.Date.Year));
}
if (gasRecords.Any())
{
numbersArray.Add(gasRecords.Min(x => x.Date.Year));
}
if (upgradeRecords.Any())
{
numbersArray.Add(upgradeRecords.Min(x => x.Date.Year));
}
if (odometerRecords.Any())
{
numbersArray.Add(odometerRecords.Min(x => x.Date.Year));
}
var minYear = numbersArray.Any() ? numbersArray.Min() : DateTime.Now.AddYears(-5).Year;
var yearDifference = DateTime.Now.Year - minYear + 1;
for (int i = 0; i < yearDifference; i++)
{
viewModel.Years.Add(DateTime.Now.AddYears(i * -1).Year);
}
//get collaborators
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
viewModel.Collaborators = collaborators;
//get MPG per month.
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleData.IsElectric, vehicleData.UseHours, userConfig.UseMPG, userConfig.UseUKMPG);
mileageData.RemoveAll(x => x.MilesPerGallon == default);
bool invertedFuelMileageUnit = fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l";
var monthlyMileageData = StaticHelper.GetBaseLineCostsNoMonthName();
monthlyMileageData.AddRange(mileageData.GroupBy(x => x.MonthId).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
Cost = x.Average(y => y.MilesPerGallon)
}));
monthlyMileageData = monthlyMileageData.GroupBy(x => x.MonthId).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
}).ToList();
if (invertedFuelMileageUnit)
{
foreach (CostForVehicleByMonth monthMileage in monthlyMileageData)
{
if (monthMileage.Cost != default)
{
monthMileage.Cost = 100 / monthMileage.Cost;
}
}
}
var mpgViewModel = new MPGForVehicleByMonth {
CostData = monthlyMileageData,
Unit = invertedFuelMileageUnit ? preferredFuelMileageUnit : fuelEconomyMileageUnit,
SortedCostData = (userConfig.UseMPG || invertedFuelMileageUnit) ? monthlyMileageData.OrderByDescending(x => x.Cost).ToList() : monthlyMileageData.OrderBy(x => x.Cost).ToList()
};
viewModel.FuelMileageForVehicleByMonth = mpgViewModel;
return PartialView("_Report", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetCollaboratorsForVehicle(int vehicleId)
{
var result = _userLogic.GetCollaboratorsForVehicle(vehicleId);
return PartialView("_Collaborators", result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult AddCollaboratorsToVehicle(int vehicleId, string username)
{
var result = _userLogic.AddCollaboratorToVehicle(vehicleId, username);
return Json(result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult DeleteCollaboratorFromVehicle(int userId, int vehicleId)
{
var result = _userLogic.DeleteCollaboratorFromVehicle(userId, vehicleId);
return Json(result);
}
[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 vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
var serviceRecords = vehicleRecords.ServiceRecords;
var gasRecords = vehicleRecords.GasRecords;
var collisionRecords = vehicleRecords.CollisionRecords;
var taxRecords = vehicleRecords.TaxRecords;
var upgradeRecords = vehicleRecords.UpgradeRecords;
var odometerRecords = vehicleRecords.OdometerRecords;
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);
odometerRecords.RemoveAll(x => x.Date.Year != year);
}
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
var userConfig = _config.GetUserConfig(User);
var totalDistanceTraveled = maxMileage - minMileage;
var totalDays = _vehicleLogic.GetOwnershipDays(vehicleData.PurchaseDate, vehicleData.SoldDate, serviceRecords, collisionRecords, gasRecords, upgradeRecords, odometerRecords, taxRecords);
var viewModel = new CostTableForVehicle
{
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),
TotalDistance = totalDistanceTraveled,
DistanceUnit = vehicleData.UseHours ? "Cost Per Hour" : userConfig.UseMPG ? "Cost Per Mile" : "Cost Per Kilometer",
NumberOfDays = totalDays
};
return PartialView("_CostTableReport", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd)
{
var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now.AddDays(daysToAdd));
var viewModel = new ReminderMakeUpForVehicle
{
NotUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.NotUrgent).Count(),
UrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.Urgent).Count(),
VeryUrgentCount = reminders.Where(x => x.Urgency == ReminderUrgency.VeryUrgent).Count(),
PastDueCount = reminders.Where(x => x.Urgency == ReminderUrgency.PastDue).Count()
};
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
{
DataType = ImportMode.ServiceRecord,
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
{
DataType = ImportMode.RepairRecord,
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
{
DataType = ImportMode.UpgradeRecord,
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
{
DataType = ImportMode.GasRecord,
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
{
DataType = ImportMode.TaxRecord,
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
{
DataType = ImportMode.OdometerRecord,
Date = x.Date,
Odometer = x.Mileage,
Files = x.Files
}));
}
if (exportTabs.Contains(ImportMode.NoteRecord))
{
var records = _noteDataAccess.GetNotesByVehicleId(vehicleId).Where(x => x.Files.Any());
attachmentData.AddRange(records.Select(x => new GenericReportModel
{
DataType = ImportMode.NoteRecord,
Date = DateTime.Now,
Odometer = 0,
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(OperationResponse.Failed());
}
return Json(OperationResponse.Succeed(result));
}
else
{
return Json(OperationResponse.Failed("No Attachments Found"));
}
}
public IActionResult GetReportParameters()
{
var viewModel = new ReportParameter() {
VisibleColumns = new List<string> {
nameof(GenericReportModel.DataType),
nameof(GenericReportModel.Date),
nameof(GenericReportModel.Odometer),
nameof(GenericReportModel.Description),
nameof(GenericReportModel.Cost),
nameof(GenericReportModel.Notes)
}
};
//get all extra fields from service records, repairs, upgrades, and tax records.
var recordTypes = new List<int>() { 0, 1, 3, 4 };
var extraFields = new List<string>();
foreach(int recordType in recordTypes)
{
extraFields.AddRange(_extraFieldDataAccess.GetExtraFieldsById(recordType).ExtraFields.Select(x => x.Name));
}
viewModel.ExtraFields = extraFields.Distinct().ToList();
return PartialView("_ReportParameters", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
public IActionResult GetVehicleHistory(int vehicleId, ReportParameter reportParameter)
{
var vehicleHistory = new VehicleHistoryViewModel();
vehicleHistory.ReportParameters = reportParameter;
vehicleHistory.VehicleData = _dataAccess.GetVehicleById(vehicleId);
var vehicleRecords = _vehicleLogic.GetVehicleRecords(vehicleId);
bool useMPG = _config.GetUserConfig(User).UseMPG;
bool useUKMPG = _config.GetUserConfig(User).UseUKMPG;
var gasViewModels = _gasHelper.GetGasRecordViewModels(vehicleRecords.GasRecords, useMPG, useUKMPG);
//filter by tags
if (reportParameter.Tags.Any())
{
if (reportParameter.TagFilter == TagFilter.Exclude)
{
vehicleRecords.OdometerRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.ServiceRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.CollisionRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.UpgradeRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.TaxRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
gasViewModels.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.GasRecords.RemoveAll(x => x.Tags.Any(y => reportParameter.Tags.Contains(y)));
}
else if (reportParameter.TagFilter == TagFilter.IncludeOnly)
{
vehicleRecords.OdometerRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.ServiceRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.CollisionRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.UpgradeRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.TaxRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
gasViewModels.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
vehicleRecords.GasRecords.RemoveAll(x => !x.Tags.Any(y => reportParameter.Tags.Contains(y)));
}
}
//filter by date range.
if (reportParameter.FilterByDateRange && !string.IsNullOrWhiteSpace(reportParameter.StartDate) && !string.IsNullOrWhiteSpace(reportParameter.EndDate))
{
var startDate = DateTime.Parse(reportParameter.StartDate).Date;
var endDate = DateTime.Parse(reportParameter.EndDate).Date;
//validate date range
if (endDate >= startDate) //allow for same day.
{
vehicleHistory.StartDate = reportParameter.StartDate;
vehicleHistory.EndDate = reportParameter.EndDate;
//remove all records with dates after the end date and dates before the start date.
vehicleRecords.OdometerRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
vehicleRecords.ServiceRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
vehicleRecords.CollisionRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
vehicleRecords.UpgradeRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
vehicleRecords.TaxRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
gasViewModels.RemoveAll(x => DateTime.Parse(x.Date).Date > endDate || DateTime.Parse(x.Date).Date < startDate);
vehicleRecords.GasRecords.RemoveAll(x => x.Date.Date > endDate || x.Date.Date < startDate);
}
}
var maxMileage = _vehicleLogic.GetMaxMileage(vehicleRecords);
vehicleHistory.Odometer = maxMileage.ToString("N0");
var minMileage = _vehicleLogic.GetMinMileage(vehicleRecords);
var distanceTraveled = maxMileage - minMileage;
if (!string.IsNullOrWhiteSpace(vehicleHistory.VehicleData.PurchaseDate))
{
var endDate = vehicleHistory.VehicleData.SoldDate;
int daysOwned = 0;
if (string.IsNullOrWhiteSpace(endDate))
{
endDate = DateTime.Now.ToShortDateString();
}
try
{
daysOwned = (DateTime.Parse(endDate) - DateTime.Parse(vehicleHistory.VehicleData.PurchaseDate)).Days;
vehicleHistory.DaysOwned = daysOwned.ToString("N0");
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
vehicleHistory.DaysOwned = string.Empty;
}
//calculate depreciation
var totalDepreciation = vehicleHistory.VehicleData.PurchasePrice - vehicleHistory.VehicleData.SoldPrice;
//we only calculate depreciation if a sold price is provided.
if (totalDepreciation != default && vehicleHistory.VehicleData.SoldPrice != default)
{
vehicleHistory.TotalDepreciation = totalDepreciation;
if (daysOwned != default)
{
vehicleHistory.DepreciationPerDay = Math.Abs(totalDepreciation / daysOwned);
}
if (distanceTraveled != default)
{
vehicleHistory.DepreciationPerMile = Math.Abs(totalDepreciation / distanceTraveled);
}
}
}
List<GenericReportModel> reportData = new List<GenericReportModel>();
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
vehicleHistory.DistanceUnit = vehicleHistory.VehicleData.UseHours ? "h" : useMPG ? "mi." : "km";
vehicleHistory.TotalGasCost = gasViewModels.Sum(x => x.Cost);
vehicleHistory.TotalCost = vehicleRecords.ServiceRecords.Sum(x => x.Cost) + vehicleRecords.CollisionRecords.Sum(x => x.Cost) + vehicleRecords.UpgradeRecords.Sum(x => x.Cost) + vehicleRecords.TaxRecords.Sum(x => x.Cost);
if (distanceTraveled != default)
{
vehicleHistory.DistanceTraveled = distanceTraveled.ToString("N0");
vehicleHistory.TotalCostPerMile = vehicleHistory.TotalCost / distanceTraveled;
vehicleHistory.TotalGasCostPerMile = vehicleHistory.TotalGasCost / distanceTraveled;
}
var averageMPG = "0";
if (gasViewModels.Any())
{
averageMPG = _gasHelper.GetAverageGasMileage(gasViewModels, useMPG);
}
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleHistory.VehicleData.IsElectric, vehicleHistory.VehicleData.UseHours, useMPG, useUKMPG);
if (fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l")
{
//conversion needed.
var newAverageMPG = decimal.Parse(averageMPG, NumberStyles.Any);
if (newAverageMPG != 0)
{
newAverageMPG = 100 / newAverageMPG;
}
averageMPG = newAverageMPG.ToString("F");
fuelEconomyMileageUnit = preferredFuelMileageUnit;
}
vehicleHistory.MPG = $"{averageMPG} {fuelEconomyMileageUnit}";
//insert servicerecords
reportData.AddRange(vehicleRecords.ServiceRecords.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Description = x.Description,
Notes = x.Notes,
Cost = x.Cost,
DataType = ImportMode.ServiceRecord,
ExtraFields = x.ExtraFields
}));
//repair records
reportData.AddRange(vehicleRecords.CollisionRecords.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Description = x.Description,
Notes = x.Notes,
Cost = x.Cost,
DataType = ImportMode.RepairRecord,
ExtraFields = x.ExtraFields
}));
reportData.AddRange(vehicleRecords.UpgradeRecords.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = x.Mileage,
Description = x.Description,
Notes = x.Notes,
Cost = x.Cost,
DataType = ImportMode.UpgradeRecord,
ExtraFields = x.ExtraFields
}));
reportData.AddRange(vehicleRecords.TaxRecords.Select(x => new GenericReportModel
{
Date = x.Date,
Odometer = 0,
Description = x.Description,
Notes = x.Notes,
Cost = x.Cost,
DataType = ImportMode.TaxRecord,
ExtraFields = x.ExtraFields
}));
vehicleHistory.VehicleHistory = reportData.OrderBy(x => x.Date).ThenBy(x => x.Odometer).ToList();
return PartialView("_VehicleHistory", vehicleHistory);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult GetMonthMPGByVehicle(int vehicleId, int year = 0)
{
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
var userConfig = _config.GetUserConfig(User);
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
var fuelEconomyMileageUnit = StaticHelper.GetFuelEconomyUnit(vehicleData.IsElectric, vehicleData.UseHours, userConfig.UseMPG, userConfig.UseUKMPG);
bool invertedFuelMileageUnit = fuelEconomyMileageUnit == "l/100km" && preferredFuelMileageUnit == "km/l";
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, userConfig.UseUKMPG);
if (year != 0)
{
mileageData.RemoveAll(x => DateTime.Parse(x.Date).Year != year);
}
mileageData.RemoveAll(x => x.MilesPerGallon == default);
var monthlyMileageData = StaticHelper.GetBaseLineCostsNoMonthName();
monthlyMileageData.AddRange(mileageData.GroupBy(x => x.MonthId).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
Cost = x.Average(y => y.MilesPerGallon)
}));
monthlyMileageData = monthlyMileageData.GroupBy(x => x.MonthId).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
}).ToList();
if (invertedFuelMileageUnit)
{
foreach (CostForVehicleByMonth monthMileage in monthlyMileageData)
{
if (monthMileage.Cost != default)
{
monthMileage.Cost = 100 / monthMileage.Cost;
}
}
}
var mpgViewModel = new MPGForVehicleByMonth
{
CostData = monthlyMileageData,
Unit = invertedFuelMileageUnit ? preferredFuelMileageUnit : fuelEconomyMileageUnit,
SortedCostData = (userConfig.UseMPG || invertedFuelMileageUnit) ? monthlyMileageData.OrderByDescending(x => x.Cost).ToList() : monthlyMileageData.OrderBy(x => x.Cost).ToList()
};
return PartialView("_MPGByMonthReport", mpgViewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult GetCostByMonthByVehicle(int vehicleId, List<ImportMode> selectedMetrics, int year = 0)
{
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
if (selectedMetrics.Contains(ImportMode.ServiceRecord))
{
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, year));
}
if (selectedMetrics.Contains(ImportMode.RepairRecord))
{
var repairRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetRepairRecordSum(repairRecords, year));
}
if (selectedMetrics.Contains(ImportMode.UpgradeRecord))
{
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, year));
}
if (selectedMetrics.Contains(ImportMode.GasRecord))
{
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, year));
}
if (selectedMetrics.Contains(ImportMode.TaxRecord))
{
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year));
}
if (selectedMetrics.Contains(ImportMode.OdometerRecord))
{
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, year));
}
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId }).OrderBy(x => x.Key.MonthId).Select(x => new CostForVehicleByMonth
{
MonthName = x.Key.MonthName,
Cost = x.Sum(y => y.Cost),
DistanceTraveled = x.Max(y => y.DistanceTraveled)
}).ToList();
return PartialView("_GasCostByMonthReport", groupedRecord);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult GetCostByMonthAndYearByVehicle(int vehicleId, List<ImportMode> selectedMetrics, int year = 0)
{
List<CostForVehicleByMonth> allCosts = StaticHelper.GetBaseLineCosts();
if (selectedMetrics.Contains(ImportMode.ServiceRecord))
{
var serviceRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetServiceRecordSum(serviceRecords, year, true));
}
if (selectedMetrics.Contains(ImportMode.RepairRecord))
{
var repairRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetRepairRecordSum(repairRecords, year, true));
}
if (selectedMetrics.Contains(ImportMode.UpgradeRecord))
{
var upgradeRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetUpgradeRecordSum(upgradeRecords, year, true));
}
if (selectedMetrics.Contains(ImportMode.GasRecord))
{
var gasRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetGasRecordSum(gasRecords, year, true));
}
if (selectedMetrics.Contains(ImportMode.TaxRecord))
{
var taxRecords = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetTaxRecordSum(taxRecords, year, true));
}
if (selectedMetrics.Contains(ImportMode.OdometerRecord))
{
var odometerRecords = _odometerRecordDataAccess.GetOdometerRecordsByVehicleId(vehicleId);
allCosts.AddRange(_reportHelper.GetOdometerRecordSum(odometerRecords, year, true));
}
var groupedRecord = allCosts.GroupBy(x => new { x.MonthName, x.MonthId, x.Year }).OrderByDescending(x=>x.Key.Year).Select(x => new CostForVehicleByMonth
{
Year = x.Key.Year,
MonthName = x.Key.MonthName,
Cost = x.Sum(y => y.Cost),
DistanceTraveled = x.Max(y => y.DistanceTraveled),
MonthId = x.Key.MonthId
}).ToList();
var vehicleData = _dataAccess.GetVehicleById(vehicleId);
var userConfig = _config.GetUserConfig(User);
var viewModel = new CostDistanceTableForVehicle { CostData = groupedRecord };
viewModel.DistanceUnit = vehicleData.UseHours ? "h" : userConfig.UseMPG ? "mi." : "km";
return PartialView("_CostDistanceTableReport", viewModel);
}
[HttpGet]
public IActionResult GetAdditionalWidgets()
{
var widgets = _fileHelper.GetWidgets();
return PartialView("_ReportWidgets", widgets);
}
}
}

View File

@@ -1,131 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetServiceRecordsByVehicleId(int vehicleId)
{
var result = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
}
return PartialView("_ServiceRecords", result);
}
[HttpPost]
public IActionResult SaveServiceRecordToVehicleId(ServiceRecordInput serviceRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), serviceRecord.VehicleId))
{
return Json(false);
}
if (serviceRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = DateTime.Parse(serviceRecord.Date),
VehicleId = serviceRecord.VehicleId,
Mileage = serviceRecord.Mileage,
Notes = $"Auto Insert From Service Record: {serviceRecord.Description}"
});
}
//move files from temp.
serviceRecord.Files = serviceRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
if (serviceRecord.Supplies.Any())
{
serviceRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(serviceRecord.Supplies, DateTime.Parse(serviceRecord.Date), serviceRecord.Description));
if (serviceRecord.CopySuppliesAttachment)
{
serviceRecord.Files.AddRange(GetSuppliesAttachments(serviceRecord.Supplies));
}
}
if (serviceRecord.DeletedRequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(serviceRecord.DeletedRequisitionHistory, serviceRecord.Description);
}
//push back any reminders
if (serviceRecord.ReminderRecordId.Any())
{
foreach (int reminderRecordId in serviceRecord.ReminderRecordId)
{
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(serviceRecord.Date), serviceRecord.Mileage);
}
}
var result = _serviceRecordDataAccess.SaveServiceRecordToVehicle(serviceRecord.ToServiceRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(serviceRecord.ToServiceRecord(), serviceRecord.Id == default ? "servicerecord.add" : "servicerecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddServiceRecordPartialView()
{
return PartialView("_ServiceRecordModal", new ServiceRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetServiceRecordForEditById(int serviceRecordId)
{
var result = _serviceRecordDataAccess.GetServiceRecordById(serviceRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new ServiceRecordInput
{
Id = result.Id,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Description = result.Description,
Mileage = result.Mileage,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags,
RequisitionHistory = result.RequisitionHistory,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields)
};
return PartialView("_ServiceRecordModal", convertedResult);
}
private bool DeleteServiceRecordWithChecks(int serviceRecordId)
{
var existingRecord = _serviceRecordDataAccess.GetServiceRecordById(serviceRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
//restore any requisitioned supplies.
if (existingRecord.RequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
}
var result = _serviceRecordDataAccess.DeleteServiceRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "servicerecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteServiceRecordById(int serviceRecordId)
{
var result = DeleteServiceRecordWithChecks(serviceRecordId);
return Json(result);
}
}
}

View File

@@ -1,215 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
private List<SupplyAvailability> CheckSupplyRecordsAvailability(List<SupplyUsage> supplyUsage)
{
//returns empty string if all supplies are available
var result = new List<SupplyAvailability>();
foreach (SupplyUsage supply in supplyUsage)
{
//get supply record.
var supplyData = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
if (supplyData == null)
{
result.Add(new SupplyAvailability { Missing = true });
}
else
{
result.Add(new SupplyAvailability { Missing = false, Description = supplyData.Description, Required = supply.Quantity, InStock = supplyData.Quantity });
}
}
return result;
}
private List<UploadedFiles> GetSuppliesAttachments(List<SupplyUsage> supplyUsage)
{
List<UploadedFiles> results = new List<UploadedFiles>();
foreach (SupplyUsage supply in supplyUsage)
{
var result = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
results.AddRange(result.Files);
}
return results;
}
private List<SupplyUsageHistory> RequisitionSupplyRecordsByUsage(List<SupplyUsage> supplyUsage, DateTime dateRequisitioned, string usageDescription)
{
List<SupplyUsageHistory> results = new List<SupplyUsageHistory>();
foreach (SupplyUsage supply in supplyUsage)
{
//get supply record.
var result = _supplyRecordDataAccess.GetSupplyRecordById(supply.SupplyId);
var unitCost = (result.Quantity != 0) ? result.Cost / result.Quantity : 0;
//deduct quantity used.
result.Quantity -= supply.Quantity;
//deduct cost.
result.Cost -= (supply.Quantity * unitCost);
//check decimal places to ensure that it always has a max of 3 decimal places.
var roundedDecimal = decimal.Round(result.Cost, 3);
if (roundedDecimal != result.Cost)
{
//Too many decimals
result.Cost = roundedDecimal;
}
//create new requisitionrrecord
var requisitionRecord = new SupplyUsageHistory
{
Id = supply.SupplyId,
Date = dateRequisitioned,
Description = usageDescription,
Quantity = supply.Quantity,
Cost = (supply.Quantity * unitCost)
};
result.RequisitionHistory.Add(requisitionRecord);
//save
_supplyRecordDataAccess.SaveSupplyRecordToVehicle(result);
requisitionRecord.Description = result.Description; //change the name of the description for plan/service/repair/upgrade records
requisitionRecord.PartNumber = result.PartNumber; //populate part number if not displayed in supplies modal.
results.Add(requisitionRecord);
}
return results;
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetSupplyRecordsByVehicleId(int vehicleId)
{
var result = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ToList();
}
return PartialView("_SupplyRecords", result);
}
[HttpGet]
public IActionResult GetSupplyRecordsForPlanRecordTemplate(int planRecordTemplateId)
{
var viewModel = new SupplyUsageViewModel();
var planRecordTemplate = _planRecordTemplateDataAccess.GetPlanRecordTemplateById(planRecordTemplateId);
if (planRecordTemplate != default && planRecordTemplate.VehicleId != default)
{
var supplies = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(planRecordTemplate.VehicleId);
if (_config.GetServerEnableShopSupplies())
{
supplies.AddRange(_supplyRecordDataAccess.GetSupplyRecordsByVehicleId(0)); // add shop supplies
}
supplies.RemoveAll(x => x.Quantity <= 0);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
supplies = supplies.OrderByDescending(x => x.Date).ToList();
}
else
{
supplies = supplies.OrderBy(x => x.Date).ToList();
}
viewModel.Supplies = supplies;
viewModel.Usage = planRecordTemplate.Supplies;
}
return PartialView("_SupplyUsage", viewModel);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetSupplyRecordsForRecordsByVehicleId(int vehicleId)
{
var result = _supplyRecordDataAccess.GetSupplyRecordsByVehicleId(vehicleId);
if (_config.GetServerEnableShopSupplies())
{
result.AddRange(_supplyRecordDataAccess.GetSupplyRecordsByVehicleId(0)); // add shop supplies
}
result.RemoveAll(x => x.Quantity <= 0);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ToList();
}
var viewModel = new SupplyUsageViewModel
{
Supplies = result
};
return PartialView("_SupplyUsage", viewModel);
}
[HttpPost]
public IActionResult SaveSupplyRecordToVehicleId(SupplyRecordInput supplyRecord)
{
//move files from temp.
supplyRecord.Files = supplyRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
var result = _supplyRecordDataAccess.SaveSupplyRecordToVehicle(supplyRecord.ToSupplyRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromSupplyRecord(supplyRecord.ToSupplyRecord(), supplyRecord.Id == default ? "supplyrecord.add" : "supplyrecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddSupplyRecordPartialView()
{
return PartialView("_SupplyRecordModal", new SupplyRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetSupplyRecordForEditById(int supplyRecordId)
{
var result = _supplyRecordDataAccess.GetSupplyRecordById(supplyRecordId);
if (result.RequisitionHistory.Any())
{
//requisition history when viewed through the supply is always immutable.
result.RequisitionHistory = result.RequisitionHistory.Select(x => new SupplyUsageHistory { Id = default, Cost = x.Cost, Description = x.Description, Date = x.Date, PartNumber = x.PartNumber, Quantity = x.Quantity }).ToList();
}
//convert to Input object.
var convertedResult = new SupplyRecordInput
{
Id = result.Id,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Description = result.Description,
PartNumber = result.PartNumber,
Quantity = result.Quantity,
PartSupplier = result.PartSupplier,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags,
RequisitionHistory = result.RequisitionHistory,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields)
};
return PartialView("_SupplyRecordModal", convertedResult);
}
private bool DeleteSupplyRecordWithChecks(int supplyRecordId)
{
var existingRecord = _supplyRecordDataAccess.GetSupplyRecordById(supplyRecordId);
if (existingRecord.VehicleId != default)
{
//security check only if not editing shop supply.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
}
var result = _supplyRecordDataAccess.DeleteSupplyRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromSupplyRecord(existingRecord, "supplyrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteSupplyRecordById(int supplyRecordId)
{
var result = DeleteSupplyRecordWithChecks(supplyRecordId);
return Json(result);
}
}
}

View File

@@ -1,121 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetTaxRecordsByVehicleId(int vehicleId)
{
var result = _taxRecordDataAccess.GetTaxRecordsByVehicleId(vehicleId);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ToList();
}
return PartialView("_TaxRecords", result);
}
[TypeFilter(typeof(CollaboratorFilter))]
[HttpPost]
public IActionResult CheckRecurringTaxRecords(int vehicleId)
{
try
{
var result = _vehicleLogic.UpdateRecurringTaxes(vehicleId);
return Json(result);
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return Json(false);
}
}
[HttpPost]
public IActionResult SaveTaxRecordToVehicleId(TaxRecordInput taxRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), taxRecord.VehicleId))
{
return Json(false);
}
//move files from temp.
taxRecord.Files = taxRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
//push back any reminders
if (taxRecord.ReminderRecordId.Any())
{
foreach (int reminderRecordId in taxRecord.ReminderRecordId)
{
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(taxRecord.Date), null);
}
}
var result = _taxRecordDataAccess.SaveTaxRecordToVehicle(taxRecord.ToTaxRecord());
_vehicleLogic.UpdateRecurringTaxes(taxRecord.VehicleId);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(taxRecord.ToTaxRecord(), taxRecord.Id == default ? "taxrecord.add" : "taxrecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddTaxRecordPartialView()
{
return PartialView("_TaxRecordModal", new TaxRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetTaxRecordForEditById(int taxRecordId)
{
var result = _taxRecordDataAccess.GetTaxRecordById(taxRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new TaxRecordInput
{
Id = result.Id,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Description = result.Description,
Notes = result.Notes,
VehicleId = result.VehicleId,
IsRecurring = result.IsRecurring,
RecurringInterval = result.RecurringInterval,
CustomMonthInterval = result.CustomMonthInterval,
Files = result.Files,
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields)
};
return PartialView("_TaxRecordModal", convertedResult);
}
private bool DeleteTaxRecordWithChecks(int taxRecordId)
{
var existingRecord = _taxRecordDataAccess.GetTaxRecordById(taxRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
var result = _taxRecordDataAccess.DeleteTaxRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromTaxRecord(existingRecord, "taxrecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteTaxRecordById(int taxRecordId)
{
var result = DeleteTaxRecordWithChecks(taxRecordId);
return Json(result);
}
}
}

View File

@@ -1,131 +0,0 @@
using CarCareTracker.Filter;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
namespace CarCareTracker.Controllers
{
public partial class VehicleController
{
[TypeFilter(typeof(CollaboratorFilter))]
[HttpGet]
public IActionResult GetUpgradeRecordsByVehicleId(int vehicleId)
{
var result = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
bool _useDescending = _config.GetUserConfig(User).UseDescending;
if (_useDescending)
{
result = result.OrderByDescending(x => x.Date).ThenByDescending(x => x.Mileage).ToList();
}
else
{
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
}
return PartialView("_UpgradeRecords", result);
}
[HttpPost]
public IActionResult SaveUpgradeRecordToVehicleId(UpgradeRecordInput upgradeRecord)
{
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), upgradeRecord.VehicleId))
{
return Json(false);
}
if (upgradeRecord.Id == default && _config.GetUserConfig(User).EnableAutoOdometerInsert)
{
_odometerLogic.AutoInsertOdometerRecord(new OdometerRecord
{
Date = DateTime.Parse(upgradeRecord.Date),
VehicleId = upgradeRecord.VehicleId,
Mileage = upgradeRecord.Mileage,
Notes = $"Auto Insert From Upgrade Record: {upgradeRecord.Description}"
});
}
//move files from temp.
upgradeRecord.Files = upgradeRecord.Files.Select(x => { return new UploadedFiles { Name = x.Name, Location = _fileHelper.MoveFileFromTemp(x.Location, "documents/") }; }).ToList();
if (upgradeRecord.Supplies.Any())
{
upgradeRecord.RequisitionHistory.AddRange(RequisitionSupplyRecordsByUsage(upgradeRecord.Supplies, DateTime.Parse(upgradeRecord.Date), upgradeRecord.Description));
if (upgradeRecord.CopySuppliesAttachment)
{
upgradeRecord.Files.AddRange(GetSuppliesAttachments(upgradeRecord.Supplies));
}
}
if (upgradeRecord.DeletedRequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(upgradeRecord.DeletedRequisitionHistory, upgradeRecord.Description);
}
//push back any reminders
if (upgradeRecord.ReminderRecordId.Any())
{
foreach (int reminderRecordId in upgradeRecord.ReminderRecordId)
{
PushbackRecurringReminderRecordWithChecks(reminderRecordId, DateTime.Parse(upgradeRecord.Date), upgradeRecord.Mileage);
}
}
var result = _upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(upgradeRecord.ToUpgradeRecord());
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(upgradeRecord.ToUpgradeRecord(), upgradeRecord.Id == default ? "upgraderecord.add" : "upgraderecord.update", User.Identity.Name));
}
return Json(result);
}
[HttpGet]
public IActionResult GetAddUpgradeRecordPartialView()
{
return PartialView("_UpgradeRecordModal", new UpgradeRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetUpgradeRecordForEditById(int upgradeRecordId)
{
var result = _upgradeRecordDataAccess.GetUpgradeRecordById(upgradeRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), result.VehicleId))
{
return Redirect("/Error/Unauthorized");
}
//convert to Input object.
var convertedResult = new UpgradeRecordInput
{
Id = result.Id,
Cost = result.Cost,
Date = result.Date.ToShortDateString(),
Description = result.Description,
Mileage = result.Mileage,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags,
RequisitionHistory = result.RequisitionHistory,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields)
};
return PartialView("_UpgradeRecordModal", convertedResult);
}
private bool DeleteUpgradeRecordWithChecks(int upgradeRecordId)
{
var existingRecord = _upgradeRecordDataAccess.GetUpgradeRecordById(upgradeRecordId);
//security check.
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId))
{
return false;
}
//restore any requisitioned supplies.
if (existingRecord.RequisitionHistory.Any())
{
_vehicleLogic.RestoreSupplyRecordsByUsage(existingRecord.RequisitionHistory, existingRecord.Description);
}
var result = _upgradeRecordDataAccess.DeleteUpgradeRecordById(existingRecord.Id);
if (result)
{
StaticHelper.NotifyAsync(_config.GetWebHookUrl(), WebHookPayload.FromGenericRecord(existingRecord, "upgraderecord.delete", User.Identity.Name));
}
return result;
}
[HttpPost]
public IActionResult DeleteUpgradeRecordById(int upgradeRecordId)
{
var result = DeleteUpgradeRecordWithChecks(upgradeRecordId);
return Json(result);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
namespace CarCareTracker.Models
{
public enum DashboardMetric
{
Default = 0,
TotalCost = 1,
CostPerMile = 2
}
}

View File

@@ -12,7 +12,6 @@
SupplyRecord = 7,
Dashboard = 8,
PlanRecord = 9,
OdometerRecord = 10,
VehicleRecord = 11
OdometerRecord = 10
}
}

View File

@@ -1,10 +0,0 @@
namespace CarCareTracker.Models
{
public enum KioskMode
{
Vehicle = 0,
Plan = 1,
Reminder = 2,
Cycle = 3
}
}

View File

@@ -2,7 +2,6 @@
{
public enum ReminderMileageInterval
{
Other = 0,
FiftyMiles = 50,
OneHundredMiles = 100,
FiveHundredMiles = 500,
@@ -15,9 +14,7 @@
FifteenThousandMiles = 15000,
TwentyThousandMiles = 20000,
ThirtyThousandMiles = 30000,
FortyThousandMiles = 40000,
FiftyThousandMiles = 50000,
SixtyThousandMiles = 60000,
OneHundredThousandMiles = 100000,
OneHundredFiftyThousandMiles = 150000
}

View File

@@ -2,7 +2,6 @@
{
public enum ReminderMonthInterval
{
Other = 0,
OneMonth = 1,
ThreeMonths = 3,
SixMonths = 6,

View File

@@ -1,8 +0,0 @@
namespace CarCareTracker.Models
{
public enum TagFilter
{
Exclude = 0,
IncludeOnly = 1
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class CollisionRecordDataAccess : ICollisionRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "collisionrecords";
public List<CollisionRecord> GetCollisionRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<CollisionRecord>(tableName);
var collisionRecords = table.Find(Query.EQ(nameof(CollisionRecord.VehicleId), vehicleId));
return collisionRecords.ToList() ?? new List<CollisionRecord>();
};
}
public CollisionRecord GetCollisionRecordById(int collisionRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<CollisionRecord>(tableName);
return table.FindById(collisionRecordId);
};
}
public bool DeleteCollisionRecordById(int collisionRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<CollisionRecord>(tableName);
table.Delete(collisionRecordId);
return true;
};
}
public bool SaveCollisionRecordToVehicle(CollisionRecord collisionRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<CollisionRecord>(tableName);
table.Upsert(collisionRecord);
return true;
};
}
public bool DeleteAllCollisionRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<CollisionRecord>(tableName);
var collisionRecords = table.DeleteMany(Query.EQ(nameof(CollisionRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class GasRecordDataAccess: IGasRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "gasrecords";
public List<GasRecord> GetGasRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<GasRecord>(tableName);
var gasRecords = table.Find(Query.EQ(nameof(GasRecord.VehicleId), vehicleId));
return gasRecords.ToList() ?? new List<GasRecord>();
};
}
public GasRecord GetGasRecordById(int gasRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<GasRecord>(tableName);
return table.FindById(gasRecordId);
};
}
public bool DeleteGasRecordById(int gasRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<GasRecord>(tableName);
table.Delete(gasRecordId);
return true;
};
}
public bool SaveGasRecordToVehicle(GasRecord gasRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<GasRecord>(tableName);
table.Upsert(gasRecord);
return true;
};
}
public bool DeleteAllGasRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<GasRecord>(tableName);
var gasRecords = table.DeleteMany(Query.EQ(nameof(GasRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class CollisionRecordDataAccess : ICollisionRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "collisionrecords";
public CollisionRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<CollisionRecord> GetCollisionRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<CollisionRecord>(tableName);
var collisionRecords = table.Find(Query.EQ(nameof(CollisionRecord.VehicleId), vehicleId));
return collisionRecords.ToList() ?? new List<CollisionRecord>();
}
public CollisionRecord GetCollisionRecordById(int collisionRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<CollisionRecord>(tableName);
return table.FindById(collisionRecordId);
}
public bool DeleteCollisionRecordById(int collisionRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<CollisionRecord>(tableName);
table.Delete(collisionRecordId);
db.Checkpoint();
return true;
}
public bool SaveCollisionRecordToVehicle(CollisionRecord collisionRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<CollisionRecord>(tableName);
table.Upsert(collisionRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllCollisionRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<CollisionRecord>(tableName);
var collisionRecords = table.DeleteMany(Query.EQ(nameof(CollisionRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,30 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
namespace CarCareTracker.External.Implementations
{
public class ExtraFieldDataAccess : IExtraFieldDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "extrafields";
public ExtraFieldDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public RecordExtraField GetExtraFieldsById(int importMode)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<RecordExtraField>(tableName);
return table.FindById(importMode) ?? new RecordExtraField();
}
public bool SaveExtraFields(RecordExtraField record)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<RecordExtraField>(tableName);
table.Upsert(record);
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class GasRecordDataAccess : IGasRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "gasrecords";
public GasRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<GasRecord> GetGasRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<GasRecord>(tableName);
var gasRecords = table.Find(Query.EQ(nameof(GasRecord.VehicleId), vehicleId));
return gasRecords.ToList() ?? new List<GasRecord>();
}
public GasRecord GetGasRecordById(int gasRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<GasRecord>(tableName);
return table.FindById(gasRecordId);
}
public bool DeleteGasRecordById(int gasRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<GasRecord>(tableName);
table.Delete(gasRecordId);
db.Checkpoint();
return true;
}
public bool SaveGasRecordToVehicle(GasRecord gasRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<GasRecord>(tableName);
table.Upsert(gasRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllGasRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<GasRecord>(tableName);
var gasRecords = table.DeleteMany(Query.EQ(nameof(GasRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class NoteDataAccess : INoteDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "notes";
public NoteDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<Note> GetNotesByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Note>(tableName);
var noteToReturn = table.Find(Query.EQ(nameof(Note.VehicleId), vehicleId));
return noteToReturn.ToList() ?? new List<Note>();
}
public Note GetNoteById(int noteId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Note>(tableName);
return table.FindById(noteId);
}
public bool SaveNoteToVehicle(Note note)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Note>(tableName);
table.Upsert(note);
db.Checkpoint();
return true;
}
public bool DeleteNoteById(int noteId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Note>(tableName);
table.Delete(noteId);
db.Checkpoint();
return true;
}
public bool DeleteAllNotesByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Note>(tableName);
var notes = table.DeleteMany(Query.EQ(nameof(Note.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class OdometerRecordDataAccess : IOdometerRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "odometerrecords";
public OdometerRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<OdometerRecord> GetOdometerRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<OdometerRecord>(tableName);
var odometerRecords = table.Find(Query.EQ(nameof(OdometerRecord.VehicleId), vehicleId));
return odometerRecords.ToList() ?? new List<OdometerRecord>();
}
public OdometerRecord GetOdometerRecordById(int odometerRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<OdometerRecord>(tableName);
return table.FindById(odometerRecordId);
}
public bool DeleteOdometerRecordById(int odometerRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<OdometerRecord>(tableName);
table.Delete(odometerRecordId);
db.Checkpoint();
return true;
}
public bool SaveOdometerRecordToVehicle(OdometerRecord odometerRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<OdometerRecord>(tableName);
table.Upsert(odometerRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllOdometerRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<OdometerRecord>(tableName);
var odometerRecords = table.DeleteMany(Query.EQ(nameof(OdometerRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class PlanRecordDataAccess : IPlanRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "planrecords";
public PlanRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<PlanRecord> GetPlanRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
var planRecords = table.Find(Query.EQ(nameof(PlanRecord.VehicleId), vehicleId));
return planRecords.ToList() ?? new List<PlanRecord>();
}
public PlanRecord GetPlanRecordById(int planRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
return table.FindById(planRecordId);
}
public bool DeletePlanRecordById(int planRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
table.Delete(planRecordId);
db.Checkpoint();
return true;
}
public bool SavePlanRecordToVehicle(PlanRecord planRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
table.Upsert(planRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllPlanRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
var planRecords = table.DeleteMany(Query.EQ(nameof(PlanRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class PlanRecordTemplateDataAccess : IPlanRecordTemplateDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "planrecordtemplates";
public PlanRecordTemplateDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<PlanRecordInput> GetPlanRecordTemplatesByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecordInput>(tableName);
var planRecords = table.Find(Query.EQ(nameof(PlanRecordInput.VehicleId), vehicleId));
return planRecords.ToList() ?? new List<PlanRecordInput>();
}
public PlanRecordInput GetPlanRecordTemplateById(int planRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecordInput>(tableName);
return table.FindById(planRecordId);
}
public bool DeletePlanRecordTemplateById(int planRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecordInput>(tableName);
table.Delete(planRecordId);
db.Checkpoint();
return true;
}
public bool SavePlanRecordTemplateToVehicle(PlanRecordInput planRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecordInput>(tableName);
table.Upsert(planRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllPlanRecordTemplatesByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<PlanRecord>(tableName);
var planRecords = table.DeleteMany(Query.EQ(nameof(PlanRecordInput.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class ReminderRecordDataAccess : IReminderRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "reminderrecords";
public ReminderRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<ReminderRecord> GetReminderRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ReminderRecord>(tableName);
var reminderRecords = table.Find(Query.EQ(nameof(ReminderRecord.VehicleId), vehicleId));
return reminderRecords.ToList() ?? new List<ReminderRecord>();
}
public ReminderRecord GetReminderRecordById(int reminderRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ReminderRecord>(tableName);
return table.FindById(reminderRecordId);
}
public bool DeleteReminderRecordById(int reminderRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ReminderRecord>(tableName);
table.Delete(reminderRecordId);
db.Checkpoint();
return true;
}
public bool SaveReminderRecordToVehicle(ReminderRecord reminderRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ReminderRecord>(tableName);
table.Upsert(reminderRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllReminderRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ReminderRecord>(tableName);
var reminderRecords = table.DeleteMany(Query.EQ(nameof(ReminderRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class ServiceRecordDataAccess : IServiceRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "servicerecords";
public ServiceRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<ServiceRecord> GetServiceRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ServiceRecord>(tableName);
var serviceRecords = table.Find(Query.EQ(nameof(ServiceRecord.VehicleId), vehicleId));
return serviceRecords.ToList() ?? new List<ServiceRecord>();
}
public ServiceRecord GetServiceRecordById(int serviceRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ServiceRecord>(tableName);
return table.FindById(serviceRecordId);
}
public bool DeleteServiceRecordById(int serviceRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ServiceRecord>(tableName);
table.Delete(serviceRecordId);
db.Checkpoint();
return true;
}
public bool SaveServiceRecordToVehicle(ServiceRecord serviceRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ServiceRecord>(tableName);
table.Upsert(serviceRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllServiceRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<ServiceRecord>(tableName);
var serviceRecords = table.DeleteMany(Query.EQ(nameof(ServiceRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class SupplyRecordDataAccess : ISupplyRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "supplyrecords";
public SupplyRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<SupplyRecord> GetSupplyRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<SupplyRecord>(tableName);
var supplyRecords = table.Find(Query.EQ(nameof(SupplyRecord.VehicleId), vehicleId));
return supplyRecords.ToList() ?? new List<SupplyRecord>();
}
public SupplyRecord GetSupplyRecordById(int supplyRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<SupplyRecord>(tableName);
return table.FindById(supplyRecordId);
}
public bool DeleteSupplyRecordById(int supplyRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<SupplyRecord>(tableName);
table.Delete(supplyRecordId);
db.Checkpoint();
return true;
}
public bool SaveSupplyRecordToVehicle(SupplyRecord supplyRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<SupplyRecord>(tableName);
table.Upsert(supplyRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllSupplyRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<SupplyRecord>(tableName);
var supplyRecords = table.DeleteMany(Query.EQ(nameof(SupplyRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class TaxRecordDataAccess : ITaxRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "taxrecords";
public TaxRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<TaxRecord> GetTaxRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<TaxRecord>(tableName);
var taxRecords = table.Find(Query.EQ(nameof(TaxRecord.VehicleId), vehicleId));
return taxRecords.ToList() ?? new List<TaxRecord>();
}
public TaxRecord GetTaxRecordById(int taxRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<TaxRecord>(tableName);
return table.FindById(taxRecordId);
}
public bool DeleteTaxRecordById(int taxRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<TaxRecord>(tableName);
table.Delete(taxRecordId);
db.Checkpoint();
return true;
}
public bool SaveTaxRecordToVehicle(TaxRecord taxRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<TaxRecord>(tableName);
table.Upsert(taxRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllTaxRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<TaxRecord>(tableName);
var taxRecords = table.DeleteMany(Query.EQ(nameof(TaxRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,53 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class TokenRecordDataAccess : ITokenRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "tokenrecords";
public TokenRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<Token> GetTokens()
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Token>(tableName);
return table.FindAll().ToList();
}
public Token GetTokenRecordByBody(string tokenBody)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Token>(tableName);
var tokenRecord = table.FindOne(Query.EQ(nameof(Token.Body), tokenBody));
return tokenRecord ?? new Token();
}
public Token GetTokenRecordByEmailAddress(string emailAddress)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Token>(tableName);
var tokenRecord = table.FindOne(Query.EQ(nameof(Token.EmailAddress), emailAddress));
return tokenRecord ?? new Token();
}
public bool CreateNewToken(Token token)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Token>(tableName);
table.Insert(token);
db.Checkpoint();
return true;
}
public bool DeleteToken(int tokenId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Token>(tableName);
table.Delete(tokenId);
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,54 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class UpgradeRecordDataAccess : IUpgradeRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
public UpgradeRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
private static string tableName = "upgraderecords";
public List<UpgradeRecord> GetUpgradeRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UpgradeRecord>(tableName);
var upgradeRecords = table.Find(Query.EQ(nameof(UpgradeRecord.VehicleId), vehicleId));
return upgradeRecords.ToList() ?? new List<UpgradeRecord>();
}
public UpgradeRecord GetUpgradeRecordById(int upgradeRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UpgradeRecord>(tableName);
return table.FindById(upgradeRecordId);
}
public bool DeleteUpgradeRecordById(int upgradeRecordId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UpgradeRecord>(tableName);
table.Delete(upgradeRecordId);
db.Checkpoint();
return true;
}
public bool SaveUpgradeRecordToVehicle(UpgradeRecord upgradeRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UpgradeRecord>(tableName);
table.Upsert(upgradeRecord);
db.Checkpoint();
return true;
}
public bool DeleteAllUpgradeRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UpgradeRecord>(tableName);
var upgradeRecords = table.DeleteMany(Query.EQ(nameof(UpgradeRecord.VehicleId), vehicleId));
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,81 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
namespace CarCareTracker.External.Implementations
{
public class UserAccessDataAccess : IUserAccessDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "useraccessrecords";
public UserAccessDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
/// <summary>
/// Gets a list of vehicles user have access to.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<UserAccess> GetUserAccessByUserId(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x => x.Id.UserId == userId).ToList();
}
public UserAccess GetUserAccessByVehicleAndUserId(int userId, int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x => x.Id.UserId == userId && x.Id.VehicleId == vehicleId).FirstOrDefault();
}
public List<UserAccess> GetUserAccessByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x => x.Id.VehicleId == vehicleId).ToList();
}
public bool SaveUserAccess(UserAccess userAccess)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
table.Upsert(userAccess);
db.Checkpoint();
return true;
}
public bool DeleteUserAccess(int userId, int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x => x.Id.UserId == userId && x.Id.VehicleId == vehicleId);
db.Checkpoint();
return true;
}
/// <summary>
/// Delete all access records when a vehicle is deleted.
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByVehicleId(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x => x.Id.VehicleId == vehicleId);
db.Checkpoint();
return true;
}
/// <summary>
/// Delee all access records when a user is deleted.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByUserId(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x => x.Id.UserId == userId);
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,38 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using CarCareTracker.Helper;
namespace CarCareTracker.External.Implementations
{
public class UserConfigDataAccess : IUserConfigDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "userconfigrecords";
public UserConfigDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public UserConfigData GetUserConfig(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserConfigData>(tableName);
return table.FindById(userId);
}
public bool SaveUserConfig(UserConfigData userConfigData)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserConfigData>(tableName);
table.Upsert(userConfigData);
db.Checkpoint();
return true;
}
public bool DeleteUserConfig(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserConfigData>(tableName);
table.Delete(userId);
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,60 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using LiteDB;
using CarCareTracker.Helper;
namespace CarCareTracker.External.Implementations
{
public class UserRecordDataAccess : IUserRecordDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "userrecords";
public UserRecordDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public List<UserData> GetUsers()
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
return table.FindAll().ToList();
}
public UserData GetUserRecordByUserName(string userName)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindOne(Query.EQ(nameof(UserData.UserName), userName));
return userRecord ?? new UserData();
}
public UserData GetUserRecordByEmailAddress(string emailAddress)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindOne(Query.EQ(nameof(UserData.EmailAddress), emailAddress));
return userRecord ?? new UserData();
}
public UserData GetUserRecordById(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindById(userId);
return userRecord ?? new UserData();
}
public bool SaveUserRecord(UserData userRecord)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
table.Upsert(userRecord);
db.Checkpoint();
return true;
}
public bool DeleteUserRecord(int userId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<UserData>(tableName);
table.Delete(userId);
db.Checkpoint();
return true;
}
}
}

View File

@@ -1,44 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
namespace CarCareTracker.External.Implementations
{
public class VehicleDataAccess : IVehicleDataAccess
{
private ILiteDBHelper _liteDB { get; set; }
private static string tableName = "vehicles";
public VehicleDataAccess(ILiteDBHelper liteDB)
{
_liteDB = liteDB;
}
public bool SaveVehicle(Vehicle vehicle)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Vehicle>(tableName);
var result = table.Upsert(vehicle);
db.Checkpoint();
return true;
}
public bool DeleteVehicle(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Vehicle>(tableName);
var result = table.Delete(vehicleId);
db.Checkpoint();
return result;
}
public List<Vehicle> GetVehicles()
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Vehicle>(tableName);
return table.FindAll().ToList();
}
public Vehicle GetVehicleById(int vehicleId)
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<Vehicle>(tableName);
return table.FindById(vehicleId);
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class NoteDataAccess: INoteDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "notes";
public List<Note> GetNotesByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Note>(tableName);
var noteToReturn = table.Find(Query.EQ(nameof(Note.VehicleId), vehicleId));
return noteToReturn.ToList() ?? new List<Note>();
};
}
public Note GetNoteById(int noteId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Note>(tableName);
return table.FindById(noteId);
};
}
public bool SaveNoteToVehicle(Note note)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Note>(tableName);
table.Upsert(note);
return true;
};
}
public bool DeleteNoteById(int noteId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Note>(tableName);
table.Delete(noteId);
return true;
};
}
public bool DeleteAllNotesByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Note>(tableName);
var notes = table.DeleteMany(Query.EQ(nameof(Note.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class OdometerRecordDataAccess : IOdometerRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "odometerrecords";
public List<OdometerRecord> GetOdometerRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<OdometerRecord>(tableName);
var odometerRecords = table.Find(Query.EQ(nameof(OdometerRecord.VehicleId), vehicleId));
return odometerRecords.ToList() ?? new List<OdometerRecord>();
};
}
public OdometerRecord GetOdometerRecordById(int odometerRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<OdometerRecord>(tableName);
return table.FindById(odometerRecordId);
};
}
public bool DeleteOdometerRecordById(int odometerRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<OdometerRecord>(tableName);
table.Delete(odometerRecordId);
return true;
};
}
public bool SaveOdometerRecordToVehicle(OdometerRecord odometerRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<OdometerRecord>(tableName);
table.Upsert(odometerRecord);
return true;
};
}
public bool DeleteAllOdometerRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<OdometerRecord>(tableName);
var odometerRecords = table.DeleteMany(Query.EQ(nameof(OdometerRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class PlanRecordDataAccess : IPlanRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "planrecords";
public List<PlanRecord> GetPlanRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<PlanRecord>(tableName);
var planRecords = table.Find(Query.EQ(nameof(PlanRecord.VehicleId), vehicleId));
return planRecords.ToList() ?? new List<PlanRecord>();
};
}
public PlanRecord GetPlanRecordById(int planRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<PlanRecord>(tableName);
return table.FindById(planRecordId);
};
}
public bool DeletePlanRecordById(int planRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<PlanRecord>(tableName);
table.Delete(planRecordId);
return true;
};
}
public bool SavePlanRecordToVehicle(PlanRecord planRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<PlanRecord>(tableName);
table.Upsert(planRecord);
return true;
};
}
public bool DeleteAllPlanRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<PlanRecord>(tableName);
var planRecords = table.DeleteMany(Query.EQ(nameof(PlanRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -1,161 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGCollisionRecordDataAccess : ICollisionRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGCollisionRecordDataAccess> _logger;
private static string tableName = "collisionrecords";
public PGCollisionRecordDataAccess(IConfiguration config, ILogger<PGCollisionRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<CollisionRecord> GetCollisionRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<CollisionRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
CollisionRecord collisionRecord = JsonSerializer.Deserialize<CollisionRecord>(reader["data"] as string);
results.Add(collisionRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<CollisionRecord>();
}
}
public CollisionRecord GetCollisionRecordById(int collisionRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new CollisionRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", collisionRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
CollisionRecord collisionRecord = JsonSerializer.Deserialize<CollisionRecord>(reader["data"] as string);
result = collisionRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new CollisionRecord();
}
}
public bool DeleteCollisionRecordById(int collisionRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", collisionRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveCollisionRecordToVehicle(CollisionRecord collisionRecord)
{
try
{
if (collisionRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", collisionRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
collisionRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (collisionRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(collisionRecord);
ctextU.Parameters.AddWithValue("id", collisionRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return collisionRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(collisionRecord);
ctext.Parameters.AddWithValue("id", collisionRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllCollisionRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,76 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGExtraFieldDataAccess : IExtraFieldDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGExtraFieldDataAccess> _logger;
private static string tableName = "extrafields";
public PGExtraFieldDataAccess(IConfiguration config, ILogger<PGExtraFieldDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT primary key, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public RecordExtraField GetExtraFieldsById(int importMode)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var results = new RecordExtraField();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", importMode);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
RecordExtraField result = JsonSerializer.Deserialize<RecordExtraField>(reader["data"] as string);
results = result;
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new RecordExtraField();
}
}
public bool SaveExtraFields(RecordExtraField record)
{
try
{
var existingRecord = GetExtraFieldsById(record.Id);
string cmd = $"INSERT INTO app.{tableName} (id, data) VALUES(@id, CAST(@data AS jsonb)) ON CONFLICT(id) DO UPDATE SET data = CAST(@data AS jsonb)";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", record.Id);
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGGasRecordDataAccess: IGasRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGGasRecordDataAccess> _logger;
private static string tableName = "gasrecords";
public PGGasRecordDataAccess(IConfiguration config, ILogger<PGGasRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<GasRecord> GetGasRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<GasRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
GasRecord gasRecord = JsonSerializer.Deserialize<GasRecord>(reader["data"] as string);
results.Add(gasRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<GasRecord>();
}
}
public GasRecord GetGasRecordById(int gasRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new GasRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", gasRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
GasRecord gasRecord = JsonSerializer.Deserialize<GasRecord>(reader["data"] as string);
result = gasRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new GasRecord();
}
}
public bool DeleteGasRecordById(int gasRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", gasRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveGasRecordToVehicle(GasRecord gasRecord)
{
try
{
if (gasRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", gasRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
gasRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (gasRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(gasRecord);
ctextU.Parameters.AddWithValue("id", gasRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return gasRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(gasRecord);
ctext.Parameters.AddWithValue("id", gasRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllGasRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,154 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGNoteDataAccess: INoteDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGNoteDataAccess> _logger;
private static string tableName = "notes";
public PGNoteDataAccess(IConfiguration config, ILogger<PGNoteDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<Note> GetNotesByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<Note>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Note note = JsonSerializer.Deserialize<Note>(reader["data"] as string);
results.Add(note);
}
}
return results;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<Note>();
}
}
public Note GetNoteById(int noteId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new Note();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", noteId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Note note = JsonSerializer.Deserialize<Note>(reader["data"] as string);
result = note;
}
}
return result;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Note();
}
}
public bool SaveNoteToVehicle(Note note)
{
try
{
if (note.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", note.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
note.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (note.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(note);
ctextU.Parameters.AddWithValue("id", note.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return note.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(note);
ctext.Parameters.AddWithValue("id", note.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteNoteById(int noteId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", noteId);
return ctext.ExecuteNonQuery() > 0;
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllNotesByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGOdometerRecordDataAccess : IOdometerRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGOdometerRecordDataAccess> _logger;
private static string tableName = "odometerrecords";
public PGOdometerRecordDataAccess(IConfiguration config, ILogger<PGOdometerRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<OdometerRecord> GetOdometerRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<OdometerRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
OdometerRecord odometerRecord = JsonSerializer.Deserialize<OdometerRecord>(reader["data"] as string);
results.Add(odometerRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<OdometerRecord>();
}
}
public OdometerRecord GetOdometerRecordById(int odometerRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new OdometerRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", odometerRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
OdometerRecord odometerRecord = JsonSerializer.Deserialize<OdometerRecord>(reader["data"] as string);
result = odometerRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new OdometerRecord();
}
}
public bool DeleteOdometerRecordById(int odometerRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", odometerRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveOdometerRecordToVehicle(OdometerRecord odometerRecord)
{
try
{
if (odometerRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", odometerRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
odometerRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (odometerRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(odometerRecord);
ctextU.Parameters.AddWithValue("id", odometerRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return odometerRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(odometerRecord);
ctext.Parameters.AddWithValue("id", odometerRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllOdometerRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGPlanRecordDataAccess : IPlanRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGPlanRecordDataAccess> _logger;
private static string tableName = "planrecords";
public PGPlanRecordDataAccess(IConfiguration config, ILogger<PGPlanRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<PlanRecord> GetPlanRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<PlanRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
PlanRecord planRecord = JsonSerializer.Deserialize<PlanRecord>(reader["data"] as string);
results.Add(planRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<PlanRecord>();
}
}
public PlanRecord GetPlanRecordById(int planRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new PlanRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", planRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
PlanRecord planRecord = JsonSerializer.Deserialize<PlanRecord>(reader["data"] as string);
result = planRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new PlanRecord();
}
}
public bool DeletePlanRecordById(int planRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", planRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SavePlanRecordToVehicle(PlanRecord planRecord)
{
try
{
if (planRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", planRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
planRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (planRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(planRecord);
ctextU.Parameters.AddWithValue("id", planRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return planRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(planRecord);
ctext.Parameters.AddWithValue("id", planRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllPlanRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGPlanRecordTemplateDataAccess : IPlanRecordTemplateDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGPlanRecordTemplateDataAccess> _logger;
private static string tableName = "planrecordtemplates";
public PGPlanRecordTemplateDataAccess(IConfiguration config, ILogger<PGPlanRecordTemplateDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<PlanRecordInput> GetPlanRecordTemplatesByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<PlanRecordInput>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
PlanRecordInput planRecord = JsonSerializer.Deserialize<PlanRecordInput>(reader["data"] as string);
results.Add(planRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<PlanRecordInput>();
}
}
public PlanRecordInput GetPlanRecordTemplateById(int planRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new PlanRecordInput();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", planRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
PlanRecordInput planRecord = JsonSerializer.Deserialize<PlanRecordInput>(reader["data"] as string);
result = planRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new PlanRecordInput();
}
}
public bool DeletePlanRecordTemplateById(int planRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", planRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SavePlanRecordTemplateToVehicle(PlanRecordInput planRecord)
{
try
{
if (planRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", planRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
planRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (planRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(planRecord);
ctextU.Parameters.AddWithValue("id", planRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return planRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(planRecord);
ctext.Parameters.AddWithValue("id", planRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllPlanRecordTemplatesByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGReminderRecordDataAccess : IReminderRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGReminderRecordDataAccess> _logger;
private static string tableName = "reminderrecords";
public PGReminderRecordDataAccess(IConfiguration config, ILogger<PGReminderRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<ReminderRecord> GetReminderRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<ReminderRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
ReminderRecord reminderRecord = JsonSerializer.Deserialize<ReminderRecord>(reader["data"] as string);
results.Add(reminderRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<ReminderRecord>();
}
}
public ReminderRecord GetReminderRecordById(int reminderRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new ReminderRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", reminderRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
ReminderRecord reminderRecord = JsonSerializer.Deserialize<ReminderRecord>(reader["data"] as string);
result = reminderRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new ReminderRecord();
}
}
public bool DeleteReminderRecordById(int reminderRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", reminderRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveReminderRecordToVehicle(ReminderRecord reminderRecord)
{
try
{
if (reminderRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", reminderRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
reminderRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (reminderRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(reminderRecord);
ctextU.Parameters.AddWithValue("id", reminderRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return reminderRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(reminderRecord);
ctext.Parameters.AddWithValue("id", reminderRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllReminderRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGServiceRecordDataAccess: IServiceRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGServiceRecordDataAccess> _logger;
private static string tableName = "servicerecords";
public PGServiceRecordDataAccess(IConfiguration config, ILogger<PGServiceRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<ServiceRecord> GetServiceRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<ServiceRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
ServiceRecord serviceRecord = JsonSerializer.Deserialize<ServiceRecord>(reader["data"] as string);
results.Add(serviceRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<ServiceRecord>();
}
}
public ServiceRecord GetServiceRecordById(int serviceRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new ServiceRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", serviceRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
ServiceRecord serviceRecord = JsonSerializer.Deserialize<ServiceRecord>(reader["data"] as string);
result = serviceRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new ServiceRecord();
}
}
public bool DeleteServiceRecordById(int serviceRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", serviceRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveServiceRecordToVehicle(ServiceRecord serviceRecord)
{
try
{
if (serviceRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", serviceRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
serviceRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (serviceRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(serviceRecord);
ctextU.Parameters.AddWithValue("id", serviceRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return serviceRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(serviceRecord);
ctext.Parameters.AddWithValue("id", serviceRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllServiceRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGSupplyRecordDataAccess : ISupplyRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGSupplyRecordDataAccess> _logger;
private static string tableName = "supplyrecords";
public PGSupplyRecordDataAccess(IConfiguration config, ILogger<PGSupplyRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<SupplyRecord> GetSupplyRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<SupplyRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
SupplyRecord supplyRecord = JsonSerializer.Deserialize<SupplyRecord>(reader["data"] as string);
results.Add(supplyRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<SupplyRecord>();
}
}
public SupplyRecord GetSupplyRecordById(int supplyRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new SupplyRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", supplyRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
SupplyRecord supplyRecord = JsonSerializer.Deserialize<SupplyRecord>(reader["data"] as string);
result = supplyRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new SupplyRecord();
}
}
public bool DeleteSupplyRecordById(int supplyRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", supplyRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveSupplyRecordToVehicle(SupplyRecord supplyRecord)
{
try
{
if (supplyRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", supplyRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
supplyRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (supplyRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(supplyRecord);
ctextU.Parameters.AddWithValue("id", supplyRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return supplyRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(supplyRecord);
ctext.Parameters.AddWithValue("id", supplyRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllSupplyRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGTaxRecordDataAccess : ITaxRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGTaxRecordDataAccess> _logger;
private static string tableName = "taxrecords";
public PGTaxRecordDataAccess(IConfiguration config, ILogger<PGTaxRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<TaxRecord> GetTaxRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<TaxRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
TaxRecord taxRecord = JsonSerializer.Deserialize<TaxRecord>(reader["data"] as string);
results.Add(taxRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<TaxRecord>();
}
}
public TaxRecord GetTaxRecordById(int taxRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new TaxRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", taxRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
TaxRecord taxRecord = JsonSerializer.Deserialize<TaxRecord>(reader["data"] as string);
result = taxRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new TaxRecord();
}
}
public bool DeleteTaxRecordById(int taxRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", taxRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveTaxRecordToVehicle(TaxRecord taxRecord)
{
try
{
if (taxRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", taxRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
taxRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (taxRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(taxRecord);
ctextU.Parameters.AddWithValue("id", taxRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return taxRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(taxRecord);
ctext.Parameters.AddWithValue("id", taxRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllTaxRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,143 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
namespace CarCareTracker.External.Implementations
{
public class PGTokenRecordDataAccess : ITokenRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGTokenRecordDataAccess> _logger;
private static string tableName = "tokenrecords";
public PGTokenRecordDataAccess(IConfiguration config, ILogger<PGTokenRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, body TEXT not null, emailaddress TEXT not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<Token> GetTokens()
{
try
{
string cmd = $"SELECT id, emailaddress, body FROM app.{tableName}";
var results = new List<Token>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Token result = new Token();
result.Id = int.Parse(reader["id"].ToString());
result.EmailAddress = reader["emailaddress"].ToString();
result.Body = reader["body"].ToString();
results.Add(result);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<Token>();
}
}
public Token GetTokenRecordByBody(string tokenBody)
{
try
{
string cmd = $"SELECT id, emailaddress, body FROM app.{tableName} WHERE body = @body";
var result = new Token();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("body", tokenBody);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result.Id = int.Parse(reader["id"].ToString());
result.EmailAddress = reader["emailaddress"].ToString();
result.Body = reader["body"].ToString();
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Token();
}
}
public Token GetTokenRecordByEmailAddress(string emailAddress)
{
try
{
string cmd = $"SELECT id, emailaddress, body FROM app.{tableName} WHERE emailaddress = @emailaddress";
var result = new Token();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("emailaddress", emailAddress);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result.Id = int.Parse(reader["id"].ToString());
result.EmailAddress = reader["emailaddress"].ToString();
result.Body = reader["body"].ToString();
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Token();
}
}
public bool CreateNewToken(Token token)
{
try
{
string cmd = $"INSERT INTO app.{tableName} (emailaddress, body) VALUES(@emailaddress, @body) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("emailaddress", token.EmailAddress);
ctext.Parameters.AddWithValue("body", token.Body);
token.Id = Convert.ToInt32(ctext.ExecuteScalar());
return token.Id != default;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteToken(int tokenId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", tokenId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,160 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGUpgradeRecordDataAccess : IUpgradeRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGUpgradeRecordDataAccess> _logger;
private static string tableName = "upgraderecords";
public PGUpgradeRecordDataAccess(IConfiguration config, ILogger<PGUpgradeRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<UpgradeRecord> GetUpgradeRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<UpgradeRecord>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UpgradeRecord upgradeRecord = JsonSerializer.Deserialize<UpgradeRecord>(reader["data"] as string);
results.Add(upgradeRecord);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<UpgradeRecord>();
}
}
public UpgradeRecord GetUpgradeRecordById(int upgradeRecordId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
var result = new UpgradeRecord();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", upgradeRecordId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UpgradeRecord upgradeRecord = JsonSerializer.Deserialize<UpgradeRecord>(reader["data"] as string);
result = upgradeRecord;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UpgradeRecord();
}
}
public bool DeleteUpgradeRecordById(int upgradeRecordId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", upgradeRecordId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool SaveUpgradeRecordToVehicle(UpgradeRecord upgradeRecord)
{
try
{
if (upgradeRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (vehicleId, data) VALUES(@vehicleId, CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", upgradeRecord.VehicleId);
ctext.Parameters.AddWithValue("data", "{}");
upgradeRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (upgradeRecord.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(upgradeRecord);
ctextU.Parameters.AddWithValue("id", upgradeRecord.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return upgradeRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(upgradeRecord);
ctext.Parameters.AddWithValue("id", upgradeRecord.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteAllUpgradeRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,212 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
namespace CarCareTracker.External.Implementations
{
public class PGUserAccessDataAccess : IUserAccessDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGUserAccessDataAccess> _logger;
private static string tableName = "useraccessrecords";
public PGUserAccessDataAccess(IConfiguration config, ILogger<PGUserAccessDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
/// <summary>
/// Gets a list of vehicles user have access to.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<UserAccess> GetUserAccessByUserId(int userId)
{
try
{
string cmd = $"SELECT userId, vehicleId FROM app.{tableName} WHERE userId = @userId";
var results = new List<UserAccess>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", userId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserAccess result = new UserAccess()
{
Id = new UserVehicle
{
UserId = int.Parse(reader["userId"].ToString()),
VehicleId = int.Parse(reader["vehicleId"].ToString())
}
};
results.Add(result);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<UserAccess>();
}
}
public UserAccess GetUserAccessByVehicleAndUserId(int userId, int vehicleId)
{
try
{
string cmd = $"SELECT userId, vehicleId FROM app.{tableName} WHERE userId = @userId AND vehicleId = @vehicleId";
UserAccess result = null;
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", userId);
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result = new UserAccess()
{
Id = new UserVehicle
{
UserId = int.Parse(reader["userId"].ToString()),
VehicleId = int.Parse(reader["vehicleId"].ToString())
}
};
return result;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UserAccess();
}
}
public List<UserAccess> GetUserAccessByVehicleId(int vehicleId)
{
try
{
string cmd = $"SELECT userId, vehicleId FROM app.{tableName} WHERE vehicleId = @vehicleId";
var results = new List<UserAccess>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserAccess result = new UserAccess()
{
Id = new UserVehicle
{
UserId = int.Parse(reader["userId"].ToString()),
VehicleId = int.Parse(reader["vehicleId"].ToString())
}
};
results.Add(result);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<UserAccess>();
}
}
public bool SaveUserAccess(UserAccess userAccess)
{
try
{
string cmd = $"INSERT INTO app.{tableName} (userId, vehicleId) VALUES(@userId, @vehicleId)";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", userAccess.Id.UserId);
ctext.Parameters.AddWithValue("vehicleId", userAccess.Id.VehicleId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteUserAccess(int userId, int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE userId = @userId AND vehicleId = @vehicleId";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", userId);
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
/// <summary>
/// Delete all access records when a vehicle is deleted.
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByVehicleId(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE vehicleId = @vehicleId";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("vehicleId", vehicleId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
/// <summary>
/// Delee all access records when a user is deleted.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByUserId(int userId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE userId = @userId";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("userId", userId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,108 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGUserConfigDataAccess: IUserConfigDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGUserConfigDataAccess> _logger;
private static string tableName = "userconfigrecords";
public PGUserConfigDataAccess(IConfiguration config, ILogger<PGUserConfigDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT primary key, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public UserConfigData GetUserConfig(int userId)
{
try
{
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
UserConfigData result = null;
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", userId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserConfigData userConfig = JsonSerializer.Deserialize<UserConfigData>(reader["data"] as string);
result = userConfig;
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UserConfigData();
}
}
public bool SaveUserConfig(UserConfigData userConfigData)
{
var existingRecord = GetUserConfig(userConfigData.Id);
try
{
if (existingRecord == null)
{
string cmd = $"INSERT INTO app.{tableName} (id, data) VALUES(@id, CAST(@data AS jsonb))";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(userConfigData);
ctext.Parameters.AddWithValue("id", userConfigData.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(userConfigData);
ctext.Parameters.AddWithValue("id", userConfigData.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteUserConfig(int userId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", userId);
ctext.ExecuteNonQuery();
return true;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,194 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
namespace CarCareTracker.External.Implementations
{
public class PGUserRecordDataAccess : IUserRecordDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGUserRecordDataAccess> _logger;
private static string tableName = "userrecords";
public PGUserRecordDataAccess(IConfiguration config, ILogger<PGUserRecordDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, username TEXT not null, emailaddress TEXT not null, password TEXT not null, isadmin BOOLEAN)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public List<UserData> GetUsers()
{
try
{
string cmd = $"SELECT id, username, emailaddress, password, isadmin FROM app.{tableName}";
var results = new List<UserData>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
UserData result = new UserData();
result.Id = int.Parse(reader["id"].ToString());
result.UserName = reader["username"].ToString();
result.EmailAddress = reader["emailaddress"].ToString();
result.Password = reader["password"].ToString();
result.IsAdmin = bool.Parse(reader["isadmin"].ToString());
results.Add(result);
}
}
return results;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<UserData>();
}
}
public UserData GetUserRecordByUserName(string userName)
{
try
{
string cmd = $"SELECT id, username, emailaddress, password, isadmin FROM app.{tableName} WHERE username = @username";
var result = new UserData();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("username", userName);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result.Id = int.Parse(reader["id"].ToString());
result.UserName = reader["username"].ToString();
result.EmailAddress = reader["emailaddress"].ToString();
result.Password = reader["password"].ToString();
result.IsAdmin = bool.Parse(reader["isadmin"].ToString());
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UserData();
}
}
public UserData GetUserRecordByEmailAddress(string emailAddress)
{
try
{
string cmd = $"SELECT id, username, emailaddress, password, isadmin FROM app.{tableName} WHERE emailaddress = @emailaddress";
var result = new UserData();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("emailaddress", emailAddress);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result.Id = int.Parse(reader["id"].ToString());
result.UserName = reader["username"].ToString();
result.EmailAddress = reader["emailaddress"].ToString();
result.Password = reader["password"].ToString();
result.IsAdmin = bool.Parse(reader["isadmin"].ToString());
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UserData();
}
}
public UserData GetUserRecordById(int userId)
{
try
{
string cmd = $"SELECT id, username, emailaddress, password, isadmin FROM app.{tableName} WHERE id = @id";
var result = new UserData();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", userId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
result.Id = int.Parse(reader["id"].ToString());
result.UserName = reader["username"].ToString();
result.EmailAddress = reader["emailaddress"].ToString();
result.Password = reader["password"].ToString();
result.IsAdmin = bool.Parse(reader["isadmin"].ToString());
}
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new UserData();
}
}
public bool SaveUserRecord(UserData userRecord)
{
try
{
if (userRecord.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (username, emailaddress, password, isadmin) VALUES(@username, @emailaddress, @password, @isadmin) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("username", userRecord.UserName);
ctext.Parameters.AddWithValue("emailaddress", userRecord.EmailAddress);
ctext.Parameters.AddWithValue("password", userRecord.Password);
ctext.Parameters.AddWithValue("isadmin", userRecord.IsAdmin);
userRecord.Id = Convert.ToInt32(ctext.ExecuteScalar());
return userRecord.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET username = @username, emailaddress = @emailaddress, password = @password, isadmin = @isadmin WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", userRecord.Id);
ctext.Parameters.AddWithValue("username", userRecord.UserName);
ctext.Parameters.AddWithValue("emailaddress", userRecord.EmailAddress);
ctext.Parameters.AddWithValue("password", userRecord.Password);
ctext.Parameters.AddWithValue("isadmin", userRecord.IsAdmin);
return ctext.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteUserRecord(int userId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", userId);
return ctext.ExecuteNonQuery() > 0;
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -1,138 +0,0 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Models;
using Npgsql;
using System.Text.Json;
namespace CarCareTracker.External.Implementations
{
public class PGVehicleDataAccess: IVehicleDataAccess
{
private NpgsqlDataSource pgDataSource;
private readonly ILogger<PGVehicleDataAccess> _logger;
private static string tableName = "vehicles";
public PGVehicleDataAccess(IConfiguration config, ILogger<PGVehicleDataAccess> logger)
{
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
_logger = logger;
try
{
//create table if not exist.
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, data jsonb not null)";
using (var ctext = pgDataSource.CreateCommand(initCMD))
{
ctext.ExecuteNonQuery();
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
}
}
public bool SaveVehicle(Vehicle vehicle)
{
try
{
if (string.IsNullOrWhiteSpace(vehicle.ImageLocation))
{
vehicle.ImageLocation = "/defaults/noimage.png";
}
if (vehicle.Id == default)
{
string cmd = $"INSERT INTO app.{tableName} (data) VALUES(CAST(@data AS jsonb)) RETURNING id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("data", "{}");
vehicle.Id = Convert.ToInt32(ctext.ExecuteScalar());
//update json data
if (vehicle.Id != default)
{
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctextU = pgDataSource.CreateCommand(cmdU))
{
var serializedData = JsonSerializer.Serialize(vehicle);
ctextU.Parameters.AddWithValue("id", vehicle.Id);
ctextU.Parameters.AddWithValue("data", serializedData);
return ctextU.ExecuteNonQuery() > 0;
}
}
return vehicle.Id != default;
}
}
else
{
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
var serializedData = JsonSerializer.Serialize(vehicle);
ctext.Parameters.AddWithValue("id", vehicle.Id);
ctext.Parameters.AddWithValue("data", serializedData);
return ctext.ExecuteNonQuery() > 0;
}
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
}
return false;
}
public bool DeleteVehicle(int vehicleId)
{
try
{
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
return ctext.ExecuteNonQuery() > 0;
}
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public List<Vehicle> GetVehicles()
{
try
{
string cmd = $"SELECT id, data FROM app.{tableName} ORDER BY id ASC";
var results = new List<Vehicle>();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
Vehicle vehicle = JsonSerializer.Deserialize<Vehicle>(reader["data"] as string);
results.Add(vehicle);
}
}
return results;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new List<Vehicle>();
}
}
public Vehicle GetVehicleById(int vehicleId)
{
try
{
string cmd = $"SELECT id, data FROM app.{tableName} WHERE id = @id";
Vehicle vehicle = new Vehicle();
using (var ctext = pgDataSource.CreateCommand(cmd))
{
ctext.Parameters.AddWithValue("id", vehicleId);
using (NpgsqlDataReader reader = ctext.ExecuteReader())
while (reader.Read())
{
vehicle = JsonSerializer.Deserialize<Vehicle>(reader["data"] as string);
}
}
return vehicle;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Vehicle();
}
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class ReminderRecordDataAccess : IReminderRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "reminderrecords";
public List<ReminderRecord> GetReminderRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ReminderRecord>(tableName);
var reminderRecords = table.Find(Query.EQ(nameof(ReminderRecord.VehicleId), vehicleId));
return reminderRecords.ToList() ?? new List<ReminderRecord>();
};
}
public ReminderRecord GetReminderRecordById(int reminderRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ReminderRecord>(tableName);
return table.FindById(reminderRecordId);
};
}
public bool DeleteReminderRecordById(int reminderRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ReminderRecord>(tableName);
table.Delete(reminderRecordId);
return true;
};
}
public bool SaveReminderRecordToVehicle(ReminderRecord reminderRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ReminderRecord>(tableName);
table.Upsert(reminderRecord);
return true;
};
}
public bool DeleteAllReminderRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ReminderRecord>(tableName);
var reminderRecords = table.DeleteMany(Query.EQ(nameof(ReminderRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class ServiceRecordDataAccess: IServiceRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "servicerecords";
public List<ServiceRecord> GetServiceRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ServiceRecord>(tableName);
var serviceRecords = table.Find(Query.EQ(nameof(ServiceRecord.VehicleId), vehicleId));
return serviceRecords.ToList() ?? new List<ServiceRecord>();
};
}
public ServiceRecord GetServiceRecordById(int serviceRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ServiceRecord>(tableName);
return table.FindById(serviceRecordId);
};
}
public bool DeleteServiceRecordById(int serviceRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ServiceRecord>(tableName);
table.Delete(serviceRecordId);
return true;
};
}
public bool SaveServiceRecordToVehicle(ServiceRecord serviceRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ServiceRecord>(tableName);
table.Upsert(serviceRecord);
return true;
};
}
public bool DeleteAllServiceRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<ServiceRecord>(tableName);
var serviceRecords = table.DeleteMany(Query.EQ(nameof(ServiceRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class SupplyRecordDataAccess : ISupplyRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "supplyrecords";
public List<SupplyRecord> GetSupplyRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<SupplyRecord>(tableName);
var supplyRecords = table.Find(Query.EQ(nameof(SupplyRecord.VehicleId), vehicleId));
return supplyRecords.ToList() ?? new List<SupplyRecord>();
};
}
public SupplyRecord GetSupplyRecordById(int supplyRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<SupplyRecord>(tableName);
return table.FindById(supplyRecordId);
};
}
public bool DeleteSupplyRecordById(int supplyRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<SupplyRecord>(tableName);
table.Delete(supplyRecordId);
return true;
};
}
public bool SaveSupplyRecordToVehicle(SupplyRecord supplyRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<SupplyRecord>(tableName);
table.Upsert(supplyRecord);
return true;
};
}
public bool DeleteAllSupplyRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<SupplyRecord>(tableName);
var supplyRecords = table.DeleteMany(Query.EQ(nameof(SupplyRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class TaxRecordDataAccess : ITaxRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "taxrecords";
public List<TaxRecord> GetTaxRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TaxRecord>(tableName);
var taxRecords = table.Find(Query.EQ(nameof(TaxRecord.VehicleId), vehicleId));
return taxRecords.ToList() ?? new List<TaxRecord>();
};
}
public TaxRecord GetTaxRecordById(int taxRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TaxRecord>(tableName);
return table.FindById(taxRecordId);
};
}
public bool DeleteTaxRecordById(int taxRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TaxRecord>(tableName);
table.Delete(taxRecordId);
return true;
};
}
public bool SaveTaxRecordToVehicle(TaxRecord taxRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TaxRecord>(tableName);
table.Upsert(taxRecord);
return true;
};
}
public bool DeleteAllTaxRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TaxRecord>(tableName);
var taxRecords = table.DeleteMany(Query.EQ(nameof(TaxRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class TokenRecordDataAccess : ITokenRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "tokenrecords";
public List<Token> GetTokens()
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Token>(tableName);
return table.FindAll().ToList();
};
}
public Token GetTokenRecordByBody(string tokenBody)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Token>(tableName);
var tokenRecord = table.FindOne(Query.EQ(nameof(Token.Body), tokenBody));
return tokenRecord ?? new Token();
};
}
public Token GetTokenRecordByEmailAddress(string emailAddress)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Token>(tableName);
var tokenRecord = table.FindOne(Query.EQ(nameof(Token.EmailAddress), emailAddress));
return tokenRecord ?? new Token();
};
}
public bool CreateNewToken(Token token)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Token>(tableName);
table.Insert(token);
return true;
};
}
public bool DeleteToken(int tokenId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Token>(tableName);
table.Delete(tokenId);
return true;
};
}
}
}

View File

@@ -0,0 +1,39 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class TorqueRecordDataAccess: ITorqueRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "torquerecords";
public TorqueRecord GetTorqueRecordById(string torqueRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TorqueRecord>(tableName);
return table.FindById(torqueRecordId);
};
}
public bool DeleteTorqueRecordById(int torqueRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TorqueRecord>(tableName);
table.Delete(torqueRecordId);
return true;
};
}
public bool SaveTorqueRecord(TorqueRecord torqueRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<TorqueRecord>(tableName);
table.Upsert(torqueRecord);
return true;
};
}
}
}

View File

@@ -0,0 +1,57 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class UpgradeRecordDataAccess : IUpgradeRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "upgraderecords";
public List<UpgradeRecord> GetUpgradeRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UpgradeRecord>(tableName);
var upgradeRecords = table.Find(Query.EQ(nameof(UpgradeRecord.VehicleId), vehicleId));
return upgradeRecords.ToList() ?? new List<UpgradeRecord>();
};
}
public UpgradeRecord GetUpgradeRecordById(int upgradeRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UpgradeRecord>(tableName);
return table.FindById(upgradeRecordId);
};
}
public bool DeleteUpgradeRecordById(int upgradeRecordId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UpgradeRecord>(tableName);
table.Delete(upgradeRecordId);
return true;
};
}
public bool SaveUpgradeRecordToVehicle(UpgradeRecord upgradeRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UpgradeRecord>(tableName);
table.Upsert(upgradeRecord);
return true;
};
}
public bool DeleteAllUpgradeRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UpgradeRecord>(tableName);
var upgradeRecords = table.DeleteMany(Query.EQ(nameof(UpgradeRecord.VehicleId), vehicleId));
return true;
};
}
}
}

View File

@@ -0,0 +1,88 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class UserAccessDataAccess : IUserAccessDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "useraccessrecords";
/// <summary>
/// Gets a list of vehicles user have access to.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<UserAccess> GetUserAccessByUserId(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x=>x.Id.UserId == userId).ToList();
};
}
public UserAccess GetUserAccessByVehicleAndUserId(int userId, int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x => x.Id.UserId == userId && x.Id.VehicleId == vehicleId).FirstOrDefault();
};
}
public List<UserAccess> GetUserAccessByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
return table.Find(x => x.Id.VehicleId == vehicleId).ToList();
};
}
public bool SaveUserAccess(UserAccess userAccess)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
table.Upsert(userAccess);
return true;
};
}
public bool DeleteUserAccess(int userId, int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x => x.Id.UserId == userId && x.Id.VehicleId == vehicleId);
return true;
};
}
/// <summary>
/// Delete all access records when a vehicle is deleted.
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByVehicleId(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x=>x.Id.VehicleId == vehicleId);
return true;
};
}
/// <summary>
/// Delee all access records when a user is deleted.
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool DeleteAllAccessRecordsByUserId(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserAccess>(tableName);
table.DeleteMany(x => x.Id.UserId == userId);
return true;
};
}
}
}

View File

@@ -0,0 +1,40 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace CarCareTracker.External.Implementations
{
public class UserConfigDataAccess: IUserConfigDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "userconfigrecords";
public UserConfigData GetUserConfig(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserConfigData>(tableName);
return table.FindById(userId);
};
}
public bool SaveUserConfig(UserConfigData userConfigData)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserConfigData>(tableName);
table.Upsert(userConfigData);
return true;
};
}
public bool DeleteUserConfig(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserConfigData>(tableName);
table.Delete(userId);
return true;
};
}
}
}

View File

@@ -0,0 +1,66 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class UserRecordDataAccess : IUserRecordDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "userrecords";
public List<UserData> GetUsers()
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
return table.FindAll().ToList();
};
}
public UserData GetUserRecordByUserName(string userName)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindOne(Query.EQ(nameof(UserData.UserName), userName));
return userRecord ?? new UserData();
};
}
public UserData GetUserRecordByEmailAddress(string emailAddress)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindOne(Query.EQ(nameof(UserData.EmailAddress), emailAddress));
return userRecord ?? new UserData();
};
}
public UserData GetUserRecordById(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
var userRecord = table.FindById(userId);
return userRecord ?? new UserData();
};
}
public bool SaveUserRecord(UserData userRecord)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
table.Upsert(userRecord);
return true;
};
}
public bool DeleteUserRecord(int userId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<UserData>(tableName);
table.Delete(userId);
return true;
};
}
}
}

View File

@@ -0,0 +1,46 @@
using CarCareTracker.External.Interfaces;
using CarCareTracker.Helper;
using CarCareTracker.Models;
using LiteDB;
namespace CarCareTracker.External.Implementations
{
public class VehicleDataAccess: IVehicleDataAccess
{
private static string dbName = StaticHelper.DbName;
private static string tableName = "vehicles";
public bool SaveVehicle(Vehicle vehicle)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Vehicle>(tableName);
var result = table.Upsert(vehicle);
return true;
};
}
public bool DeleteVehicle(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Vehicle>(tableName);
return table.Delete(vehicleId);
};
}
public List<Vehicle> GetVehicles()
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Vehicle>(tableName);
return table.FindAll().ToList();
};
}
public Vehicle GetVehicleById(int vehicleId)
{
using (var db = new LiteDatabase(dbName))
{
var table = db.GetCollection<Vehicle>(tableName);
return table.FindById(vehicleId);
};
}
}
}

View File

@@ -1,10 +0,0 @@
using CarCareTracker.Models;
namespace CarCareTracker.External.Interfaces
{
public interface IExtraFieldDataAccess
{
public RecordExtraField GetExtraFieldsById(int importMode);
public bool SaveExtraFields(RecordExtraField record);
}
}

View File

@@ -1,13 +0,0 @@
using CarCareTracker.Models;
namespace CarCareTracker.External.Interfaces
{
public interface IPlanRecordTemplateDataAccess
{
public List<PlanRecordInput> GetPlanRecordTemplatesByVehicleId(int vehicleId);
public PlanRecordInput GetPlanRecordTemplateById(int planRecordId);
public bool DeletePlanRecordTemplateById(int planRecordId);
public bool SavePlanRecordTemplateToVehicle(PlanRecordInput planRecord);
public bool DeleteAllPlanRecordTemplatesByVehicleId(int vehicleId);
}
}

View File

@@ -0,0 +1,11 @@
using CarCareTracker.Models;
namespace CarCareTracker.External.Interfaces
{
public interface ITorqueRecordDataAccess
{
public TorqueRecord GetTorqueRecordById(string torqueRecordId);
public bool DeleteTorqueRecordById(int torqueRecordId);
public bool SaveTorqueRecord(TorqueRecord torqueRecord);
}
}

View File

@@ -1,5 +1,4 @@
using CarCareTracker.Helper;
using CarCareTracker.Logic;
using CarCareTracker.Logic;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
@@ -10,41 +9,16 @@ namespace CarCareTracker.Filter
public class CollaboratorFilter: ActionFilterAttribute
{
private readonly IUserLogic _userLogic;
private readonly IConfigHelper _config;
public CollaboratorFilter(IUserLogic userLogic, IConfigHelper config) {
public CollaboratorFilter(IUserLogic userLogic) {
_userLogic = userLogic;
_config = config;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.HttpContext.User.IsInRole(nameof(UserData.IsRootUser)))
{
if (filterContext.ActionArguments.ContainsKey("vehicleId"))
{
var vehicleId = int.Parse(filterContext.ActionArguments["vehicleId"].ToString());
if (vehicleId != default)
{
var userId = int.Parse(filterContext.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
if (!_userLogic.UserCanEditVehicle(userId, vehicleId))
{
filterContext.Result = new RedirectResult("/Error/Unauthorized");
}
}
else
{
var shopSupplyEndpoints = new List<string> { "ImportToVehicleIdFromCsv", "GetSupplyRecordsByVehicleId", "ExportFromVehicleToCsv" };
if (shopSupplyEndpoints.Contains(filterContext.RouteData.Values["action"].ToString()) && !_config.GetServerEnableShopSupplies())
{
//user trying to access shop supplies but shop supplies is not enabled by root user.
filterContext.Result = new RedirectResult("/Error/Unauthorized");
}
else if (!shopSupplyEndpoints.Contains(filterContext.RouteData.Values["action"].ToString()))
{
//user trying to access any other endpoints using 0 as vehicle id.
filterContext.Result = new RedirectResult("/Error/Unauthorized");
}
}
} else
var vehicleId = int.Parse(filterContext.ActionArguments["vehicleId"].ToString());
var userId = int.Parse(filterContext.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
if (!_userLogic.UserCanEditVehicle(userId, vehicleId))
{
filterContext.Result = new RedirectResult("/Error/Unauthorized");
}

View File

@@ -2,128 +2,27 @@
using CarCareTracker.Models;
using Microsoft.Extensions.Caching.Memory;
using System.Security.Claims;
using System.Text.Json;
namespace CarCareTracker.Helper
{
public interface IConfigHelper
{
OpenIDConfig GetOpenIDConfig();
ReminderUrgencyConfig GetReminderUrgencyConfig();
MailConfig GetMailConfig();
UserConfig GetUserConfig(ClaimsPrincipal user);
bool SaveUserConfig(ClaimsPrincipal user, UserConfig configData);
bool AuthenticateRootUser(string username, string password);
bool AuthenticateRootUserOIDC(string email);
string GetWebHookUrl();
bool GetCustomWidgetsEnabled();
string GetMOTD();
string GetLogoUrl();
string GetServerLanguage();
bool GetServerDisabledRegistration();
bool GetServerEnableShopSupplies();
string GetServerPostgresConnection();
string GetAllowedFileUploadExtensions();
bool DeleteUserConfig(int userId);
bool GetInvariantApi();
public bool DeleteUserConfig(int userId);
}
public class ConfigHelper : IConfigHelper
{
private readonly IConfiguration _config;
private readonly IUserConfigDataAccess _userConfig;
private readonly ILogger<IConfigHelper> _logger;
private IMemoryCache _cache;
public ConfigHelper(IConfiguration serverConfig,
IUserConfigDataAccess userConfig,
IMemoryCache memoryCache,
ILogger<IConfigHelper> logger)
IMemoryCache memoryCache)
{
_config = serverConfig;
_userConfig = userConfig;
_cache = memoryCache;
_logger = logger;
}
public string GetWebHookUrl()
{
var webhook = CheckString("LUBELOGGER_WEBHOOK");
return webhook;
}
public bool GetCustomWidgetsEnabled()
{
return CheckBool(CheckString("LUBELOGGER_CUSTOM_WIDGETS"));
}
public bool GetInvariantApi()
{
return CheckBool(CheckString("LUBELOGGER_INVARIANT_API"));
}
public string GetMOTD()
{
var motd = CheckString("LUBELOGGER_MOTD");
return motd;
}
public OpenIDConfig GetOpenIDConfig()
{
OpenIDConfig openIdConfig = _config.GetSection("OpenIDConfig").Get<OpenIDConfig>() ?? new OpenIDConfig();
return openIdConfig;
}
public ReminderUrgencyConfig GetReminderUrgencyConfig()
{
ReminderUrgencyConfig reminderUrgencyConfig = _config.GetSection("ReminderUrgencyConfig").Get<ReminderUrgencyConfig>() ?? new ReminderUrgencyConfig();
return reminderUrgencyConfig;
}
public MailConfig GetMailConfig()
{
MailConfig mailConfig = _config.GetSection("MailConfig").Get<MailConfig>() ?? new MailConfig();
return mailConfig;
}
public string GetLogoUrl()
{
var logoUrl = CheckString("LUBELOGGER_LOGO_URL", "/defaults/lubelogger_logo.png");
return logoUrl;
}
public string GetAllowedFileUploadExtensions()
{
var allowedFileExtensions = CheckString("LUBELOGGER_ALLOWED_FILE_EXTENSIONS", StaticHelper.DefaultAllowedFileExtensions);
return allowedFileExtensions;
}
public bool AuthenticateRootUser(string username, string password)
{
var rootUsername = CheckString(nameof(UserConfig.UserNameHash));
var rootPassword = CheckString(nameof(UserConfig.UserPasswordHash));
if (string.IsNullOrWhiteSpace(rootUsername) || string.IsNullOrWhiteSpace(rootPassword))
{
return false;
}
return username == rootUsername && password == rootPassword;
}
public bool AuthenticateRootUserOIDC(string email)
{
var rootEmail = CheckString(nameof(UserConfig.DefaultReminderEmail));
var rootUserOIDC = CheckBool(CheckString(nameof(UserConfig.EnableRootUserOIDC)));
if (!rootUserOIDC || string.IsNullOrWhiteSpace(rootEmail))
{
return false;
}
return email == rootEmail;
}
public string GetServerLanguage()
{
var serverLanguage = CheckString(nameof(UserConfig.UserLanguage), "en_US");
return serverLanguage;
}
public bool GetServerDisabledRegistration()
{
var registrationDisabled = CheckBool(CheckString(nameof(UserConfig.DisableRegistration)));
return registrationDisabled;
}
public string GetServerPostgresConnection()
{
var postgresConnection = CheckString("POSTGRES_CONNECTION");
return postgresConnection;
}
public bool GetServerEnableShopSupplies()
{
return CheckBool(CheckString(nameof(UserConfig.EnableShopSupplies)));
}
public bool SaveUserConfig(ClaimsPrincipal user, UserConfig configData)
{
@@ -141,19 +40,29 @@ namespace CarCareTracker.Helper
if (!File.Exists(StaticHelper.UserConfigPath))
{
//if file doesn't exist it might be because it's running on a mounted volume in docker.
File.WriteAllText(StaticHelper.UserConfigPath, JsonSerializer.Serialize(new UserConfig()));
File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(new UserConfig()));
}
var configFileContents = File.ReadAllText(StaticHelper.UserConfigPath);
configData.EnableAuth = bool.Parse(_config[nameof(UserConfig.EnableAuth)] ?? "false");
configData.UserNameHash = _config[nameof(UserConfig.UserNameHash)] ?? string.Empty;
configData.UserPasswordHash = _config[nameof(UserConfig.UserPasswordHash)] ?? string.Empty;
File.WriteAllText(StaticHelper.UserConfigPath, JsonSerializer.Serialize(configData));
var existingUserConfig = System.Text.Json.JsonSerializer.Deserialize<UserConfig>(configFileContents);
if (existingUserConfig is not null)
{
//copy over settings that are off limits on the settings page.
configData.EnableAuth = existingUserConfig.EnableAuth;
configData.UserNameHash = existingUserConfig.UserNameHash;
configData.UserPasswordHash = existingUserConfig.UserPasswordHash;
}
else
{
configData.EnableAuth = false;
configData.UserNameHash = string.Empty;
configData.UserPasswordHash = string.Empty;
}
File.WriteAllText(StaticHelper.UserConfigPath, System.Text.Json.JsonSerializer.Serialize(configData));
_cache.Set<UserConfig>($"userConfig_{userId}", configData);
return true;
}
catch (Exception ex)
{
_logger.LogWarning(ex.Message);
return false;
}
} else
@@ -174,73 +83,22 @@ namespace CarCareTracker.Helper
var result = _userConfig.DeleteUserConfig(userId);
return result;
}
private bool CheckBool(string value, bool defaultValue = false)
{
try
{
if (string.IsNullOrWhiteSpace(value))
{
return defaultValue;
}
else if (bool.TryParse(value, out bool result))
{
return result;
}
else
{
return defaultValue;
}
} catch (Exception ex)
{
_logger.LogWarning($"ConfigHelper Warning: You might be missing keys in appsettings.json, Message: ${ex.Message}");
return defaultValue;
}
}
private string CheckString(string configName, string defaultValue = "")
{
try
{
var configValue = _config[configName] ?? defaultValue;
return configValue;
} catch(Exception ex)
{
_logger.LogWarning($"ConfigHelper Warning: You might be missing keys in appsettings.json, Message: ${ex.Message}");
return defaultValue;
}
}
public UserConfig GetUserConfig(ClaimsPrincipal user)
{
var serverConfig = new UserConfig
{
EnableCsvImports = CheckBool(CheckString(nameof(UserConfig.EnableCsvImports)), true),
UseDarkMode = CheckBool(CheckString(nameof(UserConfig.UseDarkMode))),
UseSystemColorMode = CheckBool(CheckString(nameof(UserConfig.UseSystemColorMode))),
UseMPG = CheckBool(CheckString(nameof(UserConfig.UseMPG)), true),
UseDescending = CheckBool(CheckString(nameof(UserConfig.UseDescending))),
EnableAuth = CheckBool(CheckString(nameof(UserConfig.EnableAuth))),
EnableRootUserOIDC = CheckBool(CheckString(nameof(UserConfig.EnableRootUserOIDC))),
HideZero = CheckBool(CheckString(nameof(UserConfig.HideZero))),
AutomaticDecimalFormat = CheckBool(CheckString(nameof(UserConfig.AutomaticDecimalFormat))),
UseUKMPG = CheckBool(CheckString(nameof(UserConfig.UseUKMPG))),
UseMarkDownOnSavedNotes = CheckBool(CheckString(nameof(UserConfig.UseMarkDownOnSavedNotes))),
UseThreeDecimalGasCost = CheckBool(CheckString(nameof(UserConfig.UseThreeDecimalGasCost)), true),
UseThreeDecimalGasConsumption = CheckBool(CheckString(nameof(UserConfig.UseThreeDecimalGasConsumption)), true),
EnableAutoReminderRefresh = CheckBool(CheckString(nameof(UserConfig.EnableAutoReminderRefresh))),
EnableAutoOdometerInsert = CheckBool(CheckString(nameof(UserConfig.EnableAutoOdometerInsert))),
PreferredGasMileageUnit = CheckString(nameof(UserConfig.PreferredGasMileageUnit)),
PreferredGasUnit = CheckString(nameof(UserConfig.PreferredGasUnit)),
UseUnitForFuelCost = CheckBool(CheckString(nameof(UserConfig.UseUnitForFuelCost))),
UserLanguage = CheckString(nameof(UserConfig.UserLanguage), "en_US"),
HideSoldVehicles = CheckBool(CheckString(nameof(UserConfig.HideSoldVehicles))),
EnableShopSupplies = CheckBool(CheckString(nameof(UserConfig.EnableShopSupplies))),
EnableExtraFieldColumns = CheckBool(CheckString(nameof(UserConfig.EnableExtraFieldColumns))),
VisibleTabs = _config.GetSection(nameof(UserConfig.VisibleTabs)).Get<List<ImportMode>>() ?? new UserConfig().VisibleTabs,
TabOrder = _config.GetSection(nameof(UserConfig.TabOrder)).Get<List<ImportMode>>() ?? new UserConfig().TabOrder,
UserColumnPreferences = _config.GetSection(nameof(UserConfig.UserColumnPreferences)).Get<List<UserColumnPreference>>() ?? new List<UserColumnPreference>(),
ReminderUrgencyConfig = _config.GetSection(nameof(UserConfig.ReminderUrgencyConfig)).Get<ReminderUrgencyConfig>() ?? new ReminderUrgencyConfig(),
DefaultTab = (ImportMode)int.Parse(CheckString(nameof(UserConfig.DefaultTab), "8")),
DefaultReminderEmail = CheckString(nameof(UserConfig.DefaultReminderEmail)),
DisableRegistration = CheckBool(CheckString(nameof(UserConfig.DisableRegistration)))
EnableCsvImports = bool.Parse(_config[nameof(UserConfig.EnableCsvImports)]),
UseDarkMode = bool.Parse(_config[nameof(UserConfig.UseDarkMode)]),
UseMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]),
UseDescending = bool.Parse(_config[nameof(UserConfig.UseDescending)]),
EnableAuth = bool.Parse(_config[nameof(UserConfig.EnableAuth)]),
HideZero = bool.Parse(_config[nameof(UserConfig.HideZero)]),
UseUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)]),
UseThreeDecimalGasCost = bool.Parse(_config[nameof(UserConfig.UseThreeDecimalGasCost)]),
EnableAutoReminderRefresh = bool.Parse(_config[nameof(UserConfig.EnableAutoReminderRefresh)]),
EnableAutoOdometerInsert = bool.Parse(_config[nameof(UserConfig.EnableAutoOdometerInsert)]),
VisibleTabs = _config.GetSection("VisibleTabs").Get<List<ImportMode>>(),
DefaultTab = (ImportMode)int.Parse(_config[nameof(UserConfig.DefaultTab)])
};
int userId = 0;
if (user != null)

View File

@@ -1,5 +1,4 @@
using CarCareTracker.Models;
using System.IO.Compression;
using System.IO.Compression;
namespace CarCareTracker.Helper
{
@@ -7,64 +6,18 @@ namespace CarCareTracker.Helper
{
string GetFullFilePath(string currentFilePath, bool mustExist = true);
string MoveFileFromTemp(string currentFilePath, string newFolder);
bool RenameFile(string currentFilePath, string newName);
bool DeleteFile(string currentFilePath);
string MakeBackup();
bool RestoreBackup(string fileName, bool clearExisting = false);
string MakeAttachmentsExport(List<GenericReportModel> exportData);
List<string> GetLanguages();
int ClearTempFolder();
int ClearUnlinkedThumbnails(List<string> linkedImages);
int ClearUnlinkedDocuments(List<string> linkedDocuments);
string GetWidgets();
bool WidgetsExist();
bool SaveWidgets(string widgetsData);
bool DeleteWidgets();
bool RestoreBackup(string fileName);
}
public class FileHelper : IFileHelper
{
private readonly IWebHostEnvironment _webEnv;
private readonly ILogger<IFileHelper> _logger;
private ILiteDBHelper _liteDB;
public FileHelper(IWebHostEnvironment webEnv, ILogger<IFileHelper> logger, ILiteDBHelper liteDB)
public FileHelper(IWebHostEnvironment webEnv, ILogger<IFileHelper> logger)
{
_webEnv = webEnv;
_logger = logger;
_liteDB = liteDB;
}
public List<string> GetLanguages()
{
var languagePath = Path.Combine(_webEnv.WebRootPath, "translations");
var defaultList = new List<string>() { "en_US" };
if (Directory.Exists(languagePath))
{
var listOfLanguages = Directory.GetFiles(languagePath);
if (listOfLanguages.Any())
{
defaultList.AddRange(listOfLanguages.Select(x => Path.GetFileNameWithoutExtension(x)));
}
}
return defaultList;
}
public bool RenameFile(string currentFilePath, string newName)
{
var fullFilePath = GetFullFilePath(currentFilePath);
if (!string.IsNullOrWhiteSpace(fullFilePath))
{
try
{
var originalFileName = Path.GetFileNameWithoutExtension(fullFilePath);
var newFilePath = fullFilePath.Replace(originalFileName, newName);
File.Move(fullFilePath, newFilePath);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
return false;
}
public string GetFullFilePath(string currentFilePath, bool mustExist = true)
{
@@ -85,7 +38,7 @@ namespace CarCareTracker.Helper
return string.Empty;
}
}
public bool RestoreBackup(string fileName, bool clearExisting = false)
public bool RestoreBackup(string fileName)
{
var fullFilePath = GetFullFilePath(fileName);
if (string.IsNullOrWhiteSpace(fullFilePath))
@@ -102,9 +55,7 @@ namespace CarCareTracker.Helper
//copy over images and documents.
var imagePath = Path.Combine(tempPath, "images");
var documentPath = Path.Combine(tempPath, "documents");
var translationPath = Path.Combine(tempPath, "translations");
var dataPath = Path.Combine(tempPath, StaticHelper.DbName);
var widgetPath = Path.Combine(tempPath, StaticHelper.AdditionalWidgetsPath);
var configPath = Path.Combine(tempPath, StaticHelper.UserConfigPath);
if (Directory.Exists(imagePath))
{
@@ -113,17 +64,9 @@ namespace CarCareTracker.Helper
{
Directory.CreateDirectory(existingPath);
}
else if (clearExisting)
{
var filesToDelete = Directory.GetFiles(existingPath);
foreach (string file in filesToDelete)
{
File.Delete(file);
}
}
//copy each files from temp folder to newPath
var filesToUpload = Directory.GetFiles(imagePath);
foreach (string file in filesToUpload)
foreach(string file in filesToUpload)
{
File.Copy(file, $"{existingPath}/{Path.GetFileName(file)}", true);
}
@@ -135,14 +78,6 @@ namespace CarCareTracker.Helper
{
Directory.CreateDirectory(existingPath);
}
else if (clearExisting)
{
var filesToDelete = Directory.GetFiles(existingPath);
foreach (string file in filesToDelete)
{
File.Delete(file);
}
}
//copy each files from temp folder to newPath
var filesToUpload = Directory.GetFiles(documentPath);
foreach (string file in filesToUpload)
@@ -150,39 +85,11 @@ namespace CarCareTracker.Helper
File.Copy(file, $"{existingPath}/{Path.GetFileName(file)}", true);
}
}
if (Directory.Exists(translationPath))
{
var existingPath = Path.Combine(_webEnv.WebRootPath, "translations");
if (!Directory.Exists(existingPath))
{
Directory.CreateDirectory(existingPath);
}
else if (clearExisting)
{
var filesToDelete = Directory.GetFiles(existingPath);
foreach (string file in filesToDelete)
{
File.Delete(file);
}
}
//copy each files from temp folder to newPath
var filesToUpload = Directory.GetFiles(translationPath);
foreach (string file in filesToUpload)
{
File.Copy(file, $"{existingPath}/{Path.GetFileName(file)}", true);
}
}
if (File.Exists(dataPath))
{
//Relinquish current DB file lock
_liteDB.DisposeLiteDB();
//data path will always exist as it is created on startup if not.
File.Move(dataPath, StaticHelper.DbName, true);
}
if (File.Exists(widgetPath))
{
File.Move(widgetPath, StaticHelper.AdditionalWidgetsPath, true);
}
if (File.Exists(configPath))
{
//check if config folder exists.
@@ -193,46 +100,19 @@ namespace CarCareTracker.Helper
File.Move(configPath, StaticHelper.UserConfigPath, true);
}
return true;
}
catch (Exception ex)
} catch (Exception ex)
{
_logger.LogError(ex, $"Error Restoring Database Backup: {ex.Message}");
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}_{reportModel.DataType}_{reportModel.Date.ToString("yyyy-MM-dd")}_{file.Name}{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")}";
var tempPath = Path.Combine(_webEnv.WebRootPath, $"temp/{folderName}");
var imagePath = Path.Combine(_webEnv.WebRootPath, "images");
var documentPath = Path.Combine(_webEnv.WebRootPath, "documents");
var translationPath = Path.Combine(_webEnv.WebRootPath, "translations");
var dataPath = StaticHelper.DbName;
var widgetPath = StaticHelper.AdditionalWidgetsPath;
var configPath = StaticHelper.UserConfigPath;
if (!Directory.Exists(tempPath))
Directory.CreateDirectory(tempPath);
@@ -256,28 +136,12 @@ namespace CarCareTracker.Helper
File.Copy(file, $"{newPath}/{Path.GetFileName(file)}");
}
}
if (Directory.Exists(translationPath))
{
var files = Directory.GetFiles(translationPath);
foreach(var file in files)
{
var newPath = Path.Combine(tempPath, "translations");
Directory.CreateDirectory(newPath);
File.Copy(file, $"{newPath}/{Path.GetFileName(file)}");
}
}
if (File.Exists(dataPath))
{
var newPath = Path.Combine(tempPath, "data");
Directory.CreateDirectory(newPath);
File.Copy(dataPath, $"{newPath}/{Path.GetFileName(dataPath)}");
}
if (File.Exists(widgetPath))
{
var newPath = Path.Combine(tempPath, "data");
Directory.CreateDirectory(newPath);
File.Copy(widgetPath, $"{newPath}/{Path.GetFileName(widgetPath)}");
}
if (File.Exists(configPath))
{
var newPath = Path.Combine(tempPath, "config");
@@ -333,116 +197,5 @@ namespace CarCareTracker.Helper
return false;
}
}
public int ClearTempFolder()
{
int filesDeleted = 0;
var tempPath = GetFullFilePath("temp", false);
if (Directory.Exists(tempPath))
{
//delete files
var files = Directory.GetFiles(tempPath);
foreach (var file in files)
{
File.Delete(file);
filesDeleted++;
}
//delete folders
var folders = Directory.GetDirectories(tempPath);
foreach(var folder in folders)
{
Directory.Delete(folder, true);
filesDeleted++;
}
}
return filesDeleted;
}
public int ClearUnlinkedThumbnails(List<string> linkedImages)
{
int filesDeleted = 0;
var imagePath = GetFullFilePath("images", false);
if (Directory.Exists(imagePath))
{
var files = Directory.GetFiles(imagePath);
foreach(var file in files)
{
if (!linkedImages.Contains(Path.GetFileName(file)))
{
File.Delete(file);
filesDeleted++;
}
}
}
return filesDeleted;
}
public int ClearUnlinkedDocuments(List<string> linkedDocuments)
{
int filesDeleted = 0;
var documentPath = GetFullFilePath("documents", false);
if (Directory.Exists(documentPath))
{
var files = Directory.GetFiles(documentPath);
foreach (var file in files)
{
if (!linkedDocuments.Contains(Path.GetFileName(file)))
{
File.Delete(file);
filesDeleted++;
}
}
}
return filesDeleted;
}
public string GetWidgets()
{
if (File.Exists(StaticHelper.AdditionalWidgetsPath))
{
try
{
//read file
var widgets = File.ReadAllText(StaticHelper.AdditionalWidgetsPath);
return widgets;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return string.Empty;
}
}
return string.Empty;
}
public bool WidgetsExist()
{
return File.Exists(StaticHelper.AdditionalWidgetsPath);
}
public bool SaveWidgets(string widgetsData)
{
try
{
//Delete Widgets if exists
DeleteWidgets();
File.WriteAllText(StaticHelper.AdditionalWidgetsPath, widgetsData);
return true;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteWidgets()
{
try
{
if (File.Exists(StaticHelper.AdditionalWidgetsPath))
{
File.Delete(StaticHelper.AdditionalWidgetsPath);
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@@ -5,36 +5,26 @@ namespace CarCareTracker.Helper
public interface IGasHelper
{
List<GasRecordViewModel> GetGasRecordViewModels(List<GasRecord> result, bool useMPG, bool useUKMPG);
string GetAverageGasMileage(List<GasRecordViewModel> results, bool useMPG);
string GetAverageGasMileage(List<GasRecordViewModel> results);
}
public class GasHelper : IGasHelper
{
public string GetAverageGasMileage(List<GasRecordViewModel> results, bool useMPG)
public string GetAverageGasMileage(List<GasRecordViewModel> results)
{
var recordsToCalculate = results.Where(x => x.IncludeInAverage);
if (recordsToCalculate.Any())
var recordWithCalculatedMPG = results.Where(x => x.MilesPerGallon > 0);
var minMileage = results.Min(x => x.Mileage);
if (recordWithCalculatedMPG.Any())
{
try
{
var totalMileage = recordsToCalculate.Sum(x => x.DeltaMileage);
var totalGallons = recordsToCalculate.Sum(x => x.Gallons);
var averageGasMileage = totalMileage / totalGallons;
if (!useMPG && averageGasMileage > 0)
{
averageGasMileage = 100 / averageGasMileage;
}
return averageGasMileage.ToString("F");
} catch (Exception ex)
{
return "0";
}
var maxMileage = recordWithCalculatedMPG.Max(x => x.Mileage);
var totalGallonsConsumed = recordWithCalculatedMPG.Sum(x => x.Gallons);
var deltaMileage = maxMileage - minMileage;
var averageGasMileage = (maxMileage - minMileage) / totalGallonsConsumed;
return averageGasMileage.ToString("F");
}
return "0";
}
public List<GasRecordViewModel> GetGasRecordViewModels(List<GasRecord> result, bool useMPG, bool useUKMPG)
{
//need to order by to get correct results
result = result.OrderBy(x => x.Date).ThenBy(x => x.Mileage).ToList();
var computedResults = new List<GasRecordViewModel>();
int previousMileage = 0;
decimal unFactoredConsumption = 0.00M;
@@ -57,10 +47,6 @@ namespace CarCareTracker.Helper
if (i > 0)
{
var deltaMileage = currentObject.Mileage - previousMileage;
if (deltaMileage < 0)
{
deltaMileage = 0;
}
var gasRecordViewModel = new GasRecordViewModel()
{
Id = currentObject.Id,
@@ -74,9 +60,7 @@ namespace CarCareTracker.Helper
CostPerGallon = convertedConsumption > 0.00M ? currentObject.Cost / convertedConsumption : 0,
IsFillToFull = currentObject.IsFillToFull,
MissedFuelUp = currentObject.MissedFuelUp,
Notes = currentObject.Notes,
Tags = currentObject.Tags,
ExtraFields = currentObject.ExtraFields
Notes = currentObject.Notes
};
if (currentObject.MissedFuelUp)
{
@@ -89,16 +73,9 @@ namespace CarCareTracker.Helper
else if (currentObject.IsFillToFull)
{
//if user filled to full.
if (convertedConsumption > 0.00M && deltaMileage > 0)
if (convertedConsumption > 0.00M)
{
try
{
gasRecordViewModel.MilesPerGallon = useMPG ? (unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption) : 100 / ((unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption));
}
catch (Exception ex)
{
gasRecordViewModel.MilesPerGallon = 0;
}
gasRecordViewModel.MilesPerGallon = useMPG ? (unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption) : 100 / ((unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption));
}
//reset unFactored vars
unFactoredConsumption = 0;
@@ -128,9 +105,7 @@ namespace CarCareTracker.Helper
CostPerGallon = convertedConsumption > 0.00M ? currentObject.Cost / convertedConsumption : 0,
IsFillToFull = currentObject.IsFillToFull,
MissedFuelUp = currentObject.MissedFuelUp,
Notes = currentObject.Notes,
Tags = currentObject.Tags,
ExtraFields = currentObject.ExtraFields
Notes = currentObject.Notes
});
}
previousMileage = currentObject.Mileage;

View File

@@ -1,36 +0,0 @@
using LiteDB;
namespace CarCareTracker.Helper;
public interface ILiteDBHelper
{
LiteDatabase GetLiteDB();
void DisposeLiteDB();
}
public class LiteDBHelper: ILiteDBHelper
{
public LiteDatabase db { get; set; }
public LiteDBHelper()
{
if (db == null)
{
db = new LiteDatabase(StaticHelper.DbName);
}
}
public LiteDatabase GetLiteDB()
{
if (db == null)
{
db = new LiteDatabase(StaticHelper.DbName);
}
return db;
}
public void DisposeLiteDB()
{
if (db != null)
{
db.Dispose();
db = null;
}
}
}

View File

@@ -1,7 +1,6 @@
using CarCareTracker.Models;
using MimeKit;
using MailKit.Net.Smtp;
using MailKit.Security;
using System.Net.Mail;
using System.Net;
namespace CarCareTracker.Helper
{
@@ -9,165 +8,77 @@ namespace CarCareTracker.Helper
{
OperationResponse NotifyUserForRegistration(string emailAddress, string token);
OperationResponse NotifyUserForPasswordReset(string emailAddress, string token);
OperationResponse NotifyUserForAccountUpdate(string emailAddress, string token);
OperationResponse NotifyUserForReminders(Vehicle vehicle, List<string> emailAddresses, List<ReminderRecordViewModel> reminders);
}
public class MailHelper : IMailHelper
{
private readonly MailConfig mailConfig;
private readonly IFileHelper _fileHelper;
private readonly ILogger<MailHelper> _logger;
public MailHelper(
IConfigHelper config,
IFileHelper fileHelper,
ILogger<MailHelper> logger
IConfiguration config
) {
//load mailConfig from Configuration
mailConfig = config.GetMailConfig();
_fileHelper = fileHelper;
_logger = logger;
mailConfig = config.GetSection("MailConfig").Get<MailConfig>();
}
public OperationResponse NotifyUserForRegistration(string emailAddress, string token)
{
if (string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
return OperationResponse.Failed("SMTP Server Not Setup");
return new OperationResponse { Success = false, Message = "SMTP Server Not Setup" };
}
if (string.IsNullOrWhiteSpace(emailAddress) || string.IsNullOrWhiteSpace(token)) {
return OperationResponse.Failed("Email Address or Token is invalid");
return new OperationResponse { Success = false, Message = "Email Address or Token is invalid" };
}
string emailSubject = "Your Registration Token for LubeLogger";
string emailBody = $"A token has been generated on your behalf, please complete your registration for LubeLogger using the token: {token}";
var result = SendEmail(new List<string> { emailAddress }, emailSubject, emailBody);
var result = SendEmail(emailAddress, emailSubject, emailBody);
if (result)
{
return OperationResponse.Succeed("Email Sent!");
return new OperationResponse { Success = true, Message = "Email Sent!" };
} else
{
return OperationResponse.Failed();
return new OperationResponse { Success = false, Message = StaticHelper.GenericErrorMessage };
}
}
public OperationResponse NotifyUserForPasswordReset(string emailAddress, string token)
{
if (string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
return OperationResponse.Failed("SMTP Server Not Setup");
return new OperationResponse { Success = false, Message = "SMTP Server Not Setup" };
}
if (string.IsNullOrWhiteSpace(emailAddress) || string.IsNullOrWhiteSpace(token))
{
return OperationResponse.Failed("Email Address or Token is invalid");
return new OperationResponse { Success = false, Message = "Email Address or Token is invalid" };
}
string emailSubject = "Your Password Reset Token for LubeLogger";
string emailBody = $"A token has been generated on your behalf, please reset your password for LubeLogger using the token: {token}";
var result = SendEmail(new List<string> { emailAddress }, emailSubject, emailBody);
var result = SendEmail(emailAddress, emailSubject, emailBody);
if (result)
{
return OperationResponse.Succeed("Email Sent!");
return new OperationResponse { Success = true, Message = "Email Sent!" };
}
else
{
return OperationResponse.Failed();
return new OperationResponse { Success = false, Message = StaticHelper.GenericErrorMessage };
}
}
public OperationResponse NotifyUserForAccountUpdate(string emailAddress, string token)
{
if (string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
return OperationResponse.Failed("SMTP Server Not Setup");
}
if (string.IsNullOrWhiteSpace(emailAddress) || string.IsNullOrWhiteSpace(token))
{
return OperationResponse.Failed("Email Address or Token is invalid");
}
string emailSubject = "Your User Account Update Token for LubeLogger";
string emailBody = $"A token has been generated on your behalf, please update your account for LubeLogger using the token: {token}";
var result = SendEmail(new List<string> { emailAddress}, emailSubject, emailBody);
if (result)
{
return OperationResponse.Succeed("Email Sent!");
}
else
{
return OperationResponse.Failed();
}
}
public OperationResponse NotifyUserForReminders(Vehicle vehicle, List<string> emailAddresses, List<ReminderRecordViewModel> reminders)
{
if (string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
return OperationResponse.Failed("SMTP Server Not Setup");
}
if (!emailAddresses.Any())
{
return OperationResponse.Failed("No recipients could be found");
}
if (!reminders.Any())
{
return OperationResponse.Failed("No reminders could be found");
}
//get email template, this file has to exist since it's a static file.
var emailTemplatePath = _fileHelper.GetFullFilePath(StaticHelper.ReminderEmailTemplate);
string emailSubject = $"Vehicle Reminders From LubeLogger - {DateTime.Now.ToShortDateString()}";
//construct html table.
string emailBody = File.ReadAllText(emailTemplatePath);
emailBody = emailBody.Replace("{VehicleInformation}", $"{vehicle.Year} {vehicle.Make} {vehicle.Model} #{StaticHelper.GetVehicleIdentifier(vehicle)}");
string tableBody = "";
foreach(ReminderRecordViewModel reminder in reminders)
{
var dueOn = reminder.Metric == ReminderMetric.Both ? $"{reminder.Date.ToShortDateString()} or {reminder.Mileage}" : reminder.Metric == ReminderMetric.Date ? $"{reminder.Date.ToShortDateString()}" : $"{reminder.Mileage}";
tableBody += $"<tr class='{reminder.Urgency}'><td>{StaticHelper.GetTitleCaseReminderUrgency(reminder.Urgency)}</td><td>{reminder.Description}</td><td>{dueOn}</td></tr>";
}
emailBody = emailBody.Replace("{TableBody}", tableBody);
try
{
var result = SendEmail(emailAddresses, emailSubject, emailBody);
if (result)
{
return OperationResponse.Succeed("Email Sent!");
} else
{
return OperationResponse.Failed();
}
} catch (Exception ex)
{
return OperationResponse.Failed(ex.Message);
}
}
private bool SendEmail(List<string> emailTo, string emailSubject, string emailBody) {
private bool SendEmail(string emailTo, string emailSubject, string emailBody) {
string to = emailTo;
string from = mailConfig.EmailFrom;
var server = mailConfig.EmailServer;
var message = new MimeMessage();
message.From.Add(new MailboxAddress(from, from));
foreach(string emailRecipient in emailTo)
{
message.To.Add(new MailboxAddress(emailRecipient, emailRecipient));
}
MailMessage message = new MailMessage(from, to);
message.Subject = emailSubject;
var builder = new BodyBuilder();
builder.HtmlBody = emailBody;
message.Body = builder.ToMessageBody();
using (var client = new SmtpClient())
message.Body = emailBody;
SmtpClient client = new SmtpClient(server);
client.EnableSsl = mailConfig.UseSSL;
client.Port = mailConfig.Port;
client.Credentials = new NetworkCredential(mailConfig.Username, mailConfig.Password);
try
{
client.Connect(server, mailConfig.Port, SecureSocketOptions.Auto);
//perform authentication if either username or password is provided.
//do not perform authentication if neither are provided.
if (!string.IsNullOrWhiteSpace(mailConfig.Username) || !string.IsNullOrWhiteSpace(mailConfig.Password)) {
client.Authenticate(mailConfig.Username, mailConfig.Password);
}
try
{
client.Send(message);
client.Disconnect(true);
return true;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
client.Send(message);
return true;
}
catch (Exception ex)
{
return false;
}
}
}

View File

@@ -4,72 +4,33 @@ namespace CarCareTracker.Helper
{
public interface IReminderHelper
{
ReminderRecord GetUpdatedRecurringReminderRecord(ReminderRecord existingReminder, DateTime? currentDate, int? currentMileage);
ReminderRecord GetUpdatedRecurringReminderRecord(ReminderRecord existingReminder);
List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage, DateTime dateCompare);
}
public class ReminderHelper: IReminderHelper
{
private readonly IConfigHelper _config;
public ReminderHelper(IConfigHelper config)
public ReminderRecord GetUpdatedRecurringReminderRecord(ReminderRecord existingReminder)
{
_config = config;
}
public ReminderRecord GetUpdatedRecurringReminderRecord(ReminderRecord existingReminder, DateTime? currentDate, int? currentMileage)
{
var newDate = currentDate ?? existingReminder.Date;
var newMileage = currentMileage ?? existingReminder.Mileage;
if (existingReminder.Metric == ReminderMetric.Both)
{
if (existingReminder.ReminderMonthInterval != ReminderMonthInterval.Other)
{
existingReminder.Date = newDate.AddMonths((int)existingReminder.ReminderMonthInterval);
} else
{
existingReminder.Date = newDate.Date.AddMonths(existingReminder.CustomMonthInterval);
}
if (existingReminder.ReminderMileageInterval != ReminderMileageInterval.Other)
{
existingReminder.Mileage = newMileage + (int)existingReminder.ReminderMileageInterval;
}
else
{
existingReminder.Mileage = newMileage + existingReminder.CustomMileageInterval;
}
existingReminder.Date = existingReminder.Date.AddMonths((int)existingReminder.ReminderMonthInterval);
existingReminder.Mileage += (int)existingReminder.ReminderMileageInterval;
}
else if (existingReminder.Metric == ReminderMetric.Odometer)
{
if (existingReminder.ReminderMileageInterval != ReminderMileageInterval.Other)
{
existingReminder.Mileage = newMileage + (int)existingReminder.ReminderMileageInterval;
} else
{
existingReminder.Mileage = newMileage + existingReminder.CustomMileageInterval;
}
existingReminder.Mileage += (int)existingReminder.ReminderMileageInterval;
}
else if (existingReminder.Metric == ReminderMetric.Date)
{
if (existingReminder.ReminderMonthInterval != ReminderMonthInterval.Other)
{
existingReminder.Date = newDate.AddMonths((int)existingReminder.ReminderMonthInterval);
}
else
{
existingReminder.Date = newDate.AddMonths(existingReminder.CustomMonthInterval);
}
existingReminder.Date = existingReminder.Date.AddMonths((int)existingReminder.ReminderMonthInterval);
}
return existingReminder;
}
public List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage, DateTime dateCompare)
{
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
var reminderUrgencyConfig = _config.GetReminderUrgencyConfig();
foreach (var reminder in reminders)
{
if (reminder.UseCustomThresholds)
{
reminderUrgencyConfig = reminder.CustomThresholds;
}
var reminderViewModel = new ReminderRecordViewModel()
{
Id = reminder.Id,
@@ -79,9 +40,7 @@ namespace CarCareTracker.Helper
Description = reminder.Description,
Notes = reminder.Notes,
Metric = reminder.Metric,
UserMetric = reminder.Metric,
IsRecurring = reminder.IsRecurring,
Tags = reminder.Tags
IsRecurring = reminder.IsRecurring
};
if (reminder.Metric == ReminderMetric.Both)
{
@@ -95,24 +54,24 @@ namespace CarCareTracker.Helper
reminderViewModel.Urgency = ReminderUrgency.PastDue;
reminderViewModel.Metric = ReminderMetric.Odometer;
}
else if (reminder.Date < dateCompare.AddDays(reminderUrgencyConfig.VeryUrgentDays))
else if (reminder.Date < dateCompare.AddDays(7))
{
//if less than a week from today or less than 50 miles from current mileage then very urgent.
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
//have to specify by which metric this reminder is urgent.
reminderViewModel.Metric = ReminderMetric.Date;
}
else if (reminder.Mileage < currentMileage + reminderUrgencyConfig.VeryUrgentDistance)
else if (reminder.Mileage < currentMileage + 50)
{
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
reminderViewModel.Metric = ReminderMetric.Odometer;
}
else if (reminder.Date < dateCompare.AddDays(reminderUrgencyConfig.UrgentDays))
else if (reminder.Date < dateCompare.AddDays(30))
{
reminderViewModel.Urgency = ReminderUrgency.Urgent;
reminderViewModel.Metric = ReminderMetric.Date;
}
else if (reminder.Mileage < currentMileage + reminderUrgencyConfig.UrgentDistance)
else if (reminder.Mileage < currentMileage + 100)
{
reminderViewModel.Urgency = ReminderUrgency.Urgent;
reminderViewModel.Metric = ReminderMetric.Odometer;
@@ -124,11 +83,11 @@ namespace CarCareTracker.Helper
{
reminderViewModel.Urgency = ReminderUrgency.PastDue;
}
else if (reminder.Date < dateCompare.AddDays(reminderUrgencyConfig.VeryUrgentDays))
else if (reminder.Date < dateCompare.AddDays(7))
{
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
}
else if (reminder.Date < dateCompare.AddDays(reminderUrgencyConfig.UrgentDays))
else if (reminder.Date < dateCompare.AddDays(30))
{
reminderViewModel.Urgency = ReminderUrgency.Urgent;
}
@@ -140,11 +99,11 @@ namespace CarCareTracker.Helper
reminderViewModel.Urgency = ReminderUrgency.PastDue;
reminderViewModel.Metric = ReminderMetric.Odometer;
}
else if (reminder.Mileage < currentMileage + reminderUrgencyConfig.VeryUrgentDistance)
else if (reminder.Mileage < currentMileage + 50)
{
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
}
else if (reminder.Mileage < currentMileage + reminderUrgencyConfig.UrgentDistance)
else if (reminder.Mileage < currentMileage + 100)
{
reminderViewModel.Urgency = ReminderUrgency.Urgent;
}

View File

@@ -5,166 +5,78 @@ namespace CarCareTracker.Helper
{
public interface IReportHelper
{
IEnumerable<CostForVehicleByMonth> GetOdometerRecordSum(List<OdometerRecord> odometerRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0, bool sortIntoYear = false);
IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0);
IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0);
IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0);
IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0);
IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0);
}
public class ReportHelper: IReportHelper
{
public IEnumerable<CostForVehicleByMonth> GetOdometerRecordSum(List<OdometerRecord> odometerRecords, int year = 0, bool sortIntoYear = false)
{
if (year != default)
{
odometerRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
{
return odometerRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = 0,
DistanceTraveled = x.Sum(y => y.DistanceTraveled)
});
} else
{
return odometerRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = 0,
DistanceTraveled = x.Sum(y => y.DistanceTraveled)
});
}
}
public IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0, bool sortIntoYear = false)
public IEnumerable<CostForVehicleByMonth> GetServiceRecordSum(List<ServiceRecord> serviceRecords, int year = 0)
{
if (year != default)
{
serviceRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
return serviceRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
return serviceRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = x.Sum(y => y.Cost)
});
} else
{
return serviceRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
public IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0, bool sortIntoYear = false)
public IEnumerable<CostForVehicleByMonth> GetRepairRecordSum(List<CollisionRecord> repairRecords, int year = 0)
{
if (year != default)
{
repairRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
return repairRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
return repairRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = x.Sum(y => y.Cost)
});
} else
{
return repairRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
public IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0, bool sortIntoYear = false)
public IEnumerable<CostForVehicleByMonth> GetUpgradeRecordSum(List<UpgradeRecord> upgradeRecords, int year = 0)
{
if (year != default)
{
upgradeRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
return upgradeRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
return upgradeRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = x.Sum(y => y.Cost)
});
} else
{
return upgradeRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
public IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0, bool sortIntoYear = false)
public IEnumerable<CostForVehicleByMonth> GetGasRecordSum(List<GasRecord> gasRecords, int year = 0)
{
if (year != default)
{
gasRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
return gasRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
return gasRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = x.Sum(y => y.Cost)
});
} else
{
return gasRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
public IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0, bool sortIntoYear = false)
public IEnumerable<CostForVehicleByMonth> GetTaxRecordSum(List<TaxRecord> taxRecords, int year = 0)
{
if (year != default)
{
taxRecords.RemoveAll(x => x.Date.Year != year);
}
if (sortIntoYear)
return taxRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
return taxRecords.GroupBy(x => new { x.Date.Month, x.Date.Year }).OrderBy(x => x.Key.Month).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key.Month,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key.Month),
Year = x.Key.Year,
Cost = x.Sum(y => y.Cost)
});
} else
{
return taxRecords.GroupBy(x => x.Date.Month).OrderBy(x => x.Key).Select(x => new CostForVehicleByMonth
{
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
MonthId = x.Key,
MonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x.Key),
Cost = x.Sum(y => y.Cost)
});
}
}
}

View File

@@ -1,7 +1,5 @@
using CarCareTracker.Models;
using CsvHelper;
using System.Globalization;
using System.Text.Json;
namespace CarCareTracker.Helper
{
@@ -10,91 +8,9 @@ namespace CarCareTracker.Helper
/// </summary>
public static class StaticHelper
{
public const string VersionNumber = "1.4.2";
public const string DbName = "data/cartracker.db";
public const string UserConfigPath = "config/userConfig.json";
public const string AdditionalWidgetsPath = "data/widgets.html";
public const string GenericErrorMessage = "An error occurred, please try again later";
public const string ReminderEmailTemplate = "defaults/reminderemailtemplate.txt";
public const string DefaultAllowedFileExtensions = ".png,.jpg,.jpeg,.pdf,.xls,.xlsx,.docx";
public const string SponsorsPath = "https://hargata.github.io/hargata/sponsors.json";
public const string TranslationPath = "https://hargata.github.io/lubelog_translations";
public const string TranslationDirectoryPath = $"{TranslationPath}/directory.json";
public const string ReportNote = "Report generated by LubeLogger, a Free and Open Source Vehicle Maintenance Tracker - LubeLogger.com";
public static string GetTitleCaseReminderUrgency(ReminderUrgency input)
{
switch (input)
{
case ReminderUrgency.NotUrgent:
return "Not Urgent";
case ReminderUrgency.VeryUrgent:
return "Very Urgent";
case ReminderUrgency.PastDue:
return "Past Due";
default:
return input.ToString();
}
}
public static string GetTitleCaseReminderUrgency(string input)
{
switch (input)
{
case "NotUrgent":
return "Not Urgent";
case "VeryUrgent":
return "Very Urgent";
case "PastDue":
return "Past Due";
default:
return input;
}
}
public static string GetReminderUrgencyColor(ReminderUrgency input)
{
switch (input)
{
case ReminderUrgency.NotUrgent:
return "text-bg-success";
case ReminderUrgency.VeryUrgent:
return "text-bg-danger";
case ReminderUrgency.PastDue:
return "text-bg-secondary";
default:
return "text-bg-warning";
}
}
public static string GetPlanRecordColor(PlanPriority input)
{
switch (input)
{
case PlanPriority.Critical:
return "text-bg-danger";
case PlanPriority.Normal:
return "text-bg-primary";
case PlanPriority.Low:
return "text-bg-info";
default:
return "text-bg-primary";
}
}
public static string GetPlanRecordProgress(PlanProgress input)
{
switch (input)
{
case PlanProgress.Backlog:
return "Planned";
case PlanProgress.InProgress:
return "Doing";
case PlanProgress.Testing:
return "Testing";
case PlanProgress.Done:
return "Done";
default:
return input.ToString();
}
}
public static string DbName = "data/cartracker.db";
public static string UserConfigPath = "config/userConfig.json";
public static string GenericErrorMessage = "An error occurred, please try again later";
public static string TruncateStrings(string input, int maxLength = 25)
{
@@ -184,490 +100,5 @@ namespace CarCareTracker.Helper
new CostForVehicleByMonth { MonthId = 12, Cost = 0M}
};
}
public static List<string> GetBarChartColors()
{
return new List<string> { "#00876c", "#43956e", "#67a371", "#89b177", "#a9be80", "#c8cb8b", "#e6d79b", "#e4c281", "#e3ab6b", "#e2925b", "#e07952", "#db5d4f" };
}
public static ServiceRecord GenericToServiceRecord(GenericRecord input)
{
return new ServiceRecord
{
VehicleId = input.VehicleId,
Date = input.Date,
Description = input.Description,
Cost = input.Cost,
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags,
ExtraFields = input.ExtraFields,
RequisitionHistory = input.RequisitionHistory
};
}
public static CollisionRecord GenericToRepairRecord(GenericRecord input)
{
return new CollisionRecord
{
VehicleId = input.VehicleId,
Date = input.Date,
Description = input.Description,
Cost = input.Cost,
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags,
ExtraFields = input.ExtraFields,
RequisitionHistory = input.RequisitionHistory
};
}
public static UpgradeRecord GenericToUpgradeRecord(GenericRecord input)
{
return new UpgradeRecord
{
VehicleId = input.VehicleId,
Date = input.Date,
Description = input.Description,
Cost = input.Cost,
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags,
ExtraFields = input.ExtraFields,
RequisitionHistory = input.RequisitionHistory
};
}
public static List<ExtraField> AddExtraFields(List<ExtraField> recordExtraFields, List<ExtraField> templateExtraFields)
{
if (!templateExtraFields.Any()) {
return new List<ExtraField>();
}
if (!recordExtraFields.Any())
{
return templateExtraFields;
}
var fieldNames = templateExtraFields.Select(x => x.Name);
//remove fields that are no longer present in template.
recordExtraFields.RemoveAll(x => !fieldNames.Contains(x.Name));
if (!recordExtraFields.Any())
{
return templateExtraFields;
}
var recordFieldNames = recordExtraFields.Select(x => x.Name);
//update isrequired setting
foreach (ExtraField extraField in recordExtraFields)
{
extraField.IsRequired = templateExtraFields.Where(x => x.Name == extraField.Name).First().IsRequired;
}
//append extra fields
foreach(ExtraField extraField in templateExtraFields)
{
if (!recordFieldNames.Contains(extraField.Name))
{
recordExtraFields.Add(extraField);
}
}
//re-order extra fields
recordExtraFields = recordExtraFields.OrderBy(x => templateExtraFields.FindIndex(y => y.Name == x.Name)).ToList();
return recordExtraFields;
}
public static string GetFuelEconomyUnit(bool useKwh, bool useHours, bool useMPG, bool useUKMPG)
{
string fuelEconomyUnit;
if (useKwh)
{
var distanceUnit = useHours ? "h" : (useMPG ? "mi." : "km");
fuelEconomyUnit = useMPG ? $"{distanceUnit}/kWh" : $"kWh/100{distanceUnit}";
}
else if (useMPG && useUKMPG)
{
fuelEconomyUnit = useHours ? "h/g" : "mpg";
}
else if (useUKMPG)
{
fuelEconomyUnit = useHours ? "l/100h" : "l/100mi.";
}
else
{
fuelEconomyUnit = useHours ? (useMPG ? "h/g" : "l/100h") : (useMPG ? "mpg" : "l/100km");
}
return fuelEconomyUnit;
}
public static long GetEpochFromDateTime(DateTime date)
{
return new DateTimeOffset(date).ToUnixTimeMilliseconds();
}
public static void InitMessage(IConfiguration config)
{
Console.WriteLine($"LubeLogger {VersionNumber}");
Console.WriteLine("Website: https://lubelogger.com");
Console.WriteLine("Documentation: https://docs.lubelogger.com");
Console.WriteLine("GitHub: https://github.com/hargata/lubelog");
var mailConfig = config.GetSection("MailConfig").Get<MailConfig>();
if (mailConfig != null && !string.IsNullOrWhiteSpace(mailConfig.EmailServer))
{
Console.WriteLine($"SMTP Configured for {mailConfig.EmailServer}");
} else
{
Console.WriteLine("SMTP Not Configured");
}
var motd = config["LUBELOGGER_MOTD"] ?? "Not Configured";
Console.WriteLine($"Message Of The Day: {motd}");
if (string.IsNullOrWhiteSpace(CultureInfo.CurrentCulture.Name))
{
Console.WriteLine("No Locale or Culture Configured for LubeLogger, Check Environment Variables");
}
}
public static async void NotifyAsync(string webhookURL, WebHookPayload webHookPayload)
{
if (string.IsNullOrWhiteSpace(webhookURL))
{
return;
}
var httpClient = new HttpClient();
if (webhookURL.StartsWith("discord://"))
{
webhookURL = webhookURL.Replace("discord://", "https://"); //cleanurl
//format to discord
httpClient.PostAsJsonAsync(webhookURL, DiscordWebHook.FromWebHookPayload(webHookPayload));
} else
{
httpClient.PostAsJsonAsync(webhookURL, webHookPayload);
}
}
public static string GetImportModeIcon(ImportMode importMode)
{
switch (importMode)
{
case ImportMode.ServiceRecord:
return "bi-card-checklist";
case ImportMode.RepairRecord:
return "bi-exclamation-octagon";
case ImportMode.UpgradeRecord:
return "bi-wrench-adjustable";
case ImportMode.TaxRecord:
return "bi-currency-dollar";
case ImportMode.SupplyRecord:
return "bi-shop";
case ImportMode.PlanRecord:
return "bi-bar-chart-steps";
case ImportMode.OdometerRecord:
return "bi-speedometer";
case ImportMode.GasRecord:
return "bi-fuel-pump";
case ImportMode.NoteRecord:
return "bi-journal-bookmark";
case ImportMode.ReminderRecord:
return "bi-bell";
default:
return "bi-file-bar-graph";
}
}
public static string GetVehicleIdentifier(Vehicle vehicle)
{
if (vehicle.VehicleIdentifier == "LicensePlate")
{
return vehicle.LicensePlate;
} else
{
if (vehicle.ExtraFields.Any(x=>x.Name == vehicle.VehicleIdentifier))
{
return vehicle.ExtraFields?.FirstOrDefault(x=>x.Name == vehicle.VehicleIdentifier)?.Value;
} else
{
return "N/A";
}
}
}
public static string GetVehicleIdentifier(VehicleViewModel vehicle)
{
if (vehicle.VehicleIdentifier == "LicensePlate")
{
return vehicle.LicensePlate;
}
else
{
if (vehicle.ExtraFields.Any(x => x.Name == vehicle.VehicleIdentifier))
{
return vehicle.ExtraFields?.FirstOrDefault(x => x.Name == vehicle.VehicleIdentifier)?.Value;
}
else
{
return "N/A";
}
}
}
//Translations
public static string GetTranslationDownloadPath(string continent, string name)
{
if (string.IsNullOrWhiteSpace(continent) || string.IsNullOrWhiteSpace(name)){
return string.Empty;
}
else
{
switch (continent)
{
case "NorthAmerica":
continent = "North America";
break;
case "SouthAmerica":
continent = "South America";
break;
}
return $"{TranslationPath}/{continent}/{name}.json";
}
}
public static string GetTranslationName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return string.Empty;
} else
{
try
{
string cleanedName = name.Contains("_") ? name.Replace("_", "-") : name;
string displayName = CultureInfo.GetCultureInfo(cleanedName).DisplayName;
if (string.IsNullOrWhiteSpace(displayName))
{
return name;
}
else
{
return displayName;
}
} catch (Exception ex)
{
return name;
}
}
}
//CSV Write Methods
public static void WriteGenericRecordExportModel(CsvWriter _csv, IEnumerable<GenericRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(GenericRecordExportModel.Date));
_csv.WriteField(nameof(GenericRecordExportModel.Description));
_csv.WriteField(nameof(GenericRecordExportModel.Cost));
_csv.WriteField(nameof(GenericRecordExportModel.Notes));
_csv.WriteField(nameof(GenericRecordExportModel.Odometer));
_csv.WriteField(nameof(GenericRecordExportModel.Tags));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (GenericRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.Date);
_csv.WriteField(genericRecord.Description);
_csv.WriteField(genericRecord.Cost);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Odometer);
_csv.WriteField(genericRecord.Tags);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
public static void WriteOdometerRecordExportModel(CsvWriter _csv, IEnumerable<OdometerRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(OdometerRecordExportModel.Date));
_csv.WriteField(nameof(OdometerRecordExportModel.InitialOdometer));
_csv.WriteField(nameof(OdometerRecordExportModel.Odometer));
_csv.WriteField(nameof(OdometerRecordExportModel.Notes));
_csv.WriteField(nameof(OdometerRecordExportModel.Tags));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (OdometerRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.Date);
_csv.WriteField(genericRecord.InitialOdometer);
_csv.WriteField(genericRecord.Odometer);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Tags);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
public static void WriteTaxRecordExportModel(CsvWriter _csv, IEnumerable<TaxRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(TaxRecordExportModel.Date));
_csv.WriteField(nameof(TaxRecordExportModel.Description));
_csv.WriteField(nameof(TaxRecordExportModel.Cost));
_csv.WriteField(nameof(TaxRecordExportModel.Notes));
_csv.WriteField(nameof(TaxRecordExportModel.Tags));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (TaxRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.Date);
_csv.WriteField(genericRecord.Description);
_csv.WriteField(genericRecord.Cost);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Tags);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
public static void WriteSupplyRecordExportModel(CsvWriter _csv, IEnumerable<SupplyRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(SupplyRecordExportModel.Date));
_csv.WriteField(nameof(SupplyRecordExportModel.PartNumber));
_csv.WriteField(nameof(SupplyRecordExportModel.PartSupplier));
_csv.WriteField(nameof(SupplyRecordExportModel.PartQuantity));
_csv.WriteField(nameof(SupplyRecordExportModel.Description));
_csv.WriteField(nameof(SupplyRecordExportModel.Notes));
_csv.WriteField(nameof(SupplyRecordExportModel.Cost));
_csv.WriteField(nameof(SupplyRecordExportModel.Tags));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (SupplyRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.Date);
_csv.WriteField(genericRecord.PartNumber);
_csv.WriteField(genericRecord.PartSupplier);
_csv.WriteField(genericRecord.PartQuantity);
_csv.WriteField(genericRecord.Description);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Cost);
_csv.WriteField(genericRecord.Tags);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
public static void WritePlanRecordExportModel(CsvWriter _csv, IEnumerable<PlanRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(PlanRecordExportModel.DateCreated));
_csv.WriteField(nameof(PlanRecordExportModel.DateModified));
_csv.WriteField(nameof(PlanRecordExportModel.Description));
_csv.WriteField(nameof(PlanRecordExportModel.Notes));
_csv.WriteField(nameof(PlanRecordExportModel.Type));
_csv.WriteField(nameof(PlanRecordExportModel.Priority));
_csv.WriteField(nameof(PlanRecordExportModel.Progress));
_csv.WriteField(nameof(PlanRecordExportModel.Cost));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (PlanRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.DateCreated);
_csv.WriteField(genericRecord.DateModified);
_csv.WriteField(genericRecord.Description);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Type);
_csv.WriteField(genericRecord.Priority);
_csv.WriteField(genericRecord.Progress);
_csv.WriteField(genericRecord.Cost);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
public static string HideZeroCost(string input, bool hideZero, string decorations = "")
{
if (input == 0M.ToString("C2") && hideZero)
{
return "---";
} else
{
return string.IsNullOrWhiteSpace(decorations) ? input : $"{input}{decorations}";
}
}
public static string HideZeroCost(decimal input, bool hideZero, string decorations = "")
{
if (input == default && hideZero)
{
return "---";
}
else
{
return string.IsNullOrWhiteSpace(decorations) ? input.ToString("C2") : $"{input.ToString("C2")}{decorations}";
}
}
public static JsonSerializerOptions GetInvariantOption()
{
var serializerOption = new JsonSerializerOptions();
serializerOption.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
serializerOption.Converters.Add(new InvariantConverter());
return serializerOption;
}
public static void WriteGasRecordExportModel(CsvWriter _csv, IEnumerable<GasRecordExportModel> genericRecords)
{
var extraHeaders = genericRecords.SelectMany(x => x.ExtraFields).Select(y => y.Name).Distinct();
//write headers
_csv.WriteField(nameof(GasRecordExportModel.Date));
_csv.WriteField(nameof(GasRecordExportModel.Odometer));
_csv.WriteField(nameof(GasRecordExportModel.FuelConsumed));
_csv.WriteField(nameof(GasRecordExportModel.Cost));
_csv.WriteField(nameof(GasRecordExportModel.FuelEconomy));
_csv.WriteField(nameof(GasRecordExportModel.IsFillToFull));
_csv.WriteField(nameof(GasRecordExportModel.MissedFuelUp));
_csv.WriteField(nameof(GasRecordExportModel.Notes));
_csv.WriteField(nameof(GasRecordExportModel.Tags));
foreach (string extraHeader in extraHeaders)
{
_csv.WriteField($"extrafield_{extraHeader}");
}
_csv.NextRecord();
foreach (GasRecordExportModel genericRecord in genericRecords)
{
_csv.WriteField(genericRecord.Date);
_csv.WriteField(genericRecord.Odometer);
_csv.WriteField(genericRecord.FuelConsumed);
_csv.WriteField(genericRecord.Cost);
_csv.WriteField(genericRecord.FuelEconomy);
_csv.WriteField(genericRecord.IsFillToFull);
_csv.WriteField(genericRecord.MissedFuelUp);
_csv.WriteField(genericRecord.Notes);
_csv.WriteField(genericRecord.Tags);
foreach (string extraHeader in extraHeaders)
{
var extraField = genericRecord.ExtraFields.Where(x => x.Name == extraHeader).FirstOrDefault();
_csv.WriteField(extraField != null ? extraField.Value : string.Empty);
}
_csv.NextRecord();
}
}
}
}

View File

@@ -1,197 +0,0 @@
using CarCareTracker.Models;
using Microsoft.Extensions.Caching.Memory;
using System.Text.Json;
namespace CarCareTracker.Helper
{
public interface ITranslationHelper
{
string Translate(string userLanguage, string text);
Dictionary<string, string> GetTranslations(string userLanguage);
OperationResponse SaveTranslation(string userLanguage, Dictionary<string, string> translations);
string ExportTranslation(Dictionary<string, string> translations);
}
public class TranslationHelper : ITranslationHelper
{
private readonly IFileHelper _fileHelper;
private readonly IConfiguration _config;
private readonly ILogger<ITranslationHelper> _logger;
private IMemoryCache _cache;
public TranslationHelper(IFileHelper fileHelper, IConfiguration config, IMemoryCache memoryCache, ILogger<ITranslationHelper> logger)
{
_fileHelper = fileHelper;
_config = config;
_cache = memoryCache;
_logger = logger;
}
public string Translate(string userLanguage, string text)
{
bool create = bool.Parse(_config["LUBELOGGER_TRANSLATOR"] ?? "false");
//transform input text into key.
string translationKey = text.Replace(" ", "_");
var translationFilePath = userLanguage == "en_US" ? _fileHelper.GetFullFilePath($"/defaults/en_US.json") : _fileHelper.GetFullFilePath($"/translations/{userLanguage}.json", false);
var dictionary = _cache.GetOrCreate<Dictionary<string, string>>($"lang_{userLanguage}", entry =>
{
entry.SlidingExpiration = TimeSpan.FromHours(1);
if (File.Exists(translationFilePath))
{
try
{
var translationFile = File.ReadAllText(translationFilePath);
var translationDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(translationFile);
return translationDictionary ?? new Dictionary<string, string>();
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Dictionary<string, string>();
}
}
else
{
_logger.LogError($"Could not find translation file for {userLanguage}");
return new Dictionary<string, string>();
}
});
if (dictionary != null && dictionary.ContainsKey(translationKey))
{
return dictionary[translationKey];
}
else if (create && File.Exists(translationFilePath))
{
//create entry
dictionary.Add(translationKey, text);
_logger.LogInformation($"Translation key added to {userLanguage} for {translationKey} with value {text}");
File.WriteAllText(translationFilePath, JsonSerializer.Serialize(dictionary));
return text;
}
return text;
}
private Dictionary<string, string> GetDefaultTranslation()
{
//this method always returns en_US translation.
var translationFilePath = _fileHelper.GetFullFilePath($"/defaults/en_US.json");
if (!string.IsNullOrWhiteSpace(translationFilePath))
{
//file exists.
try
{
var translationFile = File.ReadAllText(translationFilePath);
var translationDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(translationFile);
return translationDictionary ?? new Dictionary<string, string>();
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Dictionary<string, string>();
}
}
_logger.LogError($"Could not find translation file for en_US");
return new Dictionary<string, string>();
}
public Dictionary<string, string> GetTranslations(string userLanguage)
{
var defaultTranslation = GetDefaultTranslation();
if (userLanguage == "en_US")
{
return defaultTranslation;
}
var translationFilePath = _fileHelper.GetFullFilePath($"/translations/{userLanguage}.json");
if (!string.IsNullOrWhiteSpace(translationFilePath))
{
//file exists.
try
{
var translationFile = File.ReadAllText(translationFilePath);
var translationDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(translationFile);
if (translationDictionary != null)
{
foreach(var translation in translationDictionary)
{
if (defaultTranslation.ContainsKey(translation.Key))
{
defaultTranslation[translation.Key] = translation.Value;
}
}
}
return defaultTranslation ?? new Dictionary<string, string>();
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new Dictionary<string, string>();
}
}
_logger.LogError($"Could not find translation file for {userLanguage}");
return new Dictionary<string, string>();
}
public OperationResponse SaveTranslation(string userLanguage, Dictionary<string, string> translations)
{
bool create = bool.Parse(_config["LUBELOGGER_TRANSLATOR"] ?? "false");
bool isDefaultLanguage = userLanguage == "en_US";
if (isDefaultLanguage && !create)
{
return OperationResponse.Failed("The translation file name en_US is reserved.");
}
if (string.IsNullOrWhiteSpace(userLanguage))
{
return OperationResponse.Failed("File name is not provided.");
}
if (!translations.Any())
{
return OperationResponse.Failed("Translation has no data.");
}
var translationFilePath = isDefaultLanguage ? _fileHelper.GetFullFilePath($"/defaults/en_US.json") : _fileHelper.GetFullFilePath($"/translations/{userLanguage}.json", false);
try
{
if (File.Exists(translationFilePath))
{
//write to file
File.WriteAllText(translationFilePath, JsonSerializer.Serialize(translations));
_cache.Remove($"lang_{userLanguage}"); //clear out cache, force a reload from file.
} else
{
//check if directory exists first.
var translationDirectory = _fileHelper.GetFullFilePath("translations/", false);
if (!Directory.Exists(translationDirectory))
{
Directory.CreateDirectory(translationDirectory);
}
//write to file
File.WriteAllText(translationFilePath, JsonSerializer.Serialize(translations));
}
return OperationResponse.Succeed("Translation Updated");
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return OperationResponse.Failed();
}
}
public string ExportTranslation(Dictionary<string, string> translations)
{
try
{
var tempFileName = $"/temp/{Guid.NewGuid()}.json";
string uploadDirectory = _fileHelper.GetFullFilePath("temp/", false);
if (!Directory.Exists(uploadDirectory))
{
Directory.CreateDirectory(uploadDirectory);
}
var saveFilePath = _fileHelper.GetFullFilePath(tempFileName, false);
//standardize translation format for export only.
Dictionary<string, string> sortedTranslations = new Dictionary<string, string>();
foreach (var translation in translations.OrderBy(x => x.Key))
{
sortedTranslations.Add(translation.Key, translation.Value);
};
File.WriteAllText(saveFilePath, JsonSerializer.Serialize(sortedTranslations, new JsonSerializerOptions { WriteIndented = true }));
return tempFileName;
}
catch(Exception ex)
{
_logger.LogError(ex.Message);
return string.Empty;
}
}
}
}

View File

@@ -1,6 +1,11 @@
LubeLogger by Hargata Softworks is licensed under the MIT License for individual
and personal use. Commercial users and/or corporate entities are required
to maintain an active subscription in order to continue using LubeLogger.
For pricing information please contact us at hargatasoftworks@gmail.com
MIT License
Copyright (c) 2024 Hargata Softworks
Copyright (c) 2023 Hargata Softworks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

Some files were not shown because too many files have changed in this diff Show More