Пример #1
0
        //adjusts start/endtime such that a possible overtime can be billed
        public void updateFullDay(DateTime day, WorktimeStatistics wtstats, DateTime end)
        {
            if (!WorktrackerConnectInternal())
            {
                return;
            }

            var workEntries = worktracker.QueryWorkEntries(currentUser, day.Date, new TimeSpan(1, 0, 0, 0));

            if (workEntries.Count == 0)
            {
                throw new Exception("No Workentry found");
            }

            var workEntry = workEntries[0];

            var trueEnd = (workEntry.StopTime != default(DateTime) && workEntry.IsComplete) ? workEntry.StopTime : end;

            Tuple <DateTime, DateTime, TimeSpan> newTimes = calcAdaptedStartEndTimes(day, wtstats, trueEnd);

            workEntry.BreakDuration = newTimes.Item3;
            workEntry.StartTime     = newTimes.Item1;
            workEntry.StopTime      = newTimes.Item2;
            workEntry.IsComplete    = true;

            worktracker.UpdateWorkEntry(workEntry);
        }
Пример #2
0
        //This method is just for testing as I had troubles with invoking the method with out-params
        private Tuple <WorktimeStatistics, Dictionary <string, TimeSpan> > calculateOvertimeUndertimeForTesting(WorktimeStatistics originalWts, Dictionary <string, TimeSpan> originalOvertimes)
        {
            WorktimeStatistics            newWts    = null;
            Dictionary <string, TimeSpan> overtimes = null;

            calculateOvertimeUndertime(originalWts, originalOvertimes, out newWts, out overtimes);

            return(new Tuple <WorktimeStatistics, Dictionary <string, TimeSpan> >(newWts, overtimes));
        }
Пример #3
0
        public WorktimeStatistics considerOvertimeUndertime(WorktimeStatistics originalWts)
        {
            var newWts       = new WorktimeStatistics();
            var newOvertimes = new Dictionary <string, TimeSpan>();

            calculateOvertimeUndertime(originalWts, Storage.getOvertimes(), out newWts, out newOvertimes);

            Storage.updateOvertimes(newOvertimes);

            return(newWts);
        }
Пример #4
0
 public WorktimeStatistics(WorktimeStatistics wts)
 {
     projectTimes         = wts.projectTimes.ToDictionary(e => e.Key, e => e.Value);
     relativeProjectTimes = wts.relativeProjectTimes.ToDictionary(e => e.Key, e => e.Value);
     projectComments      = wts.projectComments.ToDictionary(e => e.Key, e => e.Value.ToDictionary(e1 => e1.Key, e1 => e1.Value));
     totalTime            = wts.totalTime;
     totalProjectTime     = wts.totalProjectTime;
     totalWorktime        = wts.totalWorktime;
     totalPausetime       = wts.totalPausetime;
     totalWorkbreaktime   = wts.totalWorkbreaktime;
     totalPrivateTime     = wts.totalPrivateTime;
 }
Пример #5
0
        public void updateProjectEntries(DateTime day, WorktimeStatistics wtstats)
        {
            if (!WorktrackerConnectInternal())
            {
                return;
            }

            updateWtProjects();

            var wtprojects        = joinToWtProjects(wtstats);
            var quantizedProjects = quantizeProjectsTo5(wtprojects);

            addProjectEntriesToWorktracker(day, quantizedProjects);
        }
Пример #6
0
        public Dictionary <string, TimeSpan> calcAllProjectimeAsOvertime(WorktimeStatistics wts, Dictionary <string, TimeSpan> originalOvertimes)
        {
            var newOvertimes = originalOvertimes.ToDictionary(e => e.Key, e => e.Value); //clone

            foreach (var pj in wts.projectTimes)
            {
                if (!newOvertimes.ContainsKey(pj.Key))
                {
                    newOvertimes[pj.Key] = new TimeSpan(0, 0, 0);
                }
                newOvertimes[pj.Key] += pj.Value;
            }
            return(newOvertimes);
        }
Пример #7
0
        private Dictionary <Project, float> joinToWtProjects(WorktimeStatistics wtstats)
        {
            var wtprojects = new Dictionary <Project, float>();

            foreach (var pjs in wtstats.relativeProjectTimes)
            {
                var wtprojectname = getWTProjectname(pjs.Key);
                var wtproject     = projects.FirstOrDefault(x => x.Value.UniqueName == wtprojectname).Value; //todo auslagern
                if (wtproject == null)
                {
                    throw new Exception($"WtProject name {wtprojectname} not found in Worktracker unique project Names");
                }

                if (!wtprojects.ContainsKey(wtproject))
                {
                    wtprojects[wtproject] = 0;
                }
                wtprojects[wtproject] += pjs.Value;
            }
            return(wtprojects);
        }
