Merge pull request #276 from hargata/Hargata/extra.fields

Extra Fields
This commit is contained in:
Hargata Softworks
2024-02-12 20:59:53 -07:00
committed by GitHub
44 changed files with 593 additions and 52 deletions

View File

@@ -17,18 +17,20 @@ namespace CarCareTracker.Controllers
private readonly IUserLogic _userLogic;
private readonly IFileHelper _fileHelper;
private readonly IConfigHelper _config;
public HomeController(ILogger<HomeController> logger,
private readonly IExtraFieldDataAccess _extraFieldDataAccess;
public HomeController(ILogger<HomeController> logger,
IVehicleDataAccess dataAccess,
IUserLogic userLogic,
IConfigHelper configuration,
IFileHelper fileHelper)
IFileHelper fileHelper,
IExtraFieldDataAccess extraFieldDataAccess)
{
_logger = logger;
_dataAccess = dataAccess;
_config = configuration;
_userLogic = userLogic;
_fileHelper = fileHelper;
_extraFieldDataAccess = extraFieldDataAccess;
}
private int GetUserID()
{
@@ -68,7 +70,28 @@ namespace CarCareTracker.Controllers
{
return View();
}
public IActionResult GetExtraFieldsModal(int importMode = 0)
{
var recordExtraFields = _extraFieldDataAccess.GetExtraFieldsById(importMode);
if (recordExtraFields.Id != importMode)
{
recordExtraFields.Id = importMode;
}
return PartialView("_ExtraFields", recordExtraFields);
}
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);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{

View File

@@ -52,7 +52,8 @@ namespace CarCareTracker.Controllers
"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.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)
{
@@ -97,6 +98,8 @@ namespace CarCareTracker.Controllers
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))
@@ -396,6 +399,25 @@ namespace CarCareTracker.Controllers
};
}
#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(System.Text.Json.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(new OperationResponse { Success = true, Message = $"/{tempFolder}.zip" });
@@ -441,6 +463,8 @@ namespace CarCareTracker.Controllers
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))
{
@@ -704,6 +728,23 @@ namespace CarCareTracker.Controllers
}
}
#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", System.Text.Json.JsonSerializer.Serialize(record));
ctext.ExecuteNonQuery();
}
}
#endregion
return Json(new OperationResponse { Success = true, Message = "Data Imported Successfully" });
}
catch (Exception ex)

View File

