/// <summary>
        /// Initializes a new instance of the <see cref="ComplexAnnotationReferenceCore"/> class.
        /// </summary>
        /// <param name="returnLatest">
        /// The return latest. 
        /// </param>
        /// <param name="version">
        /// The version. 
        /// </param>
        /// <param name="validFrom">
        /// The valid from. 
        /// </param>
        /// <param name="validTo">
        /// The valid to. 
        /// </param>
        public ComplexVersionReferenceCore(TertiaryBool returnLatest, string version, ITimeRange validFrom, ITimeRange validTo) 
        {
		    if (returnLatest != null)
            {
			   this._returnLatest = returnLatest;
		    }
	    	this._version = version;
	    	this._validFrom = validFrom;
		    this._validTo = validTo;
	    }
        /// <summary>
        /// Gets amount of correct answers in a given time range.
        /// </summary>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public async Task<int> GetAmountCorrectAsync(ITimeRange timeRange)
        {
            var start = new BsonDateTime(timeRange.Start);
            var end = new BsonDateTime(timeRange.End);

            var answersSuccessful =
                await
                    _repository.Find(
                        a => a.Correct == Convert.ToInt32(true) && a.SubmitDateTime > start && a.SubmitDateTime < end);

            return answersSuccessful.Count();
        }
 public bool CompareTo(RuleValue value1, RuleValue value2)
 {
     if (value1.IsTimeRange && value2.IsTime)
     {
         ITimeRange tr = value1.Value as ITimeRange;
         DateTime   dt = Convert.ToDateTime(value2.Value);
         SimpleTime st = SimpleTime.FromDateTime(dt);
         return(tr.ContainsTime(st));
     }
     else
     {
         throw new ArgumentException("CompareTo does not work with the value types provided.");
     }
 }
        /// <summary>
        /// Find out which user had made the most progress in a given time range.
        /// </summary>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public async Task<User> GetMostProgressAsync(ITimeRange timeRange)
        {
            var answers = await GetAnswersAsync(timeRange);

            var result = answers.GroupBy(answer => answer.UserId).Select(userAnswers => new
            {
                UserId = userAnswers.Key,
                Progress = userAnswers.Sum(answer => answer.Progress)
            })
                .OrderByDescending(progress => progress.Progress)
                .FirstOrDefault();

            return result == null ? null : new User { UserId = result.UserId };
        }
        /// <summary>
        ///     Get ratio of overlap between given Energiemenge and a reference.
        ///     Method is basically just another name for <see cref="GetOverlapFactor"/>
        /// </summary>
        /// <param name="em">Energiemenge</param>
        /// <param name="reference">reference time range</param>
        /// <param name="obisKz">OBIS</param>
        /// <param name="mengeneinheit">unit of measurement</param>
        /// <param name="wev">type of measurement</param>
        /// <param name="decimalRounding">post decimals</param>
        /// <returns>value between 0 (no overlap) and 1.0 (100% overlap)</returns>
        public static decimal GetCoverage(this BO.Energiemenge em, ITimeRange reference,
                                          Wertermittlungsverfahren wev, string obisKz, Mengeneinheit mengeneinheit, int decimalRounding = 10)
        {
            decimal exactResult;

            using (MiniProfiler.Current.Step(
                       $"calculating coverage for list with {em.Energieverbrauch.Count} entries."))
            {
                exactResult = em.Energieverbrauch
                              .Where(v => v.Einheit == mengeneinheit && v.Obiskennzahl == obisKz &&
                                     v.Wertermittlungsverfahren == wev)
                              .Sum(v => GetOverlapFactor(new TimeRange(v.Startdatum, v.Enddatum), reference, true));
            }

            return(Math.Round(exactResult, decimalRounding));
        }
