Exemple #1
0
        public DesignMainViewModel()
        {
            var now = TimeMerge.Utils.Calculations.NowTime;

            var mainViewModel = this;

            mainViewModel.Year  = now.Year;
            mainViewModel.Month = now.Month;
            mainViewModel.SettingsPanelVM.UserID = "D0C22AC4-B7BE-4B5E-B0CC-B99419E822B4";
            mainViewModel.UserName = "******";

            MonthData           = new TimeMerge.Model.SingleMonthData();
            MonthData.YearMonth = now;
            var webDavConnection = new WebDavConnection();

            webDavConnection.Init(SettingsPanelVM.UserID, "dummyLogin", "001122", "dummyWebDavUrl");
            mainViewModel.MonthViewModel = new SingleMonthViewModel(mainViewModel, new NoActionOnWebRequest(), webDavConnection);
            mainViewModel.MonthViewModel.SetMonthData(MonthData);

            DayData             = new TimeMerge.Model.SingleDayData();
            DayData.Day         = 1;
            DayData.IsNoWorkDay = false;
            DayData.WorkInterruptions[0].StartTime         = now - TimeSpan.FromHours(1);
            DayData.WorkInterruptions[0].EndTime           = now + TimeSpan.FromHours(7.5);
            DayData.WorkInterruptions[0].CorrectionEndTime = now + TimeSpan.FromHours(8);
            DayData.WorkInterruptions[0].Type = TimeMerge.Model.WorkInterruption.WorkInterruptionType.OBED;
            SingleDayViewModel dayVM = new SingleDayViewModel();

            dayVM.ReInit(DayData, mainViewModel.MonthViewModel, MonthData.Days);
            mainViewModel.MonthViewModel.Days.Add(dayVM);

            var holidayData = new TimeMerge.Model.SingleDayData();

            holidayData.Day         = 2;
            holidayData.IsNoWorkDay = true;
            SingleDayViewModel dayVM2 = new SingleDayViewModel();

            dayVM2.ReInit(holidayData, mainViewModel.MonthViewModel, MonthData.Days);
            mainViewModel.MonthViewModel.Days.Add(dayVM2);
        }
 private void removeSingleDayVM_onGuiThread(SingleDayViewModel dayVM)
 {
     App.Current.Dispatcher.Invoke(new Action(() => this.Days.Remove(dayVM)));
 }
        public bool LoadData()
        {
            // Load settings
            this.IsBalanceASummaryThroughAllMonths = Properties.Settings.Default.IsBalanceASummaryThroughAllMonths;

            // Load data
            bool loadFromFileWentOK = false;

            object        monthDataRaw = null;
            XmlSerializer serializer   = new XmlSerializer(typeof(SingleMonthData), new Type[] { typeof(SingleMonthData) });

            using (XmlTextReader xmlReader = new XmlTextReader(getThisMonthLocalDataFilename()))
            {
                try
                {
                    monthDataRaw = serializer.Deserialize(xmlReader);
                }
                catch (InvalidOperationException)
                {
                    // OK, this month's local cache doesn't need to exist yet
                }
                finally
                {
                    xmlReader.Close();
                }
            }

            if (monthDataRaw is SingleMonthData)
            {
                SingleMonthData monthData = monthDataRaw as SingleMonthData;

                // Copy over the loaded SingleMonthData instance to our own, local instance of SingleMonthData.
                // Try recycling each ViewModel if possible, it will improve performance.
                foreach (SingleDayData dayData in monthData.Days)
                {
                    var vmToUpdate = from SingleDayViewModel selectedDayVM in this.Days
                                     where selectedDayVM.Day == dayData.Day
                                     select selectedDayVM;
                    SingleDayViewModel dayVM = vmToUpdate.SingleOrDefault();
                    if (dayVM != null)
                    {
                        // can recycle
                        dayVM.ReInit(dayData, this, this._monthData.Days);
                    }
                    else
                    {
                        // can't recycle
                        dayVM = new SingleDayViewModel();
                        dayVM.ReInit(dayData, this, this._monthData.Days);
                        addSingleDayVM_onGuiThread(dayVM); // always access 'this.Days' collection on the Dispatcher thread
                    }
                }

                // Get rid of any superfluous single day ViewModels (e.g. if previously shown month had 31 days,
                // but the month we're going to shown now has only 30 or even less days.
                if (monthData.Days.Count > 0)
                {
                    List <SingleDayViewModel> viewmodelsToDelete = new List <SingleDayViewModel>();

                    for (int dayToDelete = monthData.Days.Count + 1; dayToDelete <= this.Days.Count; dayToDelete++)
                    {
                        var toDelete = from SingleDayViewModel selectedDayVM in this.Days
                                       where selectedDayVM.Day == dayToDelete
                                       select selectedDayVM;
                        SingleDayViewModel vmToDelete = toDelete.SingleOrDefault();
                        if (vmToDelete != null)
                        {
                            viewmodelsToDelete.Add(vmToDelete);
                        }
                    }

                    // Delete all collected day VMs at once, since this deletion directly alters elements of 'this.Days.Count'
                    foreach (var vmToDelete in viewmodelsToDelete)
                    {
                        removeSingleDayVM_onGuiThread(vmToDelete); // always access 'this.Days' collection on the Dispatcher thread
                    }
                }

                this.TransferFromPrevMonth = monthData.TransferFromPrevMonth;

                loadFromFileWentOK = true;
            }

            return(loadFromFileWentOK);
        }
        private void extractTimesTable(string tableContent)
        {
            int year  = _monthData.YearMonth.Year;
            int month = _monthData.YearMonth.Month;

            var daysCreatedList     = new List <SingleDayViewModel>();
            int lastDayNumberNeeded = 1;

            Regex exTableRows = new Regex("<tr>.*?<td class=\"r\">(.*?)</td>(.*?)</tr>");
            var   matches     = exTableRows.Matches(tableContent);

            foreach (Match oneRowMatch in matches)
            {
                int  dayNumber   = 0;
                bool isNoWorkDay = false;
                if (oneRowMatch.Groups.Count > 1 && oneRowMatch.Groups[1].Captures.Count > 0)
                {
                    var dayNumberString = oneRowMatch.Groups[1].Captures[0].Value;
                    if (dayNumberString.Contains("&gt;") && dayNumberString.Contains("&lt;"))
                    {
                        isNoWorkDay     = true;
                        dayNumberString = dayNumberString.Replace("&gt;", "");
                        dayNumberString = dayNumberString.Replace("&lt;", "");
                    }
                    else if (dayNumberString.StartsWith("=") && dayNumberString.EndsWith("="))
                    {
                        isNoWorkDay     = true;
                        dayNumberString = dayNumberString.Replace("=", "");
                    }
                    if (!Int32.TryParse(dayNumberString, out dayNumber))
                    {
                        continue; // cannot parse day number!
                    }
                    lastDayNumberNeeded = dayNumber;
                }
                if (oneRowMatch.Groups.Count > 2 && oneRowMatch.Groups[2].Captures.Count > 0)
                {
                    string oneDayData = oneRowMatch.Groups[2].Captures[0].Value;
                    oneDayData = oneDayData.Replace("&nbsp;", " ");

                    Regex exFourthToNinethCell = new Regex("(<td.*?>(.*?)</td>.*?){47}");
                    var   tdMatches            = exFourthToNinethCell.Matches(oneDayData);
                    foreach (Match oneTdMatch in tdMatches)
                    {
                        if (oneTdMatch.Groups.Count > 1 && oneTdMatch.Groups[2].Captures.Count > 46)
                        {
                            bool isNewDayVMToBeAdded = false;
                            IEnumerable <SingleDayViewModel> dayVMsMatchingThisDay = from oneDayVM in _days
                                                                                     where oneDayVM.Day == dayNumber
                                                                                     select oneDayVM;
                            var dayVM = dayVMsMatchingThisDay.FirstOrDefault();
                            if (dayVM == null)
                            {
                                isNewDayVMToBeAdded = true;

                                dayVM = new SingleDayViewModel();
                            }
                            TimeMerge.Model.SingleDayData dayData = getOrCreateSingleDayData(dayNumber);
                            dayVM.ReInit(dayData, this, this._monthData.Days);

                            dayVM.IsNoWorkDay = isNoWorkDay;

                            dayVM.IsChangeByUserAllowed = false;

                            dayVM.WorkSpan0Start = oneTdMatch.Groups[2].Captures[3].Value;
                            dayVM.WorkSpan0End   = oneTdMatch.Groups[2].Captures[4].Value;
                            dayVM.WorkSpan1Start = oneTdMatch.Groups[2].Captures[5].Value;
                            dayVM.WorkSpan1End   = oneTdMatch.Groups[2].Captures[6].Value;
                            dayVM.WorkSpan2Start = oneTdMatch.Groups[2].Captures[7].Value;
                            dayVM.WorkSpan2End   = oneTdMatch.Groups[2].Captures[8].Value;

                            dayVM.WorkSpan3Start = oneTdMatch.Groups[2].Captures[9].Value;
                            dayVM.WorkSpan3End   = oneTdMatch.Groups[2].Captures[10].Value;
                            dayVM.WorkSpan4Start = oneTdMatch.Groups[2].Captures[11].Value;
                            dayVM.WorkSpan4End   = oneTdMatch.Groups[2].Captures[12].Value;
                            dayVM.WorkSpan5Start = oneTdMatch.Groups[2].Captures[13].Value;
                            dayVM.WorkSpan5End   = oneTdMatch.Groups[2].Captures[14].Value;
                            dayVM.WorkSpan6Start = oneTdMatch.Groups[2].Captures[15].Value;
                            dayVM.WorkSpan6End   = oneTdMatch.Groups[2].Captures[16].Value;
                            dayVM.WorkSpan7Start = oneTdMatch.Groups[2].Captures[17].Value;
                            dayVM.WorkSpan7End   = oneTdMatch.Groups[2].Captures[18].Value;
                            dayVM.WorkSpan8Start = oneTdMatch.Groups[2].Captures[19].Value;
                            dayVM.WorkSpan8End   = oneTdMatch.Groups[2].Captures[20].Value;
                            dayVM.WorkSpan9Start = oneTdMatch.Groups[2].Captures[21].Value;
                            dayVM.WorkSpan9End   = oneTdMatch.Groups[2].Captures[22].Value;

                            dayVM.Interrupt0Start = oneTdMatch.Groups[2].Captures[23].Value;
                            dayVM.Interrupt0End   = oneTdMatch.Groups[2].Captures[24].Value;
                            dayVM.Interrupt0Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[25].Value);
                            dayVM.Interrupt1Start = oneTdMatch.Groups[2].Captures[26].Value;
                            dayVM.Interrupt1End   = oneTdMatch.Groups[2].Captures[27].Value;
                            dayVM.Interrupt1Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[28].Value);
                            dayVM.Interrupt2Start = oneTdMatch.Groups[2].Captures[29].Value;
                            dayVM.Interrupt2End   = oneTdMatch.Groups[2].Captures[30].Value;
                            dayVM.Interrupt2Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[31].Value);
                            dayVM.Interrupt3Start = oneTdMatch.Groups[2].Captures[32].Value;
                            dayVM.Interrupt3End   = oneTdMatch.Groups[2].Captures[33].Value;
                            dayVM.Interrupt3Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[34].Value);
                            dayVM.Interrupt4Start = oneTdMatch.Groups[2].Captures[35].Value;
                            dayVM.Interrupt4End   = oneTdMatch.Groups[2].Captures[36].Value;
                            dayVM.Interrupt4Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[37].Value);
                            dayVM.Interrupt5Start = oneTdMatch.Groups[2].Captures[38].Value;
                            dayVM.Interrupt5End   = oneTdMatch.Groups[2].Captures[39].Value;
                            dayVM.Interrupt5Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[40].Value);
                            dayVM.Interrupt6Start = oneTdMatch.Groups[2].Captures[41].Value;
                            dayVM.Interrupt6End   = oneTdMatch.Groups[2].Captures[42].Value;
                            dayVM.Interrupt6Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[43].Value);
                            dayVM.Interrupt7Start = oneTdMatch.Groups[2].Captures[44].Value;
                            dayVM.Interrupt7End   = oneTdMatch.Groups[2].Captures[45].Value;
                            dayVM.Interrupt7Type  = WorkInterruption.ParseInterruptionType(oneTdMatch.Groups[2].Captures[46].Value);

                            dayVM.IsChangeByUserAllowed = true;

                            if (isNewDayVMToBeAdded)
                            {
                                daysCreatedList.Add(dayVM);
                            }
                        }
                    }
                }
            }

            IEnumerable <SingleDayViewModel> daysDeleted = from oneDayVM in _days
                                                           where oneDayVM.Day > lastDayNumberNeeded
                                                           select oneDayVM;
            var daysDeletedList = daysDeleted.ToList(); // make the enumeration of IEnumerable<> happen right now, so that '_days' collection changes won't affect the 'Remove()' calls below

            App.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                foreach (SingleDayViewModel singleDayVM in daysCreatedList)
                {
                    _days.Add(singleDayVM);
                }

                foreach (SingleDayViewModel singleDayVM in daysDeletedList)
                {
                    _days.Remove(singleDayVM);
                }
            }));
        }
