private void MakeNewImages()
        {
            if (LimitPresenter == null)
            {
                return;
            }

            _calcImage = LimitPresenter.TmpCalcImage;
            _selectedTemperatureProfile = LimitPresenter.PreviewTemperatureProfile;
            _geographicLocation         = LimitPresenter.PreviewGeographicLocation;
            if (LimitPresenter.ThisTimeLimit.RootEntry == null)
            {
                throw new LPGException("root entry was null");
            }
            _rootEntry = LimitPresenter.ThisTimeLimit.RootEntry;
            _household = LimitPresenter.PreviewHousehold;
            TimeLimitPresenter p = null;

            if (Dispatcher == null || Thread.CurrentThread == Dispatcher.Thread)
            {
                p = LimitPresenter;
            }

            var t = new Thread(() => UpdatePictures(p));

            t.Start();
        }
        public ModularHouseholdPresenter([NotNull] ApplicationPresenter applicationPresenter, [NotNull] ModularHouseholdView view,
                                         [NotNull] ModularHousehold modularHousehold)
            : base(view, "ThisModularHousehold.HeaderString", modularHousehold, applicationPresenter)
        {
            _modularHousehold = modularHousehold;
            AssignTypes       = new ObservableCollection <object>();
            foreach (var value in Enum.GetValues(typeof(ModularHouseholdTrait.ModularHouseholdTraitAssignType)))
            {
                AssignTypes.Add(value);
            }

            if (_modularHousehold.DeviceSelection == null && DeviceSelections.Count > 0)
            {
                _modularHousehold.DeviceSelection = DeviceSelections[0];
            }

            _householdTraits = new ObservableCollection <HouseholdTrait>();
            FilterTraits(string.Empty, null);
            RefreshLivingPatterns();
            RefreshUsedIn();
            try {
                if (ThisModularHousehold.Persons.Count > 0)
                {
                    ThisModularHousehold.RefreshPersonTimeEstimates();
                }
            }
            catch (Exception ex) {
                Logger.Exception(ex);
            }
        }
예제 #3
0
        private static List <Site> MakeTravelRouteSites([NotNull] ModularHousehold mhh, [NotNull] TravelRouteSet travelRouteSet,
                                                        [NotNull][ItemNotNull] out List <Site> householdSites)
        {
            //first figure out the sites in the travel route set
            List <Site> travelRouteSites = new List <Site>();

            foreach (var route in travelRouteSet.TravelRoutes)
            {
                travelRouteSites.Add(route.TravelRoute.SiteA);
                travelRouteSites.Add(route.TravelRoute.SiteB);
            }

            travelRouteSites = travelRouteSites.Distinct().ToList();
            //then look for all the sites in the household and make sure that they are covered by the travel route
            householdSites = new List <Site>();
            foreach (Location location in mhh.CollectLocations())
            {
                Site site = travelRouteSites.FirstOrDefault(x => x.Locations.Any(y => y.Location == location));
                if (site == null)
                {
                    throw new LPGException("Could not find a site for the location " + location.PrettyName +
                                           " in the travel route set " + travelRouteSet.PrettyName);
                }

                if (!householdSites.Contains(site))
                {
                    householdSites.Add(site);
                }
            }

            return(travelRouteSites);
        }
        private static House MakeHouse([NotNull] Simulator sim, [NotNull] GlobalOptions globalOptions, [NotNull] SimpleModularHousehold smhh,
                                       [NotNull] ModularHousehold mhh)
        {
            var housename = "House for " + mhh.Name;
            var myHouse   = sim.Houses.FindFirstByName(housename);

            if (myHouse != null)
            {
                sim.Houses.DeleteItem(myHouse);
            }
            var ht = sim.HouseTypes.FindFirstByName(smhh.HouseType, FindMode.IgnoreCase);

            if (ht == null)
            {
#pragma warning disable IDE0016 // Use 'throw' expression
                throw new LPGException("Housetype " + smhh.HouseType + " was not found in the database. Maybe a typo?");
#pragma warning restore IDE0016 // Use 'throw' expression
            }
            var house = sim.Houses.CreateNewItem(sim.ConnectionString);
            house.Name                = housename;
            house.Description         = "Created by CSV Import";
            house.CreationType        = CreationType.TemplateCreated;
            house.EnergyIntensityType = globalOptions.EnergyIntensityType;
            house.HouseType           = ht;
            var geoLoc = sim.GeographicLocations.FindFirstByName(globalOptions.GeoLocName, FindMode.IgnoreCase);
            house.GeographicLocation = geoLoc;

            var temperatureProfile =
                sim.TemperatureProfiles.FindFirstByName(globalOptions.TemperatureProfileName, FindMode.IgnoreCase);
            house.TemperatureProfile = temperatureProfile;
            house.SaveToDB();
            house.AddHousehold(mhh, null, null, null);
            house.SaveToDB();
            return(house);
        }
        private void CheckPersonDefinitions([NotNull] ModularHousehold chh)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }

            foreach (var person in chh.Persons)
            {
                var classifications = new Dictionary <string, HouseholdTrait>();
                foreach (var trait in chh.Traits)
                {
                    if (trait.DstPerson == person.Person)
                    {
                        if (classifications.ContainsKey(trait.HouseholdTrait.Classification))
                        {
                            string traits = Environment.NewLine + classifications[trait.HouseholdTrait.Classification].PrettyName;
                            traits += Environment.NewLine + trait.HouseholdTrait.PrettyName;
                            throw new DataIntegrityException(
                                      "The Person " + person.Person?.Name + " in the household " + chh.PrettyName +
                                      " has more than one trait of the classification " +
                                      trait.HouseholdTrait.Classification +
                                      ". Please fix:" + traits, chh);
                        }
                        classifications.Add(trait.HouseholdTrait.Classification, trait.HouseholdTrait);
                    }
                }
            }
        }
