diff --git a/server/AyaNova/biz/WorkOrderStatusBiz.cs b/server/AyaNova/biz/WorkOrderStatusBiz.cs new file mode 100644 index 00000000..e0f80ee4 --- /dev/null +++ b/server/AyaNova/biz/WorkOrderStatusBiz.cs @@ -0,0 +1,248 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using AyaNova.Util; +using AyaNova.Api.ControllerHelpers; +using AyaNova.Models; + +namespace AyaNova.Biz +{ + internal class WorkOrderStatusBiz : BizObject, ISearchAbleObject + { + internal WorkOrderStatusBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) + { + ct = dbcontext; + UserId = currentUserId; + UserTranslationId = userTranslationId; + CurrentUserRoles = UserRoles; + BizType = AyaType.WorkOrderStatus; + } + + internal static WorkOrderStatusBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) + { + if (httpContext != null) + return new WorkOrderStatusBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); + else + return new WorkOrderStatusBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdminFull); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //EXISTS + internal async Task ExistsAsync(long id) + { + return await ct.WorkOrderStatus.AnyAsync(z => z.Id == id); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //CREATE + // + internal async Task CreateAsync(WorkOrderStatus newObject) + { + await ValidateAsync(newObject, null); + if (HasErrors) + return null; + else + { + await ct.WorkOrderStatus.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await SearchIndexAsync(newObject, true); + return newObject; + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DUPLICATE + // + internal async Task DuplicateAsync(long id) + { + var dbObject = await GetAsync(id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + WorkOrderStatus newObject = new WorkOrderStatus(); + CopyObject.Copy(dbObject, newObject, "Wiki"); + string newUniqueName = string.Empty; + bool NotUnique = true; + long l = 1; + do + { + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObject.Name, l++, 255); + NotUnique = await ct.WorkOrderStatus.AnyAsync(m => m.Name == newUniqueName); + } while (NotUnique); + newObject.Name = newUniqueName; + newObject.Id = 0; + newObject.Concurrency = 0; + await ct.WorkOrderStatus.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await SearchIndexAsync(newObject, true); + return newObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //GET + // + internal async Task GetAsync(long id, bool logTheGetEvent = true) + { + var ret = await ct.WorkOrderStatus.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); + if (logTheGetEvent && ret != null) + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, AyaEvent.Retrieved), ct); + return ret; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //UPDATE + // + internal async Task PutAsync(WorkOrderStatus putObject) + { + var dbObject = await GetAsync(putObject.Id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + if (dbObject.Concurrency != putObject.Concurrency) + { + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + + + await ValidateAsync(putObject, dbObject); + if (HasErrors) return null; + ct.Replace(dbObject, putObject); + try + { + await ct.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!await ExistsAsync(putObject.Id)) + AddError(ApiErrorCode.NOT_FOUND); + else + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + await SearchIndexAsync(putObject, false); + return putObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DELETE + // + internal async Task DeleteAsync(long id) + { + using (var transaction = await ct.Database.BeginTransactionAsync()) + { + try + { + var dbObject = await GetAsync(id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND); + return false; + } + await ValidateCanDeleteAsync(dbObject); + if (HasErrors) + return false; + ct.WorkOrderStatus.Remove(dbObject); + await ct.SaveChangesAsync(); + + //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await transaction.CommitAsync(); + } + catch + { + //Just re-throw for now, let exception handler deal, but in future may want to deal with this more here + throw; + } + return true; + } + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //SEARCH + // + private async Task SearchIndexAsync(WorkOrderStatus obj, bool isNew) + { + var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType); + DigestSearchText(obj, SearchParams); + if (isNew) + await Search.ProcessNewObjectKeywordsAsync(SearchParams); + else + await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); + } + + public async Task GetSearchResultSummary(long id) + { + var obj = await GetAsync(id, false); + var SearchParams = new Search.SearchIndexProcessObjectParameters(); + DigestSearchText(obj, SearchParams); + return SearchParams; + } + + public void DigestSearchText(WorkOrderStatus obj, Search.SearchIndexProcessObjectParameters searchParams) + { + if (obj != null) + searchParams.AddText(obj.Notes) + .AddText(obj.Name); + } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //VALIDATION + // + + private async Task ValidateAsync(WorkOrderStatus proposedObj, WorkOrderStatus currentObj) + { + + bool isNew = currentObj == null; + + //Name required + if (string.IsNullOrWhiteSpace(proposedObj.Name)) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name"); + + + + //If name is otherwise OK, check that name is unique + if (!PropertyHasErrors("Name")) + { + //Use Any command is efficient way to check existance, it doesn't return the record, just a true or false + if (await ct.WorkOrderStatus.AnyAsync(m => m.Name == proposedObj.Name && m.Id != proposedObj.Id)) + { + AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name"); + } + } + + } + + private async Task ValidateCanDeleteAsync(WorkOrderStatus inObj) + { + //Referential integrity + //FOREIGN KEY CHECKS + // if (await ct.PurchaseOrder.AnyAsync(m => m.WorkOrderStatusId == inObj.Id)) + // AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder")); + } + + + + + + + + ///////////////////////////////////////////////////////////////////// + + }//eoc + + +}//eons + diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs index b80664de..0aaadf03 100644 --- a/server/AyaNova/models/AyContext.cs +++ b/server/AyaNova/models/AyContext.cs @@ -72,7 +72,8 @@ namespace AyaNova.Models public virtual DbSet CustomerServiceRequest { get; set; } - //WorkOrder + + //WorkOrder public virtual DbSet WorkOrder { get; set; } public virtual DbSet WorkOrderItem { get; set; } public virtual DbSet WorkOrderItemExpense { get; set; } @@ -84,6 +85,7 @@ namespace AyaNova.Models public virtual DbSet WorkOrderItemTask { get; set; } public virtual DbSet WorkOrderItemTravel { get; set; } public virtual DbSet WorkOrderItemUnit { get; set; } + public virtual DbSet WorkOrderStatus { get; set; } //WorkOrderTemplate public virtual DbSet WorkOrderTemplate { get; set; } diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index b8b9b846..f804b13a 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -421,6 +421,7 @@ BEGIN when 66 then aytable = 'apartwarehouse'; when 67 then aytable = 'apartinventory'; aynamecolumn='description'; when 68 then return format('DataListColumnView %L', ayobjectid); + when 71 then aytable = 'aworkorderstatus'; else RETURN returnstr; end case; diff --git a/server/AyaNova/util/DbUtil.cs b/server/AyaNova/util/DbUtil.cs index 849226dc..018558e1 100644 --- a/server/AyaNova/util/DbUtil.cs +++ b/server/AyaNova/util/DbUtil.cs @@ -408,6 +408,7 @@ namespace AyaNova.Util await EraseTableAsync("atravelrate", conn); await EraseTableAsync("ataxcode", conn); await EraseTableAsync("aservicebank", conn); + await EraseTableAsync("aworkorderstatus", conn); //after cleanup