public FiltreretOejebliksbilledeType Filter(VirkningType targetInterval) { return(new FiltreretOejebliksbilledeType() { AttributListe = new AttributListeType() { Egenskab = Filter <EgenskabType>(this.AttributListe.Egenskab, targetInterval), RegisterOplysning = Filter <RegisterOplysningType>(this.AttributListe.RegisterOplysning, targetInterval), LokalUdvidelse = null, SundhedOplysning = Filter <SundhedOplysningType>(this.AttributListe.SundhedOplysning, targetInterval), }, TilstandListe = this.TilstandListe, BrugervendtNoegleTekst = this.BrugervendtNoegleTekst, UUID = this.UUID, RelationListe = new RelationListeType() { Aegtefaelle = Filter <PersonRelationType>(this.RelationListe.Aegtefaelle, targetInterval), RegistreretPartner = Filter <PersonRelationType>(this.RelationListe.RegistreretPartner, targetInterval), Boern = Filter <PersonFlerRelationType>(this.RelationListe.Boern, targetInterval), Bopaelssamling = Filter <PersonFlerRelationType>(this.RelationListe.Bopaelssamling, targetInterval), ErstatningAf = Filter <PersonRelationType>(this.RelationListe.ErstatningAf, targetInterval), ErstatningFor = Filter <PersonFlerRelationType>(this.RelationListe.ErstatningFor, targetInterval), Fader = Filter <PersonRelationType>(this.RelationListe.Fader, targetInterval), Moder = Filter <PersonRelationType>(this.RelationListe.Moder, targetInterval), Foraeldremyndighedsboern = Filter <PersonFlerRelationType>(this.RelationListe.Foraeldremyndighedsboern, targetInterval), Foraeldremyndighedsindehaver = Filter <PersonRelationType>(this.RelationListe.Foraeldremyndighedsindehaver, targetInterval), LokalUdvidelse = this.RelationListe.LokalUdvidelse, RetligHandleevneVaergeForPersonen = Filter <PersonRelationType>(this.RelationListe.RetligHandleevneVaergeForPersonen, targetInterval), RetligHandleevneVaergemaalsindehaver = Filter <PersonFlerRelationType>(this.RelationListe.RetligHandleevneVaergemaalsindehaver, targetInterval) } }); }
public static TInterval[] MergeIntervals <TInterval>(params TInterval[] sourceIntervals) where TInterval : IRegisteredInterval { var sortedIntervals = sourceIntervals .OrderByDescending(oio => oio.StartTS.HasValue ? oio.StartTS.Value : DateTime.MinValue) .ThenByDescending(oio => oio.RegistrationDate.Value) .ToArray(); var ret = new List <TInterval>(); if (sortedIntervals.Length > 0) { ret.Add(sortedIntervals.First()); } foreach (var interval in sortedIntervals.Skip(1)) { if (VirkningType.ToStartDateTimeOrMinValue(interval.StartTS) < VirkningType.ToStartDateTimeOrMinValue(ret.First().StartTS)) { if (!interval.EndTS.HasValue || interval.EndTS.Value > VirkningType.ToStartDateTimeOrMinValue(ret.First().StartTS)) { interval.EndTS = VirkningType.ToStartDateTimeOrMinValue(ret.First().StartTS); } ret.Insert(0, interval); } else { // Cannot insert any previous intervals if latest inserted interval has no start date } } return(ret.ToArray()); }
public static T[] Filter <T>(T[] dataArray, VirkningType targetInterval) where T : ITypeWithVirkning { if (dataArray != null) { return(dataArray.Where(dataElement => dataElement.Virkning.Intersects(targetInterval)).ToArray()); } else { return(null); } }
public void CalculateVirkning() { this.Virkning = null; var partialVirkning = GetPropertyValuesOfType <VirkningType>(this); var partialVirkning2 = GetPropertyValuesOfType <TilstandVirkningType>(this) .Select(tv => tv.ToVirkningType()); var allVirknings = partialVirkning.Concat(partialVirkning2) .Where(v => !VirkningType.IsDoubleOpen(v)); // TODO: Check this this.Virkning = allVirknings.ToArray(); }
public PersonRelationType ToPersonRelationType(Func <string, Guid> cpr2uuidFunc, bool forPreviousInterval) { return(new PersonRelationType() { ReferenceID = UnikIdType.Create(cpr2uuidFunc(ToSpousePnr())), CommentText = "", Virkning = VirkningType.Create( forPreviousInterval ? null : _CivilStatus.ToStartTS(), forPreviousInterval ? _CivilStatus.ToStartTS() : _CivilStatus.ToEndTS() ) }); }
public static bool IsDoubleOpen(VirkningType v) { if (v == null) { return(true); } if (!TidspunktType.ToDateTime(v.FraTidspunkt).HasValue&& !TidspunktType.ToDateTime(v.TilTidspunkt).HasValue) { return(true); } return(false); }
public static TRelation Create <TRelation>(Guid targetUuid, DateTime?fromDate, DateTime?toDate) where TRelation : IPersonRelationType, new() { if (targetUuid != Guid.Empty) { return(new TRelation() { //TODO: Add comment text CommentText = null, CprNumber = null, ReferenceID = UnikIdType.Create(targetUuid), // TODO: Fill virkning object from parameters Virkning = VirkningType.Create(fromDate, toDate) }); } else { throw new ArgumentNullException("targetUuid"); } }
public static TRelation Create <TRelation>(string cprNumber, DateTime?fromDate, DateTime?toDate) where TRelation : IPersonRelationType, new() { if (!string.IsNullOrEmpty(cprNumber)) { return(new TRelation() { //TODO: Add comment text CommentText = null, CprNumber = cprNumber, ReferenceID = null, // TODO: Fill virkning object from parameters Virkning = VirkningType.Create(fromDate, toDate) }); } else { throw new ArgumentNullException("cprNumber"); } }
public bool Intersects(VirkningType otherEffect) { var v1 = VirkningType.Create(this.FraTidspunkt.ToDateTime(), this.TilTidspunkt.ToDateTime()); var v2 = VirkningType.Create(otherEffect.FraTidspunkt.ToDateTime(), otherEffect.TilTidspunkt.ToDateTime()); foreach (var v in new VirkningType[] { v1, v2 }) { if (!v.FraTidspunkt.ToDateTime().HasValue) { v.FraTidspunkt = TidspunktType.Create(DateTime.MinValue); } if (!v.TilTidspunkt.ToDateTime().HasValue) { v.TilTidspunkt = TidspunktType.Create(DateTime.MaxValue); } } return(v1.FraTidspunkt.ToDateTime().Value < v2.TilTidspunkt.ToDateTime().Value && v2.FraTidspunkt.ToDateTime().Value < v1.TilTidspunkt.ToDateTime().Value); }
public static VirkningType Compose(params VirkningType[] partialEffects) { if (partialEffects == null || partialEffects.Where(ef => ef == null || ef.FraTidspunkt == null || ef.TilTidspunkt == null).Count() > 0) { throw new ArgumentNullException("partialEffects"); } // TODO: What is the default value for DateTime? in case input array is empty? var fromDate = partialEffects .Where(pe => pe.FraTidspunkt.ToDateTime().HasValue) .Select(pe => pe.FraTidspunkt.ToDateTime()) .OrderBy(d => d.Value) .FirstOrDefault(); var to = partialEffects .Where(pe => pe.TilTidspunkt.ToDateTime().HasValue) .Select(pe => pe.TilTidspunkt.ToDateTime()) .OrderByDescending(d => d.Value) .FirstOrDefault(); return(VirkningType.Create(fromDate, to)); }
public static FiltreretOejebliksbilledeType Merge(PersonIdentifier pId, VirkningType targetVirkning, RegistreringType1[] oioRegs) { return(new FiltreretOejebliksbilledeType() { AttributListe = new AttributListeType() { Egenskab = RegistreringType1.MergeIntervals <EgenskabType>(oioRegs, targetVirkning, oio => oio.AttributListe.Egenskab), RegisterOplysning = RegistreringType1.MergeIntervals <RegisterOplysningType>(oioRegs, targetVirkning, oio => oio.AttributListe.RegisterOplysning), SundhedOplysning = RegistreringType1.MergeIntervals <SundhedOplysningType>(oioRegs, targetVirkning, oio => oio.AttributListe.SundhedOplysning), LokalUdvidelse = null }, RelationListe = new RelationListeType() { Aegtefaelle = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Aegtefaelle), Boern = MergeIntervals <PersonFlerRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Boern), Bopaelssamling = MergeIntervals <PersonFlerRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Bopaelssamling), ErstatningAf = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.ErstatningAf), ErstatningFor = MergeIntervals <PersonFlerRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.ErstatningFor), Fader = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Fader), Foraeldremyndighedsboern = MergeIntervals <PersonFlerRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Foraeldremyndighedsboern), Foraeldremyndighedsindehaver = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Foraeldremyndighedsindehaver), LokalUdvidelse = null, Moder = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.Moder), RegistreretPartner = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.RegistreretPartner), RetligHandleevneVaergeForPersonen = MergeIntervals <PersonRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.RetligHandleevneVaergeForPersonen), RetligHandleevneVaergemaalsindehaver = MergeIntervals <PersonFlerRelationType>(oioRegs, targetVirkning, oio => oio.RelationListe.RetligHandleevneVaergemaalsindehaver), }, TilstandListe = new TilstandListeType() { }, BrugervendtNoegleTekst = pId.CprNumber, UUID = pId.UUID.Value.ToString() }); }
public void OrderByStartDate(bool ascending) { if (AttributListe != null) { AttributListe.Egenskab = VirkningType.OrderByStartDate <EgenskabType>(AttributListe.Egenskab, ascending); AttributListe.RegisterOplysning = VirkningType.OrderByStartDate <RegisterOplysningType>(AttributListe.RegisterOplysning, ascending); AttributListe.SundhedOplysning = VirkningType.OrderByStartDate <SundhedOplysningType>(AttributListe.SundhedOplysning, ascending); } if (RelationListe != null) { RelationListe.Aegtefaelle = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.Aegtefaelle, ascending); RelationListe.Boern = VirkningType.OrderByStartDate <PersonFlerRelationType>(RelationListe.Boern, ascending); RelationListe.Bopaelssamling = VirkningType.OrderByStartDate <PersonFlerRelationType>(RelationListe.Bopaelssamling, ascending); RelationListe.ErstatningAf = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.ErstatningAf, ascending); RelationListe.ErstatningFor = VirkningType.OrderByStartDate <PersonFlerRelationType>(RelationListe.ErstatningFor, ascending); RelationListe.Fader = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.Fader, ascending); RelationListe.Foraeldremyndighedsboern = VirkningType.OrderByStartDate <PersonFlerRelationType>(RelationListe.Foraeldremyndighedsboern, ascending); RelationListe.Foraeldremyndighedsindehaver = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.Foraeldremyndighedsindehaver, ascending); RelationListe.Moder = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.Moder, ascending); RelationListe.RegistreretPartner = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.RegistreretPartner, ascending); RelationListe.RetligHandleevneVaergeForPersonen = VirkningType.OrderByStartDate <PersonRelationType>(RelationListe.RetligHandleevneVaergeForPersonen, ascending); RelationListe.RetligHandleevneVaergemaalsindehaver = VirkningType.OrderByStartDate <PersonFlerRelationType>(RelationListe.RetligHandleevneVaergemaalsindehaver, ascending); } }
public VirkningType ToVirkningType() { return(VirkningType.Create(this.StartTS, this.EndTS)); }
public static TInterval[] CreateFromData <TInterval>(IQueryable <ITimedType> dataObjects, DataTypeTags[] allTags) where TInterval : Interval, new() { dataObjects = dataObjects.Where(o => allTags.Contains(o.Tag)); // Filter objects based on correction markers dataObjects = CorrectionMarker.Filter(dataObjects); // In case we have no correction records for history, check for possible overwrites dataObjects = Overwrite.Filter(dataObjects); // TODO: Also filter out objects that have StartDate<EndDate and an uncertainty marker on either dates (Like some HistoricalChurchInformation records) // sort by start date var sortedByStartDate = dataObjects .Select(o => new { StartTS = VirkningType.ToStartDateTimeOrMinValue(o.ToStartTS()), Object = o }) .OrderBy(o => o.StartTS) .ToArray(); var ret = new List <TInterval>(); // Group by start date foreach (var dataObject in sortedByStartDate) { var currentInterval = ret.LastOrDefault(); bool sameInterval = currentInterval != null && ( (dataObject.StartTS == currentInterval.StartTS.Value) || ( currentInterval.StartDate.Value == currentInterval.StartTS.Value && dataObject.StartTS.Date == currentInterval.StartDate ) ); if (sameInterval) { currentInterval.Data.Add(dataObject.Object); if (currentInterval.StartDate.Value == currentInterval.StartTS.Value) { currentInterval.StartTS = dataObject.StartTS; } } else { currentInterval = new TInterval() { StartTS = dataObject.StartTS, EndTS = null, Data = new List <ITimedType>(new ITimedType[] { dataObject.Object }) }; ret.Add(currentInterval); } } // Filter to only intervals that either have a non null start or that have objects that can mark interval start with null value ret = ret.Where(intvl => intvl.Data.Where(o => o.ToStartTS().HasValue || CreateIntervalIfStartTsIsNullAttribute.GetValue(o.GetType())).FirstOrDefault() != null).ToList(); // Fill the missing information foreach (var currentInterval in ret) { var missingTags = allTags.Where(tag => currentInterval.Data.Where(o => o.Tag == tag).Count() == 0); foreach (var missingTag in missingTags) { var missingTagObject = dataObjects.Where( o => o.Tag == missingTag && Utilities.Dates.DateRangeIncludes(o.ToStartTS(), o.ToEndTS(), currentInterval.StartTS) ).FirstOrDefault(); if (missingTagObject != null) { currentInterval.Data.Add(missingTagObject); } } } // Now set the end dates for (int i = 0; i < ret.Count; i++) { var currentInterval = ret[i]; if (currentInterval.StartTS == DateTime.MinValue) { currentInterval.StartTS = null; } // TODO: Do now allow Protection intervals to set end date for the last interval. Does that differ if the end date is in the future? currentInterval.EndTS = currentInterval.Data.Where(o => o.ToEndTS().HasValue).Select(o => o.ToEndTS()).Min(); if (i < ret.Count - 1) { var nextInterval = ret[i + 1]; if (currentInterval.EndTS == null || currentInterval.EndTS > nextInterval.StartTS) { currentInterval.EndTS = nextInterval.StartTS; } } } // Now extend the last interval if it was closed by a type that cannot close open ends var lastInterval = ret.LastOrDefault(); if (lastInterval != null && lastInterval.EndTS.HasValue) { var suggestedData = lastInterval.Data.Where(dataObject => CannotCloseOpenEndIntervalsAttribute.GetValue(dataObject.GetType()) == false).ToList(); var suggestedEndDate = suggestedData.Where(d => d.ToEndTS().HasValue).Select(d => d.ToEndTS()).Max(); if ( suggestedData.Count < lastInterval.Data.Count && (!suggestedEndDate.HasValue || suggestedEndDate.Value > lastInterval.EndTS.Value) ) { var suggestedInterval = new TInterval() { Data = suggestedData, StartTS = lastInterval.EndTS, EndTS = suggestedEndDate }; ret.Add(suggestedInterval); } } return(ret.ToArray()); }
public static T[] MergeIntervals <T>(RegistreringType1[] personRegistrations, VirkningType targetInterval, Func <RegistreringType1, IEnumerable <T> > populator) where T : ITypeWithVirkning { var matchesByDate = personRegistrations .SelectMany(oio => { var pop = populator(oio); if (pop == null) { pop = new T[0].AsEnumerable(); } return(pop.Select(ro => new RegisteredIntervalVirkningWrapper <T>(ro, oio.Tidspunkt.ToDateTime(), oio.BrokerUpdateDate))); }) .Where(ro => targetInterval.Intersects(ro.Item.Virkning)) .OrderBy(ro => ro.EffectiveStartTS) .ThenBy(ro => ro.RegistrationDate) .ThenBy(ro => ro.BrokerUpdateDate) .ToArray(); var ret = new List <RegisteredIntervalVirkningWrapper <T> >(); var isIMultipleInstanceTypeWithVirkning = typeof(IMultipleInstanceTypeWithVirkning).IsAssignableFrom(typeof(T)); // Now scan the effect periods from latest to first foreach (var currentInterval in matchesByDate.Reverse()) { var nextInterval = ret .Where(o => { if (isIMultipleInstanceTypeWithVirkning) { var oT = o.Item as IMultipleInstanceTypeWithVirkning; var currentT = currentInterval.Item as IMultipleInstanceTypeWithVirkning; return(oT.HasSameIntervalGroup(currentT)); } else { return(true); } } ) .FirstOrDefault(); if (nextInterval == null) { ret.Insert(0, currentInterval); } else { if (currentInterval.EffectiveStartTS < nextInterval.EffectiveStartTS) { if ( // Handling of a current married status followed by a dead marital status isIMultipleInstanceTypeWithVirkning && !currentInterval.StartTS.HasValue && currentInterval.EndTS.HasValue && nextInterval.StartTS.HasValue && !nextInterval.EndTS.HasValue && currentInterval.EndTS.Value > nextInterval.StartTS.Value) { nextInterval.EndTS = currentInterval.EndTS; } else { if (currentInterval.EffectiveEndTS > nextInterval.EffectiveStartTS) { currentInterval.EffectiveEndTS = nextInterval.EffectiveStartTS; } ret.Insert(0, currentInterval); } } } } return(ret.Select(o => o.Item).ToArray()); }