added append password and forceemail options to seeder

This commit is contained in:
2022-03-15 23:26:06 +00:00
parent d129192c9f
commit 62a2f6d7bc
4 changed files with 158 additions and 138 deletions

View File

@@ -7,6 +7,7 @@ using AyaNova.Util;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;
using Newtonsoft.Json.Linq;
using System.ComponentModel.DataAnnotations;
namespace AyaNova.Api.Controllers
{
@@ -47,13 +48,15 @@ namespace AyaNova.Api.Controllers
/// "Medium" - Local service company with multiple employees and departments dataset
/// "Large" - Large corporate multi regional dataset
/// "Huge" - Used for automated testing and development, if you choose this it will take a very long time (15 minutes to overnight)
/// TimeZoneOffset - Value in hours of local time zone offset from UTC / GMT. This ensures that data is generated relative to the desired time zone
/// E2e - End to end testing mode for development automated testing; false is default and faster
/// ForceEmail - set every generated object with an email address to this email address
/// AppendPassword - append this string to the stock passwords, useful when testing on the public internet
/// </summary>
/// <param name="size">Valid values are "Small", "Medium", "Large", "Huge"</param>
/// <param name="timeZoneOffset">Value in hours of local time zone offset from UTC / GMT. This ensures that data is generated relative to the desired time zone</param>
/// <param name="e2e">End to end testing mode for automated testing; false is default and faster</param>
/// <param name="seedOptions"></param>
/// <returns>Job Id</returns>
[HttpPost("seed/{size}/{timeZoneOffset}/{e2e}")]
public async Task<IActionResult> SeedTrialDatabase([FromRoute] string size, [FromRoute] decimal timeZoneOffset, [FromRoute] bool e2e = false)
[HttpPost("seed")]
public async Task<IActionResult> SeedTrialDatabase([FromBody] SeedOptions seedOptions)
{
if (serverState.IsClosed)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
@@ -68,7 +71,7 @@ namespace AyaNova.Api.Controllers
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Current license is not a trial license key. Only a trial can be seeded."));
}
Seeder.Level.SeedLevel seedLevel = Seeder.Level.StringToSeedLevel(size);
Seeder.Level.SeedLevel seedLevel = Seeder.Level.StringToSeedLevel(seedOptions.Size);
if (seedLevel == Seeder.Level.SeedLevel.NotValid)
return BadRequest(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, "size", "Valid values are \"small\", \"medium\", \"large\", \"huge\""));
@@ -76,25 +79,38 @@ namespace AyaNova.Api.Controllers
JObject o = JObject.FromObject(new
{
seedLevel = seedLevel,
timeZoneOffset = timeZoneOffset,
e2e = e2e
seedLevel = seedOptions.Size,
timeZoneOffset = seedOptions.TimeZoneOffset,
e2e = seedOptions.E2e,
forceEmail=seedOptions.ForceEmail,
appendPassword=seedOptions.AppendPassword
});
OpsJob j = new OpsJob();
j.Name = $"Seed test data (size={size})";
j.Name = $"Seed test data (size={seedOptions.Size})";
j.JobType = JobType.SeedTestData;
j.Exclusive = true;//don't run other jobs, this will erase the db
j.JobInfo = o.ToString();
await JobsBiz.AddJobAsync(j);
//Log
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct);
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, seedOptions.Size), ct);
return Accepted(new { JobId = j.GId });//202 accepted
}
public class SeedOptions
{
[Required]
public string Size { get; set; }
[Required]
public decimal TimeZoneOffset { get; set; }
public bool E2e { get; set; } = false;
[EmailAddress]
public string ForceEmail { get; set; }
public string AppendPassword { get; set; }
}
//------------

View File