Пример #8
0
        public Tuple <DateTime, DateTime, TimeSpan> calcAdaptedStartEndTimes(DateTime day, WorktimeStatistics wtstats, DateTime origEnd)
        {
            var newPause = wtstats.totalPausetime;
            var tmpEnd   = ((origEnd.Date == day.Date && origEnd.Hour > 22) || origEnd.Date == day.Add(new TimeSpan(24, 0, 0)).Date)
                ? (day.Date + new TimeSpan(22, 0, 0))
                : origEnd;
            var tmpStart = (tmpEnd - wtstats.totalTime);

            //if start is after 12 o'clock, pretend we started to work at 10
            if (tmpStart.TimeOfDay > new TimeSpan(12, 0, 0))
            {
                var t = tmpStart.TimeOfDay - new TimeSpan(10, 0, 0);
                tmpStart -= t;
                tmpEnd   -= t;
            }

            //if we begin before 6 o'clock, pretend that we started at least at 6
            if (tmpStart.TimeOfDay < new TimeSpan(6, 0, 0))
            {
                var t = new TimeSpan(6, 0, 0) - tmpStart.TimeOfDay;
                tmpStart += t;
                tmpEnd   += t;
            }
            var newStart = tmpEnd - wtstats.totalTime;
            var newEnd   = tmpEnd;

            //if we are finishing the current day, finish now because otherwise value will be overridden by alarm checkout
            //However, it must not start before 6 o'clock in any case
            if (day.Date == DateTime.Now.Date && tmpEnd > DateTime.Now)
            {
                var t = tmpEnd - DateTime.Now;
                if ((tmpStart - t).TimeOfDay < new TimeSpan(6, 0, 0))
                {
                    var t2 = new TimeSpan(6, 0, 0) - (tmpStart - t).TimeOfDay;
                    t -= t2;
                }
                tmpStart -= t;
                tmpEnd   -= t;
            }

            //if pause time is too short, shift start and make pause 40mins
            if (newPause < new TimeSpan(0, 40, 0))
            {
                newStart -= new TimeSpan(0, 40, 0) - wtstats.totalPausetime;
                newPause  = new TimeSpan(0, 40, 0);
            }
            return(new Tuple <DateTime, DateTime, TimeSpan>(newStart, newEnd, newPause));
        }
Пример #9
0
 public Tuple <DateTime, DateTime, TimeSpan> calcAdaptedStartEndTimes(DateTime day, WorktimeStatistics wtstats, DateTime origEnd)
 {
     throw new Exception("Worktracker not supported in current build");
 }
Пример #10
0
 public void updateFullDay(DateTime day, WorktimeStatistics wtstats, DateTime end)
 {
     throw new Exception("Worktracker not supported in current build");
 }
Пример #11
0
 public void updateProjectEntries(DateTime day, WorktimeStatistics wtstats)
 {
     throw new Exception("Worktracker not supported in current build");
 }