@@ -36,6 +36,7 @@ namespace CarCareTracker.Controllers
private readonly IReminderHelper _reminderHelper;
private readonly IReportHelper _reportHelper;
private readonly IUserLogic _userLogic;
private readonly IExtraFieldDataAccess _extraFieldDataAccess;
public VehicleController(ILogger<VehicleController> logger,
IFileHelper fileHelper,
@@ -54,6 +55,7 @@ namespace CarCareTracker.Controllers
IPlanRecordDataAccess planRecordDataAccess,
IPlanRecordTemplateDataAccess planRecordTemplateDataAccess,
IOdometerRecordDataAccess odometerRecordDataAccess,
IExtraFieldDataAccess extraFieldDataAccess,
IUserLogic userLogic,
IWebHostEnvironment webEnv,
IConfigHelper config)
@@ -75,6 +77,7 @@ namespace CarCareTracker.Controllers
_planRecordDataAccess = planRecordDataAccess;
_planRecordTemplateDataAccess = planRecordTemplateDataAccess;
_odometerRecordDataAccess = odometerRecordDataAccess;
_extraFieldDataAccess = extraFieldDataAccess;
_userLogic = userLogic;
_webEnv = webEnv;
_config = config;
@@ -589,7 +592,7 @@ namespace CarCareTracker.Controllers
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() });
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)
@@ -607,7 +610,8 @@ namespace CarCareTracker.Controllers
IsFillToFull = result.IsFillToFull,
MissedFuelUp = result.MissedFuelUp,
Notes = result.Notes,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.GasRecord).ExtraFields)
};
var vehicleData = _dataAccess.GetVehicleById(convertedResult.VehicleId);
var vehicleIsElectric = vehicleData.IsElectric;
@@ -678,7 +682,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddServiceRecordPartialView()
{
return PartialView("_ServiceRecordModal", new ServiceRecordInput());
return PartialView("_ServiceRecordModal", new ServiceRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetServiceRecordForEditById(int serviceRecordId)
@@ -695,7 +699,8 @@ namespace CarCareTracker.Controllers
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.ServiceRecord).ExtraFields)
};
return PartialView("_ServiceRecordModal", convertedResult);
}
@@ -748,7 +753,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddCollisionRecordPartialView()
{
return PartialView("_CollisionRecordModal", new CollisionRecordInput());
return PartialView("_CollisionRecordModal", new CollisionRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetCollisionRecordForEditById(int collisionRecordId)
@@ -765,7 +770,8 @@ namespace CarCareTracker.Controllers
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.RepairRecord).ExtraFields)
};
return PartialView("_CollisionRecordModal", convertedResult);
}
@@ -822,7 +828,8 @@ namespace CarCareTracker.Controllers
RecurringInterval = recurringFee.RecurringInterval,
CustomMonthInterval = recurringFee.CustomMonthInterval,
Files = recurringFee.Files,
Tags = recurringFee.Tags
Tags = recurringFee.Tags,
ExtraFields = recurringFee.ExtraFields
};
_taxRecordDataAccess.SaveTaxRecordToVehicle(recurringFee);
_taxRecordDataAccess.SaveTaxRecordToVehicle(newRecurringFee);
@@ -841,7 +848,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddTaxRecordPartialView()
{
return PartialView("_TaxRecordModal", new TaxRecordInput());
return PartialView("_TaxRecordModal", new TaxRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetTaxRecordForEditById(int taxRecordId)
@@ -860,7 +867,8 @@ namespace CarCareTracker.Controllers
RecurringInterval = result.RecurringInterval,
CustomMonthInterval = result.CustomMonthInterval,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.TaxRecord).ExtraFields)
};
return PartialView("_TaxRecordModal", convertedResult);
}
@@ -1417,7 +1425,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddUpgradeRecordPartialView()
{
return PartialView("_UpgradeRecordModal", new UpgradeRecordInput());
return PartialView("_UpgradeRecordModal", new UpgradeRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetUpgradeRecordForEditById(int upgradeRecordId)
@@ -1434,7 +1442,8 @@ namespace CarCareTracker.Controllers
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.UpgradeRecord).ExtraFields)
};
return PartialView("_UpgradeRecordModal", convertedResult);
}
@@ -1569,7 +1578,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddSupplyRecordPartialView()
{
return PartialView("_SupplyRecordModal", new SupplyRecordInput());
return PartialView("_SupplyRecordModal", new SupplyRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetSupplyRecordForEditById(int supplyRecordId)
@@ -1588,7 +1597,8 @@ namespace CarCareTracker.Controllers
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.SupplyRecord).ExtraFields)
};
return PartialView("_SupplyRecordModal", convertedResult);
}
@@ -1682,7 +1692,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddPlanRecordPartialView()
{
return PartialView("_PlanRecordModal", new PlanRecordInput());
return PartialView("_PlanRecordModal", new PlanRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields });
}
[HttpPost]
public IActionResult UpdatePlanRecordProgress(int planRecordId, PlanProgress planProgress, int odometer = 0)
@@ -1700,7 +1710,8 @@ namespace CarCareTracker.Controllers
Date = DateTime.Now,
VehicleId = existingRecord.VehicleId,
Mileage = odometer,
Notes = $"Auto Insert From Plan Record: {existingRecord.Description}"
Notes = $"Auto Insert From Plan Record: {existingRecord.Description}",
ExtraFields = existingRecord.ExtraFields
});
}
//convert plan record to service/upgrade/repair record.
@@ -1714,7 +1725,8 @@ namespace CarCareTracker.Controllers
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files
Files = existingRecord.Files,
ExtraFields = existingRecord.ExtraFields
};
_serviceRecordDataAccess.SaveServiceRecordToVehicle(newRecord);
}
@@ -1728,7 +1740,8 @@ namespace CarCareTracker.Controllers
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files
Files = existingRecord.Files,
ExtraFields = existingRecord.ExtraFields
};
_collisionRecordDataAccess.SaveCollisionRecordToVehicle(newRecord);
}
@@ -1742,7 +1755,8 @@ namespace CarCareTracker.Controllers
Description = existingRecord.Description,
Cost = existingRecord.Cost,
Notes = existingRecord.Notes,
Files = existingRecord.Files
Files = existingRecord.Files,
ExtraFields = existingRecord.ExtraFields
};
_upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(newRecord);
}
@@ -1766,7 +1780,8 @@ namespace CarCareTracker.Controllers
Cost = result.Cost,
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files
Files = result.Files,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.PlanRecord).ExtraFields)
};
return PartialView("_PlanRecordModal", convertedResult);
}
@@ -1805,7 +1820,7 @@ namespace CarCareTracker.Controllers
[HttpGet]
public IActionResult GetAddOdometerRecordPartialView()
{
return PartialView("_OdometerRecordModal", new OdometerRecordInput());
return PartialView("_OdometerRecordModal", new OdometerRecordInput() { ExtraFields = _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields });
}
[HttpGet]
public IActionResult GetOdometerRecordForEditById(int odometerRecordId)
@@ -1820,7 +1835,8 @@ namespace CarCareTracker.Controllers
Notes = result.Notes,
VehicleId = result.VehicleId,
Files = result.Files,
Tags = result.Tags
Tags = result.Tags,
ExtraFields = StaticHelper.AddExtraFields(result.ExtraFields, _extraFieldDataAccess.GetExtraFieldsById((int)ImportMode.OdometerRecord).ExtraFields)
};
return PartialView("_OdometerRecordModal", convertedResult);
}