@@ -316,7 +316,7 @@ namespace AyaNova
////////////////////////////////////////////////////////////
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
//
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IWebHostEnvironment env,
public async void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IWebHostEnvironment env,
AyContext dbContext, IApiVersionDescriptionProvider provider, AyaNova.Api.ControllerHelpers.ApiServerState apiServerState,
IServiceProvider serviceProvider)
{
@@ -633,7 +633,7 @@ namespace AyaNova
_newLog.LogInformation($"Server test mode seeding, level is {ServerBootConfig.AYANOVA_SERVER_TEST_MODE_SEEDLEVEL}, tz offset is {ServerBootConfig.AYANOVA_SERVER_TEST_MODE_TZ_OFFSET}");
AyaNova.Core.License.FetchKeyAsync(apiServerState, dbContext, _newLog, true, true).Wait();
var seed = new Util.Seeder();
seed.SeedDatabaseAsync(Seeder.Level.StringToSeedLevel(ServerBootConfig.AYANOVA_SERVER_TEST_MODE_SEEDLEVEL), ServerBootConfig.AYANOVA_SERVER_TEST_MODE_TZ_OFFSET).Wait();
seed.SeedDatabaseAsync(Seeder.Level.StringToSeedLevel(ServerBootConfig.AYANOVA_SERVER_TEST_MODE_SEEDLEVEL), ServerBootConfig.AYANOVA_SERVER_TEST_MODE_TZ_OFFSET,null,null).Wait();
// _newLog.LogInformation("Seeding completed");
}
#endif

View File

@@ -66,8 +66,11 @@ namespace AyaNova.Biz
var seedLevel = (Seeder.Level.SeedLevel)jobData["seedLevel"].Value<int>();
var timeZoneOffset = jobData["timeZoneOffset"].Value<decimal>();
var e2e = jobData["e2e"].Value<bool>();
var forceEmail = jobData["forceEmail"].Value<string>();
var appendPassword = jobData["appendPassword"].Value<string>();
var seed = new Util.Seeder();
await seed.SeedDatabaseAsync(seedLevel, job.GId, timeZoneOffset, e2e);
await seed.SeedDatabaseAsync(seedLevel, job.GId, timeZoneOffset,forceEmail,appendPassword, e2e);
await JobsBiz.LogJobAsync(job.GId, "LT:JobCompleted");
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed);
}

View File

