Files
raven/server/AyaNova/util/Seeder.cs
2021-06-17 18:37:52 +00:00

2931 lines
138 KiB
C#

using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using AyaNova.Models;
using AyaNova.Biz;
using Microsoft.Extensions.Logging;
using Bogus;
using AyaNova.Api.ControllerHelpers;
using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace AyaNova.Util
{
public class Seeder
{
public Faker Fake;
//### FAKER BIG LIST OF ALL SOURCE DATA HERE:
//https://github.com/bchavez/Bogus/blob/master/Source/Bogus/data/en.locale.json
//https://github.com/bchavez/Bogus#bogus-api-support
public Seeder()
{
Fake = new Faker();
}
public static class Level
{
public enum SeedLevel { NotValid, Small, Medium, Large, Huge };
public static SeedLevel StringToSeedLevel(string size)
{
switch (size.ToLowerInvariant())
{
case "small":
return SeedLevel.Small;
case "medium":
return SeedLevel.Medium;
case "large":
return SeedLevel.Large;
case "huge":
return SeedLevel.Huge;
default:
return SeedLevel.NotValid;
}
}
}
//////////////////////////////////////////////////////
//Seed database for trial and testing purposes
//
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Decimal timeZoneOffset)
{
await SeedDatabaseAsync(slevel, Guid.Empty, timeZoneOffset);
}
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Guid JobId, Decimal timeZoneOffset)
{
bool LogJob = JobId != Guid.Empty;
// TotalSeededUserCount = 0;
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
{
var StatusMsg = $"Seeding data, level {slevel.ToString()}, time zone offset {timeZoneOffset.ToString()}";
await LogStatusAsync(JobId, LogJob, log, StatusMsg);
//Only allow this in a trial database
if (!AyaNova.Core.License.ActiveKey.TrialLicense)
{
var msg = $"This database has a registered license key so it can't be seeded: {AyaNova.Core.License.LicenseInfoLogFormat}";
await LogStatusAsync(JobId, LogJob, log, msg);
throw new System.NotSupportedException(msg);
}
//validate timezone offset
if (timeZoneOffset > 14 || timeZoneOffset < (-12))
{
var msg = $"Time zone offset \"{timeZoneOffset.ToString()}\" is not valid";
await LogStatusAsync(JobId, LogJob, log, msg);
throw new System.NotSupportedException(msg);
}
TimeZoneOffset = timeZoneOffset;
apiServerState.SetOpsOnly("Seeding database");
ServerBootConfig.SEEDING = true;
//Erase all the data except for the license, schema and the SuperUser
await DbUtil.EmptyBizDataFromDatabaseForSeedingOrImportingAsync(log);
//Event log erase and seeding
using (var ct = ServiceProviderProvider.DBContext)
{
await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, 0, AyaType.Global, AyaEvent.EraseAllData, "(seeding preparation)"), ct);
await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, 0, AyaType.Global, AyaEvent.SeedDatabase, StatusMsg), ct);
}
apiServerState.SetOpsOnly("Seeding database with sample data");
//WIDGET sample form customization
{
var fc = new FormCustom()
{
FormKey = AyaType.Widget.ToString(),
Template = @"[
{
""fld"": ""Notes"",
""required"": true
},
{
""fld"": ""WidgetCustom1"",
""required"": false,
""type"": 1
},
{
""fld"": ""WidgetCustom2"",
""required"": true,
""type"": 4
},
{
""fld"": ""WidgetCustom3"",
""required"": false,
""type"": 5
},
{
""fld"": ""WidgetCustom4"",
""required"": false,
""type"": 6
},
{
""fld"": ""WidgetCustom5"",
""required"": false,
""type"": 8
},
{
""fld"": ""WidgetCustom6"",
""required"": false,
""type"": 2
},
{
""fld"": ""WidgetCustom7"",
""required"": false,
""type"": 3
}
]"
};
//Create and save to db
using (var ct = ServiceProviderProvider.DBContext)
await FormCustomBiz.GetBiz(ct).CreateAsync(fc);
}
//TODO: Add this back in or...fuck it?
// //Create a couple of DataListView's for development and testing
// {
// var dlv = new DataListSavedFilter()
// {
// Name = "Name starts with generic",
// UserId = 1,
// ListKey = "TestWidgetDataList",
// Public = true,
// ListView = @"[{""fld"": ""widgetname"",""filter"": {""any"":false,""items"": [{""op"": ""%-"",""value"": ""Generic""}]}}]"
// };
// //Create and save to db
// using (var ct = ServiceProviderProvider.DBContext)
// await DataListSavedFilterBiz.GetBiz(ct).CreateAsync(dlv);
// dlv = new DataListSavedFilter()
// {
// Name = "Awesome (lots of fields)",
// UserId = 1,
// ListKey = "TestWidgetDataList",
// Public = true,
// ListView = @"[{""fld"": ""widgetname"",""filter"": {""any"":false,""items"": [{""op"": ""%-"",""value"": ""Awesome""}]}},{""fld"":""widgetserial""},{""fld"":""widgetdollaramount""},{""fld"":""widgetusertype""},{""fld"":""widgetstartdate""},{""fld"":""widgetactive""},{""fld"":""username""},{""fld"":""widgettags""},{""fld"":""widgetcustom1""},{""fld"":""widgetcustom2""}]"
// };
// //Create and save to db
// using (var ct = ServiceProviderProvider.DBContext)
// await DataListSavedFilterBiz.GetBiz(ct).CreateAsync(dlv);
// }
//Seed special test data for integration testing
//log.LogInformation("Seeding known users");
await SeedKnownObjectsAsync(log);
/*
███████╗███████╗███████╗██████╗ █████╗ ██╗ ██╗ ████████╗██╗ ██╗███████╗ ████████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗
██╔════╝██╔════╝██╔════╝██╔══██╗ ██╔══██╗██║ ██║ ╚══██╔══╝██║ ██║██╔════╝ ╚══██╔══╝██║ ██║██║████╗ ██║██╔════╝ ██╔════╝
███████╗█████╗ █████╗ ██║ ██║ ███████║██║ ██║ ██║ ███████║█████╗ ██║ ███████║██║██╔██╗ ██║██║ ███╗███████╗
╚════██║██╔══╝ ██╔══╝ ██║ ██║ ██╔══██║██║ ██║ ██║ ██╔══██║██╔══╝ ██║ ██╔══██║██║██║╚██╗██║██║ ██║╚════██║
███████║███████╗███████╗██████╔╝ ██║ ██║███████╗███████╗ ██║ ██║ ██║███████╗ ██║ ██║ ██║██║██║ ╚████║╚██████╔╝███████║
╚══════╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
*/
//log.LogInformation("Seeding all other data");
switch (slevel)
{
case Level.SeedLevel.Small:
{
#region GenSmall
//This is for a busy but one man shop with a single office person handling stuff back at the shop
//PERF
await LogStatusAsync(JobId, LogJob, log, $"Seeding SMALL sample data....");
var watch = new Stopwatch();
watch.Start();
//Generate owner and lead tech
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.OpsAdminFull, UserType.Service);
//Generate one office person / secretary
await SeedUserAsync(log, 1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryFull | AuthorizationRoles.AccountingFull, UserType.NotService);
await SeedWidgetAsync(log, 3);//keeping this here for now but must remove later
await SeedCustomerAsync(log, 25);
await SeedHeadOfficeAsync(log, 10);
await SeedVendorAsync(log, 10);
await SeedProjectAsync(log, 10);
await SeedServiceRateAsync(log, 5);
await SeedTravelRateAsync(log, 3);
await SeedUnitModelAsync(log, 10);
await SeedUnitAsync(log, 20);//5 times the customers or 5 units per customer
await SeedLoanLoanUnitAsync(log, 5);
await SeedCustomerServiceRequestAsync(log, 5);
await SeedPartWarehouseAsync(log, 5);
await SeedPartAsync(log, 20, 100);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 20);
await SeedWorkOrderAsync(log, 10);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, "Small level sample data seeded in " + AyaNova.Util.DateUtil.FormatTimeSpan(watch.Elapsed));
#endregion gensmall
}
break;
case Level.SeedLevel.Medium:
{
#region GenMedium
//This is for a typical AyaNova medium busy shop
//has one location, many techs and full staff for each department
//PERF
await LogStatusAsync(JobId, LogJob, log, $"Seeding MEDIUM sample data....");
var watch = new Stopwatch();
watch.Start();
//One IT administrator, can change ops but nothing else
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminFull, UserType.NotService);
//One business administrator, can view ops issues
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited, UserType.NotService);
//One owner who doesn't control anything but views stuff
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminLimited | AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited | AuthorizationRoles.SalesLimited, UserType.NotService);
//20 techs
await SeedUserAsync(log, 20, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Service);
//2 subcontractors
await SeedUserAsync(log, 2, AuthorizationRoles.SubContractorFull, UserType.ServiceContractor);
//3 generic office people people
await SeedUserAsync(log, 3, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited, UserType.NotService);
//2 Full sales people
await SeedUserAsync(log, 2, AuthorizationRoles.SalesFull, UserType.NotService);
//1 dispatch manager
await SeedUserAsync(log, 1, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited, UserType.NotService);
//1 Inventory manager
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited, UserType.NotService);
//1 accountant / bookkeeper
await SeedUserAsync(log, 1, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NotService);
//await SeedWidgetAsync(log, 100);
await SeedCustomerAsync(log, 500);
await SeedHeadOfficeAsync(log, 20);
await SeedVendorAsync(log, 50);
await SeedProjectAsync(log, 50);
await SeedServiceRateAsync(log, 10);
await SeedTravelRateAsync(log, 5);
await SeedUnitModelAsync(log, 20);
await SeedUnitAsync(log, 2500);
await SeedLoanLoanUnitAsync(log, 10);
await SeedCustomerServiceRequestAsync(log, 10);
await SeedPartWarehouseAsync(log, 10);
await SeedPartAsync(log, 100, 300);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 30);
await SeedWorkOrderAsync(log, 30);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, "MEDIUM level sample data seeded in " + AyaNova.Util.DateUtil.FormatTimeSpan(watch.Elapsed));
#endregion genmedium
}
break;
case Level.SeedLevel.Large:
{
#region GenLarge
//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
//PERF
await LogStatusAsync(JobId, LogJob, log, $"Seeding LARGE sample data....");
var watch = new Stopwatch();
watch.Start();
//USERS
//IT administrator, can change ops but nothing else
await SeedUserAsync(log, 2, AuthorizationRoles.OpsAdminFull, UserType.NotService);
//business administrator, can view ops issues
await SeedUserAsync(log, 2, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited, UserType.NotService);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 5, AuthorizationRoles.BizAdminLimited | AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited, UserType.NotService);
//TECHS
await SeedUserAsync(log, 50, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Service);
//limited techs
await SeedUserAsync(log, 10, AuthorizationRoles.TechLimited | AuthorizationRoles.DispatchLimited, UserType.Service);
//20 subcontractors
await SeedUserAsync(log, 20, AuthorizationRoles.SubContractorFull, UserType.ServiceContractor);
//10 limited subcontractors
await SeedUserAsync(log, 10, AuthorizationRoles.SubContractorLimited, UserType.ServiceContractor);
//30 generic office people people
await SeedUserAsync(log, 30, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited, UserType.NotService);
//10 Full sales people
await SeedUserAsync(log, 10, AuthorizationRoles.SalesFull, UserType.NotService);
//5 Limited sales people
await SeedUserAsync(log, 5, AuthorizationRoles.SalesLimited, UserType.NotService);
//5 dispatch manager
await SeedUserAsync(log, 5, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited, UserType.NotService);
//5 Inventory manager
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited, UserType.NotService);
//10 Inventory manager assistants
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryLimited, UserType.NotService);
//5 accountant / bookkeeper
await SeedUserAsync(log, 5, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NotService);
//await SeedWidgetAsync(log, 100);
await SeedCustomerAsync(log, 1000);
await SeedHeadOfficeAsync(log, 40);
await SeedVendorAsync(log, 100);
await SeedProjectAsync(log, 100);
await SeedServiceRateAsync(log, 20);
await SeedTravelRateAsync(log, 10);
await SeedUnitModelAsync(log, 40);
await SeedUnitAsync(log, 5000);
await SeedLoanLoanUnitAsync(log, 20);
await SeedCustomerServiceRequestAsync(log, 20);
await SeedPartWarehouseAsync(log, 20);
await SeedPartAsync(log, 200, 600);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 50);
await SeedWorkOrderAsync(log, 60);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, "LARGE level sample data seeded in " + AyaNova.Util.DateUtil.FormatTimeSpan(watch.Elapsed));
#endregion genlarge
}
break;
case Level.SeedLevel.Huge:
{
#region GenHuge
//this is the HUGE dataset for load and other testing
//It is acceptable for this seeding to take many hours as it would normally be used rarely
//PERF
await LogStatusAsync(JobId, LogJob, log, $"Seeding HUGE sample data....");
var watch = new Stopwatch();
watch.Start();
//USERS
//IT administrator, can change ops but nothing else
await SeedUserAsync(log, 10, AuthorizationRoles.OpsAdminFull, UserType.NotService);
//business administrator, can view ops issues
await SeedUserAsync(log, 10, AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminLimited, UserType.NotService);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 20, AuthorizationRoles.BizAdminLimited | AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited | AuthorizationRoles.OpsAdminLimited, UserType.NotService);
//regular techs
await SeedUserAsync(log, 500, AuthorizationRoles.TechFull | AuthorizationRoles.DispatchLimited, UserType.Service);
//limited techs
await SeedUserAsync(log, 200, AuthorizationRoles.TechLimited | AuthorizationRoles.DispatchLimited, UserType.Service);
//subcontractors
await SeedUserAsync(log, 80, AuthorizationRoles.SubContractorFull, UserType.ServiceContractor);
//limited subcontractors
await SeedUserAsync(log, 40, AuthorizationRoles.SubContractorLimited, UserType.ServiceContractor);
//generic office people people
await SeedUserAsync(log, 200, AuthorizationRoles.DispatchLimited | AuthorizationRoles.InventoryLimited, UserType.NotService);
//20 Full sales people
await SeedUserAsync(log, 20, AuthorizationRoles.SalesFull, UserType.NotService);
//10 Limited sales people
await SeedUserAsync(log, 10, AuthorizationRoles.SalesLimited, UserType.NotService);
//dispatch manager
await SeedUserAsync(log, 20, AuthorizationRoles.DispatchFull | AuthorizationRoles.InventoryLimited, UserType.NotService);
//Inventory manager
await SeedUserAsync(log, 40, AuthorizationRoles.InventoryFull | AuthorizationRoles.DispatchLimited, UserType.NotService);
//Inventory manager assistants
await SeedUserAsync(log, 20, AuthorizationRoles.InventoryLimited, UserType.NotService);
//accountant / bookkeeper
await SeedUserAsync(log, 20, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NotService);
//await SeedWidgetAsync(log, 100);
await SeedCustomerAsync(log, 10000);
await SeedHeadOfficeAsync(log, 200);
await SeedVendorAsync(log, 500);
await SeedProjectAsync(log, 500);
await SeedServiceRateAsync(log, 100);
await SeedTravelRateAsync(log, 50);
await SeedUnitModelAsync(log, 200);
await SeedUnitAsync(log, 25000);
await SeedLoanLoanUnitAsync(log, 100);
await SeedCustomerServiceRequestAsync(log, 100);
await SeedPartWarehouseAsync(log, 100);
await SeedPartAsync(log, 1000, 3000);
await SeedPartAssemblyAsync(log, 25);
await SeedPurchaseOrderAsync(log, 250);
await SeedWorkOrderAsync(log, 300);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, "HUGE level sample data seeded in " + AyaNova.Util.DateUtil.FormatTimeSpan(watch.Elapsed));
#endregion genhuge
}
break;
}
//Seed logo files
var LogoFilesPath = System.IO.Path.Combine(ServerBootConfig.AYANOVA_CONTENT_ROOT_PATH, "resource", "rpt", "stock-report-templates");
if (System.IO.Directory.Exists(LogoFilesPath))
{
using (var ct = ServiceProviderProvider.DBContext)
{
var logo = await ct.Logo.FirstOrDefaultAsync();
if (logo == null)
{
logo = new Logo();
ct.Logo.Add(logo);
await ct.SaveChangesAsync();
}
logo.Small = System.IO.File.ReadAllBytes(System.IO.Path.Combine(LogoFilesPath, "150x50.png"));
logo.SmallType = "image/png";
logo.Medium = System.IO.File.ReadAllBytes(System.IO.Path.Combine(LogoFilesPath, "300x100.png"));
logo.MediumType = "image/png";
logo.Large = System.IO.File.ReadAllBytes(System.IO.Path.Combine(LogoFilesPath, "600x200.png"));
logo.LargeType = "image/png";
await ct.SaveChangesAsync();
}
}
await LogStatusAsync(JobId, LogJob, log, "Seeding completed successfully");
}
catch (Exception ex)
{
log.LogError(ex, "Seeder:SeedDatabase error during ops");
if (LogJob)
await JobsBiz.LogJobAsync(JobId, $"Seeder:SeedDatabase error during ops\r\n{ex.Message}");
throw;
}
finally
{
//No matter what seeding is done
ServerBootConfig.SEEDING = false;
log.LogInformation($"Seeder: setting server state back to {wasServerState.ToString()}");
apiServerState.SetState(wasServerState, wasReason);
}
}
//Log the status and also job if it's run via job
private async Task LogStatusAsync(Guid JobId, bool LogJob, ILogger log, string msg)
{
log.LogInformation(msg);
if (LogJob)
await JobsBiz.LogJobAsync(JobId, msg);
}
public long RUNNING_COUNT = 0;
public string Uniquify(string s)
{
return s + " " + (++RUNNING_COUNT).ToString();
}
private string[] TagSet = new[] { "red", "orange", "yellow", "green", "blue", "indigo", "violet", "brown", "black", "white", "silver", "gold", "fuchsia", "jade", "mauve", "purple", "quince", "xanthic", "zebra", "zone0", "zone1", "zone2", "zone3", "zone4", "zone5", "zone6", "zone7", "zone8", "zone9" };
private List<string> RandomTags()
{
var t = Fake.PickRandom(TagSet, Fake.Random.Int(1, 5));//pick up to 5 tags to apply
return new List<string>(t);
}
public enum SeedWOStatus : long
{
ManagerApprovalRequired = 1,
NeedsToBeAssigned = 2,
Scheduled = 3,
ServiceCompleted = 4,
WaitingOnCustomerApproval = 5,
WaitingOnParts = 6,
WaitingOnWarrantyReturn = 7,
WaitingToBeInvoiced = 8,
Closed = 9
}
long TCSales = 0, TCGoods = 0, TCBoth = 0;
public Decimal TimeZoneOffset = 0;
//this is supposed to output the correct UTC
//value to save to db to match the desired time input
//taking into account the timezoneoffset specified for generating data
//so for example if the tzoffset is -7 utc and a input of 9:00am
//then it should figure out what 9am in a -7 time zone is in UTC
//and return that value
public DateTime DesiredTimeInUtc(DateTime dt)
{
return dt.AddHours(0 - (double)TimeZoneOffset);
}
//////////////////////////////////////////////////////
//Seed known / expected test data for tests/development
//
public async Task SeedKnownObjectsAsync(ILogger log)
{
try
{
var KnownUserTags = new List<string>();
KnownUserTags.Add("known-user");
KnownUserTags.Add("test-role-user");
//TEST USERS
//one of each role type
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminLimited, UserType.NotService, "BizAdminLimited", "BizAdminLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminFull, UserType.NotService, "BizAdminFull", "BizAdminFull", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.DispatchLimited, UserType.NotService, "DispatchLimited", "DispatchLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.DispatchFull, UserType.NotService, "DispatchFull", "DispatchFull", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryLimited, UserType.NotService, "InventoryLimited", "InventoryLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryFull, UserType.NotService, "InventoryFull", "InventoryFull", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.AccountingFull, UserType.NotService, "Accounting", "Accounting", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.TechLimited, UserType.Service, "TechLimited", "TechLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.TechFull, UserType.Service, "TechFull", "TechFull", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.SalesLimited, UserType.NotService, "SalesLimited", "SalesLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.SalesFull, UserType.NotService, "SalesFull", "SalesFull", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminLimited, UserType.NotService, "OpsAdminLimited", "OpsAdminLimited", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminFull, UserType.NotService, "OpsAdminFull", "OpsAdminFull", KnownUserTags);
//Alternate translation users for each stock translation
await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags);
#if(DEBUG)
//PRIVACY TEST USER - this is used for a test to see if user info leaks into the logs
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminLimited, UserType.NotService, "TEST_PRIVACY_USER_ACCOUNT", "TEST_PRIVACY_USER_ACCOUNT", KnownUserTags);
//TEST NOT ACTIVE - this is used for a test to see if inactive user can login
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminLimited, UserType.NotService, false, "TEST_INACTIVE", "TEST_INACTIVE", 0, KnownUserTags);
#endif
/////////////////////////////////////////////////////
//CONTRACTS
{
await SeedTravelRateAsync(log, 1, "Bronze travel rate", true);//1
await SeedTravelRateAsync(log, 1, "Silver travel rate", true);//2
await SeedTravelRateAsync(log, 1, "Gold travel rate", true);//3
await SeedServiceRateAsync(log, 1, "Bronze service rate", true);//1
await SeedServiceRateAsync(log, 1, "Silver service rate", true);//2
await SeedServiceRateAsync(log, 1, "Gold service rate", true);//3
{
Contract c = new Contract();
c.Name = "Bronze";
c.Active = true;
c.Notes = "These are notes providing additional information when users view the contract";
c.AlertNotes = "These are alert notes displayed on workorders about this contract";
c.PartsOverridePct = 5m;
c.PartsOverrideType = ContractOverrideType.PriceDiscount;
c.ServiceRatesOverridePct = 5m;
c.ServiceRatesOverrideType = ContractOverrideType.PriceDiscount;
c.TravelRatesOverridePct = 5m;
c.TravelRatesOverrideType = ContractOverrideType.PriceDiscount;
c.ResponseTime = TimeSpan.Zero;
c.ContractServiceRatesOnly = true;
c.ServiceRateItems.Add(new ContractServiceRate() { ServiceRateId = 1 });
c.ContractTravelRatesOnly = true;
c.TravelRateItems.Add(new ContractTravelRate() { TravelRateId = 1 });
c.ContractServiceRateOverrideItems.Add(new ContractServiceRateOverride() { Tags = new string[] { "blue" }.ToList(), OverridePct = 5m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = new string[] { "blue" }.ToList(), OverridePct = 5m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = new string[] { "blue" }.ToList(), OverridePct = 10m, OverrideType = ContractOverrideType.PriceDiscount });
using (AyContext ct = ServiceProviderProvider.DBContext)
{
ContractBiz biz = ContractBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(c);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating Bronze contract\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
Contract c = new Contract();
c.Name = "Silver";
c.Active = true;
c.Notes = "These are notes providing additional information when users view the contract";
c.AlertNotes = "These are alert notes displayed on workorders about this contract";
c.PartsOverridePct = 10m;
c.PartsOverrideType = ContractOverrideType.PriceDiscount;
c.ServiceRatesOverridePct = 10m;
c.ServiceRatesOverrideType = ContractOverrideType.PriceDiscount;
c.TravelRatesOverridePct = 10;
c.TravelRatesOverrideType = ContractOverrideType.PriceDiscount;
c.ResponseTime = new TimeSpan(48, 0, 0);//48 hour response time
c.ContractServiceRatesOnly = true;
c.ServiceRateItems.Add(new ContractServiceRate() { ServiceRateId = 2 });
c.ContractTravelRatesOnly = true;
c.TravelRateItems.Add(new ContractTravelRate() { TravelRateId = 2 });
c.ContractServiceRateOverrideItems.Add(new ContractServiceRateOverride() { Tags = new string[] { "red" }.ToList(), OverridePct = 10m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = new string[] { "red" }.ToList(), OverridePct = 10m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = new string[] { "red" }.ToList(), OverridePct = 5m, OverrideType = ContractOverrideType.PriceDiscount });
using (AyContext ct = ServiceProviderProvider.DBContext)
{
ContractBiz biz = ContractBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(c);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating Silver contract\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
Contract c = new Contract();
c.Name = "Gold";
c.Active = true;
c.Notes = "These are notes providing additional information when users view the contract";
c.AlertNotes = "These are alert notes displayed on workorders about this contract";
c.PartsOverridePct = 15m;
c.PartsOverrideType = ContractOverrideType.PriceDiscount;
c.ServiceRatesOverridePct = 15m;
c.ServiceRatesOverrideType = ContractOverrideType.PriceDiscount;
c.TravelRatesOverridePct = 15m;
c.TravelRatesOverrideType = ContractOverrideType.PriceDiscount;
c.ResponseTime = new TimeSpan(24, 0, 0);//24 hour response time
c.ContractServiceRatesOnly = false;
c.ServiceRateItems.Add(new ContractServiceRate() { ServiceRateId = 3 });
c.ContractTravelRatesOnly = false;
c.TravelRateItems.Add(new ContractTravelRate() { TravelRateId = 3 });
c.ContractServiceRateOverrideItems.Add(new ContractServiceRateOverride() { Tags = new string[] { "green" }.ToList(), OverridePct = 20m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = new string[] { "green" }.ToList(), OverridePct = 20m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = new string[] { "green" }.ToList(), OverridePct = 20m, OverrideType = ContractOverrideType.PriceDiscount });
using (AyContext ct = ServiceProviderProvider.DBContext)
{
ContractBiz biz = ContractBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(c);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating Gold contract\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
////////////////////////////////
//HEADOFFICE
//
{
long HeadOfficeIdForCustomer = 0;
//seed a HO
HeadOffice ho = new HeadOffice();
ho.Name = "XYZ Head Office";
ho.Active = true;
ho.Notes = Fake.Company.CatchPhrase();
ho.Tags = RandomTags();
ho.AccountNumber = Fake.Finance.Account();
ho.Latitude = (decimal)Fake.Address.Latitude();
ho.Longitude = (decimal)Fake.Address.Longitude();
ho.Address = Fake.Address.StreetAddress();
ho.City = Fake.Address.City();
ho.Region = Fake.Address.State();
ho.Country = Fake.Address.Country();
ho.Phone1 = Fake.Phone.PhoneNumber();
ho.Phone2 = Fake.Phone.PhoneNumber();
ho.Phone3 = Fake.Phone.PhoneNumber();
ho.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
ho.EmailAddress = Fake.Internet.ExampleEmail();
ho.ContractId = 3;//gold contract
ho.ContractExpires = DateTime.UtcNow.AddYears(1);
using (AyContext ct = ServiceProviderProvider.DBContext)
{
HeadOfficeBiz biz = HeadOfficeBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(ho);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownHeadOffice error creating {ho.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
//Known HO type user
await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.HeadOffice, true, "HeadOffice", "HeadOffice", 0, KnownUserTags, null, null, NewObject.Id);
HeadOfficeIdForCustomer = NewObject.Id;
}
//CUSTOMER / HO Users
//seed a customer
Customer o = new Customer();
o.Name = "XYZ Accounting";
o.HeadOfficeId = HeadOfficeIdForCustomer;
o.BillHeadOffice = true;
o.Active = true;
o.Notes = Fake.Company.CatchPhrase();
o.Tags = RandomTags();
o.AccountNumber = Fake.Finance.Account();
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
o.Phone1 = Fake.Phone.PhoneNumber();
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
using (AyContext ct = ServiceProviderProvider.DBContext)
{
CustomerBiz biz = CustomerBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownCustomer error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
//Known customer type users
await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.Customer, true, "CustomerFull", "CustomerFull", 0, KnownUserTags, null, NewObject.Id, null);
await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.Customer, true, "CustomerLimited", "CustomerLimited", 0, KnownUserTags, null, NewObject.Id, null);
}
}
{
//VENDOR AND SUBCONTRACTORS
//Yellow Cedar Consulting
long VendorIdForSubContractorUser = 0;
Vendor o = new Vendor();
o.Name = "Yellow Cedar Consulting";
o.Active = true;
o.Notes = Fake.Company.CatchPhrase();
o.Tags = RandomTags();
o.Contact = Fake.Name.FullName();
o.ContactNotes = Fake.Name.FullName();
o.AccountNumber = Fake.Finance.Account();
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
o.Phone1 = Fake.Phone.PhoneNumber();
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
VendorBiz biz = VendorBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownVendor error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
VendorIdForSubContractorUser = NewObject.Id;
}
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorLimited, UserType.ServiceContractor, true, "SubContractorLimited", "SubContractorLimited", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorFull, UserType.ServiceContractor, true, "SubContractorFull", "SubContractorFull", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
}
/////////////////////////////////////////////////////
//Seed some test memos
{
for (int x = 0; x < 200; x++)
{
Memo memo = new Memo();
memo.Name = Fake.Lorem.Sentence();
memo.Notes = Fake.Lorem.Paragraphs();
memo.ToId = Fake.Random.Long(1, 17);
memo.FromId = Fake.Random.Long(1, 17);
memo.Tags = RandomTags();
using (AyContext ct = ServiceProviderProvider.DBContext)
{
MemoBiz biz = MemoBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(memo);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating memo\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
/////////////////////////////////////////////////////
//WorkorderStatus
{
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Manager approval required";
stat.Active = true;
stat.Color = "#c00000";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.DispatchFull | AuthorizationRoles.BizAdminFull;
stat.Notes = "Use to lock workorder and wait for approval from manager";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Needs to be assigned";
stat.Active = true;
stat.Color = "#80ffff";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.AllInsideUserRoles;
stat.Notes = "Waiting for technicians to be assigned to this work";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Scheduled";
stat.Active = true;
stat.Color = "#00ff00";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.AllInsideUserRoles;
stat.Notes = "Scheduled / ready for service";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Service completed";
stat.Active = true;
stat.Color = "#ff0000";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.DispatchFull | AuthorizationRoles.BizAdminFull;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Waiting on customer approval";
stat.Active = true;
stat.Color = "#8080ff";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.AllInsideUserRoles;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Waiting on parts";
stat.Active = true;
stat.Color = "#c0c000";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.AllInsideUserRoles;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Waiting on warranty return";
stat.Active = true;
stat.Color = "#ff00ff";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.AllInsideUserRoles;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Waiting to be invoiced";
stat.Active = true;
stat.Color = "#ffc0c0";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.AllInsideUserRoles;
stat.RemoveRoles = AuthorizationRoles.SalesFull | AuthorizationRoles.AccountingFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.BizAdminFull;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderStatus stat = new WorkOrderStatus();
stat.Name = "Closed";
stat.Active = true;
stat.Color = "#f2f2f2";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.DispatchFull | AuthorizationRoles.BizAdminFull;
stat.RemoveRoles = AuthorizationRoles.DispatchFull | AuthorizationRoles.BizAdminFull;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderStatusBiz biz = WorkOrderStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
/////////////////////////////////////////////////////
//WORKORDERITEMSTATUS
//
{
{
WorkOrderItemStatus stat = new WorkOrderItemStatus();
stat.Name = "Item is completed";
stat.Active = true;
stat.Color = "#c00000";
stat.Notes = "Indicates this item has been completed";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemStatusBiz biz = WorkOrderItemStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemStatus stat = new WorkOrderItemStatus();
stat.Name = "Item scheduled";
stat.Active = true;
stat.Color = "#00ff00";
stat.Notes = "Indicates this item has been scheduled";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemStatusBiz biz = WorkOrderItemStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemStatus stat = new WorkOrderItemStatus();
stat.Name = "Item on hold";
stat.Active = true;
stat.Color = "#0000ff";
stat.Notes = "Indicates this item is on hold";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemStatusBiz biz = WorkOrderItemStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
/////////////////////////////////////////////////////
//WORKORDERITEMPRIORITY
//
{
{
WorkOrderItemPriority stat = new WorkOrderItemPriority();
stat.Name = "Immediately";
stat.Active = true;
stat.Color = "#c00000";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemPriority stat = new WorkOrderItemPriority();
stat.Name = "24 hours";
stat.Active = true;
stat.Color = "#ff9900";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemPriority stat = new WorkOrderItemPriority();
stat.Name = "6 hours";
stat.Active = true;
stat.Color = "#ffff00";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemPriority stat = new WorkOrderItemPriority();
stat.Name = "One week";
stat.Active = true;
stat.Color = "#00ccff";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
WorkOrderItemPriority stat = new WorkOrderItemPriority();
stat.Name = "30 days";
stat.Active = true;
stat.Color = "#00ff00";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderItemPriorityBiz biz = WorkOrderItemPriorityBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating workorder item status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//=========================
}
/////////////////////////////////////////////////////
//TASKGROUP
//
{
{
TaskGroup t = new TaskGroup();
t.Name = "Clean and inspect Class 7C";
t.Active = true;
t.Notes = Fake.Lorem.Sentence();
t.Items.Add(new TaskGroupItem() { Sequence = 1, Task = "Open unit" });
t.Items.Add(new TaskGroupItem() { Sequence = 2, Task = "Test tinclavic seals" });
t.Items.Add(new TaskGroupItem() { Sequence = 3, Task = "Inspect triple-bonded polysium for cracks" });
t.Items.Add(new TaskGroupItem() { Sequence = 4, Task = "Verify thickness of zybanium shield" });
t.Items.Add(new TaskGroupItem() { Sequence = 5, Task = "Close unit" });
t.Items.Add(new TaskGroupItem() { Sequence = 6, Task = "Clean unit and confirm power up" });
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TaskGroupBiz biz = TaskGroupBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(t);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating TaskGroup\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
TaskGroup t = new TaskGroup();
t.Name = "Aerostat monitor standard refurb";
t.Active = true;
t.Notes = Fake.Lorem.Sentence();
t.Items.Add(new TaskGroupItem() { Sequence = 1, Task = "Power down unit" });
t.Items.Add(new TaskGroupItem() { Sequence = 2, Task = "Open seals" });
t.Items.Add(new TaskGroupItem() { Sequence = 3, Task = "Replace central core" });
t.Items.Add(new TaskGroupItem() { Sequence = 4, Task = "Test point B, verify +.25" });
t.Items.Add(new TaskGroupItem() { Sequence = 5, Task = "Replace seals" });
t.Items.Add(new TaskGroupItem() { Sequence = 6, Task = "Confirm power up" });
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TaskGroupBiz biz = TaskGroupBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(t);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating TaskGroup\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
/////////////////////////////////////////////////////
//TAX CODES
//
{
{
TaxCode tc = new TaxCode();
tc.Name = "Sales only";
tc.Notes = "Example sales only tax";
tc.Active = true;
tc.Tags = RandomTags();
tc.TaxAPct = 5m;
tc.TaxBPct = 0m;
tc.TaxOnTax = false;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TaxCodeBiz biz = TaxCodeBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(tc);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating TaxCode\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
TCSales = NewObject.Id;
}
}
{
TaxCode tc = new TaxCode();
tc.Name = "Goods only";
tc.Active = true;
tc.Notes = "Example goods only tax";
tc.Tags = RandomTags();
tc.TaxAPct = 7m;
tc.TaxBPct = 0;
tc.TaxOnTax = false;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TaxCodeBiz biz = TaxCodeBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(tc);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating TaxCode\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
TCGoods = NewObject.Id;
}
}
{
TaxCode tc = new TaxCode();
tc.Name = "Sales & Goods";
tc.Active = true;
tc.Notes = "Example sales and goods tax";
tc.Tags = RandomTags();
tc.TaxAPct = 5m;
tc.TaxBPct = 7m;
tc.TaxOnTax = false;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TaxCodeBiz biz = TaxCodeBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(tc);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating TaxCode\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
TCBoth = NewObject.Id;
}
}
}
/////////////////////////////////////////////////////
//GLOBAL SETTINGS
{
using (AyContext ct = ServiceProviderProvider.DBContext)
{
GlobalBizSettingsBiz biz = GlobalBizSettingsBiz.GetBiz(ct);
var gbiz = await biz.GetAsync(false);
gbiz.TaxPartPurchaseId = TCGoods;
gbiz.TaxPartSaleId = TCGoods;
gbiz.TaxRateSaleId = TCSales;
await biz.PutAsync(gbiz);
}
}
///////////////////////////////////////////////
}
catch
{
throw;
}
}
/// <summary>
/// Generate seed user with active=true
/// (override to save typing)
/// </summary>
public async Task SeedUserAsync(ILogger log, int count, AuthorizationRoles roles, UserType userType, string login, string password, List<string> tags = null)
{
try
{
await SeedUserAsync(log, count, roles, userType, true, login, password, 0, tags);
}
catch
{
throw;
}
}
public HashSet<string> HashUserNames = new HashSet<string>();
public List<long> ServiceUserIds = new List<long>();
private int TotalSeededUsers = 0;
public async Task<long> SeedUserAsync(
ILogger log, int count, AuthorizationRoles roles, UserType userType,
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
)
{
if (translationId == 0)
translationId = ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID;
//to return for code that creates a single user and needs the id
long LastSeededUserId = 0;
for (int x = 0; x < count; x++)
{
User u = new User();
u.Active = active;
do
{
u.Name = Fake.Name.FullName();
} while (!HashUserNames.Add(u.Name));
var bogusEmail = u.Name.ToLowerInvariant().Replace(" ", "_") + "@example.net";
if (login != null)
{
u.Login = login;
u.Name += " - " + login;
}
else
u.Login = bogusEmail;
if (password != null)
u.Password = password;
else
u.Password = u.Login;
u.Roles = roles;
u.UserType = userType;
u.EmployeeNumber = "A-" + (454 + TotalSeededUsers + x).ToString() + "-Y";
u.Notes = Fake.Lorem.Sentence(null, 5);//Fake.Lorem.Paragraph(2);
//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
//use provided tags or generate them
if (tags == null)
u.Tags = RandomTags();
else
u.Tags = tags;
//relations
u.VendorId = vendorId;
u.CustomerId = customerId;
u.HeadOfficeId = headofficeId;
//Children and relations
u.UserOptions = new UserOptions();
u.UserOptions.TranslationId = translationId;
u.UserOptions.EmailAddress = bogusEmail;
u.UserOptions.Hour12 = true;
u.UserOptions.CurrencyName = "USD";
u.UserOptions.UiColor = Fake.Internet.Color().ToUpperInvariant();
//this seems wrong to get a new context inside a loop but in testing is actually faster!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
UserBiz biz = UserBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(u);
if (u.UserType != UserType.NotService)
{
ServiceUserIds.Add(u.Id);
}
TotalSeededUsers++;
if (NewObject == null)
{
log.LogError($"Seeder::SeedUser error creating {u.Name}\r\n" + biz.GetErrorsAsString());
throw new System.Exception("Seeder::SeedUser error creating user\r\n" + biz.GetErrorsAsString());
}
LastSeededUserId = NewObject.Id;
}
}
return LastSeededUserId;
}
#region WIDGET
//////////////////////////////////////////////////////
//Seed widget for testing
//
public async Task SeedWidgetAsync(ILogger log, int count)
{
//this is 4 times slower than doing it inside the loop below
//seems counterintuitive but maybe it's to do with the db context not being refreshed?
//RANDOM ROLES
Array values = Enum.GetValues(typeof(UserType));
Random random = new Random();
DateTime seedStartWindow = DateTime.Now.AddYears(-1).AddMonths(-6);
DateTime seedEndWindow = DateTime.Now.AddYears(1).AddMonths(6);
for (int x = 0; x < count; x++)
{
Widget o = new Widget();
o.Name = Uniquify(Fake.Commerce.ProductName());
o.Active = true;
DateTime dtSeed = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime();
o.StartDate = dtSeed;
o.EndDate = dtSeed.AddMinutes(60).ToUniversalTime();
o.DollarAmount = Convert.ToDecimal(Fake.Commerce.Price());
//Random but valid enum
UserType randomUserType = (UserType)values.GetValue(random.Next(values.Length));
o.UserType = randomUserType;
o.Notes = Fake.Lorem.Sentence(null, 5);
o.Tags = RandomTags();
o.UserId = Fake.Random.Int(1, TotalSeededUsers);
//RANDOM CUSTOM FIELD DATA
var c1 = DateUtil.UniversalISO8661Format(Fake.Date.Between(DateTime.Now.AddYears(-1), DateTime.Now.AddYears(1)));
var c2 = Fake.Lorem.Sentence(null, 5);
var c3 = Fake.Random.Int(1, 99999999);
var c4 = Fake.Random.Bool().ToString().ToLowerInvariant();
var c5 = Fake.Random.Decimal();
o.CustomFields = $@"{{c1:""{c1}"",c2:""{c2}"",c3:{c3},c4:{c4},c5:{c5}}}";
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WidgetBiz biz = WidgetBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
if (NewObject == null)
{
log.LogError($"Seeder::SeedWidget error creating {o.Name}\r\n" + biz.GetErrorsAsString());
throw new System.Exception("Seeder::SeedWidget error creating widget\r\n" + biz.GetErrorsAsString());
}
}
}
}
#endregion
public HashSet<string> HashCompanyNames = new HashSet<string>();
private int TotalSeededCustomers = 0;
//////////////////////////////////////////////////////
//CUSTOMER
//
public async Task SeedCustomerAsync(ILogger log, int count, long? headOfficeId = null)
{
for (int x = 0; x < count; x++)
{
Customer o = new Customer();
do
{
o.Name = Fake.Company.CompanyName();
} while (!HashCompanyNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Company.CatchPhrase();
o.Tags = RandomTags();
o.AccountNumber = Fake.Finance.Account();
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
o.PostAddress = Fake.Address.StreetAddress();
o.PostCity = o.City;
o.PostRegion = o.Region;
o.PostCountry = o.Country;
o.PostCode = Fake.Address.ZipCode();
o.Phone1 = Fake.Phone.PhoneNumber();
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
if (headOfficeId != null)
{
o.HeadOfficeId = headOfficeId;
o.BillHeadOffice = true;
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
CustomerBiz biz = CustomerBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededCustomers++;
if (NewObject == null)
{
var err = $"Seeder::SeedCustomer error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
//Customer contacts
//10% chance (0-9)
if (Fake.Random.Number(9) == 4)
await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.Customer, true, null, null, 0, null, null, NewObject.Id, null);
}
}
}
private int TotalSeededHeadOffices = 0;
//////////////////////////////////////////////////////
//HEADOFFICE
//
public async Task SeedHeadOfficeAsync(ILogger log, int count)
{
for (int x = 0; x < count; x++)
{
HeadOffice o = new HeadOffice();
do
{
o.Name = Fake.Company.CompanyName();
} while (!HashCompanyNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Company.CatchPhrase();
o.Tags = RandomTags();
o.AccountNumber = Fake.Finance.Account();
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
o.PostAddress = Fake.Address.StreetAddress();
o.PostCity = o.City;
o.PostRegion = o.Region;
o.PostCountry = o.Country;
o.PostCode = Fake.Address.ZipCode();
o.Phone1 = Fake.Phone.PhoneNumber();
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
HeadOfficeBiz biz = HeadOfficeBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededHeadOffices++;
if (NewObject == null)
{
var err = $"Seeder::SeedHeadOffice error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
//HeadOffice contacts
await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.HeadOffice, true, null, null, 0, null, null, null, NewObject.Id);
//HeadOffice Customer
await SeedCustomerAsync(log, 2, NewObject.Id);
}
}
}
private int TotalSeededVendors = 0;
//////////////////////////////////////////////////////
//VENDOR
//
public async Task SeedVendorAsync(ILogger log, int count)
{
for (int x = 0; x < count; x++)
{
Vendor o = new Vendor();
do
{
o.Name = Fake.Company.CompanyName();
} while (!HashCompanyNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Company.CatchPhrase();
o.Tags = RandomTags();
o.Contact = Fake.Name.FullName();
o.ContactNotes = Fake.Name.FullName();
o.AccountNumber = Fake.Finance.Account();
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
o.Phone1 = Fake.Phone.PhoneNumber();
o.Phone2 = Fake.Phone.PhoneNumber();
o.Phone3 = Fake.Phone.PhoneNumber();
o.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
o.EmailAddress = Fake.Internet.ExampleEmail();
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
VendorBiz biz = VendorBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededVendors++;
if (NewObject == null)
{
var err = $"Seeder::SeedVendor error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashProjectNames = new HashSet<string>();
private int TotalSeededProjects = 0;
//////////////////////////////////////////////////////
//PROJECT
//
public async Task SeedProjectAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-1);
DateTime seedEndWindow = DateTime.Now.AddYears(1);
for (int x = 0; x < count; x++)
{
Project o = new Project();
do
{
var color = Fake.Commerce.Color();
o.Name = $"{char.ToUpper(color[0]) + color.Substring(1)} {Fake.Address.StreetSuffix()}";
} while (!HashProjectNames.Add(o.Name));
o.AccountNumber = Fake.Finance.Account();
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
DateTime dtSeed = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime();
o.DateStarted = dtSeed;
if (Fake.Random.Number(9) != 5)
o.DateCompleted = dtSeed.AddDays(Fake.Random.Long(2, 100));
o.ProjectOverseerId = Fake.Random.Long(2, 13);//NOTE: this is exactly 13 not total seeded users because it needs to be inside users and they're seeded first
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
ProjectBiz biz = ProjectBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededProjects++;
if (NewObject == null)
{
var err = $"Seeder::SeedProject error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashRateNames = new HashSet<string>();
private int TotalSeededServiceRates = 0;
//////////////////////////////////////////////////////
//SERVICERATE
//
public async Task SeedServiceRateAsync(ILogger log, int count, string presetName = null, bool contractOnly = false)
{
for (int x = 0; x < count; x++)
{
ServiceRate o = new ServiceRate();
do
{
if (!string.IsNullOrWhiteSpace(presetName))
{
o.Name = presetName;
}
else
{
var color = Fake.Commerce.Color();
o.Name = $"{char.ToUpper(color[0]) + color.Substring(1)} {Fake.Address.CountryCode()}";
}
} while (!HashRateNames.Add(o.Name));
o.AccountNumber = Fake.Finance.Account();
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.Cost = Fake.Random.Decimal(0.25m, 50);
o.Charge = o.Cost * 1.55m;
o.Unit = "hour";
o.ContractOnly = contractOnly;
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
ServiceRateBiz biz = ServiceRateBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededServiceRates++;
if (NewObject == null)
{
var err = $"Seeder::SeedServiceRate error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
private int TotalSeededTravelRates = 0;
//////////////////////////////////////////////////////
//TRAVELRATE
//
public async Task SeedTravelRateAsync(ILogger log, int count, string presetName = null, bool contractOnly = false)
{
var Units = new[] { "km", "miles", "hours" };
for (int x = 0; x < count; x++)
{
TravelRate o = new TravelRate();
do
{
if (!string.IsNullOrWhiteSpace(presetName))
{
o.Name = presetName;
}
else
{
var color = Fake.Commerce.Color();
o.Name = $"{char.ToUpper(color[0]) + color.Substring(1)} {Fake.Address.CountryCode()}";
}
} while (!HashRateNames.Add(o.Name));
o.AccountNumber = Fake.Finance.Account();
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.Cost = Fake.Random.Decimal(0.25m, 10);
o.Charge = o.Cost * 2m;
o.Unit = Fake.PickRandom(Units);
o.ContractOnly = contractOnly;
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
TravelRateBiz biz = TravelRateBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededTravelRates++;
if (NewObject == null)
{
var err = $"Seeder::SeedTravelRate error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashUnitModelNames = new HashSet<string>();
private int TotalSeededUnitModels = 0;
//////////////////////////////////////////////////////
//UNITMODEL
//
public async Task SeedUnitModelAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-5);
DateTime seedEndWindow = DateTime.Now.AddYears(1);
var WarrantyMonths = new[] { 1, 6, 12, 24, 36 };
var WarrantyTerms = new[] { "Parts only", "Parts and service", "Service only", "Shipping parts and service", "First month parts and service here; after is depot only" };
for (int x = 0; x < count; x++)
{
UnitModel o = new UnitModel();
do
{
o.Name = $"{Fake.Vehicle.Model()} {Fake.Commerce.Categories(1)[0]}";
} while (!HashUnitModelNames.Add(o.Name));
do
{
o.Number = Fake.Finance.Account(6);
} while (!HashUnitModelNames.Add(o.Number));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.VendorId = Fake.Random.Long(1, TotalSeededVendors);//random picks in range Inclusive but sql id's start at 1 so this is kosher (not zero based)
o.UPC = Fake.Commerce.Ean13();
o.LifeTimeWarranty = false;
o.IntroducedDate = Fake.Date.Between(seedStartWindow, DateTime.Now).ToUniversalTime();
o.Discontinued = false;
o.DiscontinuedDate = null;
o.WarrantyLength = Fake.PickRandom(WarrantyMonths);
o.WarrantyTerms = Fake.PickRandom(WarrantyTerms);
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
UnitModelBiz biz = UnitModelBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededUnitModels++;
if (NewObject == null)
{
var err = $"Seeder::SeedUnitModel error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashUnitNames = new HashSet<string>();
private int TotalSeededUnits = 0;
//////////////////////////////////////////////////////
//UNIT
//
public async Task SeedUnitAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-10);
DateTime seedEndWindow = DateTime.Now.AddYears(1);
var WarrantyMonths = new[] { 1, 6, 12, 24, 36 };
var WarrantyTerms = new[] { "Parts only", "Parts and service", "Service only", "Shipping parts and service", "First month parts and service here; after is depot only" };
for (int x = 0; x < count; x++)
{
Unit o = new Unit();
do
{
o.Serial = Fake.Finance.Account();
} while (!HashUnitNames.Add(o.Serial));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
//Override model warranty 5% chance (1/20)
if (Fake.Random.Number(1, 20) == 5)
{
o.OverrideModelWarranty = true;
o.LifeTimeWarranty = false;
o.WarrantyLength = Fake.PickRandom(WarrantyMonths);
o.WarrantyTerms = Fake.PickRandom(WarrantyTerms);
}
o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers);
o.UnitModelId = Fake.Random.Long(1, TotalSeededUnitModels);
o.BoughtHere = true;
//Unit bought elsewhere 10% chance (1/10)
if (Fake.Random.Number(1, 10) == 5)
{
o.BoughtHere = false;
o.PurchasedFromVendorId = Fake.Random.Long(1, TotalSeededVendors);
}
o.Receipt = Fake.Finance.Account(6);
o.PurchasedDate = Fake.Date.Between(seedStartWindow, DateTime.Now).ToUniversalTime();
o.Description = Fake.Commerce.ProductName();
o.ReplacedByUnitId = null;
//Has unit contract 5% chance (1/20)
if (Fake.Random.Number(1, 20) == 5)
{
o.ContractId = Fake.Random.Number(1, 3);
o.ContractExpires = DateTime.UtcNow.AddYears(1);
}
//for now no banked units in seeds
//o.UsesBanking = false;
o.Metered = false;//for now no meters either
o.Text1 = null;
o.Text2 = null;
o.Text3 = null;
o.Text4 = null;
//Unit has own address 5% chance (1/20)
if (Fake.Random.Number(1, 20) == 5)
{
o.UnitHasOwnAddress = true;
o.Latitude = (decimal)Fake.Address.Latitude();
o.Longitude = (decimal)Fake.Address.Longitude();
o.Address = Fake.Address.StreetAddress();
o.City = Fake.Address.City();
o.Region = Fake.Address.State();
o.Country = Fake.Address.Country();
}
else
{
o.UnitHasOwnAddress = false;
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
UnitBiz biz = UnitBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededUnits++;
if (NewObject == null)
{
var err = $"Seeder::SeedUnit error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
private int TotalSeededLoanUnits = 0;
//////////////////////////////////////////////////////
//LOANUNIT
//
public async Task SeedLoanLoanUnitAsync(ILogger log, int count)
{
for (int x = 0; x < count; x++)
{
LoanUnit o = new LoanUnit();
do
{
o.Serial = Fake.Finance.Account();
} while (!HashUnitNames.Add(o.Serial));
do
{
o.Name = Fake.Commerce.ProductName();
} while (!HashUnitNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.RateHour = Fake.Random.Decimal(1, 25);
o.RateHalfDay = o.RateHour * 4;
o.RateDay = o.RateHour * 8;
o.RateWeek = o.RateHour * 36.8m;
o.RateMonth = o.RateHour * 21 * 8;
o.RateYear = o.RateHour * 36.8m * 52;
o.DefaultRate = Fake.Random.Enum<LoanUnitRateUnit>();
using (AyContext ct = ServiceProviderProvider.DBContext)
{
LoanUnitBiz biz = LoanUnitBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededLoanUnits++;
if (NewObject == null)
{
var err = $"Seeder::SeedLoanUnit error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//////////////////////////////////////////////////////
//CUSTOMERSERVICEREQUEST
//
public async Task SeedCustomerServiceRequestAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-1);
DateTime seedEndWindow = DateTime.Now.AddMonths(-11);
for (int x = 0; x < count; x++)
{
CustomerServiceRequest o = new CustomerServiceRequest();
o.Name = Fake.Hacker.Phrase();
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.DateRequested = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime();
o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers);
o.RequestedByUserId = await SeedUserAsync(log, 1, AuthorizationRoles.CustomerFull, UserType.Customer, true, null, null, 0, null, null, o.CustomerId, null);
o.Status = CustomerServiceRequestStatus.Open;
o.Priority = Fake.Random.Enum<CustomerServiceRequestPriority>();
o.CustomerReferenceNumber = Fake.Finance.Account();
using (AyContext ct = ServiceProviderProvider.DBContext)
{
CustomerServiceRequestBiz biz = CustomerServiceRequestBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
if (NewObject == null)
{
var err = $"Seeder::SeedCustomerServiceRequest error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashPartWarehouseNames = new HashSet<string>();
private int TotalSeededPartWarehouses = 1;//Default warehouse is already present
//////////////////////////////////////////////////////
//PARTWAREHOUSE
//
public async Task SeedPartWarehouseAsync(ILogger log, int count)
{
for (int x = 0; x < count; x++)
{
PartWarehouse o = new PartWarehouse();
do
{
o.Name = $"WHS- {Fake.Address.StreetName()}";
} while (!HashPartWarehouseNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
PartWarehouseBiz biz = PartWarehouseBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededPartWarehouses++;
if (NewObject == null)
{
var err = $"Seeder::SeedPartWarehouse error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public HashSet<string> HashPartNumbers = new HashSet<string>();
private int TotalSeededParts = 0;
//////////////////////////////////////////////////////
//PART
//
public async Task SeedPartAsync(ILogger log, int count, int openingStockLevel)
{
//for testing purposes make a quarter (approx) of parts that are lower than restock level
int PartStockLevelParts = count / 4;
//Console.WriteLine($"SEEDER PartStockLevelParts is {PartStockLevelParts}");
for (int x = 0; x < count; x++)
{
Part o = new Part();
do
{
o.PartNumber = Fake.Finance.Account(6);
} while (!HashPartNumbers.Add(o.PartNumber));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.ManufacturerId = Fake.Random.Long(1, 3);//There are minimum 10 vendors seeded, want parts all in the first few so that some po stuff can kick in (vendorpartnumber etc)
o.ManufacturerNumber = "man-" + o.PartNumber;
o.UPC = Fake.Commerce.Ean13();
o.WholeSalerId = Fake.Random.Long(4, 6);
o.WholeSalerNumber = "ws-" + o.PartNumber;
o.AlternativeWholeSalerId = Fake.Random.Long(7, 9);
o.AlternativeWholeSalerNumber = "aws-" + o.PartNumber;
o.Cost = Fake.Random.Decimal(1, 25);
o.Retail = o.Cost * 1.2m;
o.UnitOfMeasure = "each";
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
PartBiz biz = PartBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededParts++;
if (NewObject == null)
{
var err = $"Seeder::SeedPart error creating {o.PartNumber}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
int OpeningInventoryLevel = openingStockLevel;// Fake.Random.Number(1, openingStockLevel);
PartInventoryBiz PartInventoryBizNess = PartInventoryBiz.GetBiz(ct);
// 12% chance it has serial numbers
if (Fake.Random.Number(1, 8) == 5)
{
var serialStart = Fake.Finance.Account(10).ToString();
for (int y = 0; y < OpeningInventoryLevel; y++)
{
await ct.PartSerial.AddAsync(new PartSerial() { PartId = NewObject.Id, Serial = serialStart + "-" + y.ToString() });
}
await ct.SaveChangesAsync();
}
PartInventory partInventory = null;
//Add inventory into multiple warehouses for testing
for (int y = 0; y < 3; y++)
{
int WarehouseNumber = y + 1;
//add opening inventory
partInventory = await PartInventoryBizNess.CreateAsync(new dtPartInventory() { PartId = NewObject.Id, PartWarehouseId = WarehouseNumber, Quantity = OpeningInventoryLevel, Description = "New part opening inventory" });
//Example adjustments?
if (Fake.Random.Number(1, 10) == 1) // 10% adjusted
{
//make two adjustments to have some testing data
if (partInventory != null)
partInventory = await PartInventoryBizNess.CreateAsync(new dtPartInventory() { PartId = NewObject.Id, PartWarehouseId = WarehouseNumber, Quantity = -1, Description = "example adjustment" });
if (partInventory != null)
partInventory = await PartInventoryBizNess.CreateAsync(new dtPartInventory() { PartId = NewObject.Id, PartWarehouseId = WarehouseNumber, Quantity = Fake.Random.Number(1, 3), Description = "example adjustment" });
}
if (partInventory == null)
{
var err = $"Seeder::SeedPart - error creating {o.PartNumber} INVENTORY \r\n{PartInventoryBizNess.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
if (PartStockLevelParts > 0)
{
PartStockLevelParts--;
List<PartStockLevel> partStockLevels = new List<PartStockLevel>();
partStockLevels.Add(new PartStockLevel() { PartWarehouseId = 1, PartId = NewObject.Id, MinimumQuantity = OpeningInventoryLevel * 2 });
await biz.PutStockLevelsAsync(NewObject.Id, partStockLevels);
}
}
}
}
public HashSet<string> HashPartAssemblyNames = new HashSet<string>();
private int TotalSeededPartAssemblies = 0;
//////////////////////////////////////////////////////
//PARTASSEMBLY
//
public async Task SeedPartAssemblyAsync(ILogger log, int count)
{
for (int x = 0; x < count; x++)
{
PartAssembly o = new PartAssembly();
List<long> partsAdded = new List<long>();
do
{
o.Name = "asm" + Fake.Finance.Account(4);
} while (!HashPartAssemblyNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
int partCount = Fake.Random.Int(2, 5);
for (int y = 0; y < partCount; y++)
{
long partId = 0;
do
{
partId = Fake.Random.Long(1, TotalSeededParts);
} while (partsAdded.Contains(partId));
partsAdded.Add(partId);
o.Items.Add(new PartAssemblyItem() { PartId = partId });
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
PartAssemblyBiz biz = PartAssemblyBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
TotalSeededPartAssemblies++;
if (NewObject == null)
{
var err = $"Seeder::SeedPartAssembly error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
private int TotalSeededPurchaseOrders = 0;
//////////////////////////////////////////////////////
//PURCHASE ORDER
//
public async Task SeedPurchaseOrderAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-1);
DateTime seedEndWindow = DateTime.Now.AddDays(-5);
for (int x = 0; x < count; x++)
{
PurchaseOrder o = new PurchaseOrder();
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.VendorId = Fake.Random.Long(1, 9);//this matches the range set in parts so that we get ALL vendor numbers being set
var poDate = Fake.Date.Between(seedStartWindow, seedEndWindow);
o.OrderedDate = poDate.ToUniversalTime();
o.ExpectedReceiveDate = poDate.AddDays(5).ToUniversalTime();
o.ReferenceNumber = Fake.Finance.Account(6);
o.VendorMemo = Fake.Lorem.Sentence();
if (Fake.Random.Number(1, 10) == 5)
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
o.Text1 = Fake.Lorem.Sentence(1, 3);
o.Text2 = Fake.Lorem.Sentence(1, 3);
List<long> partsAdded = new List<long>();
int partCount = Fake.Random.Int(1, 5);
//simulate some items without tax codes
bool addTaxCode = (Fake.Random.Number(1, 4) != 3);
//simulate some items not received
bool isReceived = (Fake.Random.Number(1, 4) != 3);
o.Status = isReceived ? PurchaseOrderStatus.ClosedFullReceived : PurchaseOrderStatus.OpenOrdered;
for (int y = 0; y < partCount; y++)
{
long partId = 0;
do
{
partId = Fake.Random.Long(1, TotalSeededParts);
} while (partsAdded.Contains(partId));
partsAdded.Add(partId);
var qty = Fake.Random.Int(1, 5);
var cost = Fake.Random.Decimal(1, 25);
// 50% chance it has received serial numbers
string serials = string.Empty;
if (isReceived && Fake.Random.Number() == 1)
{
var serialStart = Fake.Finance.Account().ToString();
for (int si = 0; si < qty; si++)
{
serials += serialStart + si.ToString() + ", ";
}
serials = serials.TrimEnd().TrimEnd(',');
}
o.Items.Add(new PurchaseOrderItem()
{
PartId = partId,
PartWarehouseId = Fake.Random.Long(1, 3),
QuantityOrdered = qty,
QuantityReceived = isReceived ? qty : 0,
PurchaseOrderCost = cost,
ReceivedCost = isReceived ? cost : 0,
ReceivedDate = isReceived ? o.ExpectedReceiveDate : null,
PurchaseTaxCodeId = addTaxCode ? 3 : null,//sales and goods
Serials = serials
});
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
PurchaseOrderBiz biz = PurchaseOrderBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o, false);
TotalSeededPurchaseOrders++;
if (NewObject == null)
{
var err = $"Seeder::SeedPurchaseOrder error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
public long RandomServiceTechUserId()
{
return ServiceUserIds[Fake.Random.Int(1, ServiceUserIds.Count - 1)];
}
private int TotalSeededWorkOrders = 0;
//////////////////////////////////////////////////////
//WORK ORDER
//
public async Task SeedWorkOrderAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.UtcNow.AddMonths(-9);
DateTime seedEndWindow = DateTime.UtcNow.AddMonths(3);
for (int x = 0; x < count; x++)
{
WorkOrder o = new WorkOrder();
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
var tempDate = Fake.Date.Between(seedStartWindow, seedEndWindow);
var tempHour = Fake.Random.Int(9, 17);//9am to 5 pm (except some times may be in different dst state so this will be out by an hour for example depending on time of year and time zone in question)
var woDate = DesiredTimeInUtc(new DateTime(tempDate.Year, tempDate.Month, tempDate.Day, tempHour, 0, 0));
o.CompleteByDate = woDate.AddDays(5);
// o.CustomerContactName = "contact name here";
o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers);
using (AyContext ct = ServiceProviderProvider.DBContext)
{
var cust = await ct.Customer.AsNoTracking().FirstAsync(z => z.Id == o.CustomerId);
o.Latitude = cust.Latitude;
o.Longitude = cust.Longitude;
o.Address = cust.Address;
o.City = cust.City;
o.Region = cust.Region;
o.Country = cust.Country;
if (cust.BillHeadOffice && cust.HeadOfficeId != null)
{
var head = await ct.HeadOffice.AsNoTracking().FirstAsync(z => z.Id == cust.HeadOfficeId);
o.PostAddress = head.PostAddress;
o.PostCity = head.PostCity;
o.PostRegion = head.PostRegion;
o.PostCountry = head.PostCountry;
o.PostCode = head.PostCode;
}
else
{
o.PostAddress = cust.PostAddress;
o.PostCity = cust.PostCity;
o.PostRegion = cust.PostRegion;
o.PostCountry = cust.PostCountry;
o.PostCode = cust.PostCode;
}
}
o.CustomerReferenceNumber = "crf-" + Fake.Finance.Account(4);
o.InternalReferenceNumber = "irf-" + Fake.Finance.Account(4);
o.ServiceDate = woDate;
int woItemCount = Fake.Random.Int(2, 10);
for (int y = 0; y < woItemCount; y++)
{
var woItem = new WorkOrderItem()
{
Sequence = y + 1,
Notes = $"itemnotes - {y} ",
TechNotes = $"technotes - {y}",
RequestDate = woDate.AddMinutes(y),
WorkorderItemPriorityId = Fake.Random.Long(1, 5),//there are 5 different sample priorities
WorkorderItemStatusId = Fake.Random.Long(1, 3)//there are 3 different sample woitem status
};
//UNITS
var woItemUnit = new WorkOrderItemUnit()
{
UnitId = Fake.Random.Long(1, TotalSeededUnits),
Notes = Fake.Lorem.Sentence()
};
woItem.Units.Add(woItemUnit);
woItemUnit = new WorkOrderItemUnit()
{
UnitId = Fake.Random.Long(1, TotalSeededUnits),
Notes = Fake.Lorem.Sentence()
};
woItem.Units.Add(woItemUnit);
//SCHEDULED USERS
var woItemScheduledUser = new WorkOrderItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 1,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new WorkOrderItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
//PARTS
var woItemPart = new WorkOrderItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
woItemPart = new WorkOrderItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
//PARTREQUESTS
var woItemPartRequest = new WorkOrderItemPartRequest()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1,
PurchaseOrderItemId = Fake.Random.Long(1, TotalSeededPurchaseOrders)//yes it's POITEM vs po but each po has at least one item so this will work
};
woItem.PartRequests.Add(woItemPartRequest);
woItemPartRequest = new WorkOrderItemPartRequest()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.PartRequests.Add(woItemPartRequest);
//LOANERS
var woItemLoan = new WorkOrderItemLoan()
{
OutDate = woDate.AddHours(1),
DueDate = woDate.AddHours(4),
Quantity = 4,
Rate = LoanUnitRateUnit.Hours,
LoanUnitId = Fake.Random.Long(1, TotalSeededLoanUnits)
};
woItem.Loans.Add(woItemLoan);
woItemLoan = new WorkOrderItemLoan()
{
OutDate = woDate.AddHours(2),
DueDate = woDate.AddHours(3),
Quantity = 1,
Rate = LoanUnitRateUnit.Hours,
LoanUnitId = Fake.Random.Long(1, TotalSeededLoanUnits)
};
woItem.Loans.Add(woItemLoan);
//LABOR
var techId = RandomServiceTechUserId();
var woItemLabor = new WorkOrderItemLabor()
{
UserId = techId,
ServiceRateQuantity = 1,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence()
};
woItem.Labors.Add(woItemLabor);
woItemLabor = new WorkOrderItemLabor()
{
UserId = RandomServiceTechUserId(),
ServiceRateQuantity = 2,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence()
};
woItem.Labors.Add(woItemLabor);
//TRAVEL
var woItemTravel = new WorkOrderItemTravel()
{
UserId = techId,
TravelRateQuantity = 1,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(),
Distance = Fake.Random.Decimal(1.0m, 20.0m)
};
woItem.Travels.Add(woItemTravel);
woItemTravel = new WorkOrderItemTravel()
{
UserId = RandomServiceTechUserId(),
TravelRateQuantity = 2,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(),
Distance = Fake.Random.Decimal(1.0m, 20.0m)
};
woItem.Travels.Add(woItemTravel);
//TASKS
var woItemTask = new WorkOrderItemTask()
{
CompletedByUserId = techId,
Task = "Dis-assemble",
Sequence = 1,
Status = WorkorderItemTaskCompletionType.Complete,
CompletedDate = woDate.AddHours(1)
};
woItem.Tasks.Add(woItemTask);
woItemTask = new WorkOrderItemTask()
{
CompletedByUserId = techId,
Task = "Lubricate",
Sequence = 2,
Status = WorkorderItemTaskCompletionType.NotApplicable,
CompletedDate = woDate.AddHours(1)
};
woItem.Tasks.Add(woItemTask);
woItemTask = new WorkOrderItemTask()
{
CompletedByUserId = techId,
Task = "Repair",
Sequence = 3,
Status = WorkorderItemTaskCompletionType.Complete,
CompletedDate = woDate.AddHours(1.5)
};
woItem.Tasks.Add(woItemTask);
woItemTask = new WorkOrderItemTask()
{
CompletedByUserId = techId,
Task = "Re-assemble",
Sequence = 4,
Status = WorkorderItemTaskCompletionType.Complete,
CompletedDate = woDate.AddHours(2)
};
woItem.Tasks.Add(woItemTask);
woItemTask = new WorkOrderItemTask()
{
CompletedByUserId = techId,
Task = "Test and confirm repair",
Sequence = 5,
Status = WorkorderItemTaskCompletionType.Complete,
CompletedDate = woDate.AddHours(2)
};
woItem.Tasks.Add(woItemTask);
//EXPENSES
var cost = Fake.Random.Decimal(1, 10);
var woItemExpense = new WorkOrderItemExpense()
{
UserId = RandomServiceTechUserId(),
TotalCost = cost,
ChargeAmount = cost * 1.2m,
ChargeToCustomer = true,
ReimburseUser = true,
ChargeTaxCodeId = TCGoods,
Name = Fake.Commerce.ProductName()
};
woItem.Expenses.Add(woItemExpense);
woItemExpense = new WorkOrderItemExpense()
{
UserId = RandomServiceTechUserId(),
TotalCost = cost * 2m,
ChargeAmount = cost * 2.2m,
ChargeToCustomer = true,
ReimburseUser = true,
ChargeTaxCodeId = TCGoods,
Name = Fake.Commerce.ProductName()
};
woItem.Expenses.Add(woItemExpense);
//OUTSIDE SERVICES
var ShippingCost = Fake.Random.Decimal(5, 20);
var RepairCost = Fake.Random.Decimal(50, 1000);
var woItemOutsideService = new WorkOrderItemOutsideService()
{
UnitId = Fake.Random.Long(1, TotalSeededUnits),
Notes = Fake.Lorem.Sentence(),
VendorSentToId = Fake.Random.Long(1, TotalSeededVendors),
VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors),
RMANumber = "RMA" + Fake.Finance.Account(6),
TrackingNumber = "TR" + Fake.Finance.Account(8),
RepairCost = RepairCost,
RepairPrice = RepairCost * 1.5m,
ShippingCost = ShippingCost,
ShippingPrice = ShippingCost * 1.5m,
SentDate = woDate,
ETADate = woDate.AddDays(7),
ReturnDate = woDate.AddDays(8),
TaxCodeId = 1
};
woItem.OutsideServices.Add(woItemOutsideService);
ShippingCost = Fake.Random.Decimal(5, 20);
RepairCost = Fake.Random.Decimal(50, 1000);
woItemOutsideService = new WorkOrderItemOutsideService()
{
UnitId = Fake.Random.Long(1, TotalSeededUnits),
Notes = Fake.Lorem.Sentence(),
VendorSentToId = Fake.Random.Long(1, TotalSeededVendors),
VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors),
RMANumber = "RMA" + Fake.Finance.Account(6),
TrackingNumber = "TR" + Fake.Finance.Account(8),
RepairCost = RepairCost,
RepairPrice = RepairCost * 1.5m,
ShippingCost = ShippingCost,
ShippingPrice = ShippingCost * 1.5m,
SentDate = woDate,
ETADate = woDate.AddDays(7),
ReturnDate = woDate.AddDays(8),
TaxCodeId = 1
};
woItem.OutsideServices.Add(woItemOutsideService);
o.Items.Add(woItem);
}
//sample status changes
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.NeedsToBeAssigned,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddMinutes(5)
};
o.States.Add(WoState);
}
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.Scheduled,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(1)
};
o.States.Add(WoState);
}
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.ManagerApprovalRequired,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(1).AddMinutes(5)
};
o.States.Add(WoState);
}
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.Scheduled,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(2)
};
o.States.Add(WoState);
}
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)Fake.Random.Enum<SeedWOStatus>(SeedWOStatus.Scheduled),
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(2)
};
o.States.Add(WoState);
o.LastStatusId = WoState.WorkOrderStatusId;//simulate if user added state to wo so it gets set
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct);
var NewObject = await biz.WorkOrderCreateAsync(o, false);
TotalSeededWorkOrders++;
if (NewObject == null)
{
var err = $"Seeder::SeedWorkOrder error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
}//eoc
}//eons