예제 #6
0
        public void GetCalcManagerModularHousehold03Test()
        {
            using (var wd = new WorkingDir(Utili.GetCurrentMethodAndClass()))
            {
                using (var db = new DatabaseSetup(Utili.GetCurrentMethodAndClass()))
                {
                    Config.IsInUnitTesting = true;
                    var sim = new Simulator(db.ConnectionString);
                    sim.MyGeneralConfig.ApplyOptionDefault(OutputFileDefault.ReasonableWithChartsAndPDF);
                    DeviceCategory light = null;
                    foreach (var deviceCategory in sim.DeviceCategories.MyItems)
                    {
                        deviceCategory.RefreshSubDevices();
                        if (deviceCategory.Name.Contains("Light"))
                        {
                            light = deviceCategory;
                        }
                    }
                    if (light != null)
                    {
                        Logger.Info(light.SubDevices.Count.ToString(CultureInfo.CurrentCulture));
                    }
                    sim.MyGeneralConfig.ApplyOptionDefault(OutputFileDefault.NoFiles);
                    sim.MyGeneralConfig.Enable(CalcOption.TotalsPerLoadtype);
                    sim.MyGeneralConfig.Enable(CalcOption.TotalsPerDevice);
                    sim.MyGeneralConfig.Enable(CalcOption.MakePDF);
                    sim.MyGeneralConfig.Enable(CalcOption.HouseholdContents);
                    sim.Should().NotBeNull();
                    var cmf = new CalcManagerFactory();
                    ModularHousehold chs3 = null;
                    foreach (var modularHousehold in sim.ModularHouseholds.MyItems)
                    {
                        if (modularHousehold.Name.StartsWith("CHS01", StringComparison.Ordinal))
                        {
                            chs3 = modularHousehold;
                        }
                    }
                    if (chs3 == null)
                    {
                        throw new LPGException("Could not find the household CHS01");
                    }
                    Logger.Info(chs3.ToString());
                    CalculationProfiler   calculationProfiler = new CalculationProfiler();
                    CalcStartParameterSet csps = new CalcStartParameterSet(sim.GeographicLocations[0],
                                                                           sim.TemperatureProfiles[0], chs3, EnergyIntensityType.Random, false,
                                                                           null, LoadTypePriority.Mandatory, null, null, null, sim.MyGeneralConfig.AllEnabledOptions(),
                                                                           new DateTime(2015, 1, 15), new DateTime(2015, 1, 18), new TimeSpan(0, 1, 0), ";", -1, new TimeSpan(0, 1, 0), false, false, false, 3, 3,
                                                                           calculationProfiler, wd.WorkingDirectory, false);

                    var cm = cmf.GetCalcManager(sim, csps, false);

                    cm.Run(ReportCancelFunc);
                    cm.Dispose();
                    db.Cleanup();
                }
                wd.CleanUp();
            }
        }
        private void CheckTraitsInHH([NotNull] ModularHousehold chh)
        {
            var persons = chh.Persons.Select(x => x.Person).ToList();

            foreach (var trait in chh.Traits)
            {
                if (trait.AssignType == ModularHouseholdTrait.ModularHouseholdTraitAssignType.Name &&
                    trait.HouseholdTrait.CollectAffordances(true).Count > 0)
                // no need to check traits without any affordances.
                {
                    var person = trait.DstPerson;
                    if (person == null)
                    {
                        throw new DataIntegrityException("No person was set in the trait " + trait.HouseholdTrait.Name, trait.HouseholdTrait);
                    }
                    if (!persons.Contains(person))
                    {
                        throw new DataIntegrityException(
                                  "The trait " + trait + " is assigned to " + person.PrettyName +
                                  " but that person is not in the household.", chh);
                    }

                    var foundone = false;
                    if (!trait.IsValidPerson(person))
                    {
                        throw new DataIntegrityException(
                                  "The trait " + trait.Name + " in the household " + chh.Name + " is assigned to " +
                                  trait.DstPerson + ", which seems to be invalid. This is probably not intended. " +
                                  "Please fix the desire age/gender limits or change the Person", chh);
                    }
                    if (!trait.HouseholdTrait.IsValidForPerson(person) && PerformCleanupChecks)
                    {
                        throw new DataIntegrityException(
                                  "The trait " + trait.Name + " in the household " + chh.Name + " is assigned to " +
                                  trait.DstPerson +
                                  ", which seems to be invalid. Not a single affordance in the trait is executeable. This is probably not intended. " +
                                  "Please fix the desire age/gender limits or change the Person", chh);
                    }
                    var affordances = trait.HouseholdTrait.CollectAffordances(true);
                    foreach (var aff in affordances)
                    {
                        if (aff.IsValidPerson(person))
                        {
                            foundone = true;
                        }
                    }
                    if (!foundone && PerformCleanupChecks)
                    {
                        throw new DataIntegrityException(
                                  "The trait " + trait.Name + " in the household " + chh.Name + " is assigned to " +
                                  trait.DstPerson +
                                  ", which doesn't fit any of the desires. This is probably not intended. " +
                                  "Please fix the desire age/gender limits or change the Person", chh);
                    }
                }
            }
        }
 public TravelRouteSetPresenter([NotNull] ApplicationPresenter applicationPresenter, [NotNull] TravelRouteSetView view,
                                [NotNull] TravelRouteSet routeSet) : base(view, "ThisRouteSet.Name", routeSet,
                                                                          applicationPresenter)
 {
     ThisRouteSet      = routeSet;
     _modularHousehold = Sim.ModularHouseholds[0];
     RefreshDataTable();
     RefreshRoutes();
 }