@@ -59,12 +59,12 @@ namespace AyaNova.Util
//Seed database for trial and testing purposes
//
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Decimal timeZoneOffset, bool e2e = false)
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Decimal timeZoneOffset, string forceEmail, string appendPassword, bool e2e = false)
{
await SeedDatabaseAsync(slevel, Guid.Empty, timeZoneOffset, e2e);
await SeedDatabaseAsync(slevel, Guid.Empty, timeZoneOffset, forceEmail, appendPassword, e2e);
}
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Guid JobId, Decimal timeZoneOffset, bool e2e = false)
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Guid JobId, Decimal timeZoneOffset, string forceEmail, string appendPassword, bool e2e = false)
{
bool LogJob = JobId != Guid.Empty;
_e2e = e2e;
@@ -203,7 +203,7 @@ namespace AyaNova.Util
//Seed special test data for integration testing
//log.LogInformation("Seeding known users");
await SeedKnownObjectsAsync(log);
await SeedKnownObjectsAsync(log, forceEmail, appendPassword);
/*
███████╗███████╗███████╗██████╗ █████╗ ██╗ ██╗ ████████╗██╗ ██╗███████╗ ████████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗
@@ -227,23 +227,23 @@ namespace AyaNova.Util
watch.Start();
//Generate owner and lead tech
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.OpsAdmin, UserType.Service);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.OpsAdmin, UserType.Service, forceEmail, appendPassword);
//Generate one office person / secretary
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.Accounting, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.Accounting, UserType.NotService, forceEmail, appendPassword);
//2 other techs (must always be enough to have no dupes per workorder)
await SeedUserAsync(log, 2, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 2, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
await SeedVendorAsync(log, 10);
await SeedVendorAsync(log, 10, forceEmail);
await SeedUnitModelAsync(log, 10);
await SeedCustomerAsync(log, 25, slevel);
await SeedHeadOfficeAsync(log, 10, slevel);
await SeedVendorAsync(log, 10);
await SeedCustomerAsync(log, 25, slevel, forceEmail, appendPassword);
await SeedHeadOfficeAsync(log, 10, slevel, forceEmail, appendPassword);
await SeedVendorAsync(log, 10, forceEmail);
await SeedProjectAsync(log, 3);
await SeedServiceRateAsync(log, 5);
await SeedTravelRateAsync(log, 3);
await SeedLoanLoanUnitAsync(log, 5);
await SeedCustomerServiceRequestAsync(log, 5);
await SeedCustomerServiceRequestAsync(log, 5, forceEmail, appendPassword);
await SeedPartWarehouseAsync(log, 5);
await SeedPartAsync(log, 20, 1000);
await SeedPartAssemblyAsync(log, 5);
@@ -270,39 +270,39 @@ namespace AyaNova.Util
watch.Start();
//One IT administrator, can change ops but nothing else
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword);
//One business administrator, can view ops issues
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
//One owner who doesn't control anything but views stuff
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted | AuthorizationRoles.SalesRestricted, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted | AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 5, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 5, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
//Restricted techs
// await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
//subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
//Restricted subcontractors
// await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
///////////////////////////////////////////
//3 generic office people people
await SeedUserAsync(log, 3, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 3, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//2 Full sales people
await SeedUserAsync(log, 2, AuthorizationRoles.Sales, UserType.NotService);
await SeedUserAsync(log, 2, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
//1 Service manager
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//1 Inventory manager
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
//1 accountant / bookkeeper
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
await SeedVendorAsync(log, 50);
await SeedVendorAsync(log, 50, forceEmail);
await SeedUnitModelAsync(log, 20);
await SeedCustomerAsync(log, 500, slevel);
await SeedHeadOfficeAsync(log, 20, slevel);
await SeedCustomerAsync(log, 500, slevel, forceEmail, appendPassword);
await SeedHeadOfficeAsync(log, 20, slevel, forceEmail, appendPassword);
await SeedProjectAsync(log, 5);
await SeedServiceRateAsync(log, 10);
@@ -310,7 +310,7 @@ namespace AyaNova.Util
//await SeedUnitAsync(log, 2500);
await SeedLoanLoanUnitAsync(log, 10);
await SeedCustomerServiceRequestAsync(log, 10);
await SeedCustomerServiceRequestAsync(log, 10, forceEmail, appendPassword);
await SeedPartWarehouseAsync(log, 10);
await SeedPartAsync(log, 100, 1000);
await SeedPartAssemblyAsync(log, 5);
@@ -339,45 +339,45 @@ namespace AyaNova.Util
//USERS
//IT administrator, can change ops but nothing else
await SeedUserAsync(log, 2, AuthorizationRoles.OpsAdmin, UserType.NotService);
await SeedUserAsync(log, 2, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword);
//business administrator, can view ops issues
await SeedUserAsync(log, 2, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 2, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 5, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 8, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 8, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
//Restricted techs
await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
//subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
//Restricted subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, forceEmail, appendPassword);
///////////////////////////////////////////
//30 generic office people people
await SeedUserAsync(log, 30, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 30, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//10 Full sales people
await SeedUserAsync(log, 10, AuthorizationRoles.Sales, UserType.NotService);
await SeedUserAsync(log, 10, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
//5 Restricted sales people
await SeedUserAsync(log, 5, AuthorizationRoles.SalesRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
//5 Service manager
await SeedUserAsync(log, 5, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//5 Inventory manager
await SeedUserAsync(log, 5, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
//10 Inventory manager assistants
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//5 accountant / bookkeeper
await SeedUserAsync(log, 5, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 5, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
await SeedVendorAsync(log, 100);
await SeedVendorAsync(log, 100, forceEmail);
await SeedUnitModelAsync(log, 40);
await SeedCustomerAsync(log, 1000, slevel);
await SeedHeadOfficeAsync(log, 40, slevel);
await SeedCustomerAsync(log, 1000, slevel, forceEmail, appendPassword);
await SeedHeadOfficeAsync(log, 40, slevel, forceEmail, appendPassword);
await SeedProjectAsync(log, 10);
await SeedServiceRateAsync(log, 20);
@@ -385,7 +385,7 @@ namespace AyaNova.Util
// await SeedUnitAsync(log, 5000);
await SeedLoanLoanUnitAsync(log, 20);
await SeedCustomerServiceRequestAsync(log, 20);
await SeedCustomerServiceRequestAsync(log, 20, forceEmail, appendPassword);
await SeedPartWarehouseAsync(log, 20);
await SeedPartAsync(log, 200, 1000);
await SeedPartAssemblyAsync(log, 5);
@@ -415,52 +415,52 @@ namespace AyaNova.Util
//USERS
//IT administrator, can change ops but nothing else
await SeedUserAsync(log, 10, AuthorizationRoles.OpsAdmin, UserType.NotService);
await SeedUserAsync(log, 10, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword);
//business administrator, can view ops issues
await SeedUserAsync(log, 10, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 10, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 20, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 20, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 15, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 15, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
//Restricted techs
await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
//subcontractors
await SeedUserAsync(log, 2, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
await SeedUserAsync(log, 2, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
//Restricted subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, forceEmail, appendPassword);
///////////////////////////////////////////
//generic office people people
await SeedUserAsync(log, 500, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 500, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//20 Full sales people
await SeedUserAsync(log, 60, AuthorizationRoles.Sales, UserType.NotService);
await SeedUserAsync(log, 60, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
//10 Restricted sales people
await SeedUserAsync(log, 10, AuthorizationRoles.SalesRestricted, UserType.NotService);
await SeedUserAsync(log, 10, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
//Service manager
await SeedUserAsync(log, 20, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 20, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//Inventory manager
await SeedUserAsync(log, 40, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
await SeedUserAsync(log, 40, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
//Inventory manager assistants
await SeedUserAsync(log, 20, AuthorizationRoles.InventoryRestricted, UserType.NotService);
await SeedUserAsync(log, 20, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
//accountant / bookkeeper
await SeedUserAsync(log, 20, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedUserAsync(log, 20, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
await SeedVendorAsync(log, 5000);
await SeedVendorAsync(log, 5000, forceEmail);
await SeedUnitModelAsync(log, 400);
await SeedCustomerAsync(log, 10000, slevel);
await SeedHeadOfficeAsync(log, 500, slevel);
await SeedCustomerAsync(log, 10000, slevel, forceEmail, appendPassword);
await SeedHeadOfficeAsync(log, 500, slevel, forceEmail, appendPassword);
await SeedProjectAsync(log, 1000);
await SeedServiceRateAsync(log, 200);
await SeedTravelRateAsync(log, 100);
await SeedLoanLoanUnitAsync(log, 200);
await SeedCustomerServiceRequestAsync(log, 200);
await SeedCustomerServiceRequestAsync(log, 200, forceEmail, appendPassword);
await SeedPartWarehouseAsync(log, 200);
await SeedPartAsync(log, 10000, 1000);
await SeedPartAssemblyAsync(log, 500);
@@ -586,34 +586,34 @@ namespace AyaNova.Util
//////////////////////////////////////////////////////
//Seed known / expected test data for tests/development
//
public async Task SeedKnownObjectsAsync(ILogger log)
public async Task SeedKnownObjectsAsync(ILogger log, string forceEmail, string appendPassword)
{
var KnownUserTags = new List<string>();
KnownUserTags.Add("known-user");
KnownUserTags.Add("test-role-user");
//TRIAL USERS
//one of each role type
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted, UserType.NotService, "BizAdminRestricted", "BizAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin, UserType.NotService, "BizAdmin", "BizAdmin", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.ServiceRestricted, UserType.NotService, "ServiceRestricted", "ServiceRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Service, UserType.NotService, "Service", "Service", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryRestricted, UserType.NotService, "InventoryRestricted", "InventoryRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory, UserType.NotService, "Inventory", "Inventory", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting, UserType.NotService, "Accounting", "Accounting", KnownUserTags);
KnownUserTechRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted, UserType.Service, "TechRestricted", "TechRestricted", KnownUserTags);
KnownUserTechId = await SeedUserAsync(log, 1, AuthorizationRoles.Tech, UserType.Service, "Tech", "Tech", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.SalesRestricted, UserType.NotService, "SalesRestricted", "SalesRestricted", KnownUserTags);
KnownUserSalesId = await SeedUserAsync(log, 1, AuthorizationRoles.Sales, UserType.NotService, "Sales", "Sales", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, "OpsAdminRestricted", "OpsAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService, "OpsAdmin", "OpsAdmin", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword, "BizAdminRestricted", "BizAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin, UserType.NotService, forceEmail, appendPassword, "BizAdmin", "BizAdmin", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword, "ServiceRestricted", "ServiceRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Service, UserType.NotService, forceEmail, appendPassword, "Service", "Service", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword, "InventoryRestricted", "InventoryRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory, UserType.NotService, forceEmail, appendPassword, "Inventory", "Inventory", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting, UserType.NotService, forceEmail, appendPassword, "Accounting", "Accounting", KnownUserTags);
KnownUserTechRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted, UserType.Service, forceEmail, appendPassword, "TechRestricted", "TechRestricted", KnownUserTags);
KnownUserTechId = await SeedUserAsync(log, 1, AuthorizationRoles.Tech, UserType.Service, forceEmail, appendPassword, "Tech", "Tech", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword, "SalesRestricted", "SalesRestricted", KnownUserTags);
KnownUserSalesId = await SeedUserAsync(log, 1, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword, "Sales", "Sales", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword, "OpsAdminRestricted", "OpsAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, "OpsAdmin", "OpsAdmin", KnownUserTags);
//Alternate translation users for each stock translation
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags);
//TEST NOT ACTIVE - this is used for a test to see if inactive user can login
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, false, "TEST_INACTIVE", "TEST_INACTIVE", 0, KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword, false, "TEST_INACTIVE", "TEST_INACTIVE", 0, KnownUserTags);
/////////////////////////////////////////////////////
@@ -761,7 +761,7 @@ namespace AyaNova.Util
ho.Phone3 = Fake.Phone.PhoneNumber();
ho.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
ho.EmailAddress = Fake.Internet.ExampleEmail();
ho.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
ho.ContractId = 3;//gold contract
ho.ContractExpires = DateTime.UtcNow.AddYears(1);
@@ -778,7 +778,7 @@ namespace AyaNova.Util
throw new System.Exception(err);
}
//Known HO type user
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.HeadOffice, true, "HeadOffice", "HeadOffice", 0, KnownUserTags, null, null, NewObject.Id);
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.HeadOffice, forceEmail, appendPassword, true, "HeadOffice", "HeadOffice", 0, KnownUserTags, null, null, NewObject.Id);
HeadOfficeIdForCustomer = NewObject.Id;
}
@@ -806,7 +806,7 @@ namespace AyaNova.Util
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
o.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
using (AyContext ct = ServiceProviderProvider.DBContext)
@@ -821,8 +821,8 @@ namespace AyaNova.Util
throw new System.Exception(err);
}
//Known customer type users
KnownUserCustomerId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "Customer", "Customer", 0, KnownUserTags, null, NewObject.Id, null);
KnownUserCustomerRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "CustomerRestricted", "CustomerRestricted", 0, KnownUserTags, null, NewObject.Id, null);
KnownUserCustomerId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, forceEmail, appendPassword, true, "Customer", "Customer", 0, KnownUserTags, null, NewObject.Id, null);
KnownUserCustomerRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, forceEmail, appendPassword, true, "CustomerRestricted", "CustomerRestricted", 0, KnownUserTags, null, NewObject.Id, null);
//5 units per customer
await SeedUnitAsync(log, 20, NewObject.Id);//5 times the customers or 5 units per customer
}
@@ -892,7 +892,7 @@ namespace AyaNova.Util
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
o.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
//intentional: tested and faster in loop
using (AyContext ct = ServiceProviderProvider.DBContext)
@@ -909,8 +909,8 @@ namespace AyaNova.Util
VendorIdForSubContractorUser = NewObject.Id;
}
KnownUserSubContractorRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, true, "SubContractorRestricted", "SubContractorRestricted", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
KnownUserSubContractorId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, true, "SubContractor", "SubContractor", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
KnownUserSubContractorRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, forceEmail, appendPassword, true, "SubContractorRestricted", "SubContractorRestricted", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
KnownUserSubContractorId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword, true, "SubContractor", "SubContractor", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
}
@@ -1678,7 +1678,7 @@ namespace AyaNova.Util
gbiz.Phone1 = Fake.Phone.PhoneNumber();
gbiz.Phone2 = Fake.Phone.PhoneNumber();
gbiz.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
gbiz.EmailAddress = Fake.Internet.ExampleEmail();
gbiz.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
gbiz.TaxPartPurchaseId = TCGoods;
gbiz.TaxPartSaleId = TCGoods;
@@ -1709,11 +1709,11 @@ namespace AyaNova.Util
/// Generate seed user with active=true
/// (override to save typing)
/// </summary>
public async Task<long> SeedUserAsync(ILogger log, int count, AuthorizationRoles roles, UserType userType, string login, string password, List<string> tags = null)
public async Task<long> SeedUserAsync(ILogger log, int count, AuthorizationRoles roles, UserType userType, string forceEmail, string appendPassword, string login, string password, List<string> tags = null)
{
try
{
return await SeedUserAsync(log, count, roles, userType, true, login, password, 0, tags);
return await SeedUserAsync(log, count, roles, userType, forceEmail, appendPassword, true, login, password, 0, tags);
}
catch
{
@@ -1738,7 +1738,7 @@ namespace AyaNova.Util
public async Task<long> SeedUserAsync(
ILogger log, int count, AuthorizationRoles roles, UserType userType,
ILogger log, int count, AuthorizationRoles roles, UserType userType, string forceEmail, string appendPassword,
bool active = true, string login = null, string password = null,
long translationId = 0, List<string> tags = null,
long? vendorId = null, long? customerId = null, long? headofficeId = null
@@ -1762,6 +1762,7 @@ namespace AyaNova.Util
var bogusEmail = u.Name.ToLowerInvariant().Replace(" ", "_") + "@example.net";
if (login != null)
{
u.Login = login;
@@ -1773,7 +1774,7 @@ namespace AyaNova.Util
if (password != null)
u.Password = password;
else
u.Password = u.Login;
u.Password = u.Login + appendPassword;
u.Roles = roles;
u.UserType = userType;
u.EmployeeNumber = "A-" + (454 + TotalSeededUsers + x).ToString() + "-Y";
@@ -1799,10 +1800,10 @@ namespace AyaNova.Util
//Children and relations
u.UserOptions = new UserOptions();
u.UserOptions.TranslationId = translationId;
u.UserOptions.EmailAddress = bogusEmail;
u.UserOptions.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? bogusEmail : forceEmail;
u.UserOptions.Hour12 = true;
u.UserOptions.CurrencyName = "USD";
u.UserOptions.UiColor = Fake.Internet.Color().ToUpperInvariant()+"FF";
u.UserOptions.UiColor = Fake.Internet.Color().ToUpperInvariant() + "FF";
//this seems wrong to get a new context inside a loop but in testing is actually faster!?
@@ -1834,7 +1835,7 @@ namespace AyaNova.Util
//////////////////////////////////////////////////////
//CUSTOMER
//
public async Task SeedCustomerAsync(ILogger log, int count, Level.SeedLevel slevel, long? headOfficeId = null)
public async Task SeedCustomerAsync(ILogger log, int count, Level.SeedLevel slevel, string forceEmail, string appendPassword, long? headOfficeId = null)
{
for (int x = 0; x < count; x++)
@@ -1869,7 +1870,7 @@ namespace AyaNova.Util
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
o.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
if (headOfficeId != null)
{
@@ -1895,7 +1896,7 @@ namespace AyaNova.Util
//Customer contacts
//10% chance (0-9)
if (Fake.Random.Number(9) == 4)
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, null, null, 0, null, null, NewObject.Id, null);
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, forceEmail, appendPassword, true, null, null, 0, null, null, NewObject.Id, null);
switch (slevel)
{
@@ -1917,7 +1918,7 @@ namespace AyaNova.Util
//////////////////////////////////////////////////////
//HEADOFFICE
//
public async Task SeedHeadOfficeAsync(ILogger log, int count, Level.SeedLevel slevel)
public async Task SeedHeadOfficeAsync(ILogger log, int count, Level.SeedLevel slevel, string forceEmail, string appendPassword)
{
for (int x = 0; x < count; x++)
@@ -1952,7 +1953,7 @@ namespace AyaNova.Util
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
o.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
@@ -1969,9 +1970,9 @@ namespace AyaNova.Util
throw new System.Exception(err);
}
//HeadOffice contacts
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.HeadOffice, true, null, null, 0, null, null, null, NewObject.Id);
await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.HeadOffice, forceEmail, appendPassword, true, null, null, 0, null, null, null, NewObject.Id);
//HeadOffice Customer
await SeedCustomerAsync(log, 2, slevel, NewObject.Id);
await SeedCustomerAsync(log, 2, slevel, forceEmail, appendPassword, NewObject.Id);
}
}
@@ -1982,7 +1983,7 @@ namespace AyaNova.Util
//////////////////////////////////////////////////////
//VENDOR
//
public async Task SeedVendorAsync(ILogger log, int count)
public async Task SeedVendorAsync(ILogger log, int count, string forceEmail)
{
for (int x = 0; x < count; x++)
@@ -2032,7 +2033,7 @@ namespace AyaNova.Util
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
o.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
//intentional: tested and faster in loop
using (AyContext ct = ServiceProviderProvider.DBContext)
@@ -2462,7 +2463,7 @@ namespace AyaNova.Util
//////////////////////////////////////////////////////
//CUSTOMERSERVICEREQUEST
//
public async Task SeedCustomerServiceRequestAsync(ILogger log, int count)
public async Task SeedCustomerServiceRequestAsync(ILogger log, int count, string forceEmail, string appendPassword)
{
DateTime seedStartWindow = DateTime.Now.AddMonths(-1);
DateTime seedEndWindow = DateTime.Now;
@@ -2476,7 +2477,7 @@ namespace AyaNova.Util
o.Tags = RandomTags();
o.DateRequested = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime();
o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers);
o.RequestedByUserId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, null, null, 0, null, null, o.CustomerId, null);
o.RequestedByUserId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, forceEmail, appendPassword, true, null, null, 0, null, null, o.CustomerId, null);
o.Status = CustomerServiceRequestStatus.Open;
o.Priority = Fake.Random.Enum<CustomerServiceRequestPriority>();
o.CustomerReferenceNumber = Fake.Finance.Account();
@@ -2849,7 +2850,7 @@ namespace AyaNova.Util
for (int x = 0; x < totalDays; x++)
{
int thisDayGenerateThisMany=Fake.Random.Int(0,3)+3;
int thisDayGenerateThisMany = Fake.Random.Int(0, 3) + 3;
for (int perDay = 0; perDay < thisDayGenerateThisMany; perDay++)
{
WorkOrder o = new WorkOrder();
@@ -2863,7 +2864,7 @@ namespace AyaNova.Util
bool olderThanOneWeekAgo = (woDate.Subtract(DateTime.UtcNow).TotalDays < -7);
bool isFutureDate = woDate > DateTime.UtcNow;
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow.Subtract(new TimeSpan(Fake.Random.Int(1,30),0,0,0)) : woDate;//no created dates in future but want a range of past dates to show off age of wo
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow.Subtract(new TimeSpan(Fake.Random.Int(1, 30), 0, 0, 0)) : woDate;//no created dates in future but want a range of past dates to show off age of wo
o.CompleteByDate = woDate.AddDays(5);
@@ -2934,25 +2935,25 @@ namespace AyaNova.Util
//SCHEDULED USERS
var actualScheduledUserCount = Fake.Random.Int(1, 2);
if (isFutureDate && Fake.Random.Int(1, 10) == 2)//10% chance unscheduled future wo to show off unscheduled widget
actualScheduledUserCount=0;
actualScheduledUserCount = 0;
for (int a = 0; a < actualScheduledUserCount; a++)
for (int a = 0; a < actualScheduledUserCount; a++)
{
var randomStart = Fake.Random.Int(0, 5);
var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
var randomStop = randomStart + randomHours;
var woItemScheduledUser = new WorkOrderItemScheduledUser()
{
var randomStart = Fake.Random.Int(0, 5);
var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
var randomStop = randomStart + randomHours;
var woItemScheduledUser = new WorkOrderItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = randomHours,
StartDate = woDate.AddHours(randomStart),//.AddDays(randomDays),
StopDate = woDate.AddHours(randomStop)//.AddDays(randomDays)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
UserId = RandomServiceTechUserId(),
EstimatedQuantity = randomHours,
StartDate = woDate.AddHours(randomStart),//.AddDays(randomDays),
StopDate = woDate.AddHours(randomStop)//.AddDays(randomDays)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
//PARTS