diff --git a/server/AyaNova/Startup.cs b/server/AyaNova/Startup.cs index cecb533c..ae1fb731 100644 --- a/server/AyaNova/Startup.cs +++ b/server/AyaNova/Startup.cs @@ -455,7 +455,7 @@ namespace AyaNova { AyaNova.Core.License.FetchKeyAsync(apiServerState, dbContext, _newLog).Wait(); //NOTE: For unit testing make sure the time zone is same as tester to ensure list filter by date tests will work because server is on same page as user in terms of time - Util.Seeder.SeedDatabaseAsync(Util.Seeder.SeedLevel.MediumLocalServiceCompanyTrialDataSet, -8).Wait();//############################################################################################# + Util.Seeder.SeedDatabaseAsync(Util.Seeder.SeedLevel.SmallOneManShopTrialDataSet, -8).Wait();//############################################################################################# } //TESTING #endif diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index c175492f..a5de2ebe 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -23,14 +23,14 @@ namespace AyaNova.Biz internal static WidgetBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) { - + if (httpContext != null) return new WidgetBiz(ct, UserIdFromContext.Id(httpContext.Items), UserLocaleIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); else//when called internally for internal ops there will be no context so need to set default values for that return new WidgetBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, AuthorizationRoles.BizAdminFull); } - + //////////////////////////////////////////////////////////////////////////////////////////////// //EXISTS @@ -100,7 +100,20 @@ namespace AyaNova.Biz Widget outObj = new Widget(); CopyObject.Copy(dbObj, outObj); - outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); + // outObj.Name = Util.StringUtil.NameUniquify(outObj.Name, 255); + //generate unique name + string newUniqueName = string.Empty; + bool NotUnique = true; + long l = 1; + do + { + newUniqueName = Util.StringUtil.UniqueNameBuilder(dbObj.Name, l, 255); + NotUnique = await ct.Widget.AnyAsync(m => m.Name == newUniqueName); + } while (NotUnique); + + outObj.Name = newUniqueName; + + outObj.Id = 0; outObj.ConcurrencyToken = 0; diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 48c377c2..103b5a05 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -23,7 +23,7 @@ namespace AyaNova.Util private const int DESIRED_SCHEMA_LEVEL = 9; internal const long EXPECTED_COLUMN_COUNT = 98; - internal const long EXPECTED_INDEX_COUNT = 24; + internal const long EXPECTED_INDEX_COUNT = 25; //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!! @@ -208,7 +208,7 @@ namespace AyaNova.Util //Add widget table //id, text, longtext, boolean, currency, - await ExecQueryAsync("CREATE TABLE awidget (id BIGSERIAL PRIMARY KEY, name varchar(255) not null, serial bigint not null," + + await ExecQueryAsync("CREATE TABLE awidget (id BIGSERIAL PRIMARY KEY, name varchar(255) not null unique, serial bigint not null," + "startdate timestamp, enddate timestamp, dollaramount decimal(19,5), active bool, usertype int4, count integer," + "notes text, userid bigint null, customfields text, tags varchar(255) ARRAY)"); diff --git a/server/AyaNova/util/StringUtil.cs b/server/AyaNova/util/StringUtil.cs index aee3751f..814a7ec6 100644 --- a/server/AyaNova/util/StringUtil.cs +++ b/server/AyaNova/util/StringUtil.cs @@ -115,6 +115,20 @@ namespace AyaNova.Util return ret; } + + //Used to ensure a unique name generated by appending -nnn is within length requirements by splitting and chopping part of text to keep name + public static string UniqueNameBuilder(string oldName, long appendValue, int maxLength) + { + var appendString = "-" + appendValue.ToString(); + string ret = oldName + appendString; + var diff = maxLength - ret.Length; + if (diff < 0) + { + ret = oldName.Substring(0, Math.Abs(diff)) + appendString; + } + return ret; + } + //used to trim an enum type down to only it's most relevant (rightmost) portion public static string TrimTypeName(string str) {