예제 #9
0
 public ChargingStationSetPresenter([NotNull] ApplicationPresenter applicationPresenter, [NotNull] ChargingStationSetView view,
                                    [NotNull] ChargingStationSet routeSet) : base(view, "ThisChargingStationSet.Name", routeSet,
                                                                                  applicationPresenter)
 {
     ThisChargingStationSet    = routeSet;
     _selectedModularHousehold = Sim.ModularHouseholds[0];
     _selectedTravelRouteSet   = Sim.TravelRouteSets[0];
     RefreshRelevantSites();
 }
        private static void PickATrait([NotNull] Random r,
                                       [NotNull] ModularHousehold chh,
                                       [ItemNotNull][NotNull] List <HouseholdTrait> potentialTraits,
                                       ref int traitexists,
                                       ref int classificationexists,
                                       ref int invalidForPerson,
                                       [NotNull] Person p,
                                       [CanBeNull] out HouseholdTrait trait,
                                       [ItemNotNull][NotNull] List <STTraitLimit> limits,
                                       ref int violatesLimit)
        {
            var trycount = 0;

            trait = null;
            while (trycount < 100 && trait == null)
            {
                var traitnumber       = r.Next(potentialTraits.Count);
                var success           = true;
                var traitsofThisPeron = chh.Traits.Where(t => t.DstPerson == p).Select(x => x.HouseholdTrait).ToList();
                var classifications   = traitsofThisPeron.Select(x => x.Classification).ToList();
                var traitcount        = chh.Traits.Count(x => x.HouseholdTrait == potentialTraits[traitnumber]);
                var maximumNumber     = potentialTraits[traitnumber].MaximumNumberInCHH;
                if (traitcount >= maximumNumber)
                {
                    success = false;
                    traitexists++;
                }

                if (traitsofThisPeron.Contains(potentialTraits[traitnumber]))
                {
                    success = false;
                    traitexists++;
                }
                else if (classifications.Contains(potentialTraits[traitnumber].Classification))
                {
                    success = false;
                    classificationexists++;
                }
                else if (!potentialTraits[traitnumber].IsValidForPerson(p))
                {
                    success = false;
                    invalidForPerson++;
                }
                else if (!limits.All(x => x.IsPermitted(potentialTraits[traitnumber])))
                {
                    success = false;
                    violatesLimit++;
                }

                if (success)
                {
                    trait = potentialTraits[traitnumber];
                }

                trycount++;
            }
        }
        private void CmbPreviewHouseholdSelectionChanged([CanBeNull] object sender,
                                                         [CanBeNull] SelectionChangedEventArgs e)
        {
            if (CmbPreviewHousehold.SelectedItem == null)
            {
                return;
            }

            _household = (ModularHousehold)CmbPreviewHousehold.SelectedItem;
            MakeNewImages();
        }
        public bool IsPermitted([NotNull] ModularHousehold chh)
        {
            var traits =
                chh.Traits.Where(x => x.HouseholdTrait == _trait).Select(x => x.HouseholdTrait).ToList();

            if (traits.Count <= PermittedCount - UsedCount)
            {
                return(true);
            }
            return(false);
        }
        public void RegisterMHH([NotNull] ModularHousehold chh)
        {
            var traits =
                chh.Traits.Where(x => x.HouseholdTrait == _trait).Select(x => x.HouseholdTrait).ToList();

            UsedCount += traits.Count;
            if (UsedCount > PermittedCount)
            {
                throw new LPGException("too many traits assigned!");
            }
        }
        public static List <ModularHousehold> GenerateHouseholds([NotNull] Simulator sim,
                                                                 bool generateSettlement,
                                                                 [ItemNotNull][NotNull] List <STTraitLimit> limits,
                                                                 [NotNull] HouseholdTemplate template)
        {
            if (template == null)
            {
                throw new LPGException("No template was assigned when calling the GenerateHouseholds-Function");
            }

            if (template.Persons.Count == 0)
            {
                Logger.Error("The household template " + template.Name + " has no persons. This isn't going to work.");
                return(new List <ModularHousehold>());
            }

            if (template.Vacations.Count == 0 && template.TemplateVacationType == TemplateVacationType.FromList)
            {
                Logger.Error("The household template " + template.Name + " has no vacations. This isn't going to work.");
                return(new List <ModularHousehold>());
            }

            try {
                var r               = new Random();
                var min             = 1;
                var max             = 0;
                var createdHH       = new List <ModularHousehold>();
                var numberofPersons = template.Persons.Count;
                for (var i = 0; i < template.Count; i++)
                {
                    ModularHousehold chh = null;
                    var i1 = i;
                    Logger.Get().SafeExecuteWithWait(() => chh = GenerateEmptyHousehold(sim, template, r, ref min, ref max, i1));
                    createdHH.Add(chh);
                    chh.SaveToDB();
                    AddDesiredTraits(sim, limits, template, r, numberofPersons, chh);
                    chh.SaveToDB();
                    foreach (var hhTemplateTag in template.TemplateTags)
                    {
                        chh.AddHouseholdTag(hhTemplateTag.Tag);
                    }

                    template.GeneratedHouseholds.Add(chh);
                    Logger.Info("Created household " + chh.Name);
                }

                MakeSettlement(sim, generateSettlement, template, min, max, createdHH);
                return(createdHH);
            }
            catch (Exception e) {
                Logger.Exception(e);
                throw;
            }
        }
 private static void CheckTagPersonAssignments([NotNull] ModularHousehold chh)
 {
     foreach (ModularHouseholdTrait modularHouseholdTrait in chh.Traits)
     {
         Person p = modularHouseholdTrait.DstPerson;
         if (p != null && !modularHouseholdTrait.IsValidPerson(p))
         {
             throw new DataIntegrityException("Person is not valid in the trait " + modularHouseholdTrait.HouseholdTrait.Name + " in the house " + chh.Name + ": Not a single affordance in the trait could be executed by the person, either due to age or gender restrictions on the affordances.", chh);
         }
     }
 }
