Files
raven/server/AyaNova/util/Seeder.cs
2018-09-05 23:05:43 +00:00

333 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using AyaNova.Models;
using AyaNova.Biz;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using Bogus;
using AyaNova.Api.ControllerHelpers;
namespace AyaNova.Util
{
public static class Seeder
{
public enum SeedLevel { SmallOneManShopTrialDataSet, MediumLocalServiceCompanyTrialDataSet, LargeCorporateMultiRegionalTrialDataSet };
//////////////////////////////////////////////////////
//Seed database for trial and testing purposes
//
public static void SeedDatabase(SeedLevel slevel)
{
ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("Seeder");
ApiServerState apiServerState = (ApiServerState)ServiceProviderProvider.Provider.GetService(typeof(ApiServerState));
//get the current server state so can set back to it later
ApiServerState.ServerState wasServerState = apiServerState.GetState();
string wasReason = apiServerState.Reason;
try
{
log.LogInformation("SEEDER: SeedDatabase, level is: " + slevel.ToString());
//Only allow this in a trial database
if (!AyaNova.Core.License.ActiveKey.TrialLicense)
{
throw new System.NotSupportedException("This database has a registered license key and can't be seeded.");
}
log.LogInformation("Setting server state to OpsOnly");
apiServerState.SetOpsOnly("Seeding database");
//Erase all the data except for the license, schema and the manager user
DbUtil.PrepareDatabaseForSeeding(log);
//Seed special test data for integration testing
SeedKnownUsers();
switch (slevel)
{
//This is for a busy but one man shop with a single office person handling stuff back at the shop
case SeedLevel.SmallOneManShopTrialDataSet:
//Generate owner and lead tech
GenSeedUser(1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.OpsAdminFull, UserType.Schedulable);
//Generate one office person / secretary
GenSeedUser(1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.AccountingFull, UserType.NonSchedulable);
//200 widgets
GenSeedWidget(200);
break;
//This is for a typical AyaNova medium busy shop
//has one location, many techs and full staff for each department
case SeedLevel.MediumLocalServiceCompanyTrialDataSet:
//One IT administrator, can change ops but nothing else
GenSeedUser(1, AuthorizationRoles.OpsAdminFull, UserType.NonSchedulable);
//One business administrator, can view ops issues
GenSeedUser(1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable);
//One owner who doesn't control anything but views stuff
GenSeedUser(1, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable);
//20 techs
GenSeedUser(20, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Schedulable);
//2 subcontractors
GenSeedUser(2, AuthorizationRoles.SubContractorFull, UserType.Subcontractor);
//3 sales / generic office people people
GenSeedUser(3, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited, UserType.NonSchedulable);
//1 dispatch manager
GenSeedUser(1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited, UserType.NonSchedulable);
//1 Inventory manager
GenSeedUser(1, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited, UserType.NonSchedulable);
//1 accountant / bookkeeper
GenSeedUser(1, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NonSchedulable);
//10 full on client users
GenSeedUser(10, AuthorizationRoles.ClientLimited, UserType.Client);
//10 limited client users
GenSeedUser(10, AuthorizationRoles.ClientLimited, UserType.Client);
//2000 widgets
GenSeedWidget(2000);
break;
//this is a large corporation with multiple branches in multiple locations all in the same country
//Each location has a full staff and corporate head office has an overarching staff member in charge of each location
case SeedLevel.LargeCorporateMultiRegionalTrialDataSet:
//IT administrator, can change ops but nothing else
GenSeedUser(2, AuthorizationRoles.OpsAdminFull, UserType.NonSchedulable);
//business administrator, can view ops issues
GenSeedUser(2, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable);
//owner / upper management who doesn't control anything but views stuff
GenSeedUser(5, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable);
//techs
GenSeedUser(100, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Schedulable);
//limited techs
GenSeedUser(50, AuthorizationRoles.TechLimited | AuthorizationRoles.DispatchLimited, UserType.Schedulable);
//20 subcontractors
GenSeedUser(20, AuthorizationRoles.SubContractorFull, UserType.Subcontractor);
//10 limited subcontractors
GenSeedUser(10, AuthorizationRoles.SubContractorLimited, UserType.Subcontractor);
//30 sales / generic office people people
GenSeedUser(30, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited, UserType.NonSchedulable);
//5 dispatch manager
GenSeedUser(5, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited, UserType.NonSchedulable);
//5 Inventory manager
GenSeedUser(5, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited, UserType.NonSchedulable);
//10 Inventory manager assistants
GenSeedUser(5, AuthorizationRoles.InventoryLimited, UserType.NonSchedulable);
//5 accountant / bookkeeper
GenSeedUser(5, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NonSchedulable);
//100 full on client users
GenSeedUser(100, AuthorizationRoles.ClientFull, UserType.Client);
//100 limited client users
GenSeedUser(100, AuthorizationRoles.ClientLimited, UserType.Client);
//20000 widgets
GenSeedWidget(20000);
break;
}
log.LogInformation("Seeding completed successfully");
}
catch
{
throw;
}
finally
{
log.LogInformation($"Seeder: setting server state back to {wasServerState.ToString()}");
apiServerState.SetState(wasServerState, wasReason);
}
}
//////////////////////////////////////////////////////
//Seed test data for integration tests
//
public static void SeedKnownUsers()
{
//TEST USERS
//one of each role type
GenSeedUser(1, AuthorizationRoles.BizAdminLimited, UserType.NonSchedulable, "BizAdminLimited", "BizAdminLimited");
GenSeedUser(1, AuthorizationRoles.BizAdminFull, UserType.NonSchedulable, "BizAdminFull", "BizAdminFull");
GenSeedUser(1, AuthorizationRoles.DispatchLimited, UserType.NonSchedulable, "DispatchLimited", "DispatchLimited");
GenSeedUser(1, AuthorizationRoles.DispatchFull, UserType.NonSchedulable, "DispatchFull", "DispatchFull");
GenSeedUser(1, AuthorizationRoles.InventoryLimited, UserType.NonSchedulable, "InventoryLimited", "InventoryLimited");
GenSeedUser(1, AuthorizationRoles.InventoryFull, UserType.NonSchedulable, "InventoryFull", "InventoryFull");
GenSeedUser(1, AuthorizationRoles.AccountingFull, UserType.NonSchedulable, "Accounting", "Accounting");
GenSeedUser(1, AuthorizationRoles.TechLimited, UserType.Schedulable, "TechLimited", "TechLimited");
GenSeedUser(1, AuthorizationRoles.TechFull, UserType.Schedulable, "TechFull", "TechFull");
GenSeedUser(1, AuthorizationRoles.SubContractorLimited, UserType.Subcontractor, "SubContractorLimited", "SubContractorLimited");
GenSeedUser(1, AuthorizationRoles.SubContractorFull, UserType.Subcontractor, "SubContractorFull", "SubContractorFull");
GenSeedUser(1, AuthorizationRoles.ClientLimited, UserType.Client, "ClientLimited", "ClientLimited");
GenSeedUser(1, AuthorizationRoles.ClientFull, UserType.Client, "ClientFull", "ClientFull");
GenSeedUser(1, AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable, "OpsAdminLimited", "OpsAdminLimited");
GenSeedUser(1, AuthorizationRoles.OpsAdminFull, UserType.NonSchedulable, "OpsAdminFull", "OpsAdminFull");
//PRIVACY TEST USER - this is used for a test to see if user info leaks into the logs
GenSeedUser(1, AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable, "TEST_PRIVACY_USER_ACCOUNT", "TEST_PRIVACY_USER_ACCOUNT");
//TEST NOT ACTIVE - this is used for a test to see if inactive user can login
GenSeedUser(1, AuthorizationRoles.OpsAdminLimited, UserType.NonSchedulable, false, "TEST_INACTIVE", "TEST_INACTIVE");
}
/// <summary>
/// Generate seed user with active=true
/// (override to save typing)
/// </summary>
/// <param name="count"></param>
/// <param name="roles"></param>
/// <param name="userType"></param>
/// <param name="login"></param>
/// <param name="password"></param>
public static void GenSeedUser(int count, AuthorizationRoles roles, UserType userType, string login, string password)
{
GenSeedUser(count, roles, userType, true, login, password);
}
//////////////////////////////////////////////////////
//Seed user - default login / pw is first name
//
public static void GenSeedUser(int count, AuthorizationRoles roles, UserType userType, bool active = true, string login = null, string password = null)
{
AyContext ct = ServiceProviderProvider.DBContext;
for (int x = 0; x < count; x++)
{
User u = new User();
u.Active = active;
u.OwnerId = 1;
var p = new Bogus.Person();
u.Name = p.FullName;
u.Salt = Hasher.GenerateSalt();
if (login != null)
{
u.Login = login;
u.Name += " - " + login;
}
else
u.Login = p.FirstName;
if (password != null)
u.Password = Hasher.hash(u.Salt, password);
else
u.Password = Hasher.hash(u.Salt, u.Login);
u.Roles = roles;
u.LocaleId = ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID;
u.UserType = userType;
//TODO: After have USER and HEADOFFICE and VENDOR, if usertype is subcontractor or client or headoffice it needs to set a corresponding user's parent org record id to go with it
//Children and relations
u.UserOptions = new UserOptions(1);
u.UserOptions.EmailAddress = p.Email.Replace("gmail.com","helloayanova.com").Replace("hotmail.com","helloayanova.com").Replace("yahoo.com","helloayanova.com");
ct.User.Add(u);
}
//save to get id values
ct.SaveChanges();
//Now that we have the ID values bulk add the event log entries
//To save a db call iterate the local collection in the context, but...
//can't modify the context in the foreach, even if it's another collection entirely, so need to save the id's in a temporary list
List<long> ItemsAdded = new List<long>();
foreach (User o in ct.User.Local)
{
ItemsAdded.Add(o.Id);
}
//Now we have all the id's can actually add them to the context
foreach (long l in ItemsAdded)
{
EventLogProcessor.AddEntry(new Event(1, l, AyaType.User, AyaEvent.Created), ct);
}
//Now save the Event Log entries
ct.SaveChanges();
}
//////////////////////////////////////////////////////
//Seed widget for testing
//
public static void GenSeedWidget(int count)
{
//get a context just for this op to save memory on changetracking
AyContext ct = ServiceProviderProvider.DBContext;
var f = new Bogus.Faker();
for (int x = 0; x < count; x++)
{
Widget o = new Widget();
o.Name = f.Commerce.ProductName();
o.Active = f.Random.Bool();
o.StartDate = f.Date.Between(DateTime.Now, DateTime.Now.AddMinutes(60));
o.EndDate = f.Date.Between(DateTime.Now.AddMinutes(90), DateTime.Now.AddHours(5));
o.DollarAmount = Convert.ToDecimal(f.Commerce.Price());
o.OwnerId = 1;
//this is nonsense but just to test an enum
o.Roles = AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited;
ct.Widget.Add(o);
}
//Save the changes to get the ID values
ct.SaveChanges();
//Now that we have the ID values bulk add the event log entries
//To save a db call iterate the local collection in the context, but...
//can't modify the context in the foreach, even if it's another collection entirely, so need to save the id's in a temporary list
List<long> WidgetsAdded = new List<long>();
foreach (Widget w in ct.Widget.Local)
{
WidgetsAdded.Add(w.Id);
}
//Now we have all the id's can actually add them to the context
foreach (long l in WidgetsAdded)
{
EventLogProcessor.AddEntry(new Event(1, l, AyaType.Widget, AyaEvent.Created), ct);
}
//Now save the Event Log entries
ct.SaveChanges();
}
}//eoc
}//eons