View File

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

View File

@@ -0,0 +1,80 @@
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 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))";
if (existingRecord.ExtraFields != null)
{
cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
}
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

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

View File

@@ -1,5 +1,6 @@
using CarCareTracker.Models;
using System.Globalization;
using System.Linq;
namespace CarCareTracker.Helper
{
@@ -128,7 +129,8 @@ namespace CarCareTracker.Helper
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags
Tags = input.Tags,
ExtraFields = input.ExtraFields
};
}
public static CollisionRecord GenericToRepairRecord(GenericRecord input)
@@ -142,7 +144,8 @@ namespace CarCareTracker.Helper
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags
Tags = input.Tags,
ExtraFields = input.ExtraFields
};
}
public static UpgradeRecord GenericToUpgradeRecord(GenericRecord input)
@@ -156,10 +159,31 @@ namespace CarCareTracker.Helper
Mileage = input.Mileage,
Files = input.Files,
Notes = input.Notes,
Tags = input.Tags
Tags = input.Tags,
ExtraFields = input.ExtraFields
};
}
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));
//append the fields.
foreach(ExtraField extraField in recordExtraFields)
{
extraField.IsRequired = templateExtraFields.Where(x => x.Name == extraField.Name).First().IsRequired;
}
return recordExtraFields;
}
public static string GetFuelEconomyUnit(bool useKwh, bool useHours, bool useMPG, bool useUKMPG)
{
string fuelEconomyUnit;

View File

@@ -12,6 +12,7 @@
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<SupplyUsage> Supplies { get; set; } = new List<SupplyUsage>();
public List<string> Tags { get; set; } = new List<string>();
public CollisionRecord ToCollisionRecord() { return new CollisionRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags }; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public CollisionRecord ToCollisionRecord() { return new CollisionRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags, ExtraFields = ExtraFields }; }
}
}

9
Models/ExtraField.cs Normal file
View File

@@ -0,0 +1,9 @@
namespace CarCareTracker.Models
{
public class ExtraField
{
public string Name { get; set; }
public string Value { get; set; }
public bool IsRequired { get; set; }
}
}

View File

@@ -19,5 +19,6 @@
public string Notes { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -19,6 +19,7 @@
public string Notes { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public GasRecord ToGasRecord() { return new GasRecord {
Id = Id,
Cost = Cost,
@@ -30,7 +31,8 @@
IsFillToFull = IsFillToFull,
MissedFuelUp = MissedFuelUp,
Notes = Notes,
Tags = Tags
Tags = Tags,
ExtraFields = ExtraFields
}; }
}
}

View File

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

View File

@@ -9,5 +9,6 @@
public string Notes { get; set; }
public List<string> Tags { get; set; } = new List<string>();
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -9,6 +9,7 @@
public string Notes { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public OdometerRecord ToOdometerRecord() { return new OdometerRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Mileage = Mileage, Notes = Notes, Files = Files, Tags = Tags }; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public OdometerRecord ToOdometerRecord() { return new OdometerRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Mileage = Mileage, Notes = Notes, Files = Files, Tags = Tags, ExtraFields = ExtraFields }; }
}
}

View File

@@ -13,5 +13,6 @@
public PlanPriority Priority { get; set; }
public PlanProgress Progress { get; set; }
public decimal Cost { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -14,6 +14,7 @@
public PlanPriority Priority { get; set; }
public PlanProgress Progress { get; set; }
public decimal Cost { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public PlanRecord ToPlanRecord() { return new PlanRecord {
Id = Id,
VehicleId = VehicleId,
@@ -25,7 +26,8 @@
ImportMode = ImportMode,
Cost = Cost,
Priority = Priority,
Progress = Progress
Progress = Progress,
ExtraFields = ExtraFields
}; }
}
}

View File

@@ -0,0 +1,14 @@
using LiteDB;
namespace CarCareTracker.Models
{
public class RecordExtraField
{
/// <summary>
/// Corresponds to int value of ImportMode enum
/// </summary>
[BsonId(false)]
public int Id { get; set; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -12,6 +12,7 @@
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<SupplyUsage> Supplies { get; set; } = new List<SupplyUsage>();
public List<string> Tags { get; set; } = new List<string>();
public ServiceRecord ToServiceRecord() { return new ServiceRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags }; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public ServiceRecord ToServiceRecord() { return new ServiceRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags, ExtraFields = ExtraFields }; }
}
}

View File

@@ -34,5 +34,6 @@
public string Notes { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -13,6 +13,7 @@
public string Notes { get; set; }
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public SupplyRecord ToSupplyRecord() { return new SupplyRecord {
Id = Id,
VehicleId = VehicleId,
@@ -24,7 +25,8 @@
Description = Description,
Notes = Notes,
Files = Files,
Tags = Tags
Tags = Tags,
ExtraFields = ExtraFields
}; }
}
}

View File

@@ -13,5 +13,6 @@
public int CustomMonthInterval { get; set; } = 0;
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
}
}

View File

@@ -13,6 +13,7 @@
public int CustomMonthInterval { get; set; } = 0;
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<string> Tags { get; set; } = new List<string>();
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public TaxRecord ToTaxRecord() { return new TaxRecord {
Id = Id,
VehicleId = VehicleId,
@@ -24,7 +25,8 @@
RecurringInterval = RecurringInterval,
CustomMonthInterval = CustomMonthInterval,
Files = Files,
Tags = Tags
Tags = Tags,
ExtraFields = ExtraFields
}; }
}
}

View File

@@ -12,6 +12,7 @@
public List<UploadedFiles> Files { get; set; } = new List<UploadedFiles>();
public List<SupplyUsage> Supplies { get; set; } = new List<SupplyUsage>();
public List<string> Tags { get; set; } = new List<string>();
public UpgradeRecord ToUpgradeRecord() { return new UpgradeRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags }; }
public List<ExtraField> ExtraFields { get; set; } = new List<ExtraField>();
public UpgradeRecord ToUpgradeRecord() { return new UpgradeRecord { Id = Id, VehicleId = VehicleId, Date = DateTime.Parse(Date), Cost = Cost, Mileage = Mileage, Description = Description, Notes = Notes, Files = Files, Tags = Tags, ExtraFields = ExtraFields }; }
}
}

View File

@@ -31,6 +31,7 @@ if (!string.IsNullOrWhiteSpace(builder.Configuration["POSTGRES_CONNECTION"])){
builder.Services.AddSingleton<IUserRecordDataAccess, PGUserRecordDataAccess>();
builder.Services.AddSingleton<ITokenRecordDataAccess, PGTokenRecordDataAccess>();
builder.Services.AddSingleton<IUserAccessDataAccess, PGUserAccessDataAccess>();
builder.Services.AddSingleton<IExtraFieldDataAccess, PGExtraFieldDataAccess>();
}
else
{
@@ -50,6 +51,7 @@ else
builder.Services.AddSingleton<IUserRecordDataAccess, UserRecordDataAccess>();
builder.Services.AddSingleton<ITokenRecordDataAccess, TokenRecordDataAccess>();
builder.Services.AddSingleton<IUserAccessDataAccess, UserAccessDataAccess>();
builder.Services.AddSingleton<IExtraFieldDataAccess, ExtraFieldDataAccess>();
}
//configure helpers

View File