예제 #16
0
        public void MakeTransportationDtos([NotNull] Simulator sim, [NotNull] ModularHousehold mhh,
                                           [CanBeNull] TransportationDeviceSet transportationDeviceSet,
                                           [CanBeNull] TravelRouteSet travelRouteSet,
                                           [CanBeNull] ChargingStationSet chargingStationSet,
                                           [NotNull][ItemNotNull] out List <CalcSiteDto> sites,
                                           [NotNull][ItemNotNull] out List <CalcTransportationDeviceDto> transportationDevices,
                                           [NotNull][ItemNotNull] out List <CalcTravelRouteDto> routes,
                                           [NotNull][ItemNotNull] List <CalcLocationDto> locations, [NotNull] HouseholdKey key)
        {
            if (transportationDeviceSet == null)
            {
                throw new LPGException("Transportationdeviceset was null");
            }
            if (travelRouteSet == null)
            {
                throw new LPGException("travelRouteSet was null");
            }
            if (chargingStationSet == null)
            {
                throw new LPGException("chargingStationSet was null");
            }

            if (travelRouteSet == null)
            {
                throw new LPGException("Travel Route Set was null");
            }

            var sitesFromAllTravelRoutes = MakeTravelRouteSites(mhh, travelRouteSet, out var householdSites);

            //check if all locations have sites
            CheckReachabilityofLocations(mhh.CollectLocations(), sitesFromAllTravelRoutes, mhh.Name,
                                         travelRouteSet.Name);
            //check if all sites are reachable from all other sites
            CheckRouteCompleteness(travelRouteSet, householdSites);
            // check if at least one route from each site to each other site is doable with the given transport
            CheckRouteTransportationDeviceCompleteness(travelRouteSet, householdSites, transportationDeviceSet);

            var categoriesDict = MakeCalcTransportationDeviceCategoryDtos(sim);

            sites = MakeCalcSiteDtos(householdSites, locations, categoriesDict, key, chargingStationSet);

            // figure out the transportation devices
            var selectedDevices = SelectTransportationDevices(transportationDeviceSet);

            //create the calc transportation devices
            //TODO: introduce load types
            transportationDevices = MakeTransportationDevices(selectedDevices, categoriesDict, key);

            routes = MakeTravelRoutes(travelRouteSet, householdSites, categoriesDict, sites, key);
        }
        private static void WriteHouseholdTestFunction(StreamWriter sw, ModularHousehold hh, int idx)
        {
            sw.WriteLine("");
            sw.WriteLine("[Fact]");
            sw.WriteLine("[Trait(UnitTestCategories.Category, UnitTestCategories.HouseholdTest)]");

            sw.WriteLine("public void TestHouseholdTest" + idx + "(){");
            sw.WriteLine("      const string hhguid = \"" + hh.Guid.StrVal + "\";");
            sw.WriteLine("      HouseJobTestHelper.RunSingleHouse(sim => {");
            sw.WriteLine("      var hj = HouseJobCalcPreparer.PrepareNewHouseForHouseholdTesting(sim,hhguid);");
            sw.WriteLine("      if (hj.CalcSpec?.CalcOptions == null) { throw new LPGException(); }");
            sw.WriteLine("      hj.CalcSpec.DefaultForOutputFiles = OutputFileDefault.Reasonable;");
            sw.WriteLine("return hj; }, x => {});");
            sw.WriteLine("}");
            sw.WriteLine("");
        }
 public void StartOneCalculationTest()
 {
     using (DatabaseSetup db = new DatabaseSetup(Utili.GetCurrentMethodAndClass()))
     {
         using (WorkingDir wd = new WorkingDir(Utili.GetCurrentMethodAndClass()))
         {
             Simulator        sim = new Simulator(db.ConnectionString);
             ModularHousehold hh  = sim.ModularHouseholds.It[0];
             // Guid g = Guid.NewGuid();
             CalculationOutcomesPresenter.StartOneCalculation(hh, sim.GeographicLocations[0], sim.TemperatureProfiles[0],
                                                              EnergyIntensityType.EnergySaving, wd.WorkingDirectory, sim,
                                                              false, null, null, null, false);
             db.Cleanup();
             wd.CleanUp();
         }
     }
 }
        public void SwapTagTest()
        {
            using (var db = new DatabaseSetup(Utili.GetCurrentMethodAndClass()))
            {
                Simulator              sim       = new Simulator(db.ConnectionString);
                ModularHousehold       mhh       = sim.ModularHouseholds.It[0];
                ModularHouseholdPerson mhhPerson = mhh.Persons[0];
                Person   dstPerson    = mhhPerson.Person;
                TraitTag dstTag       = sim.TraitTags.It[10];
                int      traitsBefore = mhh.Traits.Count;
                mhh.SwapPersons(mhhPerson, dstPerson, dstTag);
                int traitsAfter = mhh.Traits.Count;
                (traitsAfter).Should().Be(traitsBefore);

                db.Cleanup();
            }
        }
        private void CheckLivingPatternTraits([NotNull] ModularHousehold mhh, [NotNull] TraitTag tagForAll)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }

            foreach (var mhhPerson in mhh.Persons)
            {
                if (mhhPerson.TraitTag == null)
                {
                    throw new DataIntegrityException(
                              "The person " + mhhPerson.Person.PrettyName + " has no trait tag set.", mhh);
                }
                var traitsWithMissingTags = new List <HouseholdTrait>();
                var personTraits          = mhh.Traits.Where(x => x.DstPerson == mhhPerson.Person).ToList();
                foreach (var personTrait in personTraits)
                {
                    if (personTrait.HouseholdTrait == null)
                    {
                        throw new DataIntegrityException("HouseholdTrait was null");
                    }
                    if (personTrait.HouseholdTrait.Tags.Any(x => x.Tag == tagForAll))
                    {
                        //all is good since this trait was for everything
                        continue;
                    }
                    if (personTrait.HouseholdTrait.Tags.Any(x => mhhPerson.TraitTag.Name.StartsWith(x.Name)))
                    {
                        //the person will have the most specific tag, the traits can be more generic
                        continue;
                    }
                    traitsWithMissingTags.Add(personTrait.HouseholdTrait);
                }
                if (traitsWithMissingTags.Count > 0)
                {
                    var elementsToOpen = new List <BasicElement>
                    {
                        mhh
                    };
                    elementsToOpen.AddRange(traitsWithMissingTags);
                    throw new DataIntegrityException(
                              "The opened traits have no matching trait tag for " + mhhPerson.TraitTag, elementsToOpen);
                }
            }
        }
        public void ModularHouseholdJsonImportExporTest()
        {
            using (var db = new DatabaseSetup(Utili.GetCurrentMethodAndClass()))
            {
                Simulator        sim = new Simulator(db.ConnectionString);
                ModularHousehold mhh = sim.ModularHouseholds.It[0];
                var modjson          = mhh.GetJson();
                var newhh            = sim.ModularHouseholds.CreateNewItem(sim.ConnectionString);
                newhh.ImportFromJsonTemplate(modjson, sim);
                newhh.Should().BeEquivalentTo(mhh, options => options
                                              .Excluding(x => x.SelectedMemberPath.EndsWith(".Guid", StringComparison.OrdinalIgnoreCase) ||
                                                         x.SelectedMemberPath.EndsWith(".ID", StringComparison.OrdinalIgnoreCase) ||
                                                         x.SelectedMemberPath.EndsWith(".IntID", StringComparison.OrdinalIgnoreCase) ||
                                                         x.SelectedMemberPath.EndsWith(".ModularHouseholdID", StringComparison.OrdinalIgnoreCase) ||
                                                         x.SelectedMemberPath.EndsWith(".PrettyName", StringComparison.OrdinalIgnoreCase) ||
                                                         x.SelectedMemberPath.EndsWith(".HeaderString", StringComparison.OrdinalIgnoreCase)).Excluding(x => x.ID).Excluding(x => x.IntID));

                db.Cleanup();
            }
        }
