This commit is contained in:
2020-06-24 19:01:08 +00:00
parent b4e1f4cf92
commit b177bfefaf
4 changed files with 57 additions and 31 deletions

View File

@@ -1,13 +1,10 @@
using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using AyaNova.Util; using AyaNova.Util;
using AyaNova.Api.ControllerHelpers; using AyaNova.Api.ControllerHelpers;
using AyaNova.Models; using AyaNova.Models;
using Newtonsoft.Json.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace AyaNova.Biz namespace AyaNova.Biz
{ {
@@ -47,19 +44,22 @@ namespace AyaNova.Biz
// //
internal async Task<Translation> PutAsync(Translation putObject) internal async Task<Translation> PutAsync(Translation putObject)
{ {
Translation dbObject = await ct.Translation.SingleOrDefaultAsync(z => z.Id == putObject.Id); Translation dbObject = await ct.Translation.Include(z => z.TranslationItems).SingleOrDefaultAsync(z => z.Id == putObject.Id);
if (dbObject == null) if (dbObject == null)
{ {
AddError(ApiErrorCode.NOT_FOUND, "id"); AddError(ApiErrorCode.NOT_FOUND, "id");
return null; return null;
} }
Translation SnapshotOfOriginalDBObj = new Translation();
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); //No tags and no validation of prior state required so no snapshot required
CopyObject.Copy(putObject, dbObject, "Id"); CopyObject.Copy(putObject, dbObject, "Id");//note: won't update the child collection has to be done independently
foreach (TranslationItem ti in putObject.TranslationItems)
{
dbObject.TranslationItems.Where(z => z.Id == ti.Id).First().Display = ti.Display;
}
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency; ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
//maybe validate that there are no empty values? await ValidateAsync(dbObject);
await ValidateAsync(dbObject, SnapshotOfOriginalDBObj);
if (HasErrors) return null; if (HasErrors) return null;
try try
{ {
@@ -83,7 +83,7 @@ namespace AyaNova.Biz
// //
internal async Task<Translation> DuplicateAsync(long id) internal async Task<Translation> DuplicateAsync(long id)
{ {
Translation dbObject = await ct.Translation.SingleOrDefaultAsync(z => z.Id == id); Translation dbObject = await ct.Translation.Include(z => z.TranslationItems).SingleOrDefaultAsync(z => z.Id == id);
if (dbObject == null) if (dbObject == null)
{ {
@@ -278,7 +278,7 @@ namespace AyaNova.Biz
// //
//Can save or update? //Can save or update?
private async Task ValidateAsync(Translation proposedObj, Translation currentObj) private async Task ValidateAsync(Translation proposedObj)
{ {
//run validation and biz rules //run validation and biz rules
@@ -291,13 +291,20 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "Name", "255 char max"); AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "Name", "255 char max");
//Name must be unique //Name must be unique
if (await ct.Translation.AnyAsync(z => z.Name == proposedObj.Name)) if (await ct.Translation.AnyAsync(z => z.Name == proposedObj.Name && z.Id != proposedObj.Id))
AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name"); AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
//Ensure there are no empty keys //Ensure there are no empty keys or too long ones
if (proposedObj.TranslationItems.Where(z => z.Display.Length < 1).Any()) //fixing them up here rather than at the client as it's a bit of fuckery
//to try to validate or fix an item edited inside a data table with vuetify
//rather than try to deal with that just fix it here
foreach (var item in proposedObj.TranslationItems.Where(z => z.Display.Length < 1))
{ {
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Display", "One or more items are missing a display value"); item.Display = item.Key;
}
foreach (var item in proposedObj.TranslationItems.Where(z => z.Display.Length > 255))
{
item.Display = item.Display.Substring(0, 255);
} }
return; return;

View File

@@ -42,7 +42,7 @@ namespace AyaNova.Biz
// //
internal async Task<Widget> CreateAsync(Widget newObject) internal async Task<Widget> CreateAsync(Widget newObject)
{ {
await ValidateAsync(newObject, null); await ValidateAsync(newObject);
if (HasErrors) if (HasErrors)
return null; return null;
else else
@@ -118,7 +118,7 @@ namespace AyaNova.Biz
dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags);
dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields);
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency; ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); await ValidateAsync(dbObject);
if (HasErrors) return null; if (HasErrors) return null;
try try
{ {
@@ -216,12 +216,11 @@ namespace AyaNova.Biz
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
//VALIDATION //VALIDATION
// //
private async Task ValidateAsync(Widget proposedObj, Widget currentObj) private async Task ValidateAsync(Widget proposedObj)
{ {
//NOTE: In DB schema only name and serial are not nullable //NOTE: In DB schema only name and serial are not nullable
//run validation and biz rules //run validation and biz rules
bool isNew = currentObj == null;
//Name required //Name required
if (string.IsNullOrWhiteSpace(proposedObj.Name)) if (string.IsNullOrWhiteSpace(proposedObj.Name))

View File

@@ -8,6 +8,21 @@ namespace AyaNova.Models
{ {
public class Translation public class Translation
{ {
// public Translation() { }
// public Translation(Translation t)
// {
// Id = t.Id;
// Concurrency = t.Concurrency;
// Name = t.Name;
// CjkIndex = t.CjkIndex;
// _translationItems = new List<TranslationItem>();
// foreach (var titem in t.TranslationItems)
// {
// _translationItems.Add(new TranslationItem(titem));
// }
// }
public long Id { get; set; } public long Id { get; set; }
public uint Concurrency { get; set; } public uint Concurrency { get; set; }
@@ -17,11 +32,6 @@ namespace AyaNova.Models
public bool? Stock { get; set; } public bool? Stock { get; set; }
public bool CjkIndex { get; set; } public bool CjkIndex { get; set; }
//TODO: Defaults for user options translation settings:
// short date, short time formats
// currency symbol
//digit grouping separator symbol
//decimal symbol
//Relationship //Relationship
@@ -32,12 +42,12 @@ namespace AyaNova.Models
//is more efficient when there are many child collections (but when would that ever be desired for AyaNova?)and means no need to null check the collection //is more efficient when there are many child collections (but when would that ever be desired for AyaNova?)and means no need to null check the collection
//https://stackoverflow.com/a/20773057/8939 //https://stackoverflow.com/a/20773057/8939
private ICollection<TranslationItem> _translationItem; private ICollection<TranslationItem> _translationItems;
public virtual ICollection<TranslationItem> TranslationItems public virtual ICollection<TranslationItem> TranslationItems
{ {
get get
{ {
return this._translationItem ?? (this._translationItem = new HashSet<TranslationItem>()); return this._translationItems ?? (this._translationItems = new HashSet<TranslationItem>());
} }
} }

View File

@@ -11,12 +11,22 @@ namespace AyaNova.Models
public class TranslationItem public class TranslationItem
{ {
public TranslationItem() { }
public TranslationItem(TranslationItem t)
{
Id = t.Id;
Concurrency = t.Concurrency;
Key = t.Key;
Display = t.Display;
TranslationId = t.TranslationId;
}
public long Id { get; set; } public long Id { get; set; }
public uint Concurrency { get; set; } public uint Concurrency { get; set; }
[Required] [Required]
public string Key { get; set; } public string Key { get; set; }
[Required] //NOTE: due to various UI fuckery this is not set to required here so that the biz object
//validate code can fix it up automatically instead
public string Display { get; set; } public string Display { get; set; }
public long TranslationId { get; set; } public long TranslationId { get; set; }