From ad74143630f250f7a1fac072d244eb84cf00f498 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 1 Oct 2021 18:09:00 +0000 Subject: [PATCH] --- devdocs/deploy.txt | 4 +- .../AyaNova/Controllers/ScheduleController.cs | 145 ++++++++++++++++-- server/AyaNova/models/AyContext.cs | 2 +- ...lWorkOrder.cs => ViewScheduleWorkOrder.cs} | 2 +- server/AyaNova/util/AySchema.cs | 4 +- server/AyaNova/util/AyaNovaVersion.cs | 2 +- 6 files changed, 135 insertions(+), 24 deletions(-) rename server/AyaNova/models/{ViewSchedulePersonalWorkOrder.cs => ViewScheduleWorkOrder.cs} (91%) diff --git a/devdocs/deploy.txt b/devdocs/deploy.txt index ca05774d..9dbf7605 100644 --- a/devdocs/deploy.txt +++ b/devdocs/deploy.txt @@ -23,8 +23,8 @@ SERVER - BUMP AyaNova.csproj version number - BUILD RELEASE Run buildrelease.bat in server project folder -https://www.ayanova.com/Downloads/v8/ayanova8.alpha.132-win-x64.7z -https://www.ayanova.com/Downloads/v8/migrate132.7z +https://www.ayanova.com/Downloads/v8/ayanova8.alpha.133-win-x64.7z +https://www.ayanova.com/Downloads/v8/migrate133.7z **ARCHIVE IT, otherwise it could be false positived - COPY TO DEVOPS SERVER diff --git a/server/AyaNova/Controllers/ScheduleController.cs b/server/AyaNova/Controllers/ScheduleController.cs index 1b146a05..ad2b006d 100644 --- a/server/AyaNova/Controllers/ScheduleController.cs +++ b/server/AyaNova/Controllers/ScheduleController.cs @@ -42,6 +42,86 @@ namespace AyaNova.Api.Controllers serverState = apiServerState; } + + /// + /// Get active Scheduleable user list + /// + /// List of all scheduleable users + [HttpGet("scheduleable-user-list")] + public async Task GetScheduleableUserList() + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.WorkOrder))//WorkOrder right applies to all svc-schedule ops + return StatusCode(403, new ApiNotAuthorizedResponse()); + var o = await ct.User.AsNoTracking().Where(x => x.Active == true && x.UserType == UserType.ServiceContractor || x.UserType == UserType.Service).OrderBy(x => x.Name).Select(x => new { x.Name, x.Id }).ToListAsync(); + + return Ok(ApiOkResponse.Response(o)); + } + + + + /// + /// Get service management schedule for parameters specified + /// time zone UTC offset in minutes is required to be passed in + /// timestamps returned are in Unix Epoch milliseconds converted for local time display + /// + /// Service schedule parameters + /// From route path + /// + [HttpPost("svc")] + public async Task PostServiceSchedule([FromBody] ServiceScheduleParams p, ApiVersion apiVersion) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + List r = new List(); + + //Note: query will return records that fall within viewed range even if they start or end outside of it + //However in month view (only, rest are as is) we can see up to 6 days before or after the month so in the interest of filling those voids: + //Adjust query dates to encompass actual potential view range + DateTime ViewStart = p.Start; + DateTime ViewEnd = p.End; + //this covers the largest possible window that could display due to nearly a week of the last or next month showing + if (p.View == ScheduleView.Month) + { + ViewStart = p.Start.AddDays(-6); + ViewEnd = p.End.AddDays(6); + } + + //WORKORDERS + { + //Note: query for *overlapping* ranges, not *contained* entirely in view range + r.AddRange(await ct.ViewScheduleWorkOrder.Where(x => p.Users.Contains(x.SchedUserId) && ViewStart <= x.StopDate && x.StartDate <= ViewEnd) + .Select(x => MakeServiceWOSchedItem(x, p)) + .ToListAsync()); + } + return Ok(ApiOkResponse.Response(r)); + } + + public class ServiceScheduleParams + { + [Required] + public ScheduleView View { get; set; } + [Required] + public DateTime Start { get; set; } + [Required] + public DateTime End { get; set; } + [Required] + public ScheduleWorkOrderColorSource WisuColorSource { get; set; } + [Required] + public List Users { get; set; }//user id's to display and in order to display + [Required] + public bool Dark { get; set; }//indicate if Client is set to dark mode or not, used for colorless types to display as black or white + } + + + //############################################################### + //PERSONAL + //############################################################### + /// /// Get personal schedule for parameters specified /// time zone UTC offset in minutes is required to be passed in @@ -80,8 +160,8 @@ namespace AyaNova.Api.Controllers if (p.Wisu && (UType == UserType.Service || UType == UserType.ServiceContractor)) { //Note: query for *overlapping* ranges, not *contained* entirely in view range - r.AddRange(await ct.ViewSchedulePersonalWorkOrder.Where(x => x.SchedUserId == UserId && ViewStart <= x.StopDate && x.StartDate <= ViewEnd) - .Select(x => MakeWOSchedItem(x, p)) + r.AddRange(await ct.ViewScheduleWorkOrder.Where(x => x.SchedUserId == UserId && ViewStart <= x.StopDate && x.StartDate <= ViewEnd) + .Select(x => MakePersonalWOSchedItem(x, p)) .ToListAsync()); } @@ -91,7 +171,6 @@ namespace AyaNova.Api.Controllers r.AddRange(await ct.Reminder.Where(x => x.UserId == UserId && ViewStart <= x.StopDate && x.StartDate <= ViewEnd).Select(x => MakeReminderSchedItem(x, p)).ToListAsync()); } - //REVIEWS if (p.Reviews) { @@ -168,16 +247,32 @@ namespace AyaNova.Api.Controllers //#### UTILITY METHODS ############## - private static PersonalScheduleListItem MakeWOSchedItem(ViewSchedulePersonalWorkOrder v, PersonalScheduleParams p) + + private static ServiceScheduleListItem MakeServiceWOSchedItem(ViewScheduleWorkOrder v, ServiceScheduleParams p) { - var s = new PersonalScheduleListItem(); + var s = new ServiceScheduleListItem(); s.Id = v.WoItemSchedUserId; - s.Color = ColorFromWOItem(v, p); + s.Color = ColorFromWOItem(v, p.WisuColorSource); s.TextColor = TextColor(s.Color); s.Start = (DateTime)v.StartDate; s.End = (DateTime)v.StopDate; s.Type = AyaType.WorkOrderItemScheduledUser; - s.Name = NameFromWOItem(v, p); + s.Name = NameFromWOItem(v); + s.Editable = v.WorkOrderStatusCompleted != true && v.WorkOrderStatusLocked != true;//could be null as well which we'll consider open as it's no status set + s.UserId=v.WoItemSchedUserId; + return s; + } + + private static PersonalScheduleListItem MakePersonalWOSchedItem(ViewScheduleWorkOrder v, PersonalScheduleParams p) + { + var s = new PersonalScheduleListItem(); + s.Id = v.WoItemSchedUserId; + s.Color = ColorFromWOItem(v, p.WisuColorSource); + s.TextColor = TextColor(s.Color); + s.Start = (DateTime)v.StartDate; + s.End = (DateTime)v.StopDate; + s.Type = AyaType.WorkOrderItemScheduledUser; + s.Name = NameFromWOItem(v); s.Editable = v.WorkOrderStatusCompleted != true && v.WorkOrderStatusLocked != true;//could be null as well which we'll consider open as it's no status set return s; } @@ -212,18 +307,18 @@ namespace AyaNova.Api.Controllers - private static string ColorFromWOItem(ViewSchedulePersonalWorkOrder v, PersonalScheduleParams p) + private static string ColorFromWOItem(ViewScheduleWorkOrder v, ScheduleWorkOrderColorSource src) { - switch (p.WisuColorSource) + switch (src) { - case PersonalScheduleWorkOrderColorSource.None: + case ScheduleWorkOrderColorSource.None: return GRAY_NEUTRAL_HEXA; - case PersonalScheduleWorkOrderColorSource.WorkOrderStatus: + case ScheduleWorkOrderColorSource.WorkOrderStatus: return string.IsNullOrWhiteSpace(v.WorkOrderStatusColor) ? GRAY_NEUTRAL_HEXA : v.WorkOrderStatusColor; - case PersonalScheduleWorkOrderColorSource.WorkOrderItemStatus: + case ScheduleWorkOrderColorSource.WorkOrderItemStatus: return string.IsNullOrWhiteSpace(v.WorkOrderItemStatusColor) ? GRAY_NEUTRAL_HEXA : v.WorkOrderItemStatusColor; - case PersonalScheduleWorkOrderColorSource.WorkOrderItemPriority: + case ScheduleWorkOrderColorSource.WorkOrderItemPriority: return string.IsNullOrWhiteSpace(v.WorkOrderItemPriorityColor) ? GRAY_NEUTRAL_HEXA : v.WorkOrderItemPriorityColor; } @@ -245,14 +340,14 @@ namespace AyaNova.Api.Controllers return yiq >= 128 ? "black" : "white";//<---NOTE: this MUST be a named color due to how the style is applied at client } - private static string NameFromWOItem(ViewSchedulePersonalWorkOrder v, PersonalScheduleParams p) + private static string NameFromWOItem(ViewScheduleWorkOrder v) { // Name=[wonumber customername] return v.Serial.ToString() + " " + v.CustomerName; } - public enum PersonalScheduleWorkOrderColorSource : int + public enum ScheduleWorkOrderColorSource : int { None = 0, WorkOrderStatus = 2, @@ -277,7 +372,7 @@ namespace AyaNova.Api.Controllers [Required] public DateTime End { get; set; } [Required] - public PersonalScheduleWorkOrderColorSource WisuColorSource { get; set; } + public ScheduleWorkOrderColorSource WisuColorSource { get; set; } [Required] public bool Wisu { get; set; } [Required] @@ -305,7 +400,23 @@ namespace AyaNova.Api.Controllers public bool Editable { get; set; } } - + public class ServiceScheduleListItem + { + //Never be null dates in here even though source records might be have null dates because they are not queried for and + //can't be displayed on a calendar anyway + //user can simply filter a data table by null dates to see them + //we shouldn't have allowed null dates in the first place in v7 but here we are :) + public DateTime Start { get; set; } + public DateTime End { get; set; } + public bool Timed { get { return true; } } + public string Name { get; set; } + public string Color { get; set; } + public string TextColor { get; set; } + public AyaType Type { get; set; } + public long Id { get; set; } + public bool Editable { get; set; } + public long UserId { get; set; } + } //------------ diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs index 887d5cd6..ab5dec53 100644 --- a/server/AyaNova/models/AyContext.cs +++ b/server/AyaNova/models/AyContext.cs @@ -125,7 +125,7 @@ namespace AyaNova.Models public virtual DbSet ViewPartInventoryList { get; set; } public virtual DbSet ViewUnfulfilledPartRequestList { get; set; } public virtual DbSet ViewPartInventoryRequestList { get; set; } - public virtual DbSet ViewSchedulePersonalWorkOrder { get; set; } + public virtual DbSet ViewScheduleWorkOrder { get; set; } diff --git a/server/AyaNova/models/ViewSchedulePersonalWorkOrder.cs b/server/AyaNova/models/ViewScheduleWorkOrder.cs similarity index 91% rename from server/AyaNova/models/ViewSchedulePersonalWorkOrder.cs rename to server/AyaNova/models/ViewScheduleWorkOrder.cs index 1cda0fa1..26dbadfc 100644 --- a/server/AyaNova/models/ViewSchedulePersonalWorkOrder.cs +++ b/server/AyaNova/models/ViewScheduleWorkOrder.cs @@ -5,7 +5,7 @@ namespace AyaNova.Models //Note this is how to define a View backed model with no key (id) [Microsoft.EntityFrameworkCore.Keyless] - public class ViewSchedulePersonalWorkOrder + public class ViewScheduleWorkOrder { public long WoItemSchedUserId { get; set; } public long SchedUserId { get; set; } diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 9d821e49..20b48ea0 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -1205,8 +1205,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); //SCHEDULE VIEWS - //PERSONAL WORKORDERS - await ExecQueryAsync("CREATE VIEW VIEWSCHEDULEPERSONALWORKORDER AS SELECT " + //WORKORDERS + await ExecQueryAsync("CREATE VIEW VIEWSCHEDULEWORKORDER AS SELECT " + "AWORKORDERITEMSCHEDULEDUSER.ID AS WOITEMSCHEDUSERID, " + "AWORKORDERITEMSCHEDULEDUSER.USERID AS SCHEDUSERID, " + "AWORKORDERITEMSCHEDULEDUSER.STARTDATE, " diff --git a/server/AyaNova/util/AyaNovaVersion.cs b/server/AyaNova/util/AyaNovaVersion.cs index 98952c11..cf38a5ab 100644 --- a/server/AyaNova/util/AyaNovaVersion.cs +++ b/server/AyaNova/util/AyaNovaVersion.cs @@ -5,7 +5,7 @@ namespace AyaNova.Util /// internal static class AyaNovaVersion { - public const string VersionString = "8.0.0-alpha.132"; + public const string VersionString = "8.0.0-alpha.133"; public const string FullNameAndVersion = "AyaNova server " + VersionString; }//eoc }//eons \ No newline at end of file