Files
raven/server/AyaNova/util/Seeder.cs
2021-11-16 18:23:25 +00:00

4197 lines
194 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;
public bool _e2e = false;
//### 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, bool e2e = false)
{
await SeedDatabaseAsync(slevel, Guid.Empty, timeZoneOffset, e2e);
}
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Guid JobId, Decimal timeZoneOffset, bool e2e = false)
{
bool LogJob = JobId != Guid.Empty;
_e2e = e2e;
// 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");
// //CUSTOMER sample form customization
// {
// var fc = new FormCustom()
// {
// FormKey = AyaType.Customer.ToString(),
// Template = @"[
// {
// ""fld"": ""Notes"",
// ""required"": true
// },
// {
// ""fld"": ""CustomerCustom1"",
// ""required"": false,
// ""type"": 1
// },
// {
// ""fld"": ""CustomerCustom2"",
// ""required"": true,
// ""type"": 4
// },
// {
// ""fld"": ""CustomerCustom3"",
// ""required"": false,
// ""type"": 5
// },
// {
// ""fld"": ""CustomerCustom4"",
// ""required"": false,
// ""type"": 6
// },
// {
// ""fld"": ""CustomerCustom5"",
// ""required"": false,
// ""type"": 8
// },
// {
// ""fld"": ""CustomerCustom6"",
// ""required"": false,
// ""type"": 2
// },
// {
// ""fld"": ""CustomerCustom7"",
// ""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 = "TestCustomerDataList",
// Public = true,
// ListView = @"[{""fld"": ""customername"",""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 = "TestCustomerDataList",
// Public = true,
// ListView = @"[{""fld"": ""customername"",""filter"": {""any"":false,""items"": [{""op"": ""%-"",""value"": ""Awesome""}]}},{""fld"":""customerserial""},{""fld"":""customerdollaramount""},{""fld"":""customerusertype""},{""fld"":""customerstartdate""},{""fld"":""customeractive""},{""fld"":""username""},{""fld"":""customertags""},{""fld"":""customercustom1""},{""fld"":""customercustom2""}]"
// };
// //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.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.OpsAdmin, UserType.Service);
//Generate one office person / secretary
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.Accounting, UserType.NotService);
//2 other techs (must always be enough to have no dupes per workorder)
await SeedUserAsync(log, 2, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
await SeedVendorAsync(log, 10);
await SeedUnitModelAsync(log, 10);
await SeedCustomerAsync(log, 25, slevel);
await SeedHeadOfficeAsync(log, 10, slevel);
await SeedVendorAsync(log, 10);
await SeedProjectAsync(log, 3);
await SeedServiceRateAsync(log, 5);
await SeedTravelRateAsync(log, 3);
await SeedLoanLoanUnitAsync(log, 5);
await SeedCustomerServiceRequestAsync(log, 5);
await SeedPartWarehouseAsync(log, 5);
await SeedPartAsync(log, 20, 100);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 10);
await SeedQuoteAsync(log, 5);
await SeedPMAsync(log, 3);
await SeedWorkOrderAsync(log, 100, slevel);
//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.OpsAdmin, UserType.NotService);
//One business administrator, can view ops issues
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
//One owner who doesn't control anything but views stuff
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted | AuthorizationRoles.SalesRestricted, UserType.NotService);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 5, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
//Restricted techs
// await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
//subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
//Restricted subcontractors
// await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
///////////////////////////////////////////
//3 generic office people people
await SeedUserAsync(log, 3, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//2 Full sales people
await SeedUserAsync(log, 2, AuthorizationRoles.Sales, UserType.NotService);
//1 Service manager
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//1 Inventory manager
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
//1 accountant / bookkeeper
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedVendorAsync(log, 50);
await SeedUnitModelAsync(log, 20);
await SeedCustomerAsync(log, 500, slevel);
await SeedHeadOfficeAsync(log, 20, slevel);
await SeedProjectAsync(log, 5);
await SeedServiceRateAsync(log, 10);
await SeedTravelRateAsync(log, 5);
//await SeedUnitAsync(log, 2500);
await SeedLoanLoanUnitAsync(log, 10);
await SeedCustomerServiceRequestAsync(log, 10);
await SeedPartWarehouseAsync(log, 10);
await SeedPartAsync(log, 100, 100);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 30);
await SeedQuoteAsync(log, 5);
await SeedPMAsync(log, 3);
await SeedWorkOrderAsync(log, 900, slevel);
//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.OpsAdmin, UserType.NotService);
//business administrator, can view ops issues
await SeedUserAsync(log, 2, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 5, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 8, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
//Restricted techs
await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
//subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
//Restricted subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
///////////////////////////////////////////
//30 generic office people people
await SeedUserAsync(log, 30, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//10 Full sales people
await SeedUserAsync(log, 10, AuthorizationRoles.Sales, UserType.NotService);
//5 Restricted sales people
await SeedUserAsync(log, 5, AuthorizationRoles.SalesRestricted, UserType.NotService);
//5 Service manager
await SeedUserAsync(log, 5, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//5 Inventory manager
await SeedUserAsync(log, 5, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
//10 Inventory manager assistants
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryRestricted, UserType.NotService);
//5 accountant / bookkeeper
await SeedUserAsync(log, 5, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedVendorAsync(log, 100);
await SeedUnitModelAsync(log, 40);
await SeedCustomerAsync(log, 1000, slevel);
await SeedHeadOfficeAsync(log, 40, slevel);
await SeedProjectAsync(log, 10);
await SeedServiceRateAsync(log, 20);
await SeedTravelRateAsync(log, 10);
// await SeedUnitAsync(log, 5000);
await SeedLoanLoanUnitAsync(log, 20);
await SeedCustomerServiceRequestAsync(log, 20);
await SeedPartWarehouseAsync(log, 20);
await SeedPartAsync(log, 200, 100);
await SeedPartAssemblyAsync(log, 5);
await SeedPurchaseOrderAsync(log, 50);
await SeedQuoteAsync(log, 5);
await SeedPMAsync(log, 3);
await SeedWorkOrderAsync(log, 1800, slevel);
//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.OpsAdmin, UserType.NotService);
//business administrator, can view ops issues
await SeedUserAsync(log, 10, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
//owner / upper management who doesn't control anything but views stuff
await SeedUserAsync(log, 20, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService);
////////////////////////////////////////////////
//TECHS (LICENSE CONSUMERS)
//trial license allows 1000
//
//regular techs
await SeedUserAsync(log, 15, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service);
//Restricted techs
await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
//subcontractors
await SeedUserAsync(log, 2, AuthorizationRoles.SubContractor, UserType.ServiceContractor);
//Restricted subcontractors
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
///////////////////////////////////////////
//generic office people people
await SeedUserAsync(log, 500, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//20 Full sales people
await SeedUserAsync(log, 60, AuthorizationRoles.Sales, UserType.NotService);
//10 Restricted sales people
await SeedUserAsync(log, 10, AuthorizationRoles.SalesRestricted, UserType.NotService);
//Service manager
await SeedUserAsync(log, 20, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService);
//Inventory manager
await SeedUserAsync(log, 40, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService);
//Inventory manager assistants
await SeedUserAsync(log, 20, AuthorizationRoles.InventoryRestricted, UserType.NotService);
//accountant / bookkeeper
await SeedUserAsync(log, 20, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService);
await SeedVendorAsync(log, 5000);
await SeedUnitModelAsync(log, 400);
await SeedCustomerAsync(log, 10000, slevel);
await SeedHeadOfficeAsync(log, 500, slevel);
await SeedProjectAsync(log, 1000);
await SeedServiceRateAsync(log, 200);
await SeedTravelRateAsync(log, 100);
await SeedLoanLoanUnitAsync(log, 200);
await SeedCustomerServiceRequestAsync(log, 200);
await SeedPartWarehouseAsync(log, 200);
await SeedPartAsync(log, 10000, 100);
await SeedPartAssemblyAsync(log, 500);
await SeedPurchaseOrderAsync(log, 1000);
await SeedQuoteAsync(log, 10);
await SeedPMAsync(log, 3);//DO NOT want too many of these as they affect performance
await SeedWorkOrderAsync(log, 3600, slevel);
//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)).ToList();//pick up to 5 tags to apply
if (_e2e)
{
t.Add("e2e");
}
return t;
}
public enum SeedWOStatus : long
{
ManagerApprovalRequired = 1,
NeedsToBeAssigned = 2,
Scheduled = 3,
ServiceCompleted = 4,
WaitingOnCustomerApproval = 5,
WaitingOnParts = 6,
WaitingOnWarrantyReturn = 7,
WaitingToBeInvoiced = 8,
Closed = 9
}
long TCServices = 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)
{
var KnownUserTags = new List<string>();
KnownUserTags.Add("known-user");
KnownUserTags.Add("test-role-user");
//TRIAL USERS
//one of each role type
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted, UserType.NotService, "BizAdminRestricted", "BizAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin, UserType.NotService, "BizAdmin", "BizAdmin", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.ServiceRestricted, UserType.NotService, "ServiceRestricted", "ServiceRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Service, UserType.NotService, "Service", "Service", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryRestricted, UserType.NotService, "InventoryRestricted", "InventoryRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory, UserType.NotService, "Inventory", "Inventory", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting, UserType.NotService, "Accounting", "Accounting", KnownUserTags);
KnownUserTechRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted, UserType.Service, "TechRestricted", "TechRestricted", KnownUserTags);
KnownUserTechId = await SeedUserAsync(log, 1, AuthorizationRoles.Tech, UserType.Service, "Tech", "Tech", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.SalesRestricted, UserType.NotService, "SalesRestricted", "SalesRestricted", KnownUserTags);
KnownUserSalesId = await SeedUserAsync(log, 1, AuthorizationRoles.Sales, UserType.NotService, "Sales", "Sales", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, "OpsAdminRestricted", "OpsAdminRestricted", KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService, "OpsAdmin", "OpsAdmin", KnownUserTags);
//Alternate translation users for each stock translation
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags);
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags);
//TEST NOT ACTIVE - this is used for a test to see if inactive user can login
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, false, "TEST_INACTIVE", "TEST_INACTIVE", 0, KnownUserTags);
/////////////////////////////////////////////////////
//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 BRONZE 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 = RandomTags(), OverridePct = 5m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = RandomTags(), OverridePct = 5m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = RandomTags(), 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 SILVER 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 = RandomTags(), OverridePct = 10m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = RandomTags(), OverridePct = 10m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = RandomTags(), 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 GOLD 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 = RandomTags(), OverridePct = 20m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractTravelRateOverrideItems.Add(new ContractTravelRateOverride() { Tags = RandomTags(), OverridePct = 20m, OverrideType = ContractOverrideType.PriceDiscount });
c.ContractPartOverrideItems.Add(new ContractPartOverride() { Tags = RandomTags(), 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.Customer, 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
KnownUserCustomerId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "Customer", "Customer", 0, KnownUserTags, null, NewObject.Id, null);
KnownUserCustomerRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "CustomerRestricted", "CustomerRestricted", 0, KnownUserTags, null, NewObject.Id, null);
//5 units per customer
await SeedUnitAsync(log, 20, NewObject.Id);//5 times the customers or 5 units per customer
}
}
////////////////////////////////
//SHADOW UNITS "CUSTOMER"
//
{
//CUSTOMER / HO Users
//seed a customer
Customer o = new Customer();
o.Name = "SHADOW_UNITS_CUSTOMER";
o.Active = true;
o.Notes = "Customer to group our own Loan unit 'Shadow Units' under for tracking any required internal service to Loan Units";
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);
}
KnownCustomerForShadownUnitsId = NewObject.Id;
}
}
//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.Tags.Add("contractor");
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;
}
KnownUserSubContractorRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, true, "SubContractorRestricted", "SubContractorRestricted", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
KnownUserSubContractorId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, true, "SubContractor", "SubContractor", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
}
/////////////////////////////////////////////////////
//Seed some test memos
{
for (int x = 0; x < 50; 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 = "#FFDFDF";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
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 = "#DFFCFC";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech;
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 = "#DFFFDF";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted;
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 = "#DFDFDF";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
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 = "#DFDFFF";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech;
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 = "#DFDF9F";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech | AuthorizationRoles.Inventory;
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 = "#FFDFFF";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin | AuthorizationRoles.Tech | AuthorizationRoles.Inventory;
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 = "#FFDFDF";
stat.Completed = false;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Tech | AuthorizationRoles.Accounting | AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
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 = "#FCF1C2";//maybe white is better? I.e. no color basically
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
stat.RemoveRoles = AuthorizationRoles.Service | AuthorizationRoles.BizAdmin;
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);
}
}
}
}
//=========================
}
//--------- QUOTE STATUS
/////////////////////////////////////////////////////
//QuoteStatus
{
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "Submitted";
stat.Active = true;
stat.Color = "#c00000";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.Notes = "Use to lock quote after given to customer and wait for approval";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "Awarded";
stat.Active = true;
stat.Color = "#80ffff";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting | AuthorizationRoles.Service;
stat.Notes = "Waiting for work order to be generated";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "In progress";
stat.Active = true;
stat.Color = "#00ff00";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.Notes = "In process of completing this quote";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "Not repairable";
stat.Active = true;
stat.Color = "#ff0000";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.Notes = "Beyond economical repair";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "New";
stat.Active = true;
stat.Color = "#8080ff";
stat.Completed = false;
stat.Locked = false;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.Notes = "New quote required; Sales to complete this Quote for submission";
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
{
QuoteStatus stat = new QuoteStatus();
stat.Name = "Not awarded";
stat.Active = true;
stat.Color = "#f2f2f2";
stat.Completed = true;
stat.Locked = true;
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(stat);
if (NewObject == null)
{
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//--------- /quote status
/////////////////////////////////////////////////////
//TASKGROUP
//
{
{
TaskGroup t = new TaskGroup();
t.Name = "Clean and inspect Class 7C";
t.Active = true;
t.Notes = Fake.Lorem.Sentence(null, 3);
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(null, 3);
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 = "Services only";
tc.Notes = "Example service 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);
}
TCServices = 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 = "Services & Goods";
tc.Active = true;
tc.Notes = "Example services 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 = TCServices;
gbiz.CustomerAllowCSR = true;
gbiz.CustomerAllowNotifyCSRAccepted = true;
gbiz.CustomerAllowNotifyCSRRejected = true;
gbiz.CustomerAllowNotifyServiceImminent = true;
gbiz.CustomerAllowNotifyWOCompleted = true;
gbiz.CustomerAllowNotifyWOCreated = true;
gbiz.CustomerAllowUserSettings = true;
gbiz.CustomerAllowViewWO = true;
// gbiz.CustomerDefaultWorkOrderReportId=1;
gbiz.CustomerAllowWOWiki = true;
gbiz.CustomerAllowWOAttachments=true;
await biz.PutAsync(gbiz);
ServerGlobalBizSettings.Initialize(gbiz, null);
}
}
}
/// <summary>
/// Generate seed user with active=true
/// (override to save typing)
/// </summary>
public async Task<long> SeedUserAsync(ILogger log, int count, AuthorizationRoles roles, UserType userType, string login, string password, List<string> tags = null)
{
try
{
return 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>();
public List<long> ShadowUnitIds = new List<long>();
private int TotalSeededUsers = 0;
public long KnownUserSubContractorId = 0;
public long KnownUserSubContractorRestrictedId = 0;
public long KnownUserTechId = 0;
public long KnownUserTechRestrictedId = 0;
public long KnownUserCustomerId = 0;
public long KnownUserCustomerRestrictedId = 0;
public long KnownCustomerForShadownUnitsId = 0;
public long KnownUserSalesId = 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, 3);//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;
if (_e2e)
u.Tags.Add("e2e");
}
//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.Service)
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;
}
public HashSet<string> HashCompanyNames = new HashSet<string>();
private int TotalSeededCustomers = 0;
//////////////////////////////////////////////////////
//CUSTOMER
//
public async Task SeedCustomerAsync(ILogger log, int count, Level.SeedLevel slevel, 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.Customer, UserType.Customer, true, null, null, 0, null, null, NewObject.Id, null);
switch (slevel)
{
case Level.SeedLevel.Small:
case Level.SeedLevel.Medium:
await SeedUnitAsync(log, 2, NewObject.Id);
break;
case Level.SeedLevel.Large:
case Level.SeedLevel.Huge:
await SeedUnitAsync(log, 5, NewObject.Id);
break;
}
}
}
}
private int TotalSeededHeadOffices = 0;
//////////////////////////////////////////////////////
//HEADOFFICE
//
public async Task SeedHeadOfficeAsync(ILogger log, int count, Level.SeedLevel slevel)
{
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.Customer, UserType.HeadOffice, true, null, null, 0, null, null, null, NewObject.Id);
//HeadOffice Customer
await SeedCustomerAsync(log, 2, slevel, 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();
string vendorTypeTag = string.Empty;
switch (Fake.Random.Int(0, 4))
{
case 0:
vendorTypeTag = "supplier";
break;
case 1:
vendorTypeTag = "factory";
break;
case 2:
vendorTypeTag = "shipper";
break;
case 3:
vendorTypeTag = "contractor";
break;
case 4:
vendorTypeTag = "repair-outside";
break;
}
o.Tags.Add(vendorTypeTag);
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(null, 3);
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(null, 3);
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(null, 3);
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]} - {Fake.Finance.Account(6)}";
} while (!HashUnitModelNames.Add(o.Name));
o.Active = true;
o.Notes = Fake.Lorem.Sentence(null, 3);
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;
private Dictionary<long, List<long>> CustomerUnits = new Dictionary<long, List<long>>();
public int[] WarrantyMonths = new[] { 1, 6, 12, 24, 36 };
public string[] WarrantyTerms = new[] { "Parts only", "Parts and service", "Service only", "Shipping parts and service", "First month parts and service here; after is depot only" };
//////////////////////////////////////////////////////
//UNIT
//
public async Task SeedUnitAsync(ILogger log, int count, long customerId)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-10);
DateTime seedEndWindow = DateTime.Now.AddYears(1);
List<long> unitsAddedThisRun = new List<long>();
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(null, 3);
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 = customerId;
if (TotalSeededUnitModels > 0)//because the first known objects Customer units are before there are unit models
o.UnitModelId = Fake.Random.Long(1, TotalSeededUnitModels);
o.BoughtHere = true;
//Unit bought elsewhere 90% chance (1/10)
if (TotalSeededVendors > 0 && 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);
if (NewObject == null)
{
var err = $"Seeder::SeedUnit error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
unitsAddedThisRun.Add(NewObject.Id);
}
}
//add to customer owned units list
CustomerUnits.Add(customerId, unitsAddedThisRun);
}
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.UnitId is shadow unit
o.Active = true;
o.Notes = Fake.Lorem.Sentence(null, 3);
o.Tags = RandomTags();
o.RateHour = Fake.Random.Decimal(1, 25);
o.RateHourCost = o.RateHour / 2;
o.RateHalfDay = o.RateHour * 4;
o.RateHalfDayCost = o.RateHalfDay / 2;
o.RateDay = o.RateHour * 8;
o.RateDayCost = o.RateDay / 2;
o.RateWeek = o.RateHour * 36.8m;
o.RateWeekCost = o.RateWeek / 2;
o.RateMonth = o.RateHour * 21 * 8;
o.RateMonthCost = o.RateMonth / 2;
o.RateYear = o.RateHour * 36.8m * 52;
o.RateYearCost = o.RateYear / 2;
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);
}
else
{
//make shadow unit
Unit u = new Unit();
u.Serial = NewObject.Serial;
u.Description = NewObject.Name + " - Loaner shadow unit";
u.Active = true;
u.Notes = "Shadow unit to track internal service for Loaner item";
u.CustomerId = KnownCustomerForShadownUnitsId;
u.BoughtHere = true;
UnitBiz unitBiz = UnitBiz.GetBiz(ct);
var newUnit = await unitBiz.CreateAsync(u);
if (newUnit == null)
{
var err = $"Seeder::SeedLoanUnit error creating {o.Serial} SHADOW UNIT\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
else
{
ShadowUnitIds.Add(newUnit.Id);
//now go back and set loaner to this shadow unit
//var rerun=await biz.GetAsync(NewObject.Id,false);
//newObject is still being tracked so can just set the unitid and save it here
NewObject.UnitId = newUnit.Id;
await ct.SaveChangesAsync();
//await biz.PutAsync(NewObject);
}
}
}
}
}
//////////////////////////////////////////////////////
//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(null, 8);
o.Tags = RandomTags();
o.DateRequested = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime();
o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers);
o.RequestedByUserId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, null, null, 0, null, null, o.CustomerId, null);
o.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(null, 3);
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(null, 3);
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(null, 3);
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(null, 3);
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(null, 3);
if (Fake.Random.Number(1, 10) == 5)
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
o.Text1 = Fake.Lorem.Sentence(null, 3);
o.Text2 = Fake.Lorem.Sentence(null, 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(0, ServiceUserIds.Count - 1)];
}
/*
██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗
██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝ ██╔═══██╗██╔══██╗██╔══██╗██╔════╝██╔══██╗
██║ █╗ ██║██║ ██║██████╔╝█████╔╝█████╗██║ ██║██████╔╝██║ ██║█████╗ ██████╔╝
██║███╗██║██║ ██║██╔══██╗██╔═██╗╚════╝██║ ██║██╔══██╗██║ ██║██╔══╝ ██╔══██╗
╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗ ╚██████╔╝██║ ██║██████╔╝███████╗██║ ██║
╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝
*/
private int TotalSeededWorkOrders = 0;
//////////////////////////////////////////////////////
//WORK ORDER
//
public async Task SeedWorkOrderAsync(ILogger log, int count, Level.SeedLevel seedLevel)
{
//Goal is 5 workorders per day for each level and window
//accepting that some days will have way more and some none, it's ok
//need a very large window for huge level seeding
//small defaults
int PastMonthsToSeed = 3;
int MaximumWorkOrderItemCount = 2;
int woItemUnitCount = 2;
switch (seedLevel)
{
case Level.SeedLevel.Medium:
PastMonthsToSeed = 5;
MaximumWorkOrderItemCount = 2;
woItemUnitCount = 1;
break;
case Level.SeedLevel.Large:
PastMonthsToSeed = 11;
MaximumWorkOrderItemCount = 2;
woItemUnitCount = 1;
break;
case Level.SeedLevel.Huge:
PastMonthsToSeed = 23;
MaximumWorkOrderItemCount = 2;
woItemUnitCount = 1;
break;
}
DateTime seedStartWindow = DateTime.UtcNow.AddMonths(-PastMonthsToSeed);//goes back based on seed level
DateTime seedEndWindow = DateTime.UtcNow.AddMonths(1);//always one month from now
for (int x = 0; x < count; x++)
{
WorkOrder o = new WorkOrder();
o.Notes = Fake.Lorem.Sentence(null, 6);
o.Tags = RandomTags();
if (Fake.Random.Bool())//50% have projects
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
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, DateTimeKind.Utc));
bool isPast = (woDate.Subtract(DateTime.UtcNow).TotalDays < -7);
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow : woDate;//no created dates in future but want a range of past dates to show off age of wo
o.CompleteByDate = woDate.AddDays(5);
// o.CustomerContactName = "contact name here";
o.CustomerId = GetRandomCustomerId();//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;
var actualWorkorderItemCount = Fake.Random.Int(1, MaximumWorkOrderItemCount);
for (int y = 0; y < actualWorkorderItemCount; 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
for (int a = 0; a < woItemUnitCount; a++)
{
var woItemUnit = new WorkOrderItemUnit()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3)
};
woItem.Units.Add(woItemUnit);
}
//SCHEDULED USERS
var actualScheduledUserCount = Fake.Random.Int(1, 2);
for (int a = 0; a < actualScheduledUserCount; a++)
{
var randomStart = Fake.Random.Int(0, 5);
var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
var randomStop = randomStart + randomHours;
var woItemScheduledUser = new WorkOrderItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = randomHours,
StartDate = woDate.AddHours(randomStart),//.AddDays(randomDays),
StopDate = woDate.AddHours(randomStop)//.AddDays(randomDays)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
// {
// var randomStart = Fake.Random.Int(0, 5);
// var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
// var randomStop = randomStart + randomHours;
// var woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = RandomServiceTechUserId(),
// EstimatedQuantity = randomHours,
// StartDate = woDate.AddHours(randomStart).AddDays(randomDays),
// StopDate = woDate.AddHours(randomStop).AddDays(randomDays)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// }
// {
// var randomStart = Fake.Random.Int(0, 5);
// var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
// var randomStop = randomStart + randomHours;
// var woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = RandomServiceTechUserId(),
// EstimatedQuantity = randomHours,
// StartDate = woDate.AddHours(randomStart).AddDays(randomDays),
// StopDate = woDate.AddHours(randomStop).AddDays(randomDays)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// }
// {
// var randomStart = Fake.Random.Int(0, 5);
// var randomHours = Fake.Random.Int(1, 4);
// var randomDays = Fake.Random.Int(0, 3);
// var randomStop = randomStart + randomHours;
// var woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = RandomServiceTechUserId(),
// EstimatedQuantity = randomHours,
// StartDate = woDate.AddHours(randomStart).AddDays(randomDays),
// StopDate = woDate.AddHours(randomStop).AddDays(randomDays)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// }
// if (y == 1)
// {
// //known tech and subcontractor on every item
// var woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = KnownUserTechId,
// EstimatedQuantity = 2,
// StartDate = woDate,
// StopDate = woDate.AddHours(2)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = KnownUserSubContractorId,
// EstimatedQuantity = 2,
// StartDate = woDate,
// StopDate = woDate.AddHours(2)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// }
// if (y == 3)
// {
// //known restricted tech and subcontractor on some items
// var woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = KnownUserTechRestrictedId,
// EstimatedQuantity = 2,
// StartDate = woDate,
// StopDate = woDate.AddHours(2)
// };
// woItem.ScheduledUsers.Add(woItemScheduledUser);
// woItemScheduledUser = new WorkOrderItemScheduledUser()
// {
// UserId = KnownUserSubContractorRestrictedId,
// EstimatedQuantity = 2,
// StartDate = woDate,
// StopDate = woDate.AddHours(2)
// };
// 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
if (Fake.Random.Bool())//50%
{
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);
}
//LOANERS
if (Fake.Random.Bool())//50%
{
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);
}
//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(null, 6)
};
woItem.Labors.Add(woItemLabor);
if (Fake.Random.Bool())//50%
{
woItemLabor = new WorkOrderItemLabor()
{
UserId = RandomServiceTechUserId(),
ServiceRateQuantity = 2,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence(null, 6)
};
woItem.Labors.Add(woItemLabor);
}
//TRAVEL
if (Fake.Random.Bool())//50%
{
var woItemTravel = new WorkOrderItemTravel()
{
UserId = techId,
TravelRateQuantity = 1,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(null, 3),
Distance = Fake.Random.Int(1, 20)
};
woItem.Travels.Add(woItemTravel);
}
//TASKS
if (Fake.Random.Int(1, 4) == 2)//25% chance of task
{
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
if (Fake.Random.Int(1, 4) == 2)//25% chance
{
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
if (Fake.Random.Int(1, 10) == 2)//10% chance
{
var ShippingCost = Fake.Random.Decimal(5, 20);
var RepairCost = Fake.Random.Decimal(50, 1000);
var woItemOutsideService = new WorkOrderItemOutsideService()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3),
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 = GetRandomUnitForCustomer(o.CustomerId),
// 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
if (Fake.Random.Int(1, 4) == 2)//25% chance
{
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.NeedsToBeAssigned,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddMinutes(5)
};
o.States.Add(WoState);
}
}
if (Fake.Random.Int(1, 4) == 2)//25% chance
{
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.Scheduled,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(1)
};
o.States.Add(WoState);
}
}
if (Fake.Random.Int(1, 4) == 2)//25% chance
{
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.ManagerApprovalRequired,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(1).AddMinutes(5)
};
o.States.Add(WoState);
}
}
if (Fake.Random.Int(1, 4) == 2)//25% chance
{
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.Scheduled,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(2)
};
o.States.Add(WoState);
o.LastStatusId = WoState.WorkOrderStatusId;
}
}
//All wo ending status
//if it's in the past tag it with a completed type status
if (isPast)
{
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)SeedWOStatus.Closed,
UserId = RandomServiceTechUserId(),
Created = ((DateTime)o.ServiceDate).AddHours(2)
};
o.States.Add(WoState);
o.LastStatusId = WoState.WorkOrderStatusId;
}
}
else
{
//current-future
//10% chance it's not left in a scheduled state
//this is because we want to have users be generally available to play with appointments in the schedule form
if (Fake.Random.Int(1, 10) == 3)
{
var WoState = new WorkOrderState()
{
WorkOrderStatusId = (long)Fake.Random.Enum<SeedWOStatus>(new[] { SeedWOStatus.Scheduled, SeedWOStatus.Closed, SeedWOStatus.ServiceCompleted }),
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);
}
}
}
}
/*
██████╗ ██╗ ██╗ ██████╗ ████████╗███████╗
██╔═══██╗██║ ██║██╔═══██╗╚══██╔══╝██╔════╝
██║ ██║██║ ██║██║ ██║ ██║ █████╗
██║▄▄ ██║██║ ██║██║ ██║ ██║ ██╔══╝
╚██████╔╝╚██████╔╝╚██████╔╝ ██║ ███████╗
╚══▀▀═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
*/
private int TotalSeededQuotes = 0;
//////////////////////////////////////////////////////
//Quote
//
public async Task SeedQuoteAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.UtcNow.AddMonths(-9);
DateTime seedEndWindow = DateTime.UtcNow.AddMonths(3);
for (int x = 0; x < count; x++)
{
Quote o = new Quote();
o.Notes = Fake.Lorem.Sentence(null, 6);
o.Tags = RandomTags();
if (Fake.Random.Bool())//50% have projects
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
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, DateTimeKind.Utc));
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow : woDate;//no created dates in future but want a range of past dates to show off age of wo
o.Requested = woDate.AddDays(-2);
o.PreparedById = KnownUserSalesId;
o.CustomerId = GetRandomCustomerId();//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(1, 2);
for (int y = 0; y < woItemCount; y++)
{
var woItem = new QuoteItem()
{
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 QuoteItemUnit()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3)
};
woItem.Units.Add(woItemUnit);
woItemUnit = new QuoteItemUnit()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3)
};
woItem.Units.Add(woItemUnit);
//SCHEDULED USERS
var woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 1,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
if (y == 1)
{
//known tech and subcontractor on every item
woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = KnownUserTechId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = KnownUserSubContractorId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
if (y == 3)
{
//known restricted tech and subcontractor on some items
woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = KnownUserTechRestrictedId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new QuoteItemScheduledUser()
{
UserId = KnownUserSubContractorRestrictedId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
//PARTS
var woItemPart = new QuoteItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
woItemPart = new QuoteItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
//LOANERS
var woItemLoan = new QuoteItemLoan()
{
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 QuoteItemLoan()
{
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 QuoteItemLabor()
{
UserId = techId,
ServiceRateQuantity = 1,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence(null, 3)
};
woItem.Labors.Add(woItemLabor);
woItemLabor = new QuoteItemLabor()
{
UserId = RandomServiceTechUserId(),
ServiceRateQuantity = 2,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence(null, 3)
};
woItem.Labors.Add(woItemLabor);
//TRAVEL
var woItemTravel = new QuoteItemTravel()
{
UserId = techId,
TravelRateQuantity = 1,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(null, 3),
Distance = Fake.Random.Int(1, 20)
};
woItem.Travels.Add(woItemTravel);
woItemTravel = new QuoteItemTravel()
{
UserId = RandomServiceTechUserId(),
TravelRateQuantity = 2,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(null, 3),
Distance = Fake.Random.Int(1, 20)
};
woItem.Travels.Add(woItemTravel);
//TASKS
var woItemTask = new QuoteItemTask()
{
CompletedByUserId = techId,
Task = "Dis-assemble",
Sequence = 1,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new QuoteItemTask()
{
CompletedByUserId = techId,
Task = "Lubricate",
Sequence = 2,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new QuoteItemTask()
{
CompletedByUserId = techId,
Task = "Repair",
Sequence = 3,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new QuoteItemTask()
{
CompletedByUserId = techId,
Task = "Re-assemble",
Sequence = 4,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new QuoteItemTask()
{
CompletedByUserId = techId,
Task = "Test and confirm repair",
Sequence = 5,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
//EXPENSES
var cost = Fake.Random.Decimal(1, 10);
var woItemExpense = new QuoteItemExpense()
{
UserId = RandomServiceTechUserId(),
//TotalCost = cost,
ChargeAmount = cost * 1.2m,
ChargeToCustomer = true,
ReimburseUser = true,
ChargeTaxCodeId = TCGoods,
Name = Fake.Commerce.ProductName()
};
woItem.Expenses.Add(woItemExpense);
woItemExpense = new QuoteItemExpense()
{
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 QuoteItemOutsideService()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3),
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 QuoteItemOutsideService()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3),
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 QuoteState()
{
QuoteStatusId = 3,//In progress
UserId = RandomServiceTechUserId(),
Created = woDate.AddMinutes(5)
};
o.States.Add(WoState);
o.LastStatusId = WoState.QuoteStatusId;
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
QuoteBiz biz = QuoteBiz.GetBiz(ct);
var NewObject = await biz.QuoteCreateAsync(o, false);
TotalSeededQuotes++;
if (NewObject == null)
{
var err = $"Seeder::SeedQuote error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//---------------------- /quote ------------------------
/*
██████╗ ███╗ ███╗
██╔══██╗████╗ ████║
██████╔╝██╔████╔██║
██╔═══╝ ██║╚██╔╝██║
██║ ██║ ╚═╝ ██║
╚═╝ ╚═╝ ╚═╝
*/
private int TotalSeededPMs = 0;
//////////////////////////////////////////////////////
//PM
//
public async Task SeedPMAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.UtcNow;
DateTime seedEndWindow = DateTime.UtcNow.AddDays(3);
for (int x = 0; x < count; x++)
{
PM o = new PM();
o.Notes = Fake.Lorem.Sentence(null, 3);
o.Tags = RandomTags();
if (Fake.Random.Bool())//50% have projects
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
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, DateTimeKind.Utc));
o.CreatedDate = DateTime.UtcNow;
o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers);
//------
o.CopyAttachments = true;
o.CopyWiki = true;
o.StopGeneratingDate = woDate.AddYears(1);
o.ExcludeDaysOfWeek = AyaDaysOfWeek.Saturday | AyaDaysOfWeek.Sunday;
o.Active = true;
o.NextServiceDate = woDate.AddDays(1);
o.RepeatInterval = 1;
o.RepeatUnit = PMTimeUnit.Months;
o.GenerateBeforeInterval = 3;
o.GenerateBeforeUnit = PMTimeUnit.Days;
//------
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(1, 2);
for (int y = 0; y < woItemCount; y++)
{
var woItem = new PMItem()
{
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 PMItemUnit()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3)
};
woItem.Units.Add(woItemUnit);
woItemUnit = new PMItemUnit()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3)
};
woItem.Units.Add(woItemUnit);
//SCHEDULED USERS
var woItemScheduledUser = new PMItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 1,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new PMItemScheduledUser()
{
UserId = RandomServiceTechUserId(),
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(1)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
if (y == 1)
{
//known tech and subcontractor on every item
woItemScheduledUser = new PMItemScheduledUser()
{
UserId = KnownUserTechId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new PMItemScheduledUser()
{
UserId = KnownUserSubContractorId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
if (y == 3)
{
//known restricted tech and subcontractor on some items
woItemScheduledUser = new PMItemScheduledUser()
{
UserId = KnownUserTechRestrictedId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
woItemScheduledUser = new PMItemScheduledUser()
{
UserId = KnownUserSubContractorRestrictedId,
EstimatedQuantity = 2,
StartDate = woDate,
StopDate = woDate.AddHours(2)
};
woItem.ScheduledUsers.Add(woItemScheduledUser);
}
//PARTS
var woItemPart = new PMItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
woItemPart = new PMItemPart()
{
Quantity = 1,
PartId = Fake.Random.Long(1, TotalSeededParts),
PartWarehouseId = 1
};
woItem.Parts.Add(woItemPart);
//LOANERS
var woItemLoan = new PMItemLoan()
{
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 PMItemLoan()
{
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 PMItemLabor()
{
UserId = techId,
ServiceRateQuantity = 1,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence(null, 3)
};
woItem.Labors.Add(woItemLabor);
woItemLabor = new PMItemLabor()
{
UserId = RandomServiceTechUserId(),
ServiceRateQuantity = 2,
ServiceStartDate = woDate,
ServiceStopDate = woDate.AddHours(1),
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
ServiceDetails = Fake.Lorem.Sentence(null, 3)
};
woItem.Labors.Add(woItemLabor);
//TRAVEL
var woItemTravel = new PMItemTravel()
{
UserId = techId,
TravelRateQuantity = 1,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(null, 3),
Distance = Fake.Random.Int(1, 20)
};
woItem.Travels.Add(woItemTravel);
woItemTravel = new PMItemTravel()
{
UserId = RandomServiceTechUserId(),
TravelRateQuantity = 2,
TravelStartDate = woDate,
TravelStopDate = woDate.AddHours(1),
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
TravelDetails = Fake.Lorem.Sentence(null, 3),
Distance = Fake.Random.Int(1, 20)
};
woItem.Travels.Add(woItemTravel);
//TASKS
var woItemTask = new PMItemTask()
{
CompletedByUserId = techId,
Task = "Dis-assemble",
Sequence = 1,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new PMItemTask()
{
CompletedByUserId = techId,
Task = "Lubricate",
Sequence = 2,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new PMItemTask()
{
CompletedByUserId = techId,
Task = "Repair",
Sequence = 3,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new PMItemTask()
{
CompletedByUserId = techId,
Task = "Re-assemble",
Sequence = 4,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
woItemTask = new PMItemTask()
{
CompletedByUserId = techId,
Task = "Test and confirm repair",
Sequence = 5,
Status = WorkOrderItemTaskCompletionType.Incomplete
};
woItem.Tasks.Add(woItemTask);
//EXPENSES
var cost = Fake.Random.Decimal(1, 10);
var woItemExpense = new PMItemExpense()
{
UserId = RandomServiceTechUserId(),
//TotalCost = cost,
ChargeAmount = cost * 1.2m,
ChargeToCustomer = true,
ReimburseUser = true,
ChargeTaxCodeId = TCGoods,
Name = Fake.Commerce.ProductName()
};
woItem.Expenses.Add(woItemExpense);
woItemExpense = new PMItemExpense()
{
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 PMItemOutsideService()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3),
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 PMItemOutsideService()
{
UnitId = GetRandomUnitForCustomer(o.CustomerId),
Notes = Fake.Lorem.Sentence(null, 3),
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);
}
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
PMBiz biz = PMBiz.GetBiz(ct);
var NewObject = await biz.PMCreateAsync(o, false);
TotalSeededPMs++;
if (NewObject == null)
{
var err = $"Seeder::SeedPM error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//---------------------- /PM ------------------------
private long GetRandomUnitForCustomer(long customerId)
{
var l = CustomerUnits.Where(x => x.Key == customerId).FirstOrDefault();//Fake.Random.Long(1, TotalSeededUnits);
var numUnits = l.Value.Count();
//because faker values are INCLUSIVE and this is going to be used as an index on an array need to -1 each end of the range
var i = Fake.Random.Int(0, numUnits - 1);
return l.Value[i];
}
private long GetRandomCustomerId()
{
//return any random customer except for the shadow unit one
long ret = KnownCustomerForShadownUnitsId;
while (ret == KnownCustomerForShadownUnitsId)
ret = Fake.Random.Long(1, TotalSeededCustomers);
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
}//eoc
}//eons