예제 #22
0
        public TimeLimitPresenter([NotNull] ApplicationPresenter applicationPresenter, [NotNull] TimeLimitView view, [NotNull] TimeLimit timeLimit)
            : base(view, "ThisTimeLimit.HeaderString", timeLimit, applicationPresenter)
        {
            _dtv          = view;
            ThisTimeLimit = timeLimit;

            _previewGeographicLocation = Sim.GeographicLocations.MyItems[0];
            _previewTemperatureProfile = Sim.TemperatureProfiles.MyItems[0];
            if (Sim.ModularHouseholds.It.Count > 0)
            {
                _household = Sim.ModularHouseholds.MyItems[0];
            }
            MakeCalculatingImage();
            if (ThisTimeLimit.RootEntry == null)
            {
                ThisTimeLimit.AddTimeLimitEntry(null, Sim.DateBasedProfiles.MyItems);
            }
            RefreshAllPermissionLines();

            view.SetOneRow(ThisTimeLimit.RootEntry);
            RefreshUsedIn();
        }
        public void ModularHouseholdTest()
        {
            using (var db = new DatabaseSetup(Utili.GetCurrentMethodAndClass()))
            {
                db.ClearTable(ModularHousehold.TableName);
                db.ClearTable(ModularHouseholdTrait.TableName);
                db.ClearTable(ModularHouseholdPerson.TableName);
                var persons         = new ObservableCollection <Person>();
                var result          = new ObservableCollection <ModularHousehold>();
                var householdTraits = new ObservableCollection <HouseholdTrait>();
                var hht             = new HouseholdTrait("blub", null, "blub", db.ConnectionString, "none", 1, 100, 10, 1, 1,
                                                         TimeType.Day, 1, 1, TimeType.Day, 1, 0, EstimateType.Theoretical, "", Guid.NewGuid().ToStrGuid());
                hht.SaveToDB();
                householdTraits.Add(hht);
                var deviceSelections = new ObservableCollection <DeviceSelection>();
                var ds = new DeviceSelection("ds", null, "bla", db.ConnectionString, Guid.NewGuid().ToStrGuid());
                ds.SaveToDB();
                deviceSelections.Add(ds);
                var vacations = db.LoadVacations();
                var hhTags    = db.LoadHouseholdTags();
                var traitTags = db.LoadTraitTags();

                ModularHousehold.LoadFromDatabase(result, db.ConnectionString, householdTraits, deviceSelections, false,
                                                  persons, vacations, hhTags, traitTags);
                (result.Count).Should().Be(0);
                var chh = new ModularHousehold("blub", null, "blub", db.ConnectionString, ds, "src", null, null,
                                               EnergyIntensityType.Random, CreationType.ManuallyCreated, Guid.NewGuid().ToStrGuid());
                chh.SaveToDB();
                chh.AddTrait(hht, ModularHouseholdTrait.ModularHouseholdTraitAssignType.Age, null);
                chh.SaveToDB();
                result.Clear();
                ModularHousehold.LoadFromDatabase(result, db.ConnectionString, householdTraits, deviceSelections, false,
                                                  persons, vacations, hhTags, traitTags);
                (result.Count).Should().Be(1);
                (result[0].Traits.Count).Should().Be(1);
                db.Cleanup();
            }
        }
        private void CheckLivingPattern([NotNull] ModularHousehold mhh)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }
            foreach (var mhhPerson in mhh.Persons)
            {
                if (mhhPerson.TraitTag == null)
                {
                    continue;
                }
                var traits = mhh.Traits.Where(x => x.DstPerson == mhhPerson.Person).ToList();

                if (mhhPerson.TraitTag.Name.ToLower(CultureInfo.InvariantCulture).Contains("school"))
                {
                    //this is a school child
                    if (!traits.Any(x => x.PrettyName.ToLower(CultureInfo.InvariantCulture).Contains("school")))
                    {
                        throw new DataIntegrityException(
                                  "The " + mhhPerson.Name +
                                  " does not seem to have any school, even though the living pattern says it is a school child",
                                  mhh);
                    }
                }
                if (mhhPerson.TraitTag.Name.ToLower(CultureInfo.InvariantCulture).Contains("worker"))
                {
                    //this is an office worker
                    if (!traits.Any(x => x.PrettyName.ToLower(CultureInfo.InvariantCulture).Contains("work")))
                    {
                        throw new DataIntegrityException(
                                  "The " + mhhPerson.Name +
                                  " does not seem to have any work, even though the living pattern says it is an worker",
                                  mhh);
                    }
                }
            }
        }
        private void CheckCleanupNames([NotNull] ModularHousehold chh)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }
            var name = chh.Name;

            if (!name.StartsWith("x ", StringComparison.Ordinal) && name.Contains(" "))
            {
                name = name.Substring(0, name.IndexOf(" ", StringComparison.Ordinal));
                foreach (var person in chh.Persons)
                {
                    if (!person.Person.Name.StartsWith(name, StringComparison.CurrentCulture))
                    {
                        throw new DataIntegrityException(
                                  "In the modular household " + chh.Name + " the Person with the name " +
                                  person.Person.PrettyName +
                                  " doesn't fit. The CHxxx is not equal to the household. Please fix.", chh);
                    }
                }
            }
        }
        public static void ExportAsCSV([NotNull] ModularHousehold mhh, [NotNull] Simulator sim, [NotNull] string fullFileName)
        {
            var csv = sim.MyGeneralConfig.CSVCharacter;
            var sb  = new StringBuilder();

            sb.AppendLine("// This file was exported from LoadProfileGenerator.de");
            sb.AppendLine(
                "// It contains a household definition and can be used to easily create modified households based on the primary definition");
            sb.AppendLine(
                "// One example use could be modeling behavior changes as the occupants in an household age.");
            sb.AppendLine("// Syntax: Blank lines and all lines starting with // are ignored.");
            sb.AppendLine(
                "// a 1 means the trait applies in that case, every other value or blank means the trait doesn't apply.");
            sb.AppendLine(
                "// You can add as many cases as you want. The households in the LPG will then be labeled appropriately with the main household name and the case.");
            sb.AppendLine(
                "// Note that all names are case sensitive and the file format needs to be exactly the way it is since the parser is a bit fragile.");
            sb.AppendLine(
                "// If a person should not be added for a certain case, just remove all traits for that person in the appropriate column.");
            sb.AppendLine(
                "// Importing the same file twice will delete the previously created households, so be careful.");
            sb.AppendLine();
            sb.AppendLine();
            sb.AppendLine("Global Parameters");

            sb.Append("Household Name").Append(csv).AppendLine(mhh.PrettyName);
            sb.Append("Description").Append(csv).AppendLine(mhh.Description);
            sb.Append("DeviceSelection").Append(csv).AppendLine(mhh.DeviceSelection?.PrettyName);
            sb.Append("EnergyIntensity").Append(csv).Append(mhh.EnergyIntensityType).AppendLine();
            sb.Append("Geographic Location").Append(csv).AppendLine(sim.GeographicLocations.It[0].Name);
            sb.Append("Temperature Profile").Append(csv).AppendLine(sim.TemperatureProfiles.It[0].Name);

            var s = "";

            foreach (var tag in mhh.ModularHouseholdTags)
            {
                s += tag + csv;
            }
            sb.Append("Tags;").AppendLine(s);
            sb.AppendLine();
            sb.Append("Cases").Append(csv).Append("Case 1").Append(csv).Append("Case 2").Append(csv).Append("Case 3").Append(csv).Append("Case 4").Append(csv).AppendLine("Case 5");
            if (mhh.Vacation == null)
            {
                throw new LPGException("Vacation was null");
            }
            sb.Append("Vacation").Append(csv).AppendLine(MultiplyStrings(mhh.Vacation.PrettyName, csv));
            sb.Append("Housetype").Append(csv).AppendLine(MultiplyStrings(sim.HouseTypes[0].Name, csv));
            sb.AppendLine();
            var usedTraits = new HashSet <string>();

            foreach (var mhhPerson in mhh.Persons)
            {
                var p = mhhPerson.Person;
                sb.AppendLine();
                sb.Append("######").Append(csv).AppendLine(p.Name);
                sb.Append("Age").Append(csv).AppendLine(MakeCSVList(csv, p.Age, p.Age + 5, p.Age + 10, p.Age + 15, p.Age + 20));
                sb.Append("AverageSickdays").Append(csv).AppendLine(MakeCSVList(csv, 3, 5, 8, 10, 15));
                sb.Append("SicknessDuration").Append(csv).AppendLine(MakeCSVList(csv, 1, 1, 2, 5, 5));
                sb.Append("Gender").Append(csv).AppendLine(MultiplyStrings(p.Gender.ToString(), csv));
                string livingpattern = mhhPerson.TraitTag?.Name;
                if (livingpattern == null)
                {
                    livingpattern = "";
                }
                sb.Append("Living Pattern").Append(csv).AppendLine(MultiplyStrings(livingpattern, csv));
                sb.AppendLine();
                sb.Append("###").Append(csv).AppendLine("Traits");
                foreach (var trait in mhh.Traits.Where(x => x.DstPerson == p))
                {
                    if (!usedTraits.Contains(trait.HouseholdTrait.PrettyName))
                    {
                        usedTraits.Add(trait.HouseholdTrait.PrettyName);
                    }
                    sb.Append(trait.HouseholdTrait.PrettyName).Append(csv).AppendLine(MakeTraitPattern("1", csv));
                }
            }
            sb.AppendLine();
            sb.AppendLine();
            sb.Append("%%%%%%").Append(csv).AppendLine("Unused traits (listed here to make it easier to copy them to a person and fill in)");
            foreach (var trait in sim.HouseholdTraits.It)
            {
                if (!usedTraits.Contains(trait.PrettyName))
                {
                    sb.AppendLine(trait.PrettyName);
                }
            }
            var fi = new FileInfo(fullFileName);

            Logger.Info("Exporting to " + fi.FullName);
            using (var sw = new StreamWriter(fullFileName)) {
                sw.WriteLine(sb);
                sw.Close();
            }
        }
        public CalcHouseholdDto MakeCalcModularHouseholdDto([NotNull] Simulator sim, [NotNull] ModularHousehold mhh,
                                                            [NotNull] TemperatureProfile temperatureProfile, [NotNull] HouseholdKey householdKey, [NotNull] GeographicLocation geographicLocation,
                                                            [NotNull] out LocationDtoDict locationDict,
                                                            [CanBeNull] TransportationDeviceSet transportationDeviceSet,
                                                            [CanBeNull] TravelRouteSet travelRouteSet, EnergyIntensityType energyIntensity,
                                                            [CanBeNull] ChargingStationSet chargingStationSet)
        {
            //  _lf.RegisterKey(householdKey, mhh.PrettyName);
            var name = CalcAffordanceFactory.FixAffordanceName(mhh.Name, sim.MyGeneralConfig.CSVCharacter);

            if (geographicLocation == null)
            {
                throw new DataIntegrityException("no geographic Location was set");
            }
            var et = energyIntensity;

            if (et == EnergyIntensityType.AsOriginal)
            {
                et = mhh.EnergyIntensityType;
            }
            name = name + " " + householdKey.Key;
            var locations = mhh.CollectLocations();
            //var deviceLocationDict = new Dictionary<CalcLocation, List<IAssignableDevice>>();
            var deviceLocationDtoDict = new Dictionary <CalcLocationDto, List <IAssignableDevice> >();

            locationDict = new LocationDtoDict();
            List <DeviceCategoryDto> deviceCategoryDtos = new List <DeviceCategoryDto>();

            foreach (var deviceCategory in sim.DeviceCategories.It)
            {
                deviceCategoryDtos.Add(new DeviceCategoryDto(deviceCategory.FullPath, Guid.NewGuid().ToStrGuid()));
            }
            var locationDtos = _calcLocationDtoFactory.MakeCalcLocations(locations,
                                                                         householdKey,
                                                                         et, deviceLocationDtoDict, sim.DeviceActions.It, locationDict, deviceCategoryDtos);

            // persons

            if (mhh.Vacation == null)
            {
                throw new LPGException("Vacation was null");
            }

            var personDtos = _calcPersonDtoFactory.MakePersonDtos(mhh.Persons.ToList(), householdKey,
                                                                  mhh.Vacation.VacationTimeframes(), mhh.CollectTraitDesires(), mhh.Name);

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                _calcRepo.InputDataLogger.SaveList(personDtos.ConvertAll(x => (IHouseholdKey)x));
            }

            //mhh.Persons.ToList(),mhh.Vacation.VacationTimeframes(),  sim.MyGeneralConfig.RepetitionCount,householdKey, locs[0],name);
            //CalcPersonFactory.AddTraitDesires(mhh.CollectTraitDesires(), calcpersons,sim.MyGeneralConfig.TimeStepsPerHour, chh.Name, new Dictionary<Desire, SharedDesireValue>());
            //check if unhungry and unhungry join only have been added both
            //can't check it in the integrity checker, because that would mean having to duplicate the entire
            // desire collection logic

            /*  foreach (CalcPerson person in calcpersons) {
             *    var desires =
             *        person.PersonDesires.Desires.Values.Where(x => x.Name.ToLower().Contains("unhungry") || x.Name.ToLower().Contains("un-hungry")).ToList();
             *    if (desires.Count > 1) {
             *        throw new DataIntegrityException("More than one unhungry desire for the person " + person.Name, mhh);
             *    }
             * }*/

            // devices

            var deviceLocations = new List <DeviceLocationTuple>();

            foreach (var modularHouseholdTrait in mhh.Traits)
            {
                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (modularHouseholdTrait.HouseholdTrait != null)
                {
                    CollectDevicesFromTrait(modularHouseholdTrait.HouseholdTrait, deviceLocations);
                }
            }

            var deviceDtos = _calcDeviceDtoFactory.MakeCalcDevices(locationDtos,
                                                                   deviceLocations, et, householdKey, deviceLocationDtoDict, sim.DeviceActions.It, _ltDict, deviceCategoryDtos);

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                _calcRepo.InputDataLogger.SaveList(deviceDtos.ConvertAll(x => (IHouseholdKey)x));
            }

            //autodevs
            var autonomousDevices = mhh.CollectAutonomousDevices();

            if (mhh.Vacation == null)
            {
                throw new LPGException("Vacation was null");
            }

            var autoDevDtos = _calcDeviceDtoFactory.MakeCalcAutoDevDtos(autonomousDevices,
                                                                        energyIntensity, householdKey, mhh.Vacation.VacationTimeframes(),
                                                                        mhh.Name + "###" + householdKey,
                                                                        sim.DeviceActions.It, locationDict,
                                                                        temperatureProfile, geographicLocation, deviceCategoryDtos);

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                _calcRepo.InputDataLogger.SaveList(autoDevDtos.ConvertAll(x => (IHouseholdKey)x));
            }

            //affordances
            var affordancesAtLoc =
                new Dictionary <CalcLocationDto, List <AffordanceWithTimeLimit> >();

            foreach (var location in locations)
            {
                affordancesAtLoc.Add(locationDict.GetDtoForLocation(location), mhh.GetAllAffordancesForLocation(location));
            }
            if (mhh.Vacation == null)
            {
                throw new LPGException("Vacation was null");
            }

            List <CalcAffordanceDto> allAffordances = _calcAffordanceDtoFactory.SetCalcAffordances(locationDtos, temperatureProfile,
                                                                                                   _ltDict,
                                                                                                   geographicLocation, _random, sim.MyGeneralConfig.TimeStepsPerHour,
                                                                                                   sim.MyGeneralConfig.InternalStepSize, mhh.Vacation.VacationTimeframes(),
                                                                                                   mhh.Name + "###" + householdKey, sim.DeviceActions.MyItems, affordancesAtLoc, locationDict,
                                                                                                   out List <DateTime> bridgeDays, householdKey, deviceDtos, deviceCategoryDtos);

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                _calcRepo.InputDataLogger.SaveList(allAffordances.ConvertAll(x => (IHouseholdKey)x));
                _calcRepo.InputDataLogger.SaveList(_calcVariableRepositoryDtoFactory.GetAllVariableDtos()
                                                   .ConvertAll(x => (IHouseholdKey)x));
            }

            //                SaveVariableDefinitionsDtos(_calcVariableRepositoryDtoFactory.GetAllVariableDtos());
            //CalcVariableRepository variableRepository = _calcVariableRepositoryDtoFactory.GetRepository(householdKey);
            List <CalcSiteDto> sites = null;
            List <CalcTransportationDeviceDto> transportationDevices = null;
            List <CalcTravelRouteDto>          routes = null;

            if (_calcRepo.CalcParameters.TransportationEnabled)
            {
                _transportationDtoFactory.MakeTransportationDtos(sim, mhh, transportationDeviceSet,
                                                                 travelRouteSet, chargingStationSet,
                                                                 out sites, out transportationDevices,
                                                                 out routes, locationDtos, householdKey);
                if (_calcRepo.CalcParameters.IsSet(CalcOption.TransportationStatistics))
                {
                    _calcRepo.InputDataLogger.SaveList(sites.ConvertAll(x => (IHouseholdKey)x));
                    _calcRepo.InputDataLogger.SaveList(transportationDevices.ConvertAll(x => (IHouseholdKey)x));
                    _calcRepo.InputDataLogger.SaveList(routes.ConvertAll(x => (IHouseholdKey)x));
                }
            }
            var chh = new CalcHouseholdDto(name, mhh.IntID, temperatureProfile.Name, householdKey, Guid.NewGuid().ToStrGuid(),
                                           geographicLocation.Name,
                                           bridgeDays, autoDevDtos, locationDtos, personDtos, deviceDtos,
                                           allAffordances, mhh.Vacation.VacationTimeframes(),
                                           sites, routes, transportationDevices,
                                           mhh.Description);

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                _calcRepo.InputDataLogger.Save(householdKey, chh);
            }

            if (_calcRepo.CalcParameters.Options.Contains(CalcOption.HouseholdContents))
            {
                BridgeDayEntries bdes = new BridgeDayEntries(householdKey, chh.BridgeDays);
                _calcRepo.InputDataLogger.Save(householdKey, bdes);
            }

            return(chh);
        }
        private static void GeneralChecks([NotNull] ModularHousehold chh)
        {
            if (chh.Vacation == null)
            {
                throw new DataIntegrityException(
                          "The modular household " + chh.Name + " has no vacation set. Please choose one.", chh);
            }
            var allPersons = chh.AllPersons;

            if (allPersons.Count == 0)
            {
                throw new DataException("The household " + chh.Name + " has no persons!");
            }
            var minAge = allPersons.Select(x => x.Age).Min();
            var maxAge = allPersons.Select(x => x.Age).Max();

            if (chh.Vacation.MinimumAge > minAge || chh.Vacation.MaximumAge < maxAge)
            {
                throw new DataIntegrityException(
                          "The vacation " + chh.Vacation.PrettyName + " cannot be used in the household template " +
                          chh.PrettyName + " due to min/max age of the people. The persons have a minimum age of " +
                          minAge + " and a maximum age of " + maxAge, chh);
            }
            if (chh.Persons.Count == 0)
            {
                throw new DataIntegrityException("The modular household " + chh.Name + " has no people!", chh);
            }
            var traitCounts = new Dictionary <HouseholdTrait, int>();

            foreach (var ctrait in chh.Traits)
            {
                if (!traitCounts.ContainsKey(ctrait.HouseholdTrait))
                {
                    traitCounts.Add(ctrait.HouseholdTrait, 0);
                }
                traitCounts[ctrait.HouseholdTrait]++;
            }
            var personCount = chh.Persons.Count;

            foreach (var ctrait in chh.Traits)
            {
                var count = traitCounts[ctrait.HouseholdTrait];
                if (count > ctrait.HouseholdTrait.MaximumNumberInCHH)
                {
                    throw new DataIntegrityException(
                              "The trait " + ctrait.HouseholdTrait.Name + " is only allowed " +
                              ctrait.HouseholdTrait.MaximumNumberInCHH + " in a household, but " + chh.Name + " has " +
                              count +
                              ". Please fix.", chh);
                }
                if (personCount < ctrait.HouseholdTrait.MinimumPersonsInCHH ||
                    personCount > ctrait.HouseholdTrait.MaximumPersonsInCHH)
                {
                    throw new DataIntegrityException(
                              "The trait " + ctrait.HouseholdTrait.Name + " requires more or equal to " +
                              ctrait.HouseholdTrait.MinimumPersonsInCHH + " persons and less or equal to " +
                              ctrait.HouseholdTrait.MaximumPersonsInCHH + " persons in the household " + chh.PrettyName +
                              ". Please fix.", chh);
                }
            }
        }
        private void CheckMinimumPersonRequirements([NotNull] ModularHousehold modularHousehold,
                                                    [NotNull] ModularHouseholdPerson modularHouseholdPerson)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }

            if (modularHouseholdPerson.Person.Name.ToUpperInvariant().Contains("MAID") ||
                modularHouseholdPerson.Person.Description.ToUpperInvariant().Contains("MAID"))
            {
                return;
            }
            var traitsForPerson =
                modularHousehold.Traits.Where(x => x.DstPerson == modularHouseholdPerson.Person).ToList();
            var traitNames =
                traitsForPerson.Select(x => x.HouseholdTrait.PrettyName.ToUpperInvariant()).ToList();
            var shower = traitNames.Any(x => x.Contains("SHOWER"));

            if (!shower && modularHouseholdPerson.Person.Age > 10)
            {
                throw new DataIntegrityException(
                          "No shower in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var sleep = traitNames.Any(x => x.Contains("SLEEP"));

            if (!sleep)
            {
                throw new DataIntegrityException(
                          "No sleep in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var unhungry = traitNames.Any(x => x.Contains("UNHUNGRY"));

            if (!unhungry)
            {
                //var hungryTrait = sim.HouseholdTraits.It.First(x => x.Name.Contains("Desire for food, join only"));
                //modularHousehold.AddTrait(hungryTrait,ModularHouseholdTrait.ModularHouseholdTraitAssignType.Name, modularHouseholdPerson.Person);
                throw new DataIntegrityException("Unhungry not set in the household " + modularHousehold.PrettyName + " for " + modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var sickness = traitNames.Any(x => x.Contains("SICKNESS"));

            if (!sickness)
            {
                throw new DataIntegrityException(
                          "No sickness activities in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var toilet = traitNames.Any(x => x.Contains("TOILET"));

            if (!toilet && modularHouseholdPerson.Person.Age > 3)
            {
                throw new DataIntegrityException(
                          "No toilet activities in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var getready = traitNames.Any(x => x.Contains("READY"));

            if (!getready && modularHouseholdPerson.Person.Age > 5)
            {
                throw new DataIntegrityException(
                          "No get ready activities in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            var work   = traitNames.Any(x => x.Contains("WORK"));
            var school = traitsForPerson.Any(y => y.HouseholdTrait.Tags.Any(x => x.Name.ToUpperInvariant() == "CHILD / SCHOOL"));
            var outsideafternoonTraits =
                traitsForPerson.Where(
                    x =>
                    x.HouseholdTrait.Tags.Any(
                        y => y.Name.ToUpperInvariant().Contains("OUTSIDE AFTERNOON ENTERTAINMENT"))).ToList();

            if (outsideafternoonTraits.Count == 0 && !work && !school && modularHouseholdPerson.Person.Age > 10)
            {
                throw new DataIntegrityException(
                          "Not a single outside afternoon entertainment in the household " + modularHousehold.PrettyName +
                          " for " + modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
            if (school)
            {
                var homework = traitsForPerson.Any(x => x.HouseholdTrait.Name.ToLower(CultureInfo.InvariantCulture).Contains("homework"));
                if (!homework)
                {
                    throw new DataIntegrityException("No homework in the household " + modularHousehold.PrettyName
                                                     + " for the person " + modularHouseholdPerson.Person.PrettyName, modularHousehold);
                }
            }

            var outsideEveningTraits =
                traitsForPerson.Where(
                    x =>
                    x.HouseholdTrait.Tags.Any(
                        y => y.Name.ToUpperInvariant().Contains("OUTSIDE EVENING ENTERTAINMENT"))).ToList();

            if (outsideEveningTraits.Count == 0 && modularHouseholdPerson.Person.Age > 15)
            {
                throw new DataIntegrityException(
                          "Not a single outside evening entertainment in the household " + modularHousehold.PrettyName +
                          " for " + modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }

            var hobby =
                traitsForPerson.Where(x => x.HouseholdTrait.Tags.Any(y => y.Name.ToUpperInvariant().Contains("HOBBY")))
                .ToList();

            if (hobby.Count == 0 && modularHouseholdPerson.Person.Age > 15)
            {
                throw new DataIntegrityException(
                          "Not a single hobby in the household " + modularHousehold.PrettyName + " for " +
                          modularHouseholdPerson.Person.PrettyName, modularHousehold);
            }
        }
        private void CheckModularHouseholdsMinimum([NotNull] ModularHousehold modularHousehold)
        {
            if (!PerformCleanupChecks)
            {
                return;
            }
            if (modularHousehold.Name.StartsWith("O", StringComparison.Ordinal) ||
                modularHousehold.Name.StartsWith("x O", StringComparison.Ordinal))
            {
                return;
            }
            var laundry = modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("LAUNDRY"));

            if (!laundry)
            {
                throw new DataIntegrityException("No laundry in the household " + modularHousehold.PrettyName,
                                                 modularHousehold);
            }
            var dishwashing = modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("DISHWASH"));

            if (!dishwashing)
            {
                throw new DataIntegrityException("No dishwashing in the household " + modularHousehold.PrettyName,
                                                 modularHousehold);
            }
            var cleanBathroom =
                modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("CLEAN BATHROOM"));

            if (!cleanBathroom)
            {
                throw new DataIntegrityException(
                          "No bathroom cleaning in the household " + modularHousehold.PrettyName, modularHousehold);
            }
            var foodshopping =
                modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("FOOD SHOPPING"));

            if (!foodshopping)
            {
                throw new DataIntegrityException("No food shopping in the household " + modularHousehold.PrettyName,
                                                 modularHousehold);
            }
            var vacuum = modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("VACUUM"));

            if (!vacuum)
            {
                throw new DataIntegrityException("No vacuuming in the household " + modularHousehold.PrettyName,
                                                 modularHousehold);
            }
            var drying = modularHousehold.Traits.Any(x => x.PrettyName.ToUpperInvariant().Contains("DRY LAUNDRY"));

            if (!drying)
            {
                throw new DataIntegrityException("No laundry drying in the household " + modularHousehold.PrettyName,
                                                 modularHousehold);
            }

            foreach (var modularHouseholdPerson in modularHousehold.Persons)
            {
                CheckMinimumPersonRequirements(modularHousehold, modularHouseholdPerson);
            }
        }