Пример #12
0
        private WorktimeStatistics generateStatistics(List <WorktimeRecord> worktimeRecords)
        {
            //TODO write current desktop to storage
            var currentStats = new WorktimeStatistics();

            foreach (var wtr in worktimeRecords)
            {
                if (String.IsNullOrEmpty(wtr.ProjectName) || wtr.ProjectName.Contains("[unknown"))
                {
                    continue; //that happens e.g. for Init project rows
                }
                var currentInterval = TimeSpan.FromSeconds((wtr.End - wtr.Start).TotalSeconds);

                if (wtr.ProjectName == ProjectChangeHandler.PROJECT_WORKTIMEBREAK)
                {
                    currentStats.totalWorkbreaktime += currentInterval;
                    currentStats.totalWorktime      += currentInterval;
                }
                else if (wtr.ProjectName == ProjectChangeHandler.PROJECT_PAUSE)
                {
                    currentStats.totalPausetime += currentInterval;
                }
                else if (wtr.ProjectName == ProjectChangeHandler.PROJECT_PRIVAT)
                {
                    currentStats.totalPrivateTime += currentInterval;
                }
                else //normal project
                {
                    if (!currentStats.projectTimes.ContainsKey(wtr.ProjectName))
                    {
                        currentStats.projectTimes[wtr.ProjectName] = new TimeSpan(0, 0, 0);
                    }

                    currentStats.projectTimes[wtr.ProjectName] += currentInterval;
                    currentStats.totalProjectTime += currentInterval;
                    currentStats.totalWorktime    += currentInterval;
                }
                currentStats.totalTime += currentInterval;
                if (!currentStats.projectComments.ContainsKey(wtr.ProjectName))
                {
                    currentStats.projectComments.Add(wtr.ProjectName, new Dictionary <string, TimeSpan>());
                }

                var comment = !String.IsNullOrEmpty(wtr.Comment) ? wtr.Comment : "General";

                if (!currentStats.projectComments[wtr.ProjectName].ContainsKey(comment))
                {
                    currentStats.projectComments[wtr.ProjectName].Add(comment, new TimeSpan());
                }

                var newSum = currentStats.projectComments[wtr.ProjectName][comment] + currentInterval;
                currentStats.projectComments[wtr.ProjectName][comment] = newSum;
            }
            foreach (var project in currentStats.projectTimes)
            {
                currentStats.relativeProjectTimes[project.Key] = (float)(project.Value.TotalSeconds / currentStats.totalProjectTime.TotalSeconds) * 100;
            }

            //currentStats.totalTime.Milliseconds = 0;
            return(currentStats);
        }
Пример #13
0
        public void takeAllProjectimeAsOvertime(WorktimeStatistics wts)
        {
            var newOvertimes = calcAllProjectimeAsOvertime(wts, Storage.getOvertimes());

            Storage.updateOvertimes(newOvertimes);
        }
Пример #14
0
        public void calculateOvertimeUndertime(WorktimeStatistics originalWts, Dictionary <string, TimeSpan> originalOvertimes, out WorktimeStatistics newWts, out Dictionary <string, TimeSpan> newOvertimes)
        {
            newWts       = new WorktimeStatistics(originalWts);
            newOvertimes = originalOvertimes.ToDictionary(e => e.Key, e => e.Value); //clone

            if (originalWts.totalWorktime > maxWorktime)                             //we worked overtime
            {
                TimeSpan diff = originalWts.totalWorktime - maxWorktime;

                var projectIndex = 0;
                while (diff > new TimeSpan(0, 0, 0))
                {
                    var project = originalWts.projectTimes.Keys.ToList().ElementAt(projectIndex);
                    var time    = originalWts.projectTimes.Values.ToList().ElementAt(projectIndex);

                    var timeToSubtract = new TimeSpan(0, 0, 0);
                    if (time <= diff) //whole project time is consumed
                    {
                        if (!newOvertimes.ContainsKey(project))
                        {
                            newOvertimes[project] = new TimeSpan(0, 0, 0);
                        }
                        newOvertimes[project]       += time;
                        newWts.projectTimes[project] = new TimeSpan(0, 0, 0);
                        timeToSubtract = time;
                        diff          -= time;
                    }
                    else //project time is only partially consumed
                    {
                        if (!newOvertimes.ContainsKey(project))
                        {
                            newOvertimes[project] = new TimeSpan(0, 0, 0);
                        }
                        newOvertimes[project]        += diff;
                        newWts.projectTimes[project] -= diff;
                        timeToSubtract = diff;
                        diff           = new TimeSpan(0, 0, 0);
                    }

                    newWts.totalTime        -= timeToSubtract;
                    newWts.totalProjectTime -= timeToSubtract;
                    newWts.totalWorktime    -= timeToSubtract;

                    projectIndex++;
                }
            }
            else //we worked less time than maxTime
            {
                TimeSpan diff = maxWorktime - originalWts.totalWorktime;

                var ovtIndex = 0;
                while (diff > new TimeSpan(0, 0, 0) && sumTimespans(originalOvertimes.Values.ToList()) > new TimeSpan(0, 0, 0))
                {
                    var project = originalOvertimes.Keys.ToList().ElementAt(ovtIndex);
                    var time    = originalOvertimes.Values.ToList().ElementAt(ovtIndex);

                    var timeToAdd = new TimeSpan(0, 0, 0);
                    if (diff > time) //a whole overtime is consumed
                    {
                        timeToAdd             = time;
                        newOvertimes[project] = new TimeSpan(0, 0, 0);
                        if (!newWts.projectTimes.ContainsKey(project))
                        {
                            newWts.projectTimes[project] = new TimeSpan(0, 0, 0);
                        }
                        newWts.projectTimes[project] += time;
                        diff -= time;
                        originalOvertimes[project] -= time;
                    }
                    else //an overtime is partially consumed
                    {
                        timeToAdd              = diff;
                        newOvertimes[project] -= diff;
                        if (!newWts.projectTimes.ContainsKey(project))
                        {
                            newWts.projectTimes[project] = new TimeSpan(0, 0, 0);
                        }
                        newWts.projectTimes[project] += diff;
                        diff = new TimeSpan(0, 0, 0);
                    }

                    newWts.totalTime        += timeToAdd;
                    newWts.totalProjectTime += timeToAdd;
                    newWts.totalWorktime    += timeToAdd;

                    ovtIndex++;
                }
            }

            foreach (var project in newWts.projectTimes)
            {
                newWts.relativeProjectTimes[project.Key] = (float)(project.Value.TotalSeconds / newWts.totalProjectTime.TotalSeconds) * 100;
            }
        }
