diff --git a/.vscode/launch.json b/.vscode/launch.json
index b77f3b95..fcc80a75 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -53,7 +53,7 @@
"AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles",
"AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles",
"AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles",
- "AYANOVA_SERVER_TEST_MODE": "false",
+ "AYANOVA_SERVER_TEST_MODE": "true",
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7",
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\"
diff --git a/server/AyaNova/Controllers/UserOptionsController.cs b/server/AyaNova/Controllers/UserOptionsController.cs
index af4f5582..8199c39e 100644
--- a/server/AyaNova/Controllers/UserOptionsController.cs
+++ b/server/AyaNova/Controllers/UserOptionsController.cs
@@ -92,6 +92,41 @@ namespace AyaNova.Api.Controllers
+ //Creating a user creates a user options so no need for create ever
+ // ///
+ // /// Create UserOptions
+ // ///
+ // ///
+ // /// From route path
+ // ///
+ // [HttpPost]
+ // public async Task PostUserOptions([FromBody] UserOptions newObject, ApiVersion apiVersion)
+ // {
+ // if (!serverState.IsOpen)
+ // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
+ // // var UserId = UserIdFromContext.Id(HttpContext.Items);
+
+ // // //preclearance
+ // // //the biz object will further check
+ // // if (newObject.Id != UserId)
+ // // {
+ // // //Also used for Contacts (customer type user or ho type user)
+ // // //by users with no User right so further biz rule required depending on usertype
+ // // //this is just phase 1
+ // // if (!Authorized.HasCreateRole(HttpContext.Items, AyaType.User) && !Authorized.HasCreateRole(HttpContext.Items, AyaType.Customer))
+ // // return StatusCode(403, new ApiNotAuthorizedResponse());
+ // // }
+ // UserOptionsBiz biz = new UserOptionsBiz(ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items));
+
+ // if (!ModelState.IsValid)
+ // return BadRequest(new ApiErrorResponse(ModelState));
+ // UserOptions o = await biz.CreateAsync(newObject);
+ // if (o == null)
+ // return BadRequest(new ApiErrorResponse(biz.Errors));
+ // else
+ // return CreatedAtAction(nameof(UserOptionsController.GetUserOptions), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o));
+ // }
+
///
/// Update UserOptions
@@ -106,9 +141,8 @@ namespace AyaNova.Api.Controllers
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!ModelState.IsValid)
- {
return BadRequest(new ApiErrorResponse(ModelState));
- }
+
var UserId = UserIdFromContext.Id(HttpContext.Items);
var o = await ct.UserOptions.SingleOrDefaultAsync(z => z.UserId == id);
@@ -118,6 +152,8 @@ namespace AyaNova.Api.Controllers
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
}
+ //preclearance
+ //the biz object will further check
if (id != UserId)
{
//Also used for Contacts (customer type user or ho type user)
diff --git a/server/AyaNova/biz/UserOptionsBiz.cs b/server/AyaNova/biz/UserOptionsBiz.cs
index 0451bebe..5cfab9da 100644
--- a/server/AyaNova/biz/UserOptionsBiz.cs
+++ b/server/AyaNova/biz/UserOptionsBiz.cs
@@ -37,10 +37,50 @@ namespace AyaNova.Biz
//UPDATE
//
+ //Creating a user creates a user options so no need for create ever
+
+ // ////////////////////////////////////////////////////////////////////////////////////////////////
+ // //CREATE
+ // //
+ // internal async Task CreateAsync(UserOptions newObject)
+ // {
+
+ // User u = await ct.User.AsNoTracking().SingleOrDefaultAsync(z => z.Id == newObject.UserId);
+ // if (u == null)
+ // {
+ // AddError(ApiErrorCode.NOT_FOUND, "id");
+ // return null;
+ // }
+ // //Also used for Contacts (customer type user or ho type user)
+ // //by users with no User right but with Customer rights so need to double check here
+ // if (
+ // (u.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.Customer)) ||
+ // (!u.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.User))
+ // )
+ // {
+ // AddError(ApiErrorCode.NOT_AUTHORIZED);
+ // return null;
+ // }
+
+ // Validate(newObject);
+ // if (HasErrors)
+ // return null;
+ // else
+ // {
+
+ // await ct.UserOptions.AddAsync(newObject);
+ // await ct.SaveChangesAsync();
+ // await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
+
+ // return newObject;
+ // }
+ // }
+
+
//put
internal async Task PutAsync(UserOptions dbObject, UserOptions inObj)
{
- //todo: update to use the new PUT methodology?
+
//if it's not the user's own options then we need to check it just as for User / Contact objects
if (dbObject.Id != UserId)
{
@@ -66,7 +106,9 @@ namespace AyaNova.Biz
CopyObject.Copy(inObj, dbObject, "Id, UserId");
//Set "original" value of concurrency token to input token
//this will allow EF to check it out
- ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency;
+ //BUT NOT IF IT"S FROM A DUPLICATION OP (CONCURRENCY=0)
+ if (inObj.Concurrency != 0)
+ ct.Entry(dbObject).OriginalValues["Concurrency"] = inObj.Concurrency;
Validate(dbObject);
if (HasErrors)
diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs
index c0dc6ab3..b8d2aaf0 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 = 1;
internal const long EXPECTED_COLUMN_COUNT = 962;
- internal const long EXPECTED_INDEX_COUNT = 137;
+ internal const long EXPECTED_INDEX_COUNT = 138;
internal const long EXPECTED_CHECK_CONSTRAINTS = 415;
internal const long EXPECTED_FOREIGN_KEY_CONSTRAINTS = 118;
internal const long EXPECTED_VIEWS = 6;
@@ -464,7 +464,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
//Add user options table
await ExecQueryAsync("CREATE TABLE auseroptions (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, "
- + "userid BIGINT NOT NULL REFERENCES auser (id), translationid BIGINT NOT NULL REFERENCES atranslation (id), languageoverride TEXT, timezoneoverride TEXT, "
+ + "userid BIGINT NOT NULL UNIQUE REFERENCES auser (id), translationid BIGINT NOT NULL REFERENCES atranslation (id), languageoverride TEXT, timezoneoverride TEXT, "
+ "currencyname TEXT, hour12 BOOL NOT NULL, emailaddress TEXT, phone1 TEXT, phone2 TEXT, phone3 TEXT, uicolor VARCHAR(12) NOT NULL default '#000000', mapurltemplate TEXT)");