This commit is contained in:
2020-12-31 00:44:03 +00:00
parent 05df7600bc
commit 9d82ee64c8
4 changed files with 109 additions and 36 deletions

2
.vscode/launch.json vendored
View File

@@ -53,7 +53,7 @@
"AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles",
"AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles",
"AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles",
"AYANOVA_SERVER_TEST_MODE": "false",
"AYANOVA_SERVER_TEST_MODE": "true",
"AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small",
"AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7",
"AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\"

View File

@@ -0,0 +1,3 @@
# SERVICE BANK Placeholder
This is a placeholder page for sections that are not written yet

View File

@@ -22,8 +22,8 @@ namespace AyaNova.Util
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
private const int DESIRED_SCHEMA_LEVEL = 15;
internal const long EXPECTED_COLUMN_COUNT = 587;
internal const long EXPECTED_INDEX_COUNT = 176;
internal const long EXPECTED_COLUMN_COUNT = 596;
internal const long EXPECTED_INDEX_COUNT = 175;
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
@@ -624,7 +624,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
"entrydate timestamp not null, lastentrydate timestamp null, objecttype integer not null, objectid bigint not null, sourcetype integer not null, sourceid bigint not null, " +
"incidents decimal(19,4) not null, incidentsbalance decimal(19,4) not null, lastincidentsbalance decimal(19,4) null, " +
"currency decimal(19,4) not null, currencybalance decimal(19,4) not null, lastcurrencybalance decimal(19,4) null, " +
"hours decimal(19,4) not null, hoursbalance decimal(19,4) not null, lasthoursbalance decimal(19,4) null, "+
"hours decimal(19,4) not null, hoursbalance decimal(19,4) not null, lasthoursbalance decimal(19,4) null, " +
"CONSTRAINT UNQ_ServiceBank UNIQUE (entrydate, objectid, objecttype, incidentsbalance, hoursbalance, currencybalance), " +
"CONSTRAINT UNQ_ServiceBank_Previous_values UNIQUE (lastentrydate, objectid, objecttype, lastincidentsbalance, lasthoursbalance, lastcurrencybalance), " +
"CONSTRAINT fk_ServiceBank_self FOREIGN KEY (lastentrydate, objectid, objecttype, lastincidentsbalance, lasthoursbalance, lastcurrencybalance) references aservicebank(entrydate, objectid, objecttype, incidentsbalance, hoursbalance, currencybalance), " +
@@ -632,10 +632,10 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
"CONSTRAINT CHK_Servicebank_Valid_CurrencyBalance CHECK(currencybalance = COALESCE(lastcurrencybalance, 0) + currency), " +
"CONSTRAINT CHK_Servicebank_Valid_HoursBalance CHECK(hoursbalance = COALESCE(lasthoursbalance, 0) + hours), " +
"CONSTRAINT CHK_ServiceBank_Valid_Dates_Sequence CHECK(lastentrydate < entrydate), " +
"CONSTRAINT CHK_ServiceBank_Valid_Previous_Columns CHECK((lastentrydate IS NULL AND lastincidentsbalance IS NULL AND lastcurrencybalance IS NULL AND lasthoursbalance IS NULL) OR (lastentrydate IS NOT NULL AND lastincidentsbalance IS NOT NULL AND lastcurrencybalance IS NOT NULL AND lasthoursbalance IS NOT NULL)) "+
"CONSTRAINT CHK_ServiceBank_Valid_Previous_Columns CHECK((lastentrydate IS NULL AND lastincidentsbalance IS NULL AND lastcurrencybalance IS NULL AND lasthoursbalance IS NULL) OR (lastentrydate IS NOT NULL AND lastincidentsbalance IS NOT NULL AND lastcurrencybalance IS NOT NULL AND lasthoursbalance IS NOT NULL)) " +
" )");
await ExecQueryAsync("CREATE INDEX aservicebank_typeid_idx ON aservicebank (objectid, objecttype );");
await ExecQueryAsync("CREATE INDEX aservicebank_typeid_idx ON aservicebank (objectid, objecttype );");
//CUSTOMER
@@ -705,21 +705,6 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
await ExecQueryAsync("CREATE UNIQUE INDEX apurchaseorder_name_id_idx ON apurchaseorder (id, name);");
await ExecQueryAsync("CREATE INDEX apurchaseorder_tags ON apurchaseorder using GIN(tags)");
//UNIT
await ExecQueryAsync("CREATE TABLE aunit (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text not null unique, active bool, " +
"notes text, wiki text, customfields text, tags varchar(255) ARRAY )");
await ExecQueryAsync("CREATE UNIQUE INDEX aunit_name_id_idx ON aunit (id, name);");
await ExecQueryAsync("CREATE INDEX aunit_tags ON aunit using GIN(tags)");
//UNITMODEL
await ExecQueryAsync("CREATE TABLE aunitmodel (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text null, active bool, " +
"notes text, wiki text, customfields text, tags varchar(255) ARRAY, "+
"number text not null, vendorid bigint null references avendor(id), upc text null, lifetimewarranty bool not null, introduceddate timestamp null, " +
"discontinued bool not null, discontinueddate timestamp null, warrantylength integer null, warrantyterms text null " +
")");
await ExecQueryAsync("CREATE UNIQUE INDEX aunitmodel_name_id_idx ON aunitmodel (id, name);");
await ExecQueryAsync("CREATE INDEX aunitmodel_tags ON aunitmodel using GIN(tags)");
//VENDOR
await ExecQueryAsync("CREATE TABLE avendor (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text not null unique, active bool, " +
"notes text, wiki text, customfields text, tags varchar(255) ARRAY, webaddress text, popupnotes text, accountnumber text, " +
@@ -729,6 +714,23 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
await ExecQueryAsync("CREATE INDEX avendor_tags ON avendor using GIN(tags)");
await ExecQueryAsync("ALTER TABLE auser add FOREIGN KEY (vendorid) REFERENCES avendor(id)");
//UNIT
await ExecQueryAsync("CREATE TABLE aunit (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text not null unique, active bool, " +
"notes text, wiki text, customfields text, tags varchar(255) ARRAY )");
await ExecQueryAsync("CREATE UNIQUE INDEX aunit_name_id_idx ON aunit (id, name);");
await ExecQueryAsync("CREATE INDEX aunit_tags ON aunit using GIN(tags)");
//UNITMODEL
await ExecQueryAsync("CREATE TABLE aunitmodel (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text null, active bool, " +
"notes text, wiki text, customfields text, tags varchar(255) ARRAY, " +
"number text not null, vendorid bigint null references avendor(id), upc text null, lifetimewarranty bool not null, introduceddate timestamp null, " +
"discontinued bool not null, discontinueddate timestamp null, warrantylength integer null, warrantyterms text null " +
")");
await ExecQueryAsync("CREATE UNIQUE INDEX aunitmodel_name_id_idx ON aunitmodel (id, name);");
await ExecQueryAsync("CREATE INDEX aunitmodel_tags ON aunitmodel using GIN(tags)");
//----------
//WORKORDER
await ExecQueryAsync("CREATE TABLE aworkorder (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, serial bigint generated by default as identity not null, active bool, " +

View File

@@ -19,6 +19,7 @@ namespace AyaNova.Util
public Faker Fake;
//### FAKER BIG LIST OF ALL SOURCE DATA HERE:
//https://github.com/bchavez/Bogus/blob/master/Source/Bogus/data/en.locale.json
//https://github.com/bchavez/Bogus#bogus-api-support
public Seeder()
{
@@ -196,10 +197,6 @@ namespace AyaNova.Util
}
//Seed special test data for integration testing
//log.LogInformation("Seeding known users");
await SeedKnownObjectsAsync(log);
@@ -242,6 +239,9 @@ namespace AyaNova.Util
await SeedServiceRateAsync(log, 5);
await SeedTravelRateAsync(log, 3);
//UNITMODELS
await SeedUnitModelAsync(log, 10);
//PERF
watch.Stop();
@@ -311,6 +311,9 @@ namespace AyaNova.Util
await SeedServiceRateAsync(log, 10);
await SeedTravelRateAsync(log, 5);
//UNITMODELS
await SeedUnitModelAsync(log, 25);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, $"MEDIUM level sample data seeded in {watch.ElapsedMilliseconds} ms");
@@ -373,9 +376,6 @@ namespace AyaNova.Util
//5 accountant / bookkeeper
await SeedUserAsync(log, 5, AuthorizationRoles.AccountingFull | AuthorizationRoles.BizAdminLimited, UserType.NotService);
//WIDGETS
await SeedWidgetAsync(log, 100);
@@ -395,6 +395,9 @@ namespace AyaNova.Util
await SeedServiceRateAsync(log, 20);
await SeedTravelRateAsync(log, 10);
//UNITMODELS
await SeedUnitModelAsync(log, 30);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, $"LARGE level sample data seeded in {watch.ElapsedMilliseconds} ms");
@@ -476,6 +479,9 @@ namespace AyaNova.Util
await SeedServiceRateAsync(log, 30);
await SeedTravelRateAsync(log, 15);
//UNITMODELS
await SeedUnitModelAsync(log, 40);
//PERF
watch.Stop();
await LogStatusAsync(JobId, LogJob, log, $"HUGE level sample data seeded in {watch.ElapsedMilliseconds} ms");
@@ -546,10 +552,7 @@ namespace AyaNova.Util
return s + " " + (++RUNNING_COUNT).ToString();
}
public HashSet<string> HashUserNames = new HashSet<string>();
public HashSet<string> HashCompanyNames = new HashSet<string>();
public HashSet<string> HashProjectNames = new HashSet<string>();
public HashSet<string> HashRateNames = new HashSet<string>();
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" };
@@ -773,7 +776,7 @@ namespace AyaNova.Util
TaxCode tc = new TaxCode();
tc.Name = "Sales only";
tc.Notes = "Example sales only tax";
tc.Active=true;
tc.Active = true;
tc.Tags = RandomTags();
tc.TaxA = 0;
tc.TaxB = 0.07m;
@@ -794,7 +797,7 @@ namespace AyaNova.Util
{
TaxCode tc = new TaxCode();
tc.Name = "Goods only";
tc.Active=true;
tc.Active = true;
tc.Notes = "Example goods only tax";
tc.Tags = RandomTags();
tc.TaxB = 0;
@@ -816,7 +819,7 @@ namespace AyaNova.Util
{
TaxCode tc = new TaxCode();
tc.Name = "Sales & Goods";
tc.Active=true;
tc.Active = true;
tc.Notes = "Example sales and goods tax";
tc.Tags = RandomTags();
tc.TaxA = 0.07m;
@@ -867,6 +870,9 @@ namespace AyaNova.Util
public HashSet<string> HashUserNames = new HashSet<string>();
public async Task SeedUserAsync(
ILogger log, int count, AuthorizationRoles roles, UserType userType,
bool active = true, string login = null, string password = null,
@@ -1002,6 +1008,7 @@ namespace AyaNova.Util
#endregion
public HashSet<string> HashCompanyNames = new HashSet<string>();
//////////////////////////////////////////////////////
@@ -1180,6 +1187,7 @@ namespace AyaNova.Util
public HashSet<string> HashProjectNames = new HashSet<string>();
//////////////////////////////////////////////////////
//PROJECT
@@ -1223,6 +1231,8 @@ namespace AyaNova.Util
}
}
public HashSet<string> HashRateNames = new HashSet<string>();
//////////////////////////////////////////////////////
//SERVICERATE
//
@@ -1306,6 +1316,64 @@ namespace AyaNova.Util
}
public HashSet<string> HashUnitModelNames = new HashSet<string>();
//////////////////////////////////////////////////////
//UNITMODEL
//
public async Task SeedUnitModelAsync(ILogger log, int count)
{
DateTime seedStartWindow = DateTime.Now.AddYears(-5);
DateTime seedEndWindow = DateTime.Now.AddYears(1);
var WarrantyMonths = new[] { 1, 6, 12, 24, 36 };
var WarrantyTerms = new[] { "Parts only", "Parts and service", "Service only", "Shipping parts and service", "First month parts and service here; after is depot only" };
for (int x = 0; x < count; x++)
{
UnitModel o = new UnitModel();
do
{
o.Name = $"{Fake.Vehicle.Model()} {Fake.Commerce.Categories(1)[0]}";
} while (!HashUnitModelNames.Add(o.Name));
do
{
o.Number = Fake.Finance.Account(6);
} while (!HashUnitModelNames.Add(o.Number));
o.Active = true;
o.Notes = Fake.Lorem.Sentence();
o.Tags = RandomTags();
o.VendorId = Fake.Random.Long(1, 10);
o.UPC = Fake.Commerce.Ean13();
o.LifeTimeWarranty = false;
o.IntroducedDate = Fake.Date.Between(seedStartWindow, DateTime.Now).ToUniversalTime();
o.Discontinued = false;
o.DiscontinuedDate = null;
o.WarrantyLength = Fake.PickRandom(WarrantyMonths);
o.WarrantyTerms = Fake.PickRandom(WarrantyTerms);
//This seems wrong to do in a loop but is 4 times faster this way ?!?
using (AyContext ct = ServiceProviderProvider.DBContext)
{
UnitModelBiz biz = UnitModelBiz.GetBiz(ct);
var NewObject = await biz.CreateAsync(o);
if (NewObject == null)
{
var err = $"Seeder::SeedUnitModel error creating {o.Name}\r\n{biz.GetErrorsAsString()}";
log.LogError(err);
throw new System.Exception(err);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
}//eoc