diff --git a/docs/8.0/ayanova/docs/form-adm-license.md b/docs/8.0/ayanova/docs/form-adm-license.md index c6945674..eea573ed 100644 --- a/docs/8.0/ayanova/docs/form-adm-license.md +++ b/docs/8.0/ayanova/docs/form-adm-license.md @@ -1,3 +1,3 @@ # ADM-LICENSE Placeholder -This is a placeholder page for sections that are not written yet +todo: document how downgrade license frees up techs based on oldest login first diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 740dcdef..c97ae36a 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -8,6 +8,7 @@ using AyaNova.Models; using System; using Newtonsoft.Json.Linq; using System.Collections.Generic; +using Microsoft.Extensions.Logging; namespace AyaNova.Biz { @@ -41,15 +42,24 @@ namespace AyaNova.Biz } //Called by license processor when use downgrades to lesser amount of techs - internal static async Task DeActivateExcessiveTechs(int KeepThisManyActiveTechs) + internal static async Task DeActivateExcessiveTechs(long KeepThisManyActiveTechs, ILogger _log) { + var TotalActiveTechs = await ActiveCountAsync(); + int CountOfTechsToSetInactive = (int)(TotalActiveTechs - KeepThisManyActiveTechs); + if (CountOfTechsToSetInactive < 1) return; + _log.LogInformation($"New license is a downgrade with fewer scheduleable resources, deactivating {CountOfTechsToSetInactive} scheduleable users with the oldest last login dates to make room for the new license"); + using (AyContext ct = ServiceProviderProvider.DBContext) { - var ActiveTechList = await ct.User.AsNoTracking().Where(z => z.Active == true && ( + var ActiveTechList = await ct.User.Where(z => z.Active == true && ( z.UserType == UserType.Service || - z.UserType == UserType.ServiceContractor)).ToListAsync(); - - + z.UserType == UserType.ServiceContractor)).OrderBy(z => z.LastLogin).Take(CountOfTechsToSetInactive).ToListAsync(); + foreach (User u in ActiveTechList) + { + u.Active = false; + _log.LogInformation($"User {u.Name} set to inactive"); + } + await ct.SaveChangesAsync(); } } diff --git a/server/AyaNova/util/License.cs b/server/AyaNova/util/License.cs index 2200a1f9..b08af55e 100644 --- a/server/AyaNova/util/License.cs +++ b/server/AyaNova/util/License.cs @@ -704,19 +704,19 @@ namespace AyaNova.Core throw new ApplicationException("E1020 - Can't install a trial key into a non empty AyaNova database. Erase the database first."); } - //TODO: TECHCOUNT - new license causes exceeding count? - if (await AyaNova.Biz.UserBiz.ActiveCountAsync() > ParsedNewKey.GetLicenseFeature(SERVICE_TECHS_FEATURE_NAME).Count) + //TODO: TECHCOUNT - new license causes exceeding count? + long NewTechCount = ParsedNewKey.GetLicenseFeature(SERVICE_TECHS_FEATURE_NAME).Count; + if (await AyaNova.Biz.UserBiz.ActiveCountAsync() > NewTechCount) { - //Ok, the easy thing to do here is just set all techs inactive, but - //a trickier but probably better thing to do is set just enough techs inactive and choose them based - //on the oldest last login datetime first - throw new ApplicationException("E1020 - Can't install key, too many active techs and / or subcontractors in database. Deactivate enough to install key."); + //attempt to set enough of the eldest last login techs to inactive + await AyaNova.Biz.UserBiz.DeActivateExcessiveTechs(NewTechCount, log); + + if (await AyaNova.Biz.UserBiz.ActiveCountAsync() > NewTechCount) + throw new ApplicationException("E1020 - Can't install key, too many active techs and / or subcontractors in database. Deactivate enough to install key."); } //Update current license CurrentInDbKeyRecord.Key = RawTextNewKey; - //LOOKAT: reason, resultcode etc - //There is similar block related to this in ayschema for db schema version 8 await ct.SaveChangesAsync(); } catch (Exception ex)