Exemple #6
0
 /// <summary>
 /// Get percentage of time range covered by pure Energiemenge.
 /// </summary>
 /// <param name="em">pure Energiemenge</param>
 /// <param name="reference">time frame reference</param>
 /// <returns>value between 0 (only coverage for 1 point in time) and 1.0 (100% coverage)</returns>
 public static decimal GetCoverage(this BO4E.BO.Energiemenge em, ITimeRange reference)
 {
     using (MiniProfiler.Current.Step(nameof(GetCoverage)))
     {
         if (!IsPure(em))
         {
             throw new ArgumentException("The Energiemenge is not pure. Cannot determine parameters.");
         }
         if (em.Energieverbrauch.Count == 0)
         {
             return(0.0M);
         }
         Verbrauch v = em.Energieverbrauch.First <Verbrauch>();
         return(em.GetCoverage(reference, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit));
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeRangeMutableCore"/> class.
        /// </summary>
        /// <param name="immutable">
        /// The immutable. 
        /// </param>
        public TimeRangeMutableCore(ITimeRange immutable)
            : base(SdmxStructureType.GetFromEnum(SdmxStructureEnumType.TimeRange))
        {
            if (immutable.StartDate != null)
            {
                this.startDate = immutable.StartDate.Date;
            }

            if (immutable.EndDate != null)
            {
                this.endDate = immutable.EndDate.Date;
            }

            this._isIsRange = immutable.Range;
            this.isStartInclusive = immutable.StartInclusive;
            this.isEndInclusive = immutable.EndInclusive;
        }
Exemple #8
0
        public static ITimeRange Join(this ITimeRange value1, ITimeRange value)
        {
            if (!value.IsValid()
                || !value1.IsValid())
                throw new Exception("Invalid time range.");

            DateTime? newFromDate = value.FromDate > value1.FromDate ? value.FromDate : value1.FromDate;
            DateTime? newToDate = value.ToDate.HasValue ?
                (value1.ToDate.HasValue ?
                    (value.ToDate < value1.ToDate ? value.ToDate : value1.ToDate)
                    : value.ToDate)
                : value1.ToDate;

            TimeRange range = new TimeRange() { FromDate = newFromDate, ToDate = newToDate };

            return range.IsValid() ? range : new TimeRange();
        }
Exemple #9
0
        public void IntersectionPeriodsTimePeriodTest()
        {
            DateTime  now        = ClockProxy.Clock.Now;
            TimeRange timeRange1 = new TimeRange(new DateTime(now.Year, now.Month, 8), new DateTime(now.Year, now.Month, 18));
            TimeRange timeRange2 = new TimeRange(new DateTime(now.Year, now.Month, 10), new DateTime(now.Year, now.Month, 11));
            TimeRange timeRange3 = new TimeRange(new DateTime(now.Year, now.Month, 13), new DateTime(now.Year, now.Month, 15));
            TimeRange timeRange4 = new TimeRange(new DateTime(now.Year, now.Month, 9), new DateTime(now.Year, now.Month, 13));
            TimeRange timeRange5 = new TimeRange(new DateTime(now.Year, now.Month, 15), new DateTime(now.Year, now.Month, 17));

            TimePeriodCollection timePeriods = new TimePeriodCollection();

            timePeriods.Add(timeRange1);
            timePeriods.Add(timeRange2);
            timePeriods.Add(timeRange3);
            timePeriods.Add(timeRange4);
            timePeriods.Add(timeRange5);

            Assert.Equal(5, timePeriods.IntersectionPeriods(timeRange1).Count);
            Assert.Equal(3, timePeriods.IntersectionPeriods(timeRange2).Count);
            Assert.Equal(4, timePeriods.IntersectionPeriods(timeRange3).Count);
            Assert.Equal(4, timePeriods.IntersectionPeriods(timeRange4).Count);
            Assert.Equal(3, timePeriods.IntersectionPeriods(timeRange5).Count);

            ITimeRange            test1          = timeRange1.Copy(new TimeSpan(100, 0, 0, 0).Negate());
            ITimePeriodCollection insidePeriods1 = timePeriods.IntersectionPeriods(test1);

            Assert.Equal(0, insidePeriods1.Count);

            ITimeRange            test2          = timeRange1.Copy(new TimeSpan(100, 0, 0, 0));
            ITimePeriodCollection insidePeriods2 = timePeriods.IntersectionPeriods(test2);

            Assert.Equal(0, insidePeriods2.Count);

            TimeRange             test3          = new TimeRange(new DateTime(now.Year, now.Month, 9), new DateTime(now.Year, now.Month, 11));
            ITimePeriodCollection insidePeriods3 = timePeriods.IntersectionPeriods(test3);

            Assert.Equal(3, insidePeriods3.Count);

            TimeRange             test4          = new TimeRange(new DateTime(now.Year, now.Month, 14), new DateTime(now.Year, now.Month, 17));
            ITimePeriodCollection insidePeriods4 = timePeriods.IntersectionPeriods(test4);

            Assert.Equal(3, insidePeriods4.Count);
        }         // IntersectionPeriodsTimePeriodTest
        internal static IList <ITimeRange> GetLocalDailySlices(ITimeRange overallTimeRange, TimeZoneInfo tz = null)
        {
            if (overallTimeRange == null)
            {
                throw new ArgumentNullException(nameof(overallTimeRange), "overall time range must not be null");
            }
            if (tz == null)
            {
                tz = CentralEuropeStandardTime.CentralEuropeStandardTimezoneInfo;
            }
            if (overallTimeRange.Start.Kind == DateTimeKind.Unspecified)
            {
                throw new ArgumentException("TimeRange start must not have DateTimeKind.Unspecified",
                                            nameof(overallTimeRange));
            }
            if (overallTimeRange.End.Kind == DateTimeKind.Unspecified)
            {
                throw new ArgumentException("TimeRange end must not have DateTimeKind.Unspecified",
                                            nameof(overallTimeRange));
            }

            IList <ITimeRange> result = new List <ITimeRange>();

            if (!overallTimeRange.IsMoment)
            {
                result.Add(new TimeRange
                {
                    Start = overallTimeRange.Start,
                    End   = overallTimeRange.Start.AddDaysDST(1)
                });
                while (result.Last().End < overallTimeRange.End)
                {
                    result.Add(new TimeRange
                    {
                        Start = result.Last().Start.AddDaysDST(1),
                        End   = result.Last().End.AddDaysDST(1)
                    });
                }
            }

            return(result);
        }
        public override void Setup(DateTime newStart, DateTime newEnd)
        {
            base.Setup(newStart, newEnd);

            if (sequenceInterval is YearTimeRange)
            {
                var yearCount = (sequenceInterval as YearTimeRange).YearCount;
                sequenceInterval = new Years(newStart, yearCount);
            }
            else if (sequenceInterval is MonthTimeRange)
            {
                var monthCount = (sequenceInterval as MonthTimeRange).MonthCount;
                sequenceInterval = new Months(newStart, (YearMonth)newStart.Month, monthCount);
            }
            else
            {
                var duration = sequenceInterval.Duration + TimeSpec.MinPositiveDuration;
                sequenceInterval = new CalendarTimeRange(newStart, duration);
            }
        }
Exemple #12
0
        /// <summary>
        /// Sets StartTime and EndTime of a target range
        /// </summary>
        /// <param name="range">Target range</param>
        public void Convert(ITimeRange range)
        {
            DateTime now = DateTime.UtcNow;

            try
            {
                range.StartTime = DateTimeExtension.Max(MinValue, ConvertStartTime(now));
            }
            catch (ArgumentOutOfRangeException)
            {
                range.StartTime = MinValue;
            }
            try
            {
                range.EndTime = DateTimeExtension.Min(MaxValue, ConvertEndTime(now));
            }
            catch (ArgumentOutOfRangeException)
            {
                range.EndTime = MaxValue;
            }
        }
        /// <summary>
        ///     Test, if the single entries/intervals of the energieverbrauch array share the same duration and spacing in time.
        /// </summary>
        /// <param name="em">Energiemenge</param>
        /// <param name="reference">reference time frame</param>
        /// <param name="wev">Wertermittlungsverfahren</param>
        /// <param name="obis">OBIS-Kennzahl</param>
        /// <param name="me">Mengeneinheit</param>
        /// <param name="allowGaps">set true to allow gaps</param>
        /// <returns>
        ///     True, if all energieverbrauch entries have the same length and their start and enddatum are evenly spaced.
        ///     Also true, if there less than 2 entries in the energieverbrauch array.
        /// </returns>
        public static bool IsEvenlySpaced(this BO.Energiemenge em, ITimeRange reference, Wertermittlungsverfahren wev,
                                          string obis, Mengeneinheit me, bool allowGaps = false)
        {
            HashSet <TimeSpan> startEndDatumPeriods;

            using (MiniProfiler.Current.Step("finding time spans"))
            {
                startEndDatumPeriods = GetTimeSpans(em, wev, obis, me);
            }

            if (startEndDatumPeriods.Count < 2)
            {
                return(true);
            }
            if (allowGaps)
            {
                // each time difference must be a multiple of the smallest difference.
                using (MiniProfiler.Current.Step("Iterating over all time spans"))
                {
                    var minDiff = startEndDatumPeriods.Min().TotalSeconds;
                    foreach (var ts in startEndDatumPeriods)
                    {
                        if (Math.Abs(ts.TotalSeconds % minDiff) != 0)
                        {
                            // use profiler as logger:
                            using (MiniProfiler.Current.Step(
                                       $"Found TimeSpan {ts} with a duration of {ts.TotalSeconds}. This is no multiple of {minDiff} => not evenly spaced."))
                            {
                                return(false);
                            }
                        }
                    }
                }

                return(true);
            }

            // there must be only 1 time difference between all the elements
            return(startEndDatumPeriods.Count <= 1);
        }
        public static ITimeRange Join(this ITimeRange value1, ITimeRange value)
        {
            if (!value.IsValid() ||
                !value1.IsValid())
            {
                throw new Exception("Invalid time range.");
            }

            DateTime?newFromDate = value.FromDate > value1.FromDate ? value.FromDate : value1.FromDate;
            DateTime?newToDate   = value.ToDate.HasValue ?
                                   (value1.ToDate.HasValue ?
                                    (value.ToDate < value1.ToDate ? value.ToDate : value1.ToDate)
                    : value.ToDate)
                : value1.ToDate;

            TimeRange range = new TimeRange()
            {
                FromDate = newFromDate, ToDate = newToDate
            };

            return(range.IsValid() ? range : new TimeRange());
        }
        public void GetIntersectionTest()
        {
            TimeRange readOnlyTimeRange = new TimeRange(start, end);

            Assert.Equal(readOnlyTimeRange.GetIntersection(readOnlyTimeRange), new TimeRange(readOnlyTimeRange));

            TimeRange timeRange = new TimeRange(start, end);

            // before
            ITimeRange before1 = timeRange.GetIntersection(new TimeRange(start.AddHours(-2), start.AddHours(-1)));

            Assert.Null(before1);
            ITimeRange before2 = timeRange.GetIntersection(new TimeRange(start.AddMilliseconds(-1), start));

            Assert.Equal(before2, new TimeRange(start));
            ITimeRange before3 = timeRange.GetIntersection(new TimeRange(start.AddMilliseconds(-1), start.AddMilliseconds(1)));

            Assert.Equal(before3, new TimeRange(start, start.AddMilliseconds(1)));

            // after
            ITimeRange after1 = timeRange.GetIntersection(new TimeRange(end.AddHours(1), end.AddHours(2)));

            Assert.Null(after1);
            ITimeRange after2 = timeRange.GetIntersection(new TimeRange(end, end.AddMilliseconds(1)));

            Assert.Equal(after2, new TimeRange(end));
            ITimeRange after3 = timeRange.GetIntersection(new TimeRange(end.AddMilliseconds(-1), end.AddMilliseconds(1)));

            Assert.Equal(after3, new TimeRange(end.AddMilliseconds(-1), end));

            // intersect
            Assert.Equal(timeRange.GetIntersection(timeRange), timeRange);
            ITimeRange itersect1 = timeRange.GetIntersection(new TimeRange(start.AddMilliseconds(-1), end.AddMilliseconds(1)));

            Assert.Equal(itersect1, timeRange);
            ITimeRange itersect2 = timeRange.GetIntersection(new TimeRange(start.AddMilliseconds(1), end.AddMilliseconds(-1)));

            Assert.Equal(itersect2, new TimeRange(start.AddMilliseconds(1), end.AddMilliseconds(-1)));
        }         // GetIntersectionTest
Exemple #16
0
        private void SetAssignmentRange()
        {
            if (ContractShift == null)
            {
                return;
            }
            if (WorkDay == null ||
                WorkDay.ResourceShift == null)
            {
                return;
            }

            ITimeRange timeRange = ContractShift.WorkDayRange.GetIntersection(WorkDay.ResourceShift.WorkDayRange);

            if (timeRange == null)
            {
                return;
            }

            RangeFrom  = new TimeSpan(timeRange.Start.Hour, timeRange.Start.Minute, 0);
            RangeUntil = new TimeSpan(timeRange.End.Hour, timeRange.End.Minute, 0);
        }
        public override ITimePeriod GetTimePeriod(DateTime baseDate)
        {
            var        retrievedNumericValue = NumericValue.Match(Text).Value;
            var        numericValue          = int.Parse(retrievedNumericValue);
            var        namedEntity           = NamedEntity.Match(Text).Value;
            ITimeRange result = null;

            var lowerText = Text.ToLower();

            if (namedEntity == "minute")
            {
                result = new Minutes(baseDate.AddMinutes(-numericValue), numericValue);
            }
            else if (namedEntity == "hour")
            {
                result = new Hours(baseDate.AddHours(-numericValue), numericValue);
            }
            else if (namedEntity == "day")
            {
                result = new Days(baseDate.AddDays(-numericValue), numericValue);
            }
            else if (namedEntity == "week")
            {
                result = new Weeks(baseDate.AddDays(-numericValue * 7), numericValue);
            }
            else if (namedEntity == "month")
            {
                var moment = baseDate.AddMonths(-numericValue);
                result = new Months(moment, (YearMonth)moment.Month, numericValue);
            }
            else if (namedEntity == "year")
            {
                result = new Years(baseDate.AddYears(-numericValue), numericValue);
            }

            return(result);
        }
Exemple #18
0
        }         // GetTimeLineMoments

        // ----------------------------------------------------------------------
        private ITimeLineMomentCollection GetTimeLineMoments(ICollection <ITimePeriod> momentPeriods)
        {
            TimeLineMomentCollection timeLineMoments = new TimeLineMomentCollection();

            if (momentPeriods.Count == 0)
            {
                return(timeLineMoments);
            }

            // setup gap set with all start/end points
            ITimePeriodCollection intersections = new TimePeriodCollection();

            foreach (ITimePeriod momentPeriod in momentPeriods)
            {
                if (momentPeriod.IsMoment)
                {
                    continue;
                }

                // calculate the intersection between the periods
                ITimeRange intersection = limits.GetIntersection(momentPeriod);
                if (intersection == null || intersection.IsMoment)
                {
                    continue;
                }

                if (periodMapper != null)
                {
                    intersection = new TimeRange(MapPeriodStart(intersection.Start), MapPeriodEnd(intersection.End));
                }

                intersections.Add(intersection);
            }

            timeLineMoments.AddAll(intersections);
            return(timeLineMoments);
        }         // GetTimeLineMoments
Exemple #19
0
        public static bool ValidateTimeRange <T>(this List <T> ranges)
            where T : ITimeRange
        {
            for (int counter = 0; counter < ranges.Count; counter++)
            {
                ITimeRange range = ranges[counter];
                if (!range.ValidateTimeRange())
                {
                    return(false);
                }

                for (int subCounter = counter + 1; subCounter < ranges.Count; subCounter++)
                {
                    ITimeRange subRange = ranges[subCounter];

                    if ((subRange.StartTime <= range.StartTime & range.StartTime <= subRange.EndTime) || (subRange.StartTime < range.EndTime & range.EndTime <= subRange.EndTime) || (range.StartTime <= subRange.StartTime && range.EndTime >= subRange.EndTime))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////BUILD FROM MUTABLE OBJECT                 //////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyValuesCore"/> class.
        /// </summary>
        /// <param name="mutable">
        /// The mutable. 
        /// </param>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        public KeyValuesCore(IKeyValuesMutable mutable, ISdmxStructure parent)
            : base(SdmxStructureType.GetFromEnum(SdmxStructureEnumType.KeyValues), parent)
        {
            this.values = new List<string>();
            this.caseCadeList = new List<string>();
            this.id = mutable.Id;
            this.values.AddRange(mutable.KeyValues);

            foreach (string value in this.values)
            {
                if (mutable.IsCascadeValue(value))
                {
                    this.caseCadeList.Add(value);
                }
            }

            if (mutable.TimeRange != null)
            {
                this.timeRange = new TimeRangeCore(mutable.TimeRange, this);
            }
            Validate();
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////BUILD FROM V2.1 SCHEMA                 //////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyValuesCore"/> class.
        /// </summary>
        /// <param name="keyValueType">
        /// The key value type. 
        /// </param>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        public KeyValuesCore(ComponentValueSetType keyValueType, ISdmxStructure parent)
            : base(SdmxStructureType.GetFromEnum(SdmxStructureEnumType.KeyValues), parent)
        {
            this.values = new List<string>();
            this.caseCadeList = new List<string>();

            this.id = keyValueType.id;

            if (keyValueType.Value != null)
            {
                foreach (SimpleValueType dataKeyType in keyValueType.Value)
                {
                    this.values.Add(dataKeyType.TypedValue);
                    if (dataKeyType.cascadeValues)
                    {
                        this.caseCadeList.Add(dataKeyType.TypedValue);
                    }
                }
            }

            if (keyValueType.TimeRange != null)
            {
                this.timeRange = new TimeRangeCore(keyValueType.TimeRange, this);
            }
            Validate();
        }
Exemple #22
0
        static void Main(string[] args)
        {
            if (!EventLog.SourceExists(evtLogSrc))
            {
                EventLog.CreateEventSource(evtLogSrc, "Application");
            }
            try
            {
                var runStartTime = DateTime.Now;
                EventLog.WriteEntry(evtLogSrc, string.Format("Run started {0}.", runStartTime.ToString()), EventLogEntryType.Information);
                string   groupPrefix            = "";
                int      cycleOffset            = -1;
                string   accountsLstNm          = "Accounts";
                string   ratesLstNm             = "Rates";
                string   fixedConsumptionsLstNm = "Fixed Consumptions";
                string   consumptionsLstNm      = "Consumptions";
                string   chargesLstNm           = "Charges";
                string   billingPeriodStr       = "1m";
                bool     isCycleOpen            = false;
                bool?    incremental            = null;
                string   lastRunFileName        = "billease_last_run.log";
                DateTime cycleCalibrationDate   = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1, 0, 0, 0, DateTimeKind.Local);

                Dictionary <string, List <KeyValuePair <string, string> > > listColumnsToCopy = new Dictionary <string, List <KeyValuePair <string, string> > >();
                listColumnsToCopy.Add("Account", new List <KeyValuePair <string, string> >());
                listColumnsToCopy.Add("Rate", new List <KeyValuePair <string, string> >());
                listColumnsToCopy.Add("Consumption", new List <KeyValuePair <string, string> >());
                var options = new OptionSet()
                {
                    { "p|prefix_of_group=", v => groupPrefix = v }
                    , { "o|offset_of_cycle=", v => cycleOffset = int.Parse(v) }
                    , { "b|billing_period=", v => billingPeriodStr = v }
                    , { "d|cycle_calibration_date=", v => cycleCalibrationDate = DateTime.ParseExact(v, "yyyy-MM-dd", CultureInfo.InvariantCulture) }
                    , { "a|accounts_list_name=", v => accountsLstNm = v }
                    , { "r|rates_list_name=", v => ratesLstNm = v }
                    , { "f|fixed_consumptions_list_name=", v => fixedConsumptionsLstNm = v }
                    , { "c|consumptions_list_name=", v => consumptionsLstNm = v }
                    , { "h|charges_list_name=", v => chargesLstNm = v }
                    , { "A|account_columns_to_copy=", v => {
                            var src = v;
                            var dst = v;
                            if (v.Contains(":"))
                            {
                                src = v.Substring(0, v.IndexOf(":"));
                                dst = v.Substring(v.IndexOf(":") + 1);
                            }
                            listColumnsToCopy["Account"].Add(new KeyValuePair <string, string>(src, dst));
                        } }
                    , { "R|rate_columns_to_copy=", v => {
                            var src = v;
                            var dst = v;
                            if (v.Contains(":"))
                            {
                                src = v.Substring(0, v.IndexOf(":"));
                                dst = v.Substring(v.IndexOf(":") + 1);
                            }
                            listColumnsToCopy["Rate"].Add(new KeyValuePair <string, string>(src, dst));
                        } }
                    , { "C|consumption_columns_to_copy=", v => {
                            var src = v;
                            var dst = v;
                            if (v.Contains(":"))
                            {
                                src = v.Substring(0, v.IndexOf(":"));
                                dst = v.Substring(v.IndexOf(":") + 1);
                            }
                            listColumnsToCopy["Consumption"].Add(new KeyValuePair <string, string>(src, dst));
                        } }
                    , { "O|is_cycle_open=", v => isCycleOpen = Convert.ToBoolean(v) }
                    , { "i|incremental=", v => incremental = Convert.ToBoolean(v) }
                    , { "l|last_run_log_file_name=", v => lastRunFileName = v }
                };
                List <String> extraArgs = options.Parse(args);
                if (incremental == null)
                {
                    incremental = isCycleOpen;
                }
                ServicePointManager.ServerCertificateValidationCallback = MyCertHandler;
                var cc = new ClientContext(extraArgs[0]);
                cc.Credentials = System.Net.CredentialCache.DefaultCredentials;

                Match  billingPeriodMatch = Regex.Match(billingPeriodStr, @"(\d)([mdy])");
                int    billingPeriod      = 0;
                string billingPeriodUOM   = null;
                if (billingPeriodMatch.Success)
                {
                    billingPeriod    = Int32.Parse(billingPeriodMatch.Groups[1].Value);
                    billingPeriodUOM = billingPeriodMatch.Groups[2].Value;
                }

                var      billingCycleStart = DateTime.Now;
                TimeSpan s = billingCycleStart - cycleCalibrationDate;
                switch (billingPeriodUOM)
                {
                case "d":
                    billingCycleStart = cycleCalibrationDate.AddDays(s.TotalDays - (s.TotalDays % billingPeriod) + cycleOffset * billingPeriod);
                    break;

                case "m":
                    int monthDiff = (billingCycleStart.Year - cycleCalibrationDate.Year) * 12 + billingCycleStart.Month - cycleCalibrationDate.Month;
                    billingCycleStart = cycleCalibrationDate.AddMonths(monthDiff - (monthDiff % billingPeriod) + cycleOffset * billingPeriod);
                    break;

                case "y":
                    int yearDiff = (int)s.TotalDays / 365;
                    billingCycleStart = cycleCalibrationDate.AddYears(yearDiff - (yearDiff % billingPeriod) + cycleOffset * billingPeriod);
                    break;
                }
                DateTime nextBillingcycleStart = DateTime.Now;
                switch (billingPeriodUOM)
                {
                case "d":
                    nextBillingcycleStart = billingCycleStart.AddDays(billingPeriod);
                    break;

                case "m":
                    nextBillingcycleStart = billingCycleStart.AddMonths(billingPeriod);
                    break;

                case "y":
                    nextBillingcycleStart = billingCycleStart.AddYears(billingPeriod);
                    break;
                }
                TimeRange billingRange = new TimeRange(billingCycleStart, nextBillingcycleStart);

                // get last run timestamp
                var lastRunTs = new DateTime(1970, 01, 01);
                try
                {
                    string[] lines        = System.IO.File.ReadAllLines(lastRunFileName);
                    DateTime lastRunCycle = DateTime.Parse(lines[0]);
                    if (lastRunCycle.Date == billingCycleStart.Date)
                    {
                        lastRunTs = DateTime.Parse(lines[1]);
                    }
                }
                catch
                {
                }


                // delete consumptions associated with deleted fixed consumptions
                var query = new CamlQuery();
                query.ViewXml = string.Format(@"<View><Query>
   <Where>
    <And>
      <Eq>
          <FieldRef Name='Cycle' />
          <Value Type='DateTime'>{0}</Value>
      </Eq>
      <And>
        <IsNull>
           <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' />
        </IsNull>
        <Geq>
           <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' LookupId='TRUE' />
           <Value Type=”Lookup”>0</Value>
        </Geq>
      </And>
    </And>
   </Where>
</Query></View>", billingCycleStart.ToString("yyyy-MM-dd"));
                var consumptionLst         = cc.Web.Lists.GetByTitle(consumptionsLstNm);
                var consumptionFC          = consumptionLst.Fields;
                var consumptionDeletionLIC = consumptionLst.GetItems(query);
                cc.Load(consumptionFC);
                cc.Load(consumptionDeletionLIC);
                cc.ExecuteQuery();
                while (consumptionDeletionLIC.Count > 0)
                {
                    var consumptionLI = consumptionDeletionLIC[0];
                    consumptionLI.DeleteObject();
                    cc.ExecuteQuery();
                }

                // delete charges associated with deleted consumptions
                query         = new CamlQuery();
                query.ViewXml = string.Format(@"<View><Query>
   <Where>
    <And>
      <Eq>
          <FieldRef Name='Cycle' />
          <Value Type='DateTime'>{0}</Value>
      </Eq>
      <And>
        <IsNull>
           <FieldRef Name='Consumption_x0020_Ref' />
        </IsNull>
        <Geq>
           <FieldRef Name='Consumption_x0020_Ref' LookupId='TRUE' />
           <Value Type=”Lookup”>0</Value>
        </Geq>
      </And>
    </And>
   </Where>
</Query></View>", billingCycleStart.ToString("yyyy-MM-dd"));
                var chgLst             = cc.Web.Lists.GetByTitle(chargesLstNm);
                var chargesDeletionLIC = chgLst.GetItems(query);
                cc.Load(chargesDeletionLIC);
                cc.ExecuteQuery();
                while (chargesDeletionLIC.Count > 0)
                {
                    var chargeLI = chargesDeletionLIC[0];
                    chargeLI.DeleteObject();
                    cc.ExecuteQuery();
                }

                // populate or update consumptions from fixed consumptions
                query         = new CamlQuery();
                query.ViewXml = string.Format(@"
<View><Query>
   <Where>
     <And>
        <Or>
          <IsNull>
             <FieldRef Name='Service_x0020_Start' />
          </IsNull>
          <Lt>
             <FieldRef Name='Service_x0020_Start' />
             <Value Type='DateTime'>{0}</Value>
          </Lt>
        </Or>
        <Or>
          <IsNull>
             <FieldRef Name='Service_x0020_End' />
          </IsNull>
          <Gt>
             <FieldRef Name='Service_x0020_End' />
             <Value Type='DateTime'>{1}</Value>
          </Gt>
        </Or>
     </And>
   </Where>
</Query></View>", nextBillingcycleStart.ToString("yyyy-MM-dd"), billingCycleStart.ToString("yyyy-MM-dd"));
                var             fixedConsumptionsLst = cc.Web.Lists.GetByTitle(fixedConsumptionsLstNm);
                var             fixedConsumptionLIC  = fixedConsumptionsLst.GetItems(query);
                FieldCollection fixedConsumptionFC   = fixedConsumptionsLst.Fields;
                cc.Load(fixedConsumptionFC);
                cc.Load(fixedConsumptionLIC);
                try
                {
                    cc.ExecuteQuery();
                    foreach (var fixedConsumptionLI in fixedConsumptionLIC)
                    {
                        try
                        {
                            // check if consumption exists for the current billing cycle
                            var consumptionItemQuery = new CamlQuery();
                            consumptionItemQuery.ViewXml = string.Format(@"
<View><Query>
   <Where>
    <And>
        <Eq>
            <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' LookupId='TRUE' />
            <Value Type='Lookup'>{0}</Value>
        </Eq>
        <Eq>
            <FieldRef Name='Cycle' />
            <Value Type='DateTime'>{1}</Value>
        </Eq>
    </And>
   </Where>
</Query></View>", fixedConsumptionLI["ID"], billingCycleStart.ToString("yyyy-MM-dd"));
                            var _consumptionLIC = consumptionLst.GetItems(consumptionItemQuery);
                            cc.Load(_consumptionLIC);
                            cc.ExecuteQuery();
                            ListItem consumptionItem;
                            if (_consumptionLIC.Count > 0)
                            {
                                if (((DateTime)fixedConsumptionLI["Modified"]) < ((DateTime)_consumptionLIC[0]["Modified"]))
                                {
                                    continue;
                                }
                                consumptionItem = _consumptionLIC[0];
                            }
                            else
                            {
                                ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                                consumptionItem = consumptionLst.AddItem(itemCreateInfo);
                            }
                            foreach (Field field in fixedConsumptionFC)
                            {
                                if (field.FromBaseType && field.InternalName != "Title")
                                {
                                    continue;
                                }

                                if (consumptionFC.FirstOrDefault(f =>
                                                                 (!f.FromBaseType || f.InternalName == "Title") && f.InternalName == field.InternalName
                                                                 ) == null)
                                {
                                    continue;
                                }
                                consumptionItem[field.InternalName] = fixedConsumptionLI[field.InternalName];
                            }

                            // calculate proration
                            try
                            {
                                if (fixedConsumptionLI["Prorated"] != null &&
                                    fixedConsumptionLI["Prorated"].ToString().Contains("Yes")
                                    )
                                {
                                    DateTime serviceStart = DateTime.MinValue;
                                    DateTime serviceEnd   = DateTime.MaxValue;
                                    if (fixedConsumptionLI["Service_x0020_Start"] != null)
                                    {
                                        serviceStart = ((DateTime)fixedConsumptionLI["Service_x0020_Start"]).ToLocalTime();
                                    }
                                    if (fixedConsumptionLI["Service_x0020_End"] != null)
                                    {
                                        serviceEnd = ((DateTime)fixedConsumptionLI["Service_x0020_End"]).ToLocalTime();
                                    }
                                    TimeRange  serviceRange = new TimeRange(serviceStart, serviceEnd);
                                    ITimeRange overlap      = serviceRange.GetIntersection(billingRange);
                                    double     portion      = overlap.Duration.TotalDays / billingRange.Duration.TotalDays;
                                    if (fixedConsumptionLI["Quantity"] != null)
                                    {
                                        var proratedQty = ((double)fixedConsumptionLI["Quantity"]) * portion;
                                        if (fixedConsumptionLI["Prorated"].ToString() != "Yes")
                                        {
                                            proratedQty = Convert.ToInt32(proratedQty);
                                        }
                                        consumptionItem["Quantity"] = proratedQty;
                                    }
                                    if (fixedConsumptionLI["Amount"] != null)
                                    {
                                        consumptionItem["Amount"] = ((double)fixedConsumptionLI["Amount"]) * portion;
                                    }
                                }
                            }
                            catch
                            {
                                EventLog.WriteEntry(evtLogSrc, string.Format("Error calculating proration for fixed consumption with ID={0}", fixedConsumptionLI["ID"]), EventLogEntryType.Error);
                            }

                            consumptionItem["Cycle"] = billingCycleStart;
                            FieldLookupValue lookup = new FieldLookupValue();
                            lookup.LookupId = (int)fixedConsumptionLI["ID"];
                            consumptionItem["Fixed_x0020_Consumption_x0020_Re"] = lookup;
                            consumptionItem.Update();
                            cc.ExecuteQuery();
                        }
                        catch (Exception ex)
                        {
                            EventLog.WriteEntry(evtLogSrc, string.Format("Error creating consumption from fixed consumption with ID {0}.\n{1}", (int)fixedConsumptionLI["ID"], ex.ToString()), EventLogEntryType.Error);
                        }
                    }
                }
                catch (Exception ex)
                {
                    EventLog.WriteEntry(evtLogSrc, string.Format("Error creating consumption from fixed consumption.\n{0}", ex.ToString()), EventLogEntryType.Error);
                }

                // set incremental to false if there are updated accounts or rates since last run,
                foreach (var lstNm in new string[] { ratesLstNm, accountsLstNm })
                {
                    if (incremental != false)
                    {
                        query         = new CamlQuery();
                        query.ViewXml = string.Format(@"
<View>
  <Query>
    <Where>
      <Gt>
          <FieldRef Name='Modified' />
          <Value IncludeTimeValue='true' Type='DateTime'>{0}</Value>
      </Gt>
    </Where>
  </Query>
  <RowLimit>1</RowLimit>
</View>", lastRunTs.ToString("yyyy-MM-ddTHH:mm:ssZ"));
                        var lst = cc.Web.Lists.GetByTitle(lstNm);
                        var lic = lst.GetItems(query);
                        cc.Load(lic);
                        cc.ExecuteQuery();
                        if (lic.Count > 0)
                        {
                            incremental = false;
                        }
                    }
                }
                // populate or update charge from consumption
                query = new CamlQuery();
                string viewXml = null;
                if (incremental == false)
                {
                    viewXml = string.Format(@"
<View><Query>
   <Where>
      <Eq>
         <FieldRef Name='Cycle' />
         <Value Type='DateTime'>{0}</Value>
      </Eq>
   </Where>
</Query></View>", billingCycleStart.ToString("yyyy-MM-dd"));
                }
                else
                {
                    viewXml = string.Format(@"
<View><Query>
   <Where>
    <And>
      <Eq>
         <FieldRef Name='Cycle' />
         <Value Type='DateTime'>{0}</Value>
      </Eq>
      <Gt>
         <FieldRef Name='Modified' />
         <Value IncludeTimeValue='true' Type='DateTime'>{1}</Value>
      </Gt>
    </And>
   </Where>
</Query></View>", billingCycleStart.ToString("yyyy-MM-dd"), lastRunTs.ToString("yyyy-MM-ddTHH:mm:ssZ"));
                }
                query.ViewXml = viewXml;

                var consumptionLIC = consumptionLst.GetItems(query);
                cc.Load(consumptionLIC, items => items.IncludeWithDefaultProperties(
                            item => item["HasUniqueRoleAssignments"]
                            ));
                cc.Load(cc.Web.RoleDefinitions);
                var gc = cc.Web.SiteGroups;
                cc.Load(gc);
                cc.ExecuteQuery();
                var restReadRD = cc.Web.RoleDefinitions.GetByName("Restricted Read");
                var readRD     = cc.Web.RoleDefinitions.GetByName("Read");

                foreach (var consumptionLI in consumptionLIC)
                {
                    ListItem chgItem;
                    // check if charges exists
                    var chgItemQuery = new CamlQuery();
                    chgItemQuery.ViewXml = string.Format(@"
<View><Query>
   <Where>
      <Eq>
         <FieldRef Name='Consumption_x0020_Ref' LookupId='TRUE' />
         <Value Type='Lookup'>{0}</Value>
      </Eq>
   </Where>
</Query></View>", consumptionLI["ID"]);
                    var chgLIC = chgLst.GetItems(chgItemQuery);
                    cc.Load(chgLIC);
                    cc.ExecuteQuery();
                    if (chgLIC.Count > 0)
                    {
                        chgItem = chgLIC[0];
                        if (isCycleOpen && incremental != false && ((DateTime)consumptionLI["Modified"]) < ((DateTime)chgItem["Modified"]))
                        {
                            continue;
                        }
                        chgItem.ResetRoleInheritance();
                        cc.ExecuteQuery();
                    }
                    else
                    {
                        // create new charges item
                        ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                        chgItem = chgLst.AddItem(itemCreateInfo);
                    }

                    // get org item
                    var orgItemQuery = new CamlQuery();
                    orgItemQuery.ViewXml = string.Format(@"
<View><Query>
   <Where>
      <Eq>
         <FieldRef Name='ID' />
         <Value Type='Counter'>{0}</Value>
      </Eq>
   </Where>
</Query></View>", ((FieldLookupValue)consumptionLI["Account"]).LookupId);
                    var orgLst = cc.Web.Lists.GetByTitle(accountsLstNm);
                    var orgLIC = orgLst.GetItems(orgItemQuery);
                    cc.Load(orgLIC);
                    // get rate item
                    var rateItemQuery = new CamlQuery();
                    rateItemQuery.ViewXml = string.Format(@"<View><Query>
   <Where>
      <Eq>
         <FieldRef Name='ID' />
         <Value Type='Counter'>{0}</Value>
      </Eq>
   </Where>
</Query></View>", ((FieldLookupValue)consumptionLI["Rate"]).LookupId);
                    var rateLst = cc.Web.Lists.GetByTitle(ratesLstNm);
                    var rateLIC = rateLst.GetItems(rateItemQuery);
                    cc.Load(rateLIC);
                    cc.ExecuteQuery();
                    var orgItem  = orgLIC.First();
                    var rateItem = rateLIC.First();

                    chgItem["Account"]          = orgItem["Title"];
                    chgItem["Title"]            = consumptionLI["Title"];
                    chgItem["Cycle"]            = consumptionLI["Cycle"];
                    chgItem["Unit_x0020_Price"] = rateItem["Unit_x0020_Price"];
                    chgItem["Denominator"]      = rateItem["Denominator"];
                    chgItem["UOM"]      = rateItem["UOM"];
                    chgItem["Quantity"] = consumptionLI["Quantity"];
                    FieldLookupValue lookup = new FieldLookupValue();
                    lookup.LookupId = (int)consumptionLI["ID"];
                    chgItem["Consumption_x0020_Ref"] = lookup;

                    // the order of list enumeration is important
                    foreach (var lstNm in new string[] { "Account", "Rate", "Consumption" })
                    {
                        KeyValuePair <string, List <KeyValuePair <string, string> > > listColumnToCopy = new KeyValuePair <string, List <KeyValuePair <string, string> > >(lstNm, listColumnsToCopy[lstNm]);
                        if (listColumnToCopy.Value.Count <= 0)
                        {
                            continue;
                        }
                        ListItem item = null;
                        switch (listColumnToCopy.Key)
                        {
                        case "Account":
                            item = orgItem;
                            break;

                        case "Rate":
                            item = rateItem;
                            break;

                        case "Consumption":
                            item = consumptionLI;
                            break;
                        }
                        foreach (var columnNVP in listColumnToCopy.Value)
                        {
                            try
                            {
                                if (item[columnNVP.Key] != null)
                                {
                                    chgItem[columnNVP.Value] = item[columnNVP.Key];
                                }
                            }
                            catch
                            {
                                EventLog.WriteEntry(evtLogSrc, string.Format(@"Cannot copy column {0} in list {1} for consumption ID={2}", columnNVP.Key, listColumnToCopy.Key, consumptionLI["ID"]), EventLogEntryType.Error);
                            }
                        }
                    }

                    if (consumptionLI["Amount"] != null)
                    {
                        chgItem["Amount"] = consumptionLI["Amount"];
                    }
                    else if (consumptionLI["Quantity"] != null &&
                             rateItem["Denominator"] != null &&
                             rateItem["Unit_x0020_Price"] != null &&
                             rateItem["Denominator"] != null &&
                             (double)rateItem["Denominator"] > 0)
                    {
                        var normalizedQty = (double)consumptionLI["Quantity"] / (double)rateItem["Denominator"];
                        try
                        {
                            if (rateItem["Round_x0020_Up"] != null && rateItem["Round_x0020_Up"] as Nullable <bool> == true)
                            {
                                normalizedQty = Math.Ceiling((double)consumptionLI["Quantity"] / (double)rateItem["Denominator"]);
                            }
                        }
                        catch
                        {
                            EventLog.WriteEntry(evtLogSrc, string.Format("Error calculate round up for rate ID={0}, consumption ID={1}", rateItem["ID"], consumptionLI["ID"]), EventLogEntryType.Error);
                        }
                        chgItem["Amount"] = (double)rateItem["Unit_x0020_Price"] * normalizedQty;
                    }
                    if (chgItem.FieldValues.ContainsKey("Amount"))
                    {
                        chgItem.Update();
                        cc.ExecuteQuery();
                    }
                    else
                    {
                        EventLog.WriteEntry(evtLogSrc, "Cannot calculate amount for consumption item " + consumptionLI["ID"], EventLogEntryType.Error);
                    }

                    if (!isCycleOpen)
                    {
                        if (!consumptionLI.HasUniqueRoleAssignments)
                        {
                            consumptionLI.BreakRoleInheritance(true, false);
                            cc.ExecuteQuery();
                        }
                        cc.Load(consumptionLI.RoleAssignments, items => items.Include(
                                    ra => ra.RoleDefinitionBindings.Include(
                                        rdb => rdb.Name
                                        )
                                    ));
                        cc.ExecuteQuery();

                        foreach (var ra in consumptionLI.RoleAssignments)
                        {
                            bool addRead = false;
                            foreach (var rdbo in ra.RoleDefinitionBindings)
                            {
                                if (rdbo.Name == "Contribute")
                                {
                                    ra.RoleDefinitionBindings.Remove(rdbo);
                                    addRead = true;
                                }
                            }
                            if (addRead)
                            {
                                ra.RoleDefinitionBindings.Add(readRD);
                            }
                            ra.Update();
                        }
                        cc.ExecuteQuery();
                    }
                }

                var chargesLst = cc.Web.Lists.GetByTitle("Charges");
                var chargesLIC = chargesLst.GetItems(query);
                cc.Load(chargesLIC, items => items.Include(
                            item => item["Account"]
                            , item => item["HasUniqueRoleAssignments"]
                            ));
                cc.ExecuteQuery();
                foreach (var chargeLI in chargesLIC)
                {
                    if (!chargeLI.HasUniqueRoleAssignments)
                    {
                        chargeLI.BreakRoleInheritance(true, false);
                    }
                    foreach (var g in gc)
                    {
                        if (g.LoginName == (groupPrefix + chargeLI["Account"].ToString()))
                        {
                            var rdb = new RoleDefinitionBindingCollection(cc);
                            rdb.Add(restReadRD);
                            chargeLI.RoleAssignments.Add(g, rdb);
                            break;
                        }
                    }
                    cc.ExecuteQuery();
                }
                var runEndTime = DateTime.Now;
                EventLog.WriteEntry(evtLogSrc, string.Format("Run ended {0}, lasting {1} minutes.", runEndTime.ToString(), (runEndTime - runStartTime).TotalMinutes.ToString("0.00")), EventLogEntryType.Information);
                System.IO.File.Delete(lastRunFileName);
                System.IO.File.WriteAllLines(lastRunFileName, new string[] { billingCycleStart.ToShortDateString(), runStartTime.ToString() });
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(evtLogSrc, string.Format("{0}\n", ex.ToString()), EventLogEntryType.Error);
                throw;
            }
        }
Exemple #23
0
 public static bool IsJoin(this ITimeRange value1, ITimeRange value)
 {
     return !value.Join(value1).IsEmpty();
 }
Exemple #24
0
        public static TimeSpan GetDuration(this Verbrauch v)
        {
            ITimeRange tr = v.GetTimeRange();

            return(tr.Duration);
        }
Exemple #25
0
        public override ITimePeriod GetTimePeriod(DateTime baseDate)
        {
            var        date        = baseDate.Date;
            var        time        = baseDate.TimeOfDay;
            var        namedEntity = string.Empty;
            ITimeRange result      = null;

            var lowerText = Text.ToLower();

            if (lowerText == "today")
            {
                result = new Day(date);
            }
            else if (lowerText == "tonight")
            {
                result = GetTimeOfDayPeriod(TimeOfDay.Night, date);
            }
            else if (lowerText == "last night")
            {
                result = GetTimeOfDayPeriod(TimeOfDay.Night, date.AddDays(-1));
            }
            else if (lowerText.StartsWith("yesterday"))
            {
                if (lowerText == "yesterday")
                {
                    result = new Day(date.AddDays(-1));
                }
                else if (lowerText == "yesterday morning")
                {
                    result = GetTimeOfDayPeriod(TimeOfDay.Morning, date.AddDays(-1));
                }
                else if (lowerText == "yesterday afternoon")
                {
                    result = GetTimeOfDayPeriod(TimeOfDay.Afternoon, date.AddDays(-1));
                }
            }
            else if (lowerText.StartsWith("tomorrow"))
            {
                if (lowerText == "tomorrow")
                {
                    result = new Day(date.AddDays(1));
                }
                else if (lowerText == "tomorrow morning")
                {
                    result = GetTimeOfDayPeriod(TimeOfDay.Morning, date.AddDays(1));
                }
                else if (lowerText == "tomorrow afternoon")
                {
                    result = GetTimeOfDayPeriod(TimeOfDay.Afternoon, date.AddDays(1));
                }
                else if (lowerText == "tomorrow night")
                {
                    result = GetTimeOfDayPeriod(TimeOfDay.Night, date.AddDays(1));
                }
            }
            else if (lowerText.StartsWith("next ") || lowerText.StartsWith("last ") || lowerText.StartsWith("this"))
            {
                var pieces = lowerText.Split(' ');
                if (pieces.Length == 2)
                {
                    var inPast   = pieces[0] == "last";
                    var inFuture = pieces[0] == "next";
                    namedEntity = pieces[1];

                    if (namedEntity == "week")
                    {
                        result = new Week(date);
                        if (inPast)
                        {
                            result = (result as Week).GetPreviousWeek();
                        }
                        else if (inFuture)
                        {
                            result = (result as Week).GetNextWeek();
                        }
                    }
                    else if (namedEntity == "month")
                    {
                        result = new Month(date);
                        if (inPast)
                        {
                            result = (result as Month).GetPreviousMonth();
                        }
                        else if (inFuture)
                        {
                            result = (result as Month).GetNextMonth();
                        }
                    }
                    else if (namedEntity == "year")
                    {
                        result = new Year(date);
                        if (inPast)
                        {
                            result = (result as Year).GetPreviousYear();
                        }
                        else if (inFuture)
                        {
                            result = (result as Year).GetNextYear();
                        }
                    }
                }
            }
            else if (NamedDate.IsMatch(Text))
            {
                namedEntity = NamedDate.Match(Text).Value;
            }

            //Handle named entities (eg. "Wednesday" or "January")
            if (!string.IsNullOrEmpty(namedEntity))
            {
                var inPast = lowerText.StartsWith("last ");

                //TODO: Support "this" named entity (eg. "this March" is the March in the baseDate year)

                if (DateComponent.GetWeekDayFromName(namedEntity) != -1)
                {
                    var moment = DateComponent.GetNextDateFromWeekDay(namedEntity, date);
                    result = new Day(moment);
                    if (inPast)
                    {
                        result = new Day(moment.AddDays(-7));
                    }
                }
                else if (DateComponent.GetMonthFromName(namedEntity) != -1)
                {
                    var moment = DateComponent.GetNextDateFromMonth(namedEntity, date);
                    result = new Month(moment);
                    if (inPast)
                    {
                        result = new Month(moment.AddMonths(-12));
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Gets all submitted answers in a time range.
        /// </summary>
        /// <param name="timeRange">The time range for which to retrieve answers.</param>
        /// <returns></returns>
        private async Task<IEnumerable<SubmittedAnswer>> GetAnswersAsync(ITimeRange timeRange)
        {
            var start = new BsonDateTime(timeRange.Start);
            var end = new BsonDateTime(timeRange.End);

            return await _repository.Find(a => a.SubmitDateTime > start && a.SubmitDateTime < end);
        }
        /// <summary>
        /// Gets amount of answers in a given time range.
        /// </summary>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public async Task<int> GetAmountOfAnswersAsync(ITimeRange timeRange)
        {
            var answers = await GetAnswersAsync(timeRange);

            return answers.Count();
        }
Exemple #28
0
 public void OnAvailableRangeChanged(ITimeRange availableRange)
 {
     if (_infoListener != null)
     {
         _infoListener.OnAvailableRangeChanged(availableRange);
     }
 }
Exemple #29
0
 public static DateTimeOffset GetCenterTime(this ITimeRange item)
 {
     return(item.Timestamp.AddTicks(item.TimeRange.Ticks / 2));
 }
Exemple #30
0
 public static bool OverlapsWith(this Verbrauch v1, ITimeRange tr2)
 {
     return(new TimeRange(v1.Startdatum, v1.Enddatum).OverlapsWith(tr2));
 }
        /// <summary>
        /// Returns a <see cref="PlausibilityReport"/> that compares <paramref name="emReference"/> with <paramref name="emOther"/>.
        /// within the interval defined in <paramref name="timeframe"/>.
        /// </summary>
        /// <param name="emReference">reference Energiemenge (reference = used for normalisation)</param>
        /// <param name="emOther">other Energiemenge</param>
        /// <param name="timeframe">time frame to be analysed. If null, the overlap of <paramref name="emReference"/> and <paramref name="emOther"/> is used.</param>
        /// <param name="ignoreLocation">By default (false) an ArgumentException is thrown if the <see cref="BO4E.BO.Energiemenge.LokationsId"/> do not match. Setting this flag suppresses the error.</param>
        /// <returns>a <see cref="PlausibilityReport"/></returns>
        public static PlausibilityReport GetPlausibilityReport(this BO4E.BO.Energiemenge emReference, BO4E.BO.Energiemenge emOther, ITimeRange timeframe = null, bool ignoreLocation = false)
        {
            using (MiniProfiler.Current.Step(nameof(GetPlausibilityReport)))
            {
                TimeRange trReference = emReference.GetTimeRange();
                TimeRange trOther     = emOther.GetTimeRange();
                if (timeframe == null)
                {
                    ITimeRange overlap = trReference.GetIntersection(trOther);
                    if (!ignoreLocation)
                    {
                        if (!(emReference.LokationsId == emOther.LokationsId && emReference.LokationsTyp == emOther.LokationsTyp))
                        {
                            throw new ArgumentException($"locations do not match! '{emReference.LokationsId}' ({emReference.LokationsTyp}) != '{emOther.LokationsId}' ({emOther.LokationsTyp})");
                        }
                    }
                    timeframe = overlap;
                }
                Tuple <decimal, Mengeneinheit> consumptionReference;
                Tuple <decimal, Mengeneinheit> consumptionOtherRaw;
                using (MiniProfiler.Current.Step("Get Consumptions for overlap:"))
                {
                    consumptionReference = emReference.GetConsumption(timeframe);
                    consumptionOtherRaw  = emOther.GetConsumption(timeframe);
                }

                Tuple <decimal, Mengeneinheit> consumptionOther;
                if (consumptionReference.Item2 != consumptionOtherRaw.Item2)
                {
                    // unit mismatch
                    if (consumptionReference.Item2.IsConvertibleTo(consumptionOtherRaw.Item2))
                    {
                        consumptionOther = new Tuple <decimal, Mengeneinheit>(consumptionOtherRaw.Item1 * consumptionOtherRaw.Item2.GetConversionFactor(consumptionReference.Item2), consumptionReference.Item2);
                    }
                    else
                    {
                        throw new ArgumentException($"The unit {consumptionOtherRaw.Item2} is not comparable to {consumptionReference.Item2}!");
                    }
                }
                else
                {
                    consumptionOther = consumptionOtherRaw;
                }

                decimal absoluteDeviation = consumptionOther.Item1 - consumptionReference.Item1;
                decimal?relativeDeviation;
                try
                {
                    relativeDeviation = absoluteDeviation / consumptionReference.Item1;
                }
                catch (DivideByZeroException)
                {
                    relativeDeviation = null;
                }

                Verbrauch vReference = emReference.Energieverbrauch.FirstOrDefault(); // copies obiskennzahl, wertermittlungsverfahren...
                vReference.Wert       = consumptionReference.Item1;
                vReference.Einheit    = consumptionReference.Item2;
                vReference.Startdatum = timeframe.Start;
                vReference.Enddatum   = timeframe.End;

                Verbrauch vOther = emOther.Energieverbrauch.FirstOrDefault(); // copies obiskennzahl, wertermittlungsverfahren...
                vOther.Wert       = consumptionOther.Item1;
                vOther.Einheit    = consumptionOther.Item2;
                vOther.Startdatum = timeframe.Start;
                vOther.Enddatum   = timeframe.End;

                var pr = new PlausibilityReport()
                {
                    LokationsId        = emReference.LokationsId,
                    ReferenceTimeFrame = new BO4E.COM.Zeitraum()
                    {
                        Startdatum = timeframe.Start, Enddatum = timeframe.End
                    },
                    VerbrauchReference       = vReference,
                    VerbrauchOther           = vOther,
                    AbsoluteDeviation        = Math.Abs(absoluteDeviation),
                    AbsoluteDeviationEinheit = consumptionReference.Item2
                };
                if (relativeDeviation.HasValue)
                {
                    pr.RelativeDeviation = Math.Round(relativeDeviation.Value, 4);
                }
                else
                {
                    pr.RelativeDeviation = null;
                }
                return(pr);
            }
        }
 public void OnAvailableRangeChanged(ITimeRange availableRange)
 {
     _availableRangeValuesUs = availableRange.GetCurrentBoundsUs(_availableRangeValuesUs);
     Log.Debug(Tag, "availableRange [" + availableRange.IsStatic + ", " + _availableRangeValuesUs[0]
                    + ", " + _availableRangeValuesUs[1] + "]");
 }
        /// <summary>
        /// Gets the most studied objectives based on amount of answers.
        /// </summary>
        /// <param name="timeRange"></param>
        /// <returns>Top three studied objectives</returns>
        public async Task<IEnumerable<LearningObjective>> GetTopObjectivesAsync(ITimeRange timeRange)
        {
            const int amount = 3;

            var answers = await GetAnswersAsync(timeRange);

            return answers.GroupBy(a => a.LearningObjective)
                .OrderByDescending(l => l.Count())
                .Select(l => new LearningObjective { Name = l.Key })
                .Take(amount);
        }
        /// <summary>
        /// Most difficulty is calculated by which learning objective had the lowest shared difficulty level.
        /// </summary>
        /// <remarks>
        /// Assumptions are that:
        /// 1.) Difficulty is relative over all domains.
        /// 2.) Difficulty is properly calibrated
        /// 
        /// Note: unfortunately but logically this seems to return the easiest learning goal studied.
        /// </remarks>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public async Task<LearningObjective> GetMostDifficultAsync(ITimeRange timeRange)
        {
            var answers = await GetAnswersAsync(timeRange);

            double testDouble;
            var result = answers.GroupBy(answer => answer.LearningObjective).Select(objectiveAnswers => new
            {
                Name = objectiveAnswers.Key,
                Difficulty =
                    objectiveAnswers.Where(a => double.TryParse(a.Difficulty, out testDouble))
                        .Average(a => double.Parse(a.Difficulty))
            })
                .OrderBy(d => d.Difficulty)
                .FirstOrDefault();

            return result == null ? null : new LearningObjective { Name = result.Name };
        }
 public void OnAvailableRangeChanged(int p0, ITimeRange p1)
 {
     // Do nothing.
 }
Exemple #36
0
 public static bool ValidateTimeRange(this ITimeRange range)
 {
     return(range.StartTime < range.EndTime);
 }
Exemple #37
0
        public static HashSet <Verbrauch> Merge(this Verbrauch v1, Verbrauch v2, bool redundant, Boolean biased)
        {
            HashSet <Verbrauch> result = new HashSet <Verbrauch>();

            if (v1.Obiskennzahl == v2.Obiskennzahl && v1.Wertermittlungsverfahren == v2.Wertermittlungsverfahren && v1.Einheit == v2.Einheit)
            {
                if (v1.OverlapsWith(v2))
                {
                    // don't wanna deal with time running backwards.
                    //Debug.Assert(v1.enddatum >= v1.startdatum);
                    //Debug.Assert(v2.enddatum >= v2.startdatum);
                    TimeRange  tr1     = new TimeRange(v1.Startdatum, v1.Enddatum);
                    TimeRange  tr2     = new TimeRange(v2.Startdatum, v2.Enddatum);
                    ITimeRange overlap = v1.GetIntersection(v2);
                    if (v1.Einheit.IsExtensive())
                    {
                        Verbrauch vmerge = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren
                        };
                        if (redundant)
                        {
                            decimal exclusiveV1Wert = (decimal)(tr1.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v1.Wert / ((decimal)tr1.Duration.TotalSeconds);
                            decimal exclusiveV2Wert = (decimal)(tr2.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v2.Wert / ((decimal)tr2.Duration.TotalSeconds);
                            decimal overlapV1Wert   = ((decimal)overlap.Duration.TotalSeconds * v1.Wert) / (decimal)(tr1.Duration.TotalSeconds);
                            decimal overlapV2Wert   = ((decimal)overlap.Duration.TotalSeconds * v2.Wert) / (decimal)(tr2.Duration.TotalSeconds);
                            if (biased == true)
                            {
                                // biased ==> assume that v2 is contained in v1
                                vmerge.Startdatum = v1.Startdatum;
                                vmerge.Enddatum   = v1.Enddatum;
                                if (exclusiveV1Wert == 0.0M && exclusiveV2Wert == 0.0M && overlapV1Wert == overlapV2Wert)
                                {
                                    vmerge.Wert = overlapV1Wert;
                                }
                                else
                                {
                                    vmerge.Wert = v1.Wert - overlapV2Wert; // overlapV1Wert;
                                }
                            }
                            else if (biased == false)
                            {
                                vmerge.Startdatum = v1.Startdatum;
                                vmerge.Enddatum   = v2.Startdatum;
                                vmerge.Wert       = v1.Wert - overlapV2Wert;
                            }
                            else // biased null
                            {
                                vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                                vmerge.Enddatum   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                                if (overlapV1Wert != overlapV2Wert)
                                {
                                    throw new ArgumentException("The inequality is unsolvable.");
                                }
                                vmerge.Wert = exclusiveV1Wert + overlapV1Wert + exclusiveV2Wert;
                            }
                        }
                        else
                        {
                            vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                            vmerge.Enddatum   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                            vmerge.Wert       = v1.Wert + v2.Wert;
                        }
                        result.Add(vmerge);
                    }
                    else
                    {
                        Verbrauch vmerge1 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum,
                            Enddatum                 = overlap.Start,
                            Wert = v1.Startdatum < v2.Startdatum ? v1.Wert : v2.Wert
                        };
                        Verbrauch vmerge2 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = overlap.Start,
                            Enddatum                 = overlap.End
                        };
                        if (redundant)
                        {
                            if (v1.Wert != v2.Wert)
                            {
                                throw new ArgumentException($"Data cannot be redundant if values ({v1.Wert}{v1.Einheit} vs. {v2.Wert}{v2.Einheit}) don't match for interval [{vmerge2.Startdatum}, {vmerge2.Enddatum}).");
                            }
                            vmerge2.Wert = v1.Wert;
                        }
                        else
                        {
                            vmerge2.Wert = v1.Wert + v2.Wert;
                        }
                        Verbrauch vmerge3 = new Verbrauch()
                        {
                            Obiskennzahl             = v1.Obiskennzahl,
                            Einheit                  = v1.Einheit,
                            Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                            Startdatum               = overlap.End,
                            Enddatum                 = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum,
                            Wert = v1.Enddatum > v2.Enddatum ? v1.Wert : v2.Wert
                        };
                        result.Add(vmerge1);
                        result.Add(vmerge2);
                        result.Add(vmerge3);
                    }
                }
                else if (v1.Startdatum == v2.Enddatum || v2.Startdatum == v1.Enddatum)
                {
                    DateTime  start  = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum;
                    DateTime  stop   = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum;
                    Verbrauch vmerge = new Verbrauch()
                    {
                        Obiskennzahl             = v1.Obiskennzahl,
                        Einheit                  = v1.Einheit,
                        Wertermittlungsverfahren = v1.Wertermittlungsverfahren,
                        Startdatum               = start,
                        Enddatum                 = stop
                    };
                    if (v1.Einheit.IsExtensive())
                    {
                        vmerge.Wert = v1.Wert + v2.Wert;
                        result.Add(vmerge);
                    }
                    else if (v1.Wert == v2.Wert) // implicitly intensive
                    {
                        vmerge.Wert = v1.Wert;
                        result.Add(vmerge);
                    }
                    else
                    {
                        // merging intensive verbrauch with different values is not possible.
                        result.Add(v1);
                        result.Add(v2);
                    }
                }
                else
                {
                    // laaaangweilig ;)
                    result.Add(v1);
                    result.Add(v2);
                }
            }
            else
            {
                // laaaangweilig ;)
                result.Add(v1);
                result.Add(v2);
            }
            result.RemoveWhere(v => v.Einheit.IsIntensive() && new TimeRange(v.Startdatum, v.Enddatum).Duration.TotalMilliseconds == 0);
            return(result);
        }
        /// <summary>
        /// Calculates total progress by summing the progress of all submitted answers.
        /// </summary>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public async Task<int> GetTotalProgressAsync(ITimeRange timeRange)
        {
            var answers = await GetAnswersAsync(timeRange);

            return answers.Sum(a => a.Progress);
        }
Exemple #39
0
 public static ITimeRange GetIntersection(this Verbrauch v1, ITimeRange tr2)
 {
     return(new TimeRange(v1.Startdatum, v1.Enddatum).GetIntersection(tr2));
 }
Exemple #40
0
        /// <summary>
        /// Generate a <see cref="CompletenessReport"/> for the given refenrence time frame <paramref name="reference"/>
        /// </summary>
        /// <param name="em">Energiemenge</param>
        /// <param name="reference">reference time frame</param>
        /// <returns></returns>
        public static CompletenessReport GetCompletenessReport(this BO4E.BO.Energiemenge em, ITimeRange reference)
        {
            var combis = em.GetWevObisMeCombinations();

            if (combis.Count != 1)
            {
                string  errorMessage;
                decimal?coverage;
                if (combis.Count == 0)
                {
                    errorMessage = $"Cannot use autoconfigured method because there are no values.";
                    coverage     = 0;
                }
                else
                {
                    errorMessage = $"Cannot use autoconfigured method because there are {combis.Count}>1 distinct (wertermittlungsverfahren, obis, einheit) tuple present: {JsonConvert.SerializeObject(combis, new StringEnumConverter())}";
                    coverage     = null;
                }
                return(new CompletenessReport()
                {
                    LokationsId = em.LokationsId,
                    ReferenceTimeFrame = new Zeitraum()
                    {
                        Startdatum = reference.Start,
                        Enddatum = reference.End
                    },
                    Coverage = coverage,
                    ErrorMessage = errorMessage
                });
            }
            var combi = combis.First();

            return(em.GetCompletenessReport(reference, combi.Item1, combi.Item2, combi.Item3));
        }
Exemple #41
0
 public static DateTimeOffset GetEndTime(this ITimeRange item)
 {
     return(item.Timestamp + item.TimeRange);
 }
Exemple #42
0
        /// <summary>
        /// Generate a <see cref="CompletenessReport"/> for the given parameters.
        /// </summary>
        /// <param name="em">Energiemenge</param>
        /// <param name="reference">reference time frame</param>
        /// <param name="wev">Wertermittlungsverfahren</param>
        /// <param name="obiskennzahl">OBIS Kennzahl</param>
        /// <param name="einheit">Mengeneinheit</param>
        /// <returns>the completeness report</returns>
        public static CompletenessReport GetCompletenessReport(this BO4E.BO.Energiemenge em, ITimeRange reference, Wertermittlungsverfahren wev, string obiskennzahl, Mengeneinheit einheit)
        {
            CompletenessReport result;

            using (MiniProfiler.Current.Step("create completeness report skeleton + find the coverage"))
            {
                result = new CompletenessReport
                {
                    LokationsId = em.LokationsId,
                    Einheit     = einheit,
                    Coverage    = GetCoverage(em, reference, wev, obiskennzahl, einheit),
                    wertermittlungsverfahren = wev,
                    Obiskennzahl             = obiskennzahl,
                    ReferenceTimeFrame       = new Zeitraum
                    {
                        Startdatum = DateTime.SpecifyKind(reference.Start, DateTimeKind.Utc),
                        Enddatum   = DateTime.SpecifyKind(reference.End, DateTimeKind.Utc)
                    },
                };
            }
            if (em.Energieverbrauch != null && em.Energieverbrauch.Count > 0)
            {
                /*using (MiniProfiler.Current.Step("populating time slices of/with missing/null values"))
                 * {
                 *  result.values = em.GetMissingTimeRanges(reference, wev, obis, einheit)
                 *      .Select(mtr => new CompletenessReport.BasicVerbrauch
                 *      {
                 *          startdatum = DateTime.SpecifyKind(mtr.Start, DateTimeKind.Utc),
                 *          enddatum = DateTime.SpecifyKind(mtr.End, DateTimeKind.Utc),
                 *          wert = null
                 *      }).ToList<CompletenessReport.BasicVerbrauch>();
                 * }
                 * using (MiniProfiler.Current.Step("populating time slices existing values"))
                 * {
                 *  result.values.AddRange(
                 *  em.energieverbrauch
                 *  //.AsParallel<Verbrauch>()
                 *  .Where(v => v.obiskennzahl == obis && v.einheit == einheit && v.wertermittlungsverfahren == wev)
                 *  .Select(v => new CompletenessReport.BasicVerbrauch
                 *  {
                 *      startdatum = DateTime.SpecifyKind(v.startdatum, DateTimeKind.Utc),
                 *      enddatum = DateTime.SpecifyKind(v.enddatum, DateTimeKind.Utc),
                 *      wert = v.wert
                 *  })
                 *  .ToList<CompletenessReport.BasicVerbrauch>());
                 * }*/
                using (MiniProfiler.Current.Step("Setting aggregated gaps"))
                {
                    var        nonNullValues = new TimePeriodCollection(em.Energieverbrauch.Select(v => new TimeRange(v.Startdatum, v.Enddatum)));
                    ITimeRange limits;
                    if (result.ReferenceTimeFrame != null && result.ReferenceTimeFrame.Startdatum.HasValue && result.ReferenceTimeFrame.Enddatum.HasValue)
                    {
                        limits = new TimeRange(result.ReferenceTimeFrame.Startdatum.Value, result.ReferenceTimeFrame.Enddatum.Value);
                    }
                    else
                    {
                        limits = null;
                    }
                    var gaps = (new TimeGapCalculator <TimeRange>()).GetGaps(nonNullValues, limits: limits);
                    result.Gaps = gaps.Select(gap => new CompletenessReport.BasicVerbrauch()
                    {
                        Startdatum = gap.Start,
                        Enddatum   = gap.End,
                        Wert       = null
                    }).ToList();
                }

                /*using (MiniProfiler.Current.Step("sorting result"))
                 * {
                 *  result.values.Sort(new BasicVerbrauchDateTimeComparer());
                 * }*/
                if (em.IsPure(checkUserProperties: true))
                {
                    try
                    {
                        foreach (var kvp in em.Energieverbrauch.Where(v => v.UserProperties != null).SelectMany(v => v.UserProperties))
                        {
                            if (result.UserProperties == null)
                            {
                                result.UserProperties = new Dictionary <string, JToken>();
                            }
                            if (!result.UserProperties.ContainsKey(kvp.Key))
                            {
                                result.UserProperties.Add(kvp.Key, kvp.Value);
                            }
                        }
                    }
                    catch (InvalidOperationException)
                    {
                        // ok, there's no Verbrauch with user properties.
                    }
                }
            }

            /*else
             * {
             *  result.coverage = null;
             *  result._errorMessage = "energieverbrauch is empty";
             * }*/
            return(result);
        }
Exemple #43
0
 public static ITimeRange OffsetBy(this ITimeRange range, TimeSpan offset)
 {
     return(Timestamp.Create(range.Timestamp - offset, range.TimeRange));
 }
Exemple #44
0
        private FProcessingSlot FindProcessingSlot(List <ITimeRange> processingPositions, ITimeRange workingQueueSlot, long jobDuration)
        {
            var processingIsPossible = processingPositions.FirstOrDefault(processing =>
                                                                          SlotComparerBasic(workingQueueSlot, processing, jobDuration));

            if (processingIsPossible == null)
            {
                return(null);
            }

            var earliestProcessingStart = (new[] { processingIsPossible.Start, workingQueueSlot.Start }).Max();

            return(new FProcessingSlot(earliestProcessingStart, earliestProcessingStart + jobDuration));
        }
Exemple #45
0
 public void OnAvailableRangeChanged(int p0, ITimeRange p1)
 {
     // do nothing
 }
Exemple #46
0
        public PossibleProcessingPosition GetSuitableQueueingPositionFromProposals(ProposalForCapabilityProvider proposalForCapabilityProvider, long jobDuration)
        {
            var possibleProcessingPosition = new PossibleProcessingPosition(proposalForCapabilityProvider.GetCapabilityProvider);
            var setupDuration =
                proposalForCapabilityProvider.GetCapabilityProvider.ResourceSetups.Sum(x => x.SetupTime);

            var mainResources = proposalForCapabilityProvider.GetResources(usedInSetup: true, usedInProcess: true);
            var possibleMainQueuingPositions = GetQueueingPositions(proposalForCapabilityProvider, mainResources, jobDuration);

            var setupResources = proposalForCapabilityProvider.GetResources(usedInSetup: true, usedInProcess: false);
            var possibleSetupQueuingPositions = GetQueueingPositions(proposalForCapabilityProvider, setupResources, jobDuration);

            var processingResources = proposalForCapabilityProvider.GetResources(usedInSetup: false, usedInProcess: true);
            var possibleProcessingQueuingPositions = GetQueueingPositions(proposalForCapabilityProvider, processingResources, jobDuration);

            // Apporach 1.
            // 1. Durchlaufe alle MainScopes

            // S ->S<---->S<-->  <---------
            // R ->S      S|xxx|    <------- ----   ------
            // W ------->  |xxx|   <------- ------------

            // Reduziere den Möglichen Zeitaum der Main Ressourcen
            // R1 ----  |      |-----  ------
            // R2 ------|      |   -------
            // E1 ------|      |-------------|              inf|

            // Prüfe ob Bearbeitungsressourcen notwendig sind
            // --> Nein --> Continue
            // --> JA --> Reduziere den Möglichen Bearbeitungsraum mit Werker
            // E1 ------|      |-------------|              inf|
            // W ----------|   |------    ------|           inf|
            // E2 ---------|   |------    ------|           inf|

            // prüfe ob setup notwenig ist
            // --> Nein --> Return
            // --> Ja --> Passe den notwendigen setup raum an
            // E1 ------|               |-------------|              inf|
            // W ----------|            |------    ------|           inf|
            // E2 ---------         |xxx|------    ------|           inf|
            // E3 ------|           |--------------------|           inf|


            // prüfe auf setup ressourcen.
            // S -|  |---|          |--|    |---------|
            // E3 ------|           |--------------------|           inf|
            // E4 -------|          |--------------------|           inf|

            // Von allen möglichen Setups innerhalb des scopes Nimm das Letzte aus E4.

            // Minimiere den Zeitraum zwischen SetupEnde und Bearbeitungsstart


            // Approach 2

            // 1. Nimm über alle MainResourcen die kleine ProcessingStartzeit
            // 2. Prüfe ob ein setup notwenig ist und ermittle alle start und endwerte --> sind bereits da
            // 3. Wenn Setup notwendig, prüfe ob alle anderen resourcen zu den Setups und Processing Starts frei sind
            //  --> ja Lücke gefunden
            //  --> nein nimm die ProcessingStartzeit und rechne + 1
            //  goto 2. --> flieg raus aus dem Slot und nimm den nächsten slot, wenn Zeit nicht mehr reicht
            // goto 1. mit einer größeren Pr


            foreach (var mainScope in possibleMainQueuingPositions)
            {
                ITimeRange setupSlot      = null;
                ITimeRange processingSlot = null;

                /*
                 * CASE WITH SETUP
                 */
                if (mainScope.IsRequieringSetup)
                {
                    possibleProcessingPosition.RequireSetup = true;
                    long earliestProcessingStart = mainScope.Scope.Start + setupDuration;
                    long earliestSetupStart      = mainScope.Scope.Start;
                    setupSlot      = new FSetupSlot(earliestSetupStart, earliestProcessingStart);
                    processingSlot = new FProcessingSlot(start: earliestProcessingStart, end: earliestProcessingStart + jobDuration);
                    var mainProcessingSlots = new List <ITimeRange>();
                    if (setupResources.Count != 0) // Setup RESOURCE Is Required.
                    {
                        // Machine includes Setup time in the Queuing Position if required.
                        var setupIsPossible = possibleSetupQueuingPositions.FirstOrDefault(setup
                                                                                           => SlotComparerSetup(mainScope.Scope, setup.Scope, jobDuration, setupDuration));
                        if (setupIsPossible == null)
                        {
                            continue;
                        }

                        earliestSetupStart      = (new[] { setupIsPossible.Scope.Start, mainScope.Scope.Start }).Max();
                        earliestProcessingStart = earliestSetupStart + setupDuration;
                        setupSlot      = new FSetupSlot(start: earliestSetupStart, end: earliestProcessingStart);
                        processingSlot = new FProcessingSlot(start: earliestProcessingStart, end: earliestProcessingStart + jobDuration);

                        /*
                         * CASE 1 ONLY MAIN RESOURCE AND SETUP RESSOURCE // WITH SETUP
                         */

                        if (processingResources.Count == 0)
                        {
                            mainProcessingSlots = new List <ITimeRange> {
                                setupSlot, processingSlot
                            };
                            mainResources.ForEach(resourceRef => possibleProcessingPosition.Add(resourceRef, CreateScopeConfirmation(mainProcessingSlots, earliestSetupStart), earliestProcessingStart));
                            setupResources.ForEach(resourceRef => possibleProcessingPosition.Add(resourceRef, CreateScopeConfirmation(setupSlot, earliestSetupStart)));
                            break;
                        }
                    }

                    /*
                     * CASE 2 ONLY MAIN RESOURCE // WITH SETUP
                     */

                    if (processingResources.Count == 0) //
                    {
                        mainProcessingSlots = new List <ITimeRange> {
                            setupSlot, processingSlot
                        };
                        mainResources.ForEach(resourceRef => possibleProcessingPosition.Add(resourceRef, CreateScopeConfirmation(mainProcessingSlots, earliestSetupStart), earliestProcessingStart));
                        break;
                    }

                    var processingScope = new FScope(start: earliestProcessingStart, end: mainScope.Scope.End);
                    // seek for worker to process operation
                    var processingResourceSlot = FindProcessingSlot(possibleProcessingQueuingPositions.Where(x => x.IsQueueAble)
                                                                    .Select(x => x.Scope).ToList(), processingScope, jobDuration);
                    // set if a new is found
                    if (processingResourceSlot == null)
                    {
                        continue;
                    }

                    processingSlot = new FProcessingSlot(start: processingResourceSlot.Start, end: processingResourceSlot.End);

                    mainProcessingSlots = new List <ITimeRange> {
                        setupSlot, processingSlot
                    };
                    mainResources.ForEach(x => possibleProcessingPosition.Add(x, CreateScopeConfirmation(mainProcessingSlots, earliestSetupStart)));
                    processingResources.ForEach(x => possibleProcessingPosition.Add(x, CreateScopeConfirmation(processingSlot, earliestSetupStart), processingSlot.Start));
                    if (setupResources.Count > 0)
                    {
                        setupResources.ForEach(x =>
                                               possibleProcessingPosition.Add(x, CreateScopeConfirmation(new List <ITimeRange> {
                            setupSlot
                        }, earliestSetupStart)));
                    }
                    break;
                }
                else
                {
                    /*
                     * CASE NoSetup
                     */
                    ITimeRange mainSlot = null;
                    if (processingResources.Count == 0)
                    {
                        mainSlot = new FProcessingSlot(start: mainScope.Scope.Start, end: mainScope.Scope.Start + jobDuration);
                        mainResources.ForEach(x => possibleProcessingPosition.Add(x, CreateScopeConfirmation(mainSlot, mainSlot.Start), mainSlot.Start));
                        break;
                    }
                    processingSlot = FindProcessingSlot(possibleProcessingQueuingPositions.Where(x => x.IsQueueAble)
                                                        .Select(x => x.Scope).ToList(), mainScope.Scope, jobDuration);
                    // set if a new is found
                    if (processingSlot == null)
                    {
                        continue;
                    }

                    mainSlot = new FProcessingSlot(start: processingSlot.Start, end: processingSlot.Start + jobDuration);

                    mainResources.ForEach(x => possibleProcessingPosition.Add(x, CreateScopeConfirmation(mainSlot, mainSlot.Start)));
                    processingResources.ForEach(x => possibleProcessingPosition.Add(x, CreateScopeConfirmation(mainSlot, mainSlot.Start), mainSlot.Start));
                    break;
                }
            }

            return(possibleProcessingPosition);
        }