Пример #15
0
        //------------------------------------------------
        //------------------------------------------------

        private void AnalyzeWorktimes()
        {
            if (WorktimeAnalyzer == null)
            {
                return;
            }

            try
            {
                var projectStatistics = WorktimeAnalyzer.AnalyzeWorkday(Form.dateTimePicker1.Value);

                WorktimeStatistics projectStatisticsReal = null;
                if (Form.flagConsiderOvertime.Checked)
                {
                    Dictionary <string, TimeSpan> newOvertimes = null;
                    WorktimeAnalyzer.calculateOvertimeUndertime(projectStatistics, storage.getOvertimes(), out projectStatisticsReal, out newOvertimes);
                }
                else
                {
                    projectStatisticsReal = projectStatistics;
                }

                Form.currentOvertime.Text = WorktimeAnalyzer.sumTimespans(storage.getOvertimes().Values.ToList()).FormatForOvertime();
                Form.ProjectTimesSummary.Series.Clear();

                Series series = new Series
                {
                    Name = "projects",
                    IsVisibleInLegend = false,
                    ChartType         = SeriesChartType.Column
                };
                Form.ProjectTimesSummary.Series.Add(series);

                foreach (var project in projectStatisticsReal.projectTimes)
                {
                    series.Points.Add(project.Value.TotalMinutes);
                    var p = series.Points.Last();
                    p.AxisLabel = project.Key;
                    p.Label     = Math.Round(projectStatisticsReal.relativeProjectTimes[project.Key]).ToString() + "%";

                    if (projectStatisticsReal.projectComments.ContainsKey(project.Key)) //can happen for overtime, probably not the most appropriate solution
                    {
                        p.ToolTip = "Total: " + Math.Round(project.Value.TotalHours, 1) + "h\n" +
                                    String.Join("\n",
                                                projectStatisticsReal.projectComments[project.Key]
                                                .OrderByDescending(s => s.Value.Ticks) //order by comment timespan-sum
                                                .Select(s => Math.Round(s.Value.TotalHours, 1) + "h: " + s.Key)
                                                );
                    }
                }
                Form.ProjectTimesSummary.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0;
                Form.ProjectTimesSummary.ChartAreas[0].AxisY.MajorGrid.LineWidth = 0;
                Form.ProjectTimesSummary.ChartAreas[0].BackColor = System.Drawing.SystemColors.Control;
                Form.ProjectTimesSummary.ChartAreas[0].RecalculateAxesScale();
                Form.ProjectTimesSummary.Invalidate();
                Form.ProjectTimesSummary.Visible = true;

                Form.totalTime.Text     = projectStatisticsReal.totalTime.ToString(@"hh\:mm\:ss");
                Form.PrivateTime.Text   = projectStatisticsReal.totalPrivateTime.ToString(@"hh\:mm\:ss");
                Form.PauseTime.Text     = projectStatisticsReal.totalPausetime.ToString(@"hh\:mm\:ss");
                Form.Worktime.Text      = projectStatisticsReal.totalWorktime.ToString(@"hh\:mm\:ss");
                Form.ProjectTime.Text   = projectStatisticsReal.totalProjectTime.ToString(@"hh\:mm\:ss");
                Form.Workbreaktime.Text = projectStatisticsReal.totalWorkbreaktime.ToString(@"hh\:mm\:ss");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }