diff --git a/.vscode/launch.json b/.vscode/launch.json index b77f3b95..fcc80a75 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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\\" diff --git a/server/AyaNova/util/Seeder.cs b/server/AyaNova/util/Seeder.cs index e2a5e497..9a0f560f 100644 --- a/server/AyaNova/util/Seeder.cs +++ b/server/AyaNova/util/Seeder.cs @@ -229,14 +229,16 @@ namespace AyaNova.Util //Generate one office person / secretary await SeedUserAsync(log, 1, AuthorizationRoles.Service | AuthorizationRoles.Inventory | AuthorizationRoles.Accounting, UserType.NotService); // await SeedWidgetAsync(log, 3);//keeping this here for now but must remove later + await SeedVendorAsync(log, 10); + await SeedUnitModelAsync(log, 10); await SeedCustomerAsync(log, 25); await SeedHeadOfficeAsync(log, 10); await SeedVendorAsync(log, 10); await SeedProjectAsync(log, 3); await SeedServiceRateAsync(log, 5); await SeedTravelRateAsync(log, 3); - await SeedUnitModelAsync(log, 10); - await SeedUnitAsync(log, 20);//5 times the customers or 5 units per customer + + //await SeedUnitAsync(log, 20);//5 times the customers or 5 units per customer await SeedLoanLoanUnitAsync(log, 5); await SeedCustomerServiceRequestAsync(log, 5); await SeedPartWarehouseAsync(log, 5); @@ -284,14 +286,16 @@ namespace AyaNova.Util await SeedUserAsync(log, 1, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService); //await SeedWidgetAsync(log, 100); + await SeedVendorAsync(log, 50); + await SeedUnitModelAsync(log, 20); await SeedCustomerAsync(log, 500); await SeedHeadOfficeAsync(log, 20); - await SeedVendorAsync(log, 50); + await SeedProjectAsync(log, 5); await SeedServiceRateAsync(log, 10); await SeedTravelRateAsync(log, 5); - await SeedUnitModelAsync(log, 20); - await SeedUnitAsync(log, 2500); + + //await SeedUnitAsync(log, 2500); await SeedLoanLoanUnitAsync(log, 10); await SeedCustomerServiceRequestAsync(log, 10); await SeedPartWarehouseAsync(log, 10); @@ -349,14 +353,16 @@ namespace AyaNova.Util await SeedUserAsync(log, 5, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService); //await SeedWidgetAsync(log, 100); + await SeedVendorAsync(log, 100); + await SeedUnitModelAsync(log, 40); await SeedCustomerAsync(log, 1000); await SeedHeadOfficeAsync(log, 40); - await SeedVendorAsync(log, 100); + await SeedProjectAsync(log, 10); await SeedServiceRateAsync(log, 20); await SeedTravelRateAsync(log, 10); - await SeedUnitModelAsync(log, 40); - await SeedUnitAsync(log, 5000); + + // await SeedUnitAsync(log, 5000); await SeedLoanLoanUnitAsync(log, 20); await SeedCustomerServiceRequestAsync(log, 20); await SeedPartWarehouseAsync(log, 20); @@ -415,14 +421,16 @@ namespace AyaNova.Util await SeedUserAsync(log, 20, AuthorizationRoles.Accounting | AuthorizationRoles.BizAdminRestricted, UserType.NotService); //await SeedWidgetAsync(log, 100); + await SeedVendorAsync(log, 500); + await SeedUnitModelAsync(log, 200); await SeedCustomerAsync(log, 10000); await SeedHeadOfficeAsync(log, 200); - await SeedVendorAsync(log, 500); + await SeedProjectAsync(log, 20); await SeedServiceRateAsync(log, 100); await SeedTravelRateAsync(log, 50); - await SeedUnitModelAsync(log, 200); - await SeedUnitAsync(log, 25000); + + //await SeedUnitAsync(log, 25000); await SeedLoanLoanUnitAsync(log, 100); await SeedCustomerServiceRequestAsync(log, 100); await SeedPartWarehouseAsync(log, 100); @@ -578,9 +586,9 @@ namespace AyaNova.Util //Alternate translation users for each stock translation - await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags); - await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags); - await SeedUserAsync(log, 1, AuthorizationRoles.All, UserType.NotService, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags); + await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "de", "de", await TranslationBiz.TranslationNameToIdStaticAsync("de"), KnownUserTags); + await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "es", "es", await TranslationBiz.TranslationNameToIdStaticAsync("es"), KnownUserTags); + await SeedUserAsync(log, 1, AuthorizationRoles.BizAdmin | AuthorizationRoles.OpsAdmin, UserType.NotService, true, "fr", "fr", await TranslationBiz.TranslationNameToIdStaticAsync("fr"), KnownUserTags); #if(DEBUG) //PRIVACY TEST USER - this is used for a test to see if user info leaks into the logs @@ -798,12 +806,50 @@ namespace AyaNova.Util //Known customer type users KnownUserCustomerId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "Customer", "Customer", 0, KnownUserTags, null, NewObject.Id, null); KnownUserCustomerRestrictedId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, "CustomerRestricted", "CustomerRestricted", 0, KnownUserTags, null, NewObject.Id, null); + //5 units per customer + await SeedUnitAsync(log, 20, NewObject.Id);//5 times the customers or 5 units per customer } - } + + + //////////////////////////////// + //SHADOW UNITS "CUSTOMER" + // { - //VENDOR AND SUBCONTRACTORS + + + //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"; + + + + 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(); @@ -1474,6 +1520,7 @@ namespace AyaNova.Util public HashSet HashUserNames = new HashSet(); public List ServiceUserIds = new List(); + public List ShadowUnitIds = new List(); private int TotalSeededUsers = 0; public long KnownUserSubContractorId = 0; public long KnownUserSubContractorRestrictedId = 0; @@ -1481,6 +1528,7 @@ namespace AyaNova.Util public long KnownUserTechRestrictedId = 0; public long KnownUserCustomerId = 0; public long KnownUserCustomerRestrictedId = 0; + public long KnownCustomerForShadownUnitsId = 0; public async Task SeedUserAsync( @@ -1693,6 +1741,9 @@ namespace AyaNova.Util //10% chance (0-9) if (Fake.Random.Number(9) == 4) await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, null, null, 0, null, null, NewObject.Id, null); + + //5 units per customer + await SeedUnitAsync(log, 20, NewObject.Id);//5 times the customers or 5 units per customer } } } @@ -2021,17 +2072,19 @@ namespace AyaNova.Util public HashSet HashUnitNames = new HashSet(); - private int TotalSeededUnits = 0; + //private int TotalSeededUnits = 0; + private Dictionary> CustomerUnits = new Dictionary>(); + ////////////////////////////////////////////////////// //UNIT // - public async Task SeedUnitAsync(ILogger log, int count) + public async Task SeedUnitAsync(ILogger log, int count, long customerId) { DateTime seedStartWindow = DateTime.Now.AddYears(-10); DateTime seedEndWindow = DateTime.Now.AddYears(1); var WarrantyMonths = new[] { 1, 6, 12, 24, 36 }; var WarrantyTerms = new[] { "Parts only", "Parts and service", "Service only", "Shipping parts and service", "First month parts and service here; after is depot only" }; - + List unitsAddedThisRun = new List(); for (int x = 0; x < count; x++) { Unit o = new Unit(); @@ -2053,12 +2106,13 @@ namespace AyaNova.Util o.WarrantyTerms = Fake.PickRandom(WarrantyTerms); } - o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers); - o.UnitModelId = Fake.Random.Long(1, TotalSeededUnitModels); + 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 (Fake.Random.Number(1, 10) != 5) + if (TotalSeededVendors > 0 && Fake.Random.Number(1, 10) != 5) { o.BoughtHere = false; o.PurchasedFromVendorId = Fake.Random.Long(1, TotalSeededVendors); @@ -2105,15 +2159,21 @@ namespace AyaNova.Util { UnitBiz biz = UnitBiz.GetBiz(ct); var NewObject = await biz.CreateAsync(o); - TotalSeededUnits++; + if (NewObject == null) { var err = $"Seeder::SeedUnit error creating {o.Serial}\r\n{biz.GetErrorsAsString()}"; log.LogError(err); throw new System.Exception(err); } + + unitsAddedThisRun.Add(NewObject.Id); } } + + //add to customer owned units list + CustomerUnits.Add(customerId, unitsAddedThisRun); + } @@ -2141,6 +2201,7 @@ namespace AyaNova.Util o.Name = Fake.Commerce.ProductName(); } while (!HashUnitNames.Add(o.Name)); + //o.UnitId is shadow unit o.Active = true; o.Notes = Fake.Lorem.Sentence(); @@ -2172,6 +2233,29 @@ namespace AyaNova.Util log.LogError(err); throw new System.Exception(err); } + else + { + //make shadow unit + Unit u = new Unit(); + u.Serial = NewObject.Serial; + u.Name = NewObject.Name + " - Loaner shadow unit"; + u.Active = true; + u.Notes = "Shadow unit to track internal service for Loaner Unit"; + 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); + } + } } } } @@ -2195,7 +2279,7 @@ namespace AyaNova.Util o.Notes = Fake.Lorem.Sentence(); o.Tags = RandomTags(); o.DateRequested = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime(); - o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers); + o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers); o.RequestedByUserId = await SeedUserAsync(log, 1, AuthorizationRoles.Customer, UserType.Customer, true, null, null, 0, null, null, o.CustomerId, null); o.Status = CustomerServiceRequestStatus.Open; o.Priority = Fake.Random.Enum(); @@ -2536,7 +2620,7 @@ namespace AyaNova.Util o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow : woDate;//no created dates in future but want a range of past dates to show off age of wo o.CompleteByDate = woDate.AddDays(5); // o.CustomerContactName = "contact name here"; - o.CustomerId = Fake.Random.Long(1, TotalSeededCustomers); + o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers); using (AyContext ct = ServiceProviderProvider.DBContext) { @@ -2590,14 +2674,14 @@ namespace AyaNova.Util //UNITS var woItemUnit = new WorkOrderItemUnit() { - UnitId = Fake.Random.Long(1, TotalSeededUnits), + UnitId = GetRandomUnitForCustomer(o.CustomerId), Notes = Fake.Lorem.Sentence() }; woItem.Units.Add(woItemUnit); woItemUnit = new WorkOrderItemUnit() { - UnitId = Fake.Random.Long(1, TotalSeededUnits), + UnitId = GetRandomUnitForCustomer(o.CustomerId), Notes = Fake.Lorem.Sentence() }; woItem.Units.Add(woItemUnit); @@ -2868,7 +2952,7 @@ namespace AyaNova.Util var RepairCost = Fake.Random.Decimal(50, 1000); var woItemOutsideService = new WorkOrderItemOutsideService() { - UnitId = Fake.Random.Long(1, TotalSeededUnits), + UnitId = GetRandomUnitForCustomer(o.CustomerId), Notes = Fake.Lorem.Sentence(), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), @@ -2889,7 +2973,7 @@ namespace AyaNova.Util RepairCost = Fake.Random.Decimal(50, 1000); woItemOutsideService = new WorkOrderItemOutsideService() { - UnitId = Fake.Random.Long(1, TotalSeededUnits), + UnitId = GetRandomUnitForCustomer(o.CustomerId), Notes = Fake.Lorem.Sentence(), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), @@ -2981,6 +3065,23 @@ namespace AyaNova.Util } + private long GetRandomUnitForCustomer(long customerId) + { + var l = CustomerUnits.Where(x => x.Key == customerId).FirstOrDefault();//Fake.Random.Long(1, TotalSeededUnits); + var numUnits = l.Value.Count(); + var i = Fake.Random.Int(0, numUnits - 1); + return l.Value[i]; + } + + private long GetRandomCustomerId() + { + //return any random customer except for the shadow unit one + long ret = KnownCustomerForShadownUnitsId; + while (ret == KnownCustomerForShadownUnitsId) + ret = Fake.Random.Long(0, TotalSeededCustomers); + return ret; + } + ////////////////////////////////////////////////////////////////////////////////////////////////// }//eoc