4180 lines
198 KiB
C#
4180 lines
198 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, string forceEmail, string appendPassword, bool e2e = false)
|
|
{
|
|
await SeedDatabaseAsync(slevel, Guid.Empty, timeZoneOffset, forceEmail, appendPassword, e2e);
|
|
}
|
|
|
|
public async Task SeedDatabaseAsync(Level.SeedLevel slevel, Guid JobId, Decimal timeZoneOffset, string forceEmail, string appendPassword, bool e2e = false)
|
|
{
|
|
bool LogJob = JobId != Guid.Empty;
|
|
_e2e = e2e;
|
|
// 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, JobId);
|
|
//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, forceEmail, appendPassword);
|
|
/*
|
|
|
|
███████╗███████╗███████╗██████╗ █████╗ ██╗ ██╗ ████████╗██╗ ██╗███████╗ ████████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗
|
|
██╔════╝██╔════╝██╔════╝██╔══██╗ ██╔══██╗██║ ██║ ╚══██╔══╝██║ ██║██╔════╝ ╚══██╔══╝██║ ██║██║████╗ ██║██╔════╝ ██╔════╝
|
|
███████╗█████╗ █████╗ ██║ ██║ ███████║██║ ██║ ██║ ███████║█████╗ ██║ ███████║██║██╔██╗ ██║██║ ███╗███████╗
|
|
╚════██║██╔══╝ ██╔══╝ ██║ ██║ ██╔══██║██║ ██║ ██║ ██╔══██║██╔══╝ ██║ ██╔══██║██║██║╚██╗██║██║ ██║╚════██║
|
|
███████║███████╗███████╗██████╔╝ ██║ ██║███████╗███████╗ ██║ ██║ ██║███████╗ ██║ ██║ ██║██║██║ ╚████║╚██████╔╝███████║
|
|
╚══════╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
|
|
|
|
*/
|
|
//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, forceEmail, appendPassword);
|
|
//Generate one office person / secretary
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.Accounting, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
//2 other techs (must always be enough to have no dupes per workorder)
|
|
await SeedUserAsync(log, 2, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
|
|
await SeedVendorAsync(log, 10, forceEmail);
|
|
await SeedUnitModelAsync(log, 10);
|
|
await SeedCustomerAsync(log, 25, slevel, forceEmail, appendPassword);
|
|
await SeedHeadOfficeAsync(log, 10, slevel, forceEmail, appendPassword);
|
|
await SeedVendorAsync(log, 10, forceEmail);
|
|
await SeedProjectAsync(log, 3);
|
|
await SeedServiceRateAsync(log, 5);
|
|
await SeedTravelRateAsync(log, 3);
|
|
await SeedLoanLoanUnitAsync(log, 5);
|
|
await SeedCustomerServiceRequestAsync(log, 5, forceEmail, appendPassword);
|
|
await SeedPartWarehouseAsync(log, 5);
|
|
await SeedPartAsync(log, 20, 1000);
|
|
await SeedPartAssemblyAsync(log, 5);
|
|
await SeedPurchaseOrderAsync(log, 10);
|
|
await SeedQuoteAsync(log, 5);
|
|
await SeedPMAsync(log, 3);
|
|
await SeedWorkOrderAsync(log, 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, forceEmail, appendPassword);
|
|
//One business administrator, can view ops issues
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//One owner who doesn't control anything but views stuff
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted | AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
////////////////////////////////////////////////
|
|
//TECHS (LICENSE CONSUMERS)
|
|
//trial license allows 1000
|
|
//
|
|
//regular techs
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
//Restricted techs
|
|
// await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service);
|
|
//subcontractors
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
|
|
//Restricted subcontractors
|
|
// await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor);
|
|
///////////////////////////////////////////
|
|
//3 generic office people people
|
|
await SeedUserAsync(log, 3, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//2 Full sales people
|
|
await SeedUserAsync(log, 2, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
|
|
//1 Service manager
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//1 Inventory manager
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//1 accountant / bookkeeper
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
await SeedVendorAsync(log, 50, forceEmail);
|
|
await SeedUnitModelAsync(log, 20);
|
|
await SeedCustomerAsync(log, 500, slevel, forceEmail, appendPassword);
|
|
await SeedHeadOfficeAsync(log, 20, slevel, forceEmail, appendPassword);
|
|
|
|
await SeedProjectAsync(log, 5);
|
|
await SeedServiceRateAsync(log, 10);
|
|
await SeedTravelRateAsync(log, 5);
|
|
|
|
//await SeedUnitAsync(log, 2500);
|
|
await SeedLoanLoanUnitAsync(log, 10);
|
|
await SeedCustomerServiceRequestAsync(log, 10, forceEmail, appendPassword);
|
|
await SeedPartWarehouseAsync(log, 10);
|
|
await SeedPartAsync(log, 100, 1000);
|
|
await SeedPartAssemblyAsync(log, 5);
|
|
await SeedPurchaseOrderAsync(log, 30);
|
|
await SeedQuoteAsync(log, 5);
|
|
await SeedPMAsync(log, 3);
|
|
await SeedWorkOrderAsync(log, 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, forceEmail, appendPassword);
|
|
//business administrator, can view ops issues
|
|
await SeedUserAsync(log, 2, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//owner / upper management who doesn't control anything but views stuff
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
////////////////////////////////////////////////
|
|
//TECHS (LICENSE CONSUMERS)
|
|
//trial license allows 1000
|
|
//
|
|
//regular techs
|
|
await SeedUserAsync(log, 8, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
//Restricted techs
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
//subcontractors
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
|
|
//Restricted subcontractors
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, forceEmail, appendPassword);
|
|
///////////////////////////////////////////
|
|
|
|
//30 generic office people people
|
|
await SeedUserAsync(log, 30, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//10 Full sales people
|
|
await SeedUserAsync(log, 10, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
|
|
//5 Restricted sales people
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//5 Service manager
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//5 Inventory manager
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//10 Inventory manager assistants
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//5 accountant / bookkeeper
|
|
await SeedUserAsync(log, 5, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
await SeedVendorAsync(log, 100, forceEmail);
|
|
await SeedUnitModelAsync(log, 40);
|
|
await SeedCustomerAsync(log, 1000, slevel, forceEmail, appendPassword);
|
|
await SeedHeadOfficeAsync(log, 40, slevel, forceEmail, appendPassword);
|
|
|
|
await SeedProjectAsync(log, 10);
|
|
await SeedServiceRateAsync(log, 20);
|
|
await SeedTravelRateAsync(log, 10);
|
|
|
|
// await SeedUnitAsync(log, 5000);
|
|
await SeedLoanLoanUnitAsync(log, 20);
|
|
await SeedCustomerServiceRequestAsync(log, 20, forceEmail, appendPassword);
|
|
await SeedPartWarehouseAsync(log, 20);
|
|
await SeedPartAsync(log, 200, 1000);
|
|
await SeedPartAssemblyAsync(log, 5);
|
|
await SeedPurchaseOrderAsync(log, 50);
|
|
await SeedQuoteAsync(log, 5);
|
|
await SeedPMAsync(log, 3);
|
|
await SeedWorkOrderAsync(log, 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();
|
|
|
|
|
|
//INSIDE USERS - 730 total inside users here plus couple dozen known users below
|
|
//IT administrator, can change ops but nothing else
|
|
await SeedUserAsync(log, 10, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword);
|
|
//business administrator, can view ops issues
|
|
await SeedUserAsync(log, 10, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//owner / upper management who doesn't control anything but views stuff
|
|
await SeedUserAsync(log, 20, AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted | AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
////////////////////////////////////////////////
|
|
//TECHS (LICENSE CONSUMERS)
|
|
//
|
|
//
|
|
|
|
//########### WARNING: if more than 250 techs must update Rockfish::ravenkeyfactory::GetRavenTrialKey to allow for more
|
|
//regular techs
|
|
await SeedUserAsync(log, 15, AuthorizationRoles.Tech | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
//Restricted techs
|
|
await SeedUserAsync(log, 2, AuthorizationRoles.TechRestricted | AuthorizationRoles.ServiceRestricted, UserType.Service, forceEmail, appendPassword);
|
|
//subcontractors
|
|
await SeedUserAsync(log, 2, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword);
|
|
//Restricted subcontractors
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.SubContractorRestricted, UserType.ServiceContractor, forceEmail, appendPassword);
|
|
///////////////////////////////////////////
|
|
|
|
//generic office people people
|
|
await SeedUserAsync(log, 500, AuthorizationRoles.ServiceRestricted | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//20 Full sales people
|
|
await SeedUserAsync(log, 60, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword);
|
|
//10 Restricted sales people
|
|
await SeedUserAsync(log, 10, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//Service manager
|
|
await SeedUserAsync(log, 20, AuthorizationRoles.Service | AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//Inventory manager
|
|
await SeedUserAsync(log, 40, AuthorizationRoles.Inventory | AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//Inventory manager assistants
|
|
await SeedUserAsync(log, 20, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
//accountant / bookkeeper
|
|
await SeedUserAsync(log, 20, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword);
|
|
|
|
await SeedVendorAsync(log, 5000, forceEmail);
|
|
await SeedUnitModelAsync(log, 400);
|
|
|
|
//######### WARNING trial license size limits: Each Head office is up to 3 users generated, each customer is up to 1 generated so assume fully generated
|
|
await SeedCustomerAsync(log, 10000, slevel, forceEmail, appendPassword);//## WARNING AFFECTS LICENSE potentially 10,000 CUSTOMER users
|
|
await SeedHeadOfficeAsync(log, 500, slevel, forceEmail, appendPassword);//## WARNING AFFECTS LICENSE potentially 1500 CUSTOMER users
|
|
|
|
await SeedProjectAsync(log, 1000);
|
|
await SeedServiceRateAsync(log, 200);
|
|
await SeedTravelRateAsync(log, 100);
|
|
|
|
await SeedLoanLoanUnitAsync(log, 200);
|
|
await SeedCustomerServiceRequestAsync(log, 200, forceEmail, appendPassword);//## WARNING AFFECTS LICENSE potentially 200 CUSTOMER users from this
|
|
await SeedPartWarehouseAsync(log, 200);
|
|
await SeedPartAsync(log, 10000, 1000);
|
|
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, 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, string forceEmail, string appendPassword)
|
|
{
|
|
var KnownUserTags = new List<string>();
|
|
KnownUserTags.Add("known-user");
|
|
KnownUserTags.Add("test-role-user");
|
|
//TRIAL USERS
|
|
//one of each role type
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdminRestricted, UserType.NotService, forceEmail, appendPassword, "BizAdminRestricted", "BizAdminRestricted", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin, UserType.NotService, forceEmail, appendPassword, "BizAdmin", "BizAdmin", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.ServiceRestricted, UserType.NotService, forceEmail, appendPassword, "ServiceRestricted", "ServiceRestricted", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Service, UserType.NotService, forceEmail, appendPassword, "Service", "Service", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.InventoryRestricted, UserType.NotService, forceEmail, appendPassword, "InventoryRestricted", "InventoryRestricted", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Inventory, UserType.NotService, forceEmail, appendPassword, "Inventory", "Inventory", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.Accounting, UserType.NotService, forceEmail, appendPassword, "Accounting", "Accounting", KnownUserTags);
|
|
KnownUserTechRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.TechRestricted, UserType.Service, forceEmail, appendPassword, "TechRestricted", "TechRestricted", KnownUserTags);
|
|
KnownUserTechId = await SeedUserAsync(log, 1, AuthorizationRoles.Tech, UserType.Service, forceEmail, appendPassword, "Tech", "Tech", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.SalesRestricted, UserType.NotService, forceEmail, appendPassword, "SalesRestricted", "SalesRestricted", KnownUserTags);
|
|
KnownUserSalesId = await SeedUserAsync(log, 1, AuthorizationRoles.Sales, UserType.NotService, forceEmail, appendPassword, "Sales", "Sales", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword, "OpsAdminRestricted", "OpsAdminRestricted", KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, "OpsAdmin", "OpsAdmin", KnownUserTags);
|
|
|
|
//Alternate translation users for each stock translation
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags);
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, forceEmail, appendPassword, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags);
|
|
|
|
//TEST NOT ACTIVE - this is used for a test to see if inactive user can login
|
|
await SeedUserAsync(log, 1, AuthorizationRoles.OpsAdminRestricted, UserType.NotService, forceEmail, appendPassword, 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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
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, forceEmail, appendPassword, 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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
|
|
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, forceEmail, appendPassword, true, "Customer", "Customer", 0, KnownUserTags, null, NewObject.Id, null);
|
|
KnownUserCustomerRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, forceEmail, appendPassword, true, "CustomerRestricted", "CustomerRestricted", 0, KnownUserTags, null, NewObject.Id, null);
|
|
//5 units per customer
|
|
await SeedUnitAsync(log, 20, NewObject.Id);//5 times the customers or 5 units per customer
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////
|
|
//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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
//intentional: tested and faster in loop
|
|
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, forceEmail, appendPassword, true, "SubContractorRestricted", "SubContractorRestricted", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
|
|
KnownUserSubContractorId = await SeedUserAsync(log, 1, AuthorizationRoles.SubContractor, UserType.ServiceContractor, forceEmail, appendPassword, true, "SubContractor", "SubContractor", 0, KnownUserTags, VendorIdForSubContractorUser, null, null);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
//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 = "#FFDFDFFF";
|
|
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 = "#DFFCFCFF";
|
|
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 = "#DFFFDFFF";
|
|
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 = "#DFDFDFFF";
|
|
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 = "#DFDFFFFF";
|
|
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 = "#DFDF9FFF";
|
|
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 = "#FFDFFFFF";
|
|
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 = "#FFDFDFFF";
|
|
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 = "#CDC4AAFF";//boring oatmeal
|
|
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 = "#C00000FF";
|
|
|
|
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 = "#00FF00FF";
|
|
|
|
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 = "#0000FFFF";
|
|
|
|
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 = "#C00000FF";
|
|
|
|
|
|
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 = "#FF9900FF";
|
|
|
|
|
|
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 = "#FFFF00FF";
|
|
|
|
|
|
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 = "#00CCFFFF";
|
|
|
|
|
|
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 = "#00FF00FF";
|
|
|
|
|
|
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 = "#C00000FF";
|
|
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 = "#80FFFFFF";
|
|
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 = "#00FF00FF";
|
|
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 = "#FF0000FF";
|
|
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 = "#8080FFFF";
|
|
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 = "#F2F2F2FF";
|
|
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)
|
|
{
|
|
|
|
//get the default customer work order report by name, currently chosen is "Customer Invoice"
|
|
ReportBiz rptb = ReportBiz.GetBiz(ct);
|
|
var reportList = await rptb.GetReportListAsync(AyaType.WorkOrder);
|
|
var SampleCustomerWorkOrderReportId = reportList.Where(z => z.Name == "Customer Invoice").Select(z => z.Id).First();
|
|
|
|
GlobalBizSettingsBiz biz = GlobalBizSettingsBiz.GetBiz(ct);
|
|
var gbiz = await biz.GetAsync(false);
|
|
|
|
gbiz.Latitude = (decimal)Fake.Address.Latitude();
|
|
gbiz.Longitude = (decimal)Fake.Address.Longitude();
|
|
gbiz.Address = Fake.Address.StreetAddress();
|
|
gbiz.City = Fake.Address.City();
|
|
gbiz.Region = Fake.Address.State();
|
|
gbiz.Country = Fake.Address.Country();
|
|
gbiz.PostAddress = Fake.Address.StreetAddress();
|
|
gbiz.PostCity = gbiz.City;
|
|
gbiz.PostRegion = gbiz.Region;
|
|
gbiz.PostCountry = gbiz.Country;
|
|
gbiz.PostCode = Fake.Address.ZipCode();
|
|
gbiz.Phone1 = Fake.Phone.PhoneNumber();
|
|
gbiz.Phone2 = Fake.Phone.PhoneNumber();
|
|
gbiz.WebAddress = Fake.Internet.Protocol() + "://example." + Fake.Internet.DomainSuffix();
|
|
gbiz.EmailAddress = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
gbiz.TaxPartPurchaseId = TCGoods;
|
|
gbiz.TaxPartSaleId = TCGoods;
|
|
gbiz.TaxRateSaleId = TCServices;
|
|
gbiz.CustomerAllowCSR = true;
|
|
gbiz.CustomerAllowCreateUnit = true;
|
|
gbiz.CustomerAllowNotifyCSRAccepted = true;
|
|
gbiz.CustomerAllowNotifyCSRRejected = true;
|
|
gbiz.CustomerAllowNotifyServiceImminent = true;
|
|
gbiz.CustomerAllowNotifyWOCompleted = true;
|
|
gbiz.CustomerAllowNotifyWOCreated = true;
|
|
gbiz.CustomerAllowUserSettings = true;
|
|
gbiz.CustomerAllowViewWO = true;
|
|
gbiz.CustomerDefaultWorkOrderReportId = SampleCustomerWorkOrderReportId;
|
|
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 forceEmail, string appendPassword, string login, string password, List<string> tags = null)
|
|
{
|
|
try
|
|
{
|
|
return await SeedUserAsync(log, count, roles, userType, forceEmail, appendPassword, 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, string forceEmail, string appendPassword,
|
|
bool active = true, string login = null, string password = null,
|
|
long translationId = 0, List<string> tags = null,
|
|
long? vendorId = null, long? customerId = null, long? headofficeId = null
|
|
)
|
|
{
|
|
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;
|
|
u.AllowLogin=true;
|
|
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 + appendPassword;
|
|
else
|
|
u.Password = u.Login + appendPassword;
|
|
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 = string.IsNullOrWhiteSpace(forceEmail) ? bogusEmail : forceEmail;
|
|
u.UserOptions.Hour12 = true;
|
|
u.UserOptions.CurrencyName = "USD";
|
|
u.UserOptions.UiColor = Fake.Internet.Color().ToUpperInvariant() + "FF";
|
|
|
|
|
|
//this seems wrong to get a new context inside a loop but in testing is actually faster!?
|
|
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, string forceEmail, string appendPassword, 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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
if (headOfficeId != null)
|
|
{
|
|
o.HeadOfficeId = headOfficeId;
|
|
o.BillHeadOffice = true;
|
|
}
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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, forceEmail, appendPassword, true, null, null, 0, null, null, NewObject.Id, null);
|
|
|
|
switch (slevel)
|
|
{
|
|
case Level.SeedLevel.Small:
|
|
case Level.SeedLevel.Medium:
|
|
await SeedUnitAsync(log, 5, NewObject.Id);
|
|
break;
|
|
case Level.SeedLevel.Large:
|
|
case Level.SeedLevel.Huge:
|
|
await SeedUnitAsync(log, 10, NewObject.Id);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private int TotalSeededHeadOffices = 0;
|
|
//////////////////////////////////////////////////////
|
|
//HEADOFFICE
|
|
//
|
|
public async Task SeedHeadOfficeAsync(ILogger log, int count, Level.SeedLevel slevel, string forceEmail, string appendPassword)
|
|
{
|
|
|
|
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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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, forceEmail, appendPassword, true, null, null, 0, null, null, null, NewObject.Id);
|
|
//HeadOffice Customer
|
|
await SeedCustomerAsync(log, 2, slevel, forceEmail, appendPassword, NewObject.Id);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private int TotalSeededVendors = 0;
|
|
//////////////////////////////////////////////////////
|
|
//VENDOR
|
|
//
|
|
public async Task SeedVendorAsync(ILogger log, int count, string forceEmail)
|
|
{
|
|
|
|
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 = string.IsNullOrWhiteSpace(forceEmail) ? Fake.Internet.ExampleEmail() : forceEmail;
|
|
|
|
//intentional: tested and faster in loop
|
|
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 = MoneyUtil.Round(Fake.Random.Decimal(0.25m, 50));
|
|
o.Charge = MoneyUtil.Round(o.Cost * 1.55m);
|
|
o.Unit = "hour";
|
|
o.ContractOnly = contractOnly;
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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 = MoneyUtil.Round(Fake.Random.Decimal(0.25m, 10));
|
|
o.Charge = MoneyUtil.Round(o.Cost * 2m);
|
|
o.Unit = Fake.PickRandom(Units);
|
|
o.ContractOnly = contractOnly;
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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);
|
|
|
|
//intentional: tested and faster in loop
|
|
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;
|
|
}
|
|
|
|
//intentional: tested and faster in loop
|
|
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
|
|
if (CustomerUnits.ContainsKey(customerId))
|
|
{
|
|
CustomerUnits[customerId].AddRange(unitsAddedThisRun);
|
|
}
|
|
else
|
|
{
|
|
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 = MoneyUtil.Round(Fake.Random.Decimal(1, 25));
|
|
o.RateHourCost = MoneyUtil.Round(o.RateHour / 2);
|
|
o.RateHalfDay = MoneyUtil.Round(o.RateHour * 4);
|
|
o.RateHalfDayCost = MoneyUtil.Round(o.RateHalfDay / 2);
|
|
o.RateDay = MoneyUtil.Round(o.RateHour * 8);
|
|
o.RateDayCost = MoneyUtil.Round(o.RateDay / 2);
|
|
o.RateWeek = MoneyUtil.Round(o.RateHour * 36.8m);
|
|
o.RateWeekCost = MoneyUtil.Round(o.RateWeek / 2);
|
|
o.RateMonth = MoneyUtil.Round(o.RateHour * 21 * 8);
|
|
o.RateMonthCost = MoneyUtil.Round(o.RateMonth / 2);
|
|
o.RateYear = MoneyUtil.Round(o.RateHour * 36.8m * 52);
|
|
o.RateYearCost = MoneyUtil.Round(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, string forceEmail, string appendPassword)
|
|
{
|
|
DateTime seedStartWindow = DateTime.Now.AddMonths(-1);
|
|
DateTime seedEndWindow = DateTime.Now;
|
|
|
|
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, forceEmail, appendPassword, true, null, null, 0, null, null, o.CustomerId, null);
|
|
o.Status = CustomerServiceRequestStatus.Open;
|
|
o.Priority = Fake.Random.Enum<CustomerServiceRequestPriority>();
|
|
o.CustomerReferenceNumber = Fake.Finance.Account();
|
|
|
|
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();
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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> HashPartNames = 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.Name = Fake.Finance.Account(6);
|
|
} while (!HashPartNames.Add(o.Name));
|
|
|
|
|
|
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.Name;
|
|
o.UPC = Fake.Commerce.Ean13();
|
|
|
|
o.WholeSalerId = Fake.Random.Long(4, 6);
|
|
o.WholeSalerNumber = "ws-" + o.Name;
|
|
|
|
o.AlternativeWholeSalerId = Fake.Random.Long(7, 9);
|
|
o.AlternativeWholeSalerNumber = "aws-" + o.Name;
|
|
|
|
o.Cost = MoneyUtil.Round(Fake.Random.Decimal(1, 25));
|
|
o.Retail = MoneyUtil.Round(o.Cost * 1.2m);
|
|
o.UnitOfMeasure = "each";
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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.Name}\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.Name} 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 });
|
|
}
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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 = MoneyUtil.Round(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
|
|
});
|
|
}
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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)
|
|
public async Task SeedWorkOrderAsync(ILogger log, Level.SeedLevel seedLevel)
|
|
{
|
|
//Goal is 3-6 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
|
|
|
|
int totalDays = (int)(seedEndWindow - seedStartWindow).TotalDays;
|
|
|
|
|
|
//generate 3-6 per day starting with oldest seed start window up to seed end window
|
|
|
|
for (int x = 0; x < totalDays; x++)
|
|
{
|
|
int thisDayGenerateThisMany = Fake.Random.Int(0, 3) + 3;
|
|
for (int perDay = 0; perDay < thisDayGenerateThisMany; perDay++)
|
|
{
|
|
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 = seedStartWindow.AddDays(x);
|
|
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 olderThanOneWeekAgo = (woDate.Subtract(DateTime.UtcNow).TotalDays < -7);
|
|
bool isFutureDate = woDate > DateTime.UtcNow;
|
|
|
|
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow.Subtract(new TimeSpan(Fake.Random.Int(1, 30), 0, 0, 0)) : woDate;//no created dates in future but want a range of past dates to show off age of wo
|
|
|
|
|
|
o.CompleteByDate = woDate.AddDays(5);
|
|
|
|
|
|
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 = GetNextUnitForCustomer(o.CustomerId),
|
|
Notes = Fake.Lorem.Sentence(null, 3)
|
|
};
|
|
woItem.Units.Add(woItemUnit);
|
|
}
|
|
|
|
//SCHEDULED USERS
|
|
var actualScheduledUserCount = Fake.Random.Int(1, 2);
|
|
if (isFutureDate && Fake.Random.Int(1, 10) == 2)//10% chance unscheduled future wo to show off unscheduled widget
|
|
actualScheduledUserCount = 0;
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
//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);
|
|
}
|
|
|
|
|
|
var techId = RandomServiceTechUserId();
|
|
//LABOR
|
|
if (!isFutureDate)
|
|
{
|
|
|
|
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 = isFutureDate ? WorkOrderItemTaskCompletionType.Incomplete : WorkOrderItemTaskCompletionType.Complete,
|
|
CompletedDate = isFutureDate ? null : woDate.AddHours(1)
|
|
};
|
|
woItem.Tasks.Add(woItemTask);
|
|
|
|
woItemTask = new WorkOrderItemTask()
|
|
{
|
|
CompletedByUserId = techId,
|
|
Task = "Lubricate",
|
|
Sequence = 2,
|
|
Status = WorkOrderItemTaskCompletionType.NotApplicable,
|
|
CompletedDate = isFutureDate ? null : woDate.AddHours(1)
|
|
};
|
|
woItem.Tasks.Add(woItemTask);
|
|
|
|
|
|
woItemTask = new WorkOrderItemTask()
|
|
{
|
|
CompletedByUserId = techId,
|
|
Task = "Repair",
|
|
Sequence = 3,
|
|
Status = isFutureDate ? WorkOrderItemTaskCompletionType.Incomplete : WorkOrderItemTaskCompletionType.Complete,
|
|
CompletedDate = isFutureDate ? null : woDate.AddHours(1.5)
|
|
};
|
|
woItem.Tasks.Add(woItemTask);
|
|
|
|
woItemTask = new WorkOrderItemTask()
|
|
{
|
|
CompletedByUserId = techId,
|
|
Task = "Re-assemble",
|
|
Sequence = 4,
|
|
Status = isFutureDate ? WorkOrderItemTaskCompletionType.Incomplete : WorkOrderItemTaskCompletionType.Complete,
|
|
CompletedDate = isFutureDate ? null : woDate.AddHours(2)
|
|
};
|
|
woItem.Tasks.Add(woItemTask);
|
|
|
|
woItemTask = new WorkOrderItemTask()
|
|
{
|
|
CompletedByUserId = techId,
|
|
Task = "Test and confirm repair",
|
|
Sequence = 5,
|
|
Status = isFutureDate ? WorkOrderItemTaskCompletionType.Incomplete : WorkOrderItemTaskCompletionType.Complete,
|
|
CompletedDate = isFutureDate ? null : woDate.AddHours(2)
|
|
};
|
|
woItem.Tasks.Add(woItemTask);
|
|
}
|
|
|
|
|
|
|
|
//EXPENSES
|
|
if (!isFutureDate)
|
|
{
|
|
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 = MoneyUtil.Round(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 = MoneyUtil.Round(cost * 2.2m),
|
|
ChargeToCustomer = true,
|
|
ReimburseUser = true,
|
|
ChargeTaxCodeId = TCGoods,
|
|
Name = Fake.Commerce.ProductName()
|
|
|
|
};
|
|
woItem.Expenses.Add(woItemExpense);
|
|
}
|
|
}
|
|
|
|
|
|
//OUTSIDE SERVICES
|
|
if (!isFutureDate && Fake.Random.Int(1, 10) == 2)//10% chance
|
|
{
|
|
var ShippingCost = MoneyUtil.Round(Fake.Random.Decimal(5, 20));
|
|
var RepairCost = MoneyUtil.Round(Fake.Random.Decimal(50, 1000));
|
|
var woItemOutsideService = new WorkOrderItemOutsideService()
|
|
{
|
|
UnitId = GetNextUnitForCustomer(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 = MoneyUtil.Round(RepairCost * 1.5m),
|
|
ShippingCost = ShippingCost,
|
|
ShippingPrice = MoneyUtil.Round(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);
|
|
o.LastStatusId = WoState.WorkOrderStatusId;
|
|
}
|
|
}
|
|
|
|
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);
|
|
o.LastStatusId = WoState.WorkOrderStatusId;
|
|
}
|
|
}
|
|
|
|
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);
|
|
o.LastStatusId = WoState.WorkOrderStatusId;
|
|
}
|
|
}
|
|
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 (olderThanOneWeekAgo)
|
|
{
|
|
if (Fake.Random.Int(1, 10) != 3) //10% overdue for showing off widget overdue
|
|
{
|
|
var WoState = new WorkOrderState()
|
|
{
|
|
WorkOrderStatusId = (long)SeedWOStatus.Closed,
|
|
UserId = RandomServiceTechUserId(),
|
|
Created = ((DateTime)o.ServiceDate).AddHours(2)//TODO: set this based on completed date above to come
|
|
};
|
|
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
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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 = GetNextUnitForCustomer(o.CustomerId),
|
|
Notes = Fake.Lorem.Sentence(null, 3)
|
|
};
|
|
woItem.Units.Add(woItemUnit);
|
|
|
|
woItemUnit = new QuoteItemUnit()
|
|
{
|
|
UnitId = GetNextUnitForCustomer(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 = GetNextUnitForCustomer(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 = GetNextUnitForCustomer(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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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 = GetNextUnitForCustomer(o.CustomerId),
|
|
Notes = Fake.Lorem.Sentence(null, 3)
|
|
};
|
|
woItem.Units.Add(woItemUnit);
|
|
|
|
woItemUnit = new PMItemUnit()
|
|
{
|
|
UnitId = GetNextUnitForCustomer(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 = GetNextUnitForCustomer(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 = GetNextUnitForCustomer(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);
|
|
}
|
|
|
|
|
|
|
|
//intentional: tested and faster in loop
|
|
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 int lastUnitIndex = -1;
|
|
private long lastCustomer = -1;
|
|
private long GetNextUnitForCustomer(long customerId)//tries to ensure no dupes in same wo
|
|
{
|
|
if (lastCustomer != customerId)
|
|
{
|
|
//reset flags
|
|
lastCustomer = customerId;
|
|
lastUnitIndex = -1;
|
|
}
|
|
lastUnitIndex++;
|
|
|
|
var l = CustomerUnits.Where(x => x.Key == customerId).First();
|
|
if (lastUnitIndex > (l.Value.Count() - 1))
|
|
{
|
|
lastUnitIndex = 0;
|
|
}
|
|
return l.Value[lastUnitIndex];
|
|
}
|
|
|
|
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 |