@@ -0,0 +1,124 @@
@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
}
@model RecordExtraField
<script>
var extraFields = [];
</script>
<div class="modal-header">
<h5 class="modal-title">@(translator.Translate(userLanguage, "Manage Extra Fields"))</h5>
<button type="button" class="btn-close" onclick="hideExtraFieldModal()" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<div class="row">
<div class="col-12">
<select class="form-select" onchange="refreshExtraFieldModal()" id="extraFieldTab">
<!option @(Model.Id == (int)ImportMode.ServiceRecord ? "selected" : "") value="@((int)ImportMode.ServiceRecord)">@translator.Translate(userLanguage, "Service Record")</!option>
<!option @(Model.Id == (int)ImportMode.RepairRecord ? "selected" : "") value="@((int)ImportMode.RepairRecord)">@translator.Translate(userLanguage, "Repairs")</!option>
<!option @(Model.Id == (int)ImportMode.UpgradeRecord ? "selected" : "") value="@((int)ImportMode.UpgradeRecord)">@translator.Translate(userLanguage, "Upgrades")</!option>
<!option @(Model.Id == (int)ImportMode.GasRecord ? "selected" : "") value="@((int)ImportMode.GasRecord)">@translator.Translate(userLanguage, "Fuel")</!option>
<!option @(Model.Id == (int)ImportMode.TaxRecord ? "selected" : "") value="@((int)ImportMode.TaxRecord)">@translator.Translate(userLanguage, "Tax")</!option>
<!option @(Model.Id == (int)ImportMode.SupplyRecord ? "selected" : "") value="@((int)ImportMode.SupplyRecord)">@translator.Translate(userLanguage, "Supplies")</!option>
<!option @(Model.Id == (int)ImportMode.PlanRecord ? "selected" : "") value="@((int)ImportMode.PlanRecord)">@translator.Translate(userLanguage, "Planner")</!option>
<!option @(Model.Id == (int)ImportMode.OdometerRecord ? "selected" : "") value="@((int)ImportMode.OdometerRecord)">@translator.Translate(userLanguage, "Odometer")</!option>
</select>
</div>
</div>
<div class="row">
<div class="col-12">
<table class="table table-hover">
<thead class="sticky-top">
<tr class="d-flex">
<th scope="col" class="col-8">@translator.Translate(userLanguage, "Name")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Required")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
</tr>
</thead>
<tbody>
@if (Model.ExtraFields != null)
{
@foreach (ExtraField extraField in Model.ExtraFields)
{
<script>
extraFields.push({ name: decodeHTMLEntities('@extraField.Name'), isRequired: @extraField.IsRequired.ToString().ToLower()});
</script>
<tr class="d-flex">
<td class="col-8">@extraField.Name</td>
<td class="col-2"><input class="form-check-input" type="checkbox" onchange="updateExtraFieldIsRequired(decodeHTMLEntities('@extraField.Name'), this)" value="" @(extraField.IsRequired ? "checked" : "") /></td>
<td class="col-2"><button type="button" onclick="deleteExtraField(decodeHTMLEntities('@extraField.Name'))" class="btn btn-danger"><i class="bi bi-trash"></i></button></td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideExtraFieldModal()">@translator.Translate(userLanguage, "Close")</button>
<button type="button" class="btn btn-primary" onclick="addExtraField()">@translator.Translate(userLanguage, "Add New Field")</button>
</div>
<script>
var importMode = @Model.Id;
function addExtraField() {
Swal.fire({
title: 'Field Name',
html: `
<input type="text" id="inputExtraFieldName" class="swal2-input" placeholder="Field Name">
`,
confirmButtonText: 'Add',
focusConfirm: false,
preConfirm: () => {
const extraFieldName = $("#inputExtraFieldName").val();
if (!extraFieldName || extraFieldName.trim() == '') {
Swal.showValidationMessage(`Field names cannot be blank`);
} else if (extraFields.filter(x => x.name == extraFieldName).length > 0) {
Swal.showValidationMessage(`Field names must be unique`);
}
return { extraFieldName }
},
}).then(function (result) {
if (result.isConfirmed) {
extraFields.push({ name: result.value.extraFieldName, isRequired: false});
updateExtraFields();
}
});
}
function updateExtraFieldIsRequired(fieldId, checkbox){
var indexToEdit = extraFields.findIndex(x => x.name == fieldId);
var extraFieldToEdit = extraFields[indexToEdit];
extraFieldToEdit.isRequired = $(checkbox).is(":checked");
updateExtraFields();
}
function deleteExtraField(fieldId) {
extraFields = extraFields.filter(x => x.name != fieldId);
updateExtraFields();
}
function refreshExtraFieldModal() {
var selectedExtraFieldTab = $("#extraFieldTab").val();
$.post(`/Home/GetExtraFieldsModal?importMode=${selectedExtraFieldTab}`, function (data) {
if (data) {
$("#extraFieldModalContent").html(data);
} else {
errorToast(genericErrorMessage());
}
});
}
function updateExtraFields() {
$.post('/Home/UpdateExtraFields', { id: importMode, extraFields: extraFields }, function (data) {
if (data) {
$("#extraFieldModalContent").html(data);
} else {
errorToast(genericErrorMessage());
}
});
}
</script>

View File

@@ -178,6 +178,16 @@
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-md-6">
<span class="lead">@translator.Translate(userLanguage, "Manage Extra Fields")</span>
<div class="row">
<div class="col-12 d-grid">
<button onclick="showExtraFieldModal()" class="btn btn-primary btn-md">@translator.Translate(userLanguage, "Add/Remove Extra Fields")</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
@@ -229,7 +239,22 @@
</ul>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="extraFieldModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="extraFieldModalContent">
</div>
</div>
</div>
<script>
function showExtraFieldModal() {
$.get(`/Home/GetExtraFieldsModal?importMode=0`, function (data) {
$("#extraFieldModalContent").html(data);
$("#extraFieldModal").modal('show');
});
}
function hideExtraFieldModal() {
$("#extraFieldModal").modal('hide');
}
function getCheckedTabs() {
var visibleTabs = $("#visibleTabs :checked").map(function () {
return this.value;
@@ -283,13 +308,13 @@
window.location.href = data;
});
}
function openUploadLanguage(){
function openUploadLanguage() {
$("#inputLanguage").click();
}
function openRestoreBackup() {
$("#inputBackup").click();
}
function uploadLanguage(event){
function uploadLanguage(event) {
let formData = new FormData();
formData.append("file", event.files[0]);
sloader.show();
@@ -308,7 +333,7 @@
errorToast(response.message);
}
},
error: function(){
error: function () {
sloader.hide();
errorToast("An error has occurred, please check the file size and try again later.");
}
@@ -351,9 +376,9 @@
Swal.fire({
title: 'Setup Credentials',
html: `
<input type="text" id="authUsername" class="swal2-input" placeholder="Username">
<input type="password" id="authPassword" class="swal2-input" placeholder="Password">
`,
<input type="text" id="authUsername" class="swal2-input" placeholder="Username">
<input type="password" id="authPassword" class="swal2-input" placeholder="Password">
`,
confirmButtonText: 'Setup',
focusConfirm: false,
preConfirm: () => {

View File

@@ -39,6 +39,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="collisionRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -86,6 +86,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.GasRecord.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="gasRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -31,6 +31,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="odometerRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -43,6 +43,14 @@
<!option value="InProgress" @(Model.Progress == PlanProgress.InProgress ? "selected" : "")>@translator.Translate(userLanguage, "Doing")</!option>
<!option value = "Testing" @(Model.Progress == PlanProgress.Testing ? "selected" : "")>@translator.Translate(userLanguage, "Testing")</!option>
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
@if (!isNew)
{
<label>@($"{translator.Translate(userLanguage, "Date Created")}: {Model.DateCreated}")</label>

View File

@@ -39,6 +39,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="serviceRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -45,6 +45,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="supplyRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -33,6 +33,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="taxRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

View File

@@ -39,6 +39,14 @@
<!option value="@tag">@tag</!option>
}
</select>
@foreach (ExtraField field in Model.ExtraFields)
{
var elementId = Guid.NewGuid();
<div class="extra-field">
<label for="@elementId">@field.Name</label>
<input type="text" id="@elementId" class="form-control @(field.IsRequired ? "extra-field-required" : "")" placeholder="@field.Name" value="@field.Value">
</div>
}
</div>
<div class="col-md-6 col-12">
<label for="upgradeRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>

File diff suppressed because one or more lines are too long

View File

@@ -88,6 +88,10 @@ function getAndValidateCollisionRecordValues() {
var addReminderRecord = $("#addReminderCheck").is(":checked");
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (collisionDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#collisionRecordDate").addClass("is-invalid");
@@ -124,6 +128,7 @@ function getAndValidateCollisionRecordValues() {
files: uploadedFiles,
supplies: selectedSupplies,
tags: collisionTags,
addReminderRecord: addReminderRecord
addReminderRecord: addReminderRecord,
extraFields: extraFields.extraFields
}
}

View File

@@ -87,6 +87,10 @@ function getAndValidateGasRecordValues() {
var gasRecordId = getGasRecordModelData().id;
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (gasDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#gasRecordDate").addClass("is-invalid");
@@ -134,7 +138,8 @@ function getAndValidateGasRecordValues() {
tags: gasTags,
isFillToFull: gasIsFillToFull,
missedFuelUp: gasIsMissed,
notes: gasNotes
notes: gasNotes,
extraFields: extraFields.extraFields
}
}

View File

@@ -85,6 +85,10 @@ function getAndValidateOdometerRecordValues() {
var odometerRecordId = getOdometerRecordModelData().id;
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (serviceDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#odometerRecordDate").addClass("is-invalid");
@@ -105,6 +109,7 @@ function getAndValidateOdometerRecordValues() {
mileage: serviceMileage,
notes: serviceNotes,
tags: serviceTags,
files: uploadedFiles
files: uploadedFiles,
extraFields: extraFields.extraFields
}
}

View File

@@ -159,6 +159,10 @@ function getAndValidatePlanRecordValues() {
var planRecordId = getPlanRecordModelData().id;
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (planDescription.trim() == '') {
hasError = true;
$("#planRecordDescription").addClass("is-invalid");
@@ -183,7 +187,8 @@ function getAndValidatePlanRecordValues() {
supplies: selectedSupplies,
priority: planPriority,
progress: planProgress,
importMode: planType
importMode: planType,
extraFields: extraFields.extraFields
}
}
//drag and drop stuff.

View File

@@ -88,6 +88,10 @@ function getAndValidateServiceRecordValues() {
var addReminderRecord = $("#addReminderCheck").is(":checked");
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (serviceDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#serviceRecordDate").addClass("is-invalid");
@@ -124,6 +128,7 @@ function getAndValidateServiceRecordValues() {
files: uploadedFiles,
supplies: selectedSupplies,
tags: serviceTags,
addReminderRecord: addReminderRecord
addReminderRecord: addReminderRecord,
extraFields: extraFields.extraFields
}
}

View File

@@ -386,4 +386,25 @@ function showBulkImportModal(mode) {
}
function hideBulkImportModal() {
$("#bulkImportModal").modal('hide');
}
function getAndValidateExtraFields() {
var hasError = false;
var outputData = [];
$(".extra-field").map((index, elem) => {
var extraFieldName = $(elem).children("label").text();
var extraFieldInput = $(elem).children("input");
var extraFieldValue = extraFieldInput.val();
var extraFieldIsRequired = extraFieldInput.hasClass('extra-field-required');
if (extraFieldIsRequired && extraFieldValue.trim() == '') {
hasError = true;
extraFieldInput.addClass("is-invalid");
} else {
extraFieldInput.removeClass("is-invalid");
}
//only push fields with value in them
if (extraFieldValue.trim() != '') {
outputData.push({ name: extraFieldName, value: extraFieldValue, isRequired: extraFieldIsRequired });
}
});
return { hasError: hasError, extraFields: outputData };
}

View File

@@ -89,6 +89,10 @@ function getAndValidateSupplyRecordValues() {
var supplyRecordId = getSupplyRecordModelData().id;
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (supplyDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#supplyRecordDate").addClass("is-invalid");
@@ -125,6 +129,7 @@ function getAndValidateSupplyRecordValues() {
notes: supplyNotes,
quantity: supplyQuantity,
files: uploadedFiles,
tags: supplyTags
tags: supplyTags,
extraFields: extraFields.extraFields
}
}

View File

@@ -126,6 +126,10 @@ function getAndValidateTaxRecordValues() {
var addReminderRecord = $("#addReminderCheck").is(":checked");
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (taxDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#taxRecordDate").addClass("is-invalid");
@@ -157,6 +161,7 @@ function getAndValidateTaxRecordValues() {
customMonthInterval: customMonthInterval,
tags: taxTags,
files: uploadedFiles,
addReminderRecord: addReminderRecord
addReminderRecord: addReminderRecord,
extraFields: extraFields.extraFields
}
}

View File

@@ -88,6 +88,10 @@ function getAndValidateUpgradeRecordValues() {
var addReminderRecord = $("#addReminderCheck").is(":checked");
//validation
var hasError = false;
var extraFields = getAndValidateExtraFields();
if (extraFields.hasError) {
hasError = true;
}
if (upgradeDate.trim() == '') { //eliminates whitespace.
hasError = true;
$("#upgradeRecordDate").addClass("is-invalid");
@@ -124,6 +128,7 @@ function getAndValidateUpgradeRecordValues() {
files: uploadedFiles,
supplies: selectedSupplies,
tags: upgradeTags,
addReminderRecord: addReminderRecord
addReminderRecord: addReminderRecord,
extraFields: extraFields.extraFields
}
}