Exemple #5
0
        private string getWorkSpanToolTip(int workSpanIndex, bool isInterruption = false)
        {
            var now = TimeMerge.Utils.Calculations.NowTime;

            DateTime startWithCorrections, endWithCorrections;
            TimeSpan workSpanDuration;
            string   hintZeroTimeHit = string.Empty;

            bool hasCorrections = false;

            if (isInterruption)
            {
                hasCorrections       = _dayData.WorkInterruptions[workSpanIndex].HasCorrectionData;
                startWithCorrections = _dayData.WorkInterruptions[workSpanIndex].GetStartTimeIncludingCorrections();
                endWithCorrections   = _dayData.WorkInterruptions[workSpanIndex].GetEndTimeIncludingCorrections();
                workSpanDuration     = _dayData.WorkInterruptions[workSpanIndex].Duration;
            }
            else
            {
                hasCorrections       = _dayData.WorkSpans[workSpanIndex].HasCorrectionData;
                startWithCorrections = _dayData.WorkSpans[workSpanIndex].GetStartTimeIncludingCorrections();
                endWithCorrections   = _dayData.WorkSpans[workSpanIndex].GetEndTimeIncludingCorrections();
                workSpanDuration     = _dayData.WorkSpans[workSpanIndex].Duration;
            }

            string virtualTimeEnding = getWorkSpanVirtualTimeEnding(workSpanIndex, isInterruption);
            string tooltip           = null;

            if (hasCorrections)
            {
                DateTime start, end;
                if (isInterruption)
                {
                    start = _dayData.WorkInterruptions[workSpanIndex].StartTime;
                    end   = _dayData.WorkInterruptions[workSpanIndex].EndTime;
                }
                else
                {
                    start = _dayData.WorkSpans[workSpanIndex].StartTime;
                    end   = _dayData.WorkSpans[workSpanIndex].EndTime;
                }

                tooltip = string.Format(CultureInfo.InvariantCulture, "Korekcia z {0:t} - {1:t}", start, end);

                if (isInterruption && _dayData.WorkInterruptions[workSpanIndex].CorrectedType.HasValue)
                {
                    tooltip += string.Format(", z typu {0}", _dayData.WorkInterruptions[workSpanIndex].CorrectedType.GetValueOrDefault());
                }
            }

            // When "virtual time ending" is in effect, show some additional info about how long to be in work yet today
            if (!string.IsNullOrEmpty(virtualTimeEnding))
            {
                // Get current time, ignoring the seconds part
                var nowWithNoSeconds = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0);

                DateTime calculationBaseTime;
                if (workSpanDuration.TotalMinutes > 0)
                {
                    calculationBaseTime = nowWithNoSeconds; // current whole-month balance was calculated based on current time
                }
                else
                {
                    calculationBaseTime = startWithCorrections; // current whole-month balance was calculated based on WorkSpan start time
                }
                // Calculate when the current minuses will be get rid of, at what time of today
                DateTime timeWhenZeroIsHit = calculationBaseTime.AddMinutes(-this._parentMonthVM.BalanceWholeMonth.TotalMinutes);

                TimeSpan lunchDuration = this.GetLunchDuration();

                // If the +0:00 zero balance cannot be achieved today (e.g. too much minuses), then show no info about it
                if (timeWhenZeroIsHit.DayOfYear == calculationBaseTime.DayOfYear)
                {
                    // The +0:00 zero balance can be achieved today, when user will be at work until 'timeWhenZeroIsHit'
                    if (!string.IsNullOrEmpty(tooltip))
                    {
                        tooltip += System.Environment.NewLine;
                    }
                    if (this._parentMonthVM.BalanceWholeMonth.TotalMinutes < 0)
                    {
                        hintZeroTimeHit += String.Format("+0:00 sa dosiahne o {1:t}", System.Environment.NewLine, timeWhenZeroIsHit);
                        if (lunchDuration.Ticks == 0)
                        {
                            DateTime timeWhenZeroIsHitWithLunch = timeWhenZeroIsHit + TimeSpan.FromMinutes(SingleDayData.LunchTimeMinimalTime);
                            if (timeWhenZeroIsHitWithLunch.DayOfYear == calculationBaseTime.DayOfYear)
                            {
                                hintZeroTimeHit += string.Format(" (s obedom o {0:t})", timeWhenZeroIsHitWithLunch);
                            }
                        }
                    }
                    else
                    {
                        hintZeroTimeHit += String.Format("+0:00 bol dosiahnutý o {1:t}", System.Environment.NewLine, timeWhenZeroIsHit);
                        if (lunchDuration.Ticks == 0)
                        {
                            DateTime timeWhenZeroIsHitWithLunch = timeWhenZeroIsHit + TimeSpan.FromMinutes(SingleDayData.LunchTimeMinimalTime);
                            if (timeWhenZeroIsHitWithLunch.DayOfYear == calculationBaseTime.DayOfYear)
                            {
                                hintZeroTimeHit += string.Format(" (s obedom o {0:t})", timeWhenZeroIsHitWithLunch);
                            }
                        }
                    }

                    tooltip += hintZeroTimeHit;
                }
            }

            // Notes for the day
            string notes = Utils.NotesContentFormatter.NotesWithIndent(0, NotesContent);

            if (!string.IsNullOrWhiteSpace(notes))
            {
                if (!string.IsNullOrWhiteSpace(tooltip))
                {
                    tooltip += "\r\n";
                }
                tooltip += notes;
            }

            _parentMonthVM.SetTimeSpanHintForZeroHit(SingleDayViewModel.GetSpanGlobalID(this.Day, workSpanIndex, isInterruption), hintZeroTimeHit);

            return(tooltip);
        }