Пример #1
0
        /// <summary>
        /// UserId, Start, Finish, Type, ObjectId, ObjectTypeId, ObjectName, Duration, PercentCompleted,
        /// PriorityId, StateId, FinishDate, Highlight, IsNewMessage, IsOverdue, AssignmentId, AssignmentName
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="curDate"></param>
        /// <param name="fromDate"></param>
        /// <param name="toDate"></param>
        /// <param name="objectTypes"></param>
        /// <param name="highlightedItems"></param>
        /// <param name="getPastTime"></param>
        /// <param name="getOffTime"></param>
        /// <param name="mergeBreaks"></param>
        /// <param name="strictBorder"></param>
        /// <returns></returns>
        public static DataTable GetResourceUtilization(
			int userId,
			DateTime curDate,
			DateTime fromDate, 
			DateTime toDate,
			ArrayList objectTypes,	/*ArrayList arr = new ArrayList();arr.Add(ObjectTypes.Task);arr.Add(ObjectTypes.ToDo);arr.Add(ObjectTypes.CalendarEntry);arr.Add(ObjectTypes.Document);arr.Add(ObjectTypes.Issue);*/
			List<KeyValuePair<int, int>> highlightedItems,	/* key:ObjectId, value:ObjectTypeId */
			bool getPastTime,
			bool getOffTime,
			bool mergeBreaks,
			bool strictBorder)
        {
            /* �������� �������:
             * 1. �������� ������ � ������������, ������ ���������� ����� ����� �������� ������� � ������ ���������
             *    (��� �������� ����� ��������� ������� ������ �� ������ �������� ��� � �� ����� ���������� ���)
             * 2. ������ ����������� ���������� TimeType.Past (��������� �����) � TimeType.Off.
             *    �.�. �� ��������� �� ����� - ���������.
             * 3. �� ��������� �������� ��������� ���������� � ������� ������� ����� (TimeType.Free)
             * 4. ��������� ���������� � ��������� ������� � �������������� �������.
             * 5. ������ ��� ����������� �� ������, ��������� ������ ���������� TimeType.CalendarEntry
             *    � ������������ ��������� ��������������� ���� � �������������� �������
             * 6. ������ WorkPinnedUp, ��������� ������ ���������� TimeType�.Sticked
             *    � ������������ ��������� ��������������� ���� � �������������� �������
             * 7. ������ ������, ���������, ��������� (��������������� � ������ ��������) �
             *    ������������ ���� � ��� � ������� �� ���������� TimeType.WorkUrgent -
             *    TimeTime.WorkLow (� ����������� �� ����������) � ������������ ���������
             *    ��������������� ���� � �������������� �������.
             *
             * �� ������ ����� ������� � ������� �������.
             * ����� ��� ������������� ����� ����� ������������� �������� �� �����������
             *
             * - �������� "mergeBreaks" ����������, ���� �� ���������� ����������� ��������� ������
             * - �������� "strictBorder" ����������, ��� ����� ��������� � �������������� �������, ����
             *   ������ �������� �� ������� ���������� ���������. ���� true, �� ��������� ����� ������
             *   ����� �������� �� �������� fromDate � toDate. ���� false, �� ����� ������������
             *   �������� ��������� ����� ������
             */

            // round dates to minutes
            fromDate = fromDate.Date.AddHours(fromDate.Hour).AddMinutes(fromDate.Minute);
            toDate = toDate.Date.AddHours(toDate.Hour).AddMinutes(toDate.Minute);
            curDate = curDate.Date.AddHours(curDate.Hour).AddMinutes(curDate.Minute);

            if (fromDate >= toDate)
                throw new ArgumentException("fromDate, toDate");

            DataTable resultTable;	// Resulting table
            int calendarId = -1;	// Calendar Id
            int userCalendarId = -1;	// UserCalendar Id
            List<TimeType> timeList;	// Main array. It contains information about
                                        // every minute allocation from the 00:00 of current date
                                        // to 24:00 of the toDate
            int freeTimeCounter;	// Counter of free time
            DateTime curCalDate;	// Current Date in Calendar timezone
            DateTime fromCalDate;	// FromDate in Calendar timezone
            DateTime toCalDate;		// ToDate in Calendar timezone
            int curMinute;			// Total minutes elapsed from 00:00 of current day
            int fromMinute;			// Total minutes elapsed from 00:00 of current day to fromDate (curDate < fromdate)
                                    // or total minutes elapsed from 00:00 of current day (fromdate > curDate)
            int toMinute;			// Total minutes elapsed from 00:00 of current day to toDate
            TimeSpan ts;			// Auxiliary variable
            CalendarHelper calendarHelper;	// Auxiliary class
            int intervalDuration;	// total minutes from 00:00 of current date to 24:00 of the toDate

            bool getTasks = objectTypes.Contains(ObjectTypes.Task);
            bool getTodo = objectTypes.Contains(ObjectTypes.ToDo);
            bool getIncidents = objectTypes.Contains(ObjectTypes.Issue);
            bool getDocuments = objectTypes.Contains(ObjectTypes.Document);
            DataTable objectTable;

            #region PreStep: initial actions
            // Resulting DataTable definition
            resultTable = new DataTable();
            resultTable.Locale = CultureInfo.InvariantCulture;

            resultTable.Columns.Add("UserId", typeof(int));
            resultTable.Columns.Add("Start", typeof(DateTime));
            resultTable.Columns.Add("Finish", typeof(DateTime));
            resultTable.Columns.Add("Type", typeof(TimeType));
            resultTable.Columns.Add("ObjectId", typeof(int));
            resultTable.Columns.Add("ObjectTypeId", typeof(int));
            resultTable.Columns.Add("ObjectName", typeof(string));
            resultTable.Columns.Add("Duration", typeof(int));
            resultTable.Columns.Add("PercentCompleted", typeof(int));
            resultTable.Columns.Add("PriorityId", typeof(int));
            resultTable.Columns.Add("StateId", typeof(int));
            resultTable.Columns.Add("FinishDate", typeof(DateTime));
            resultTable.Columns.Add("Highlight", typeof(bool));
            resultTable.Columns.Add("IsNewMessage", typeof(bool));	// for incidents
            resultTable.Columns.Add("IsOverdue", typeof(bool));
            resultTable.Columns.Add("AssignmentId", typeof(string));
            resultTable.Columns.Add("AssignmentName", typeof(string));
            resultTable.Columns.Add("ProjectTitle", typeof(string));

            DateTime fromUtcDate = Security.CurrentUser.CurrentTimeZone.ToUniversalTime(fromDate);
            DateTime toUtcDate = Security.CurrentUser.CurrentTimeZone.ToUniversalTime(toDate);
            DateTime curUtcDate = Security.CurrentUser.CurrentTimeZone.ToUniversalTime(curDate);

            // if we have past time
            if (fromDate < curDate)
            {
                if (curDate < toDate)
                {
                    if (getPastTime)
                    {
                        AddRow(resultTable, userId, fromDate, curDate, TimeType.Past);
                    }
                }
                else // all time is past
                {
                    if (getPastTime)
                    {
                        AddRow(resultTable, userId, fromDate, toDate, TimeType.Past);
                    }
                    return resultTable;
                }
            }

            // Get User Calendar info
            using (IDataReader reader = GetUserCalendarByUser(userId))
            {
                if (reader.Read())
                {
                    calendarId = (int)reader["CalendarId"];
                    userCalendarId = (int)reader["UserCalendarId"];
                }
            }

            // Check user calendar existance
            if (calendarId < 0)	// if calendar doesn't exist
            {
                if (getOffTime)
                {
                    if (strictBorder)
                    {
                        AddRow(resultTable,
                            userId,
                            (fromDate > curDate) ? fromDate : curDate,
                            toDate,
                            TimeType.Off);
                    }
                    else
                    {
                        AddRow(resultTable,
                            userId,
                            curDate,
                            toDate.AddDays(1),	// no border in graph
                            TimeType.Off);
                    }

                }

                return resultTable;
            }

            UserLight ul = UserLight.Load(userId);
            int timeZoneId = ul.TimeZoneId;

            // Calendar TimeZone
            McTimeZone timeZoneInfo = McTimeZone.Load(timeZoneId);
            if (timeZoneInfo == null)
                throw new ArgumentException("Unknown TimeZoneId = '" + timeZoneId.ToString() + "'.");
            TimeZone calendarTimeZone = new Mediachase.Ibn.Data.UserTimeZone("Calendar Time Zone",
                timeZoneInfo.Bias,
                timeZoneInfo.DaylightBias,
                timeZoneInfo.DaylightMonth,
                timeZoneInfo.DaylightDayOfWeek,
                timeZoneInfo.DaylightWeek,
                timeZoneInfo.DaylightHour,
                timeZoneInfo.StandardBias,
                timeZoneInfo.StandardMonth,
                timeZoneInfo.StandardDayOfWeek,
                timeZoneInfo.StandardWeek,
                timeZoneInfo.StandardHour);

            curCalDate = calendarTimeZone.ToLocalTime(curUtcDate);
            fromCalDate = calendarTimeZone.ToLocalTime(fromUtcDate);
            toCalDate = calendarTimeZone.ToLocalTime(toUtcDate);

            curMinute = curCalDate.Hour * 60 + curCalDate.Minute;
            if (fromDate < curDate)
            {
                fromMinute = curMinute;
            }
            else
            {
                ts = fromCalDate.Subtract(curCalDate.Date);
                fromMinute = (int)ts.TotalMinutes;
            }
            ts = toCalDate.Subtract(curCalDate.Date);
            toMinute = (int)ts.TotalMinutes;
            #endregion

            #region Step 1: Array creation
            // leveling to the start of date
            if (toCalDate == toCalDate.Date)
                ts = toCalDate.Date.Subtract(curCalDate.Date);
            else
                ts = toCalDate.Date.AddDays(1).Subtract(curCalDate.Date);
            intervalDuration = (int)ts.TotalMinutes;

            if (intervalDuration == 0)
            {
                return resultTable;
            }

            // Calendar Helper
            calendarHelper = new CalendarHelper(curCalDate.Date, calendarTimeZone);
            calendarHelper.FromCalDate = fromCalDate;
            calendarHelper.ToCalDate = toCalDate;
            calendarHelper.IntervalDuration = intervalDuration;
            calendarHelper.HighlightedItems = highlightedItems;

            // array creation
            timeList = new List<TimeType>(intervalDuration);
            #endregion

            #region Step 2: Default array allocation
            for (int i = 0; i < intervalDuration; i++)
            {
                if (i < curMinute)
                    timeList.Add(TimeType.Past);
                else
                    timeList.Add(TimeType.Off);
            }
            #endregion

            #region Step 3: Data from calendar
            ProcessCalendarInfo(timeList, curCalDate, toCalDate, calendarId, userCalendarId, toMinute);
            #endregion

            #region Step 4: Add information about time off to resulting table
            TimeType curType = TimeType.Past;
            int startMinute = 0;
            int endMinute;
            freeTimeCounter = 0;

            for (int i = 0; i < intervalDuration; i++)
            {
                if (timeList[i] == TimeType.Free)
                    freeTimeCounter++;

                if (timeList[i] != curType)	// if type is changed
                {
                    endMinute = i;
                    if (getOffTime && curType == TimeType.Off && startMinute < toMinute && endMinute > fromMinute)
                    {
                        if (strictBorder)
                        {
                            if (startMinute < fromMinute)
                                startMinute = fromMinute;
                            if (endMinute > toMinute)
                                endMinute = toMinute;
                        }
                        if (startMinute < endMinute)
                        {
                            AddRow(resultTable, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), TimeType.Off);
                        }
                    }
                    startMinute = i;
                    curType = timeList[i];
                    continue;
                }
            }

            // Last interval
            if (getOffTime && curType == TimeType.Off && startMinute < toMinute)
            {
                endMinute = intervalDuration + 24*60;	// hide border
                if (strictBorder)
                {
                    if (startMinute < fromMinute)
                        startMinute = fromMinute;
                    if (endMinute > toMinute)
                        endMinute = toMinute;
                }
                if (startMinute < endMinute)
                {
                    AddRow(resultTable, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), TimeType.Off);
                }
            }

            if (freeTimeCounter == 0)
                return resultTable;

            //----------------------
            #endregion

            #region Step 5: Process Events
            if (objectTypes.Contains(ObjectTypes.CalendarEntry))
            {
                int entryType = (int)CalendarView.CalendarFilter.Appointment | (int)CalendarView.CalendarFilter.Event | (int)CalendarView.CalendarFilter.Meeting;
                DataTable events = CalendarView.GetListCalendarEntriesByUser(curDate.Date, (toDate == toDate.Date) ? toDate : toDate.Date.AddDays(1), true, true, false, entryType, userId);

                // ID, Type, Title, Description, StartDate, FinishDate, ShowStartDate, ShowFinishDate, StateId
                foreach (DataRow row in events.Rows)
                {
                    if ((int)row["StateId"] == (int)ObjectStates.Completed || (int)row["StateId"] == (int)ObjectStates.Suspended)
                        continue;

                    DateTime objectStartDate = calendarHelper.GetCalendarDate((DateTime)row["StartDate"]);
                    DateTime objectFinishDate = calendarHelper.GetCalendarDate((DateTime)row["FinishDate"]);

                    if (objectStartDate >= ((toCalDate.Date == toCalDate) ? toCalDate : toCalDate.Date.AddDays(1)) || objectFinishDate <= curCalDate.Date)
                        continue;	// we don't need objects which have dates outside our period

                    // round dates to the diapason boundaries
                    if (objectStartDate < curCalDate.Date)
                        objectStartDate = curCalDate.Date;
                    if (objectFinishDate > ((toCalDate.Date == toCalDate) ? toCalDate : toCalDate.Date.AddDays(1)))
                        objectFinishDate = (toCalDate.Date == toCalDate) ? toCalDate : toCalDate.Date.AddDays(1);

                    // Get number of minutes between objectStartDate/objectFinishDate and curCalDate.Date
                    ts = objectStartDate.Subtract(curCalDate.Date);
                    startMinute = (int)ts.TotalMinutes;
                    ts = objectFinishDate.Subtract(curCalDate.Date);
                    endMinute = (int)ts.TotalMinutes;

                    // feel the array
                    for (int i = startMinute; i < endMinute; i++)
                    {
                        if (timeList[i] != TimeType.Past) // we shouldn't change the past time
                            timeList[i] = TimeType.CalendarEntry;
                    }

                    // Add info to result table
                    if (startMinute < toMinute && endMinute > fromMinute)
                    {
                        int duration = endMinute - startMinute;
                        if (strictBorder)
                        {
                            if (startMinute < fromMinute)
                                startMinute = fromMinute;
                            if (endMinute > toMinute)
                                endMinute = toMinute;
                        }
                        else if (startMinute < curMinute)
                        {
                            startMinute = curMinute;
                        }

                        if (startMinute < endMinute)
                        {
                            AddRow(resultTable, highlightedItems, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), TimeType.CalendarEntry, (int)row["ID"], (int)ObjectTypes.CalendarEntry, row["Title"].ToString(), duration, 0, (int)row["PriorityId"], (int)row["StateId"], (DateTime)row["FinishDate"], null, null, String.Empty, false, false, false);
                        }
                    }
                }

                freeTimeCounter = 0;
                for (int i = 0; i < intervalDuration; i++)
                {
                    if (timeList[i] == TimeType.Free)
                        freeTimeCounter++;
                }
                if (freeTimeCounter == 0)
                    return resultTable;
            }
            #endregion

            #region Step 6: Process WorkPinnedUp
            objectTable = DBCalendar.GetListStickedObjectsUtc(userId, getTasks, getTodo, getIncidents, getDocuments);

            ProcessObjectTable(timeList, curCalDate, userId, objectTable, resultTable, freeTimeCounter, fromMinute, toMinute, calendarHelper, mergeBreaks, strictBorder, true);
            #endregion

            #region Step 7: Process Tasks, Todo, Incidents
            objectTable = DBCalendar.GetListObjectsInPriorityOrderUtc(userId, curUtcDate, toUtcDate, getTasks, getTodo, getIncidents, getDocuments);

            ProcessObjectTable(timeList, curCalDate, userId, objectTable, resultTable, freeTimeCounter, fromMinute, toMinute, calendarHelper, mergeBreaks, strictBorder, false);
            #endregion

            return resultTable;
        }
Пример #2
0
        private static void ProcessObjectTable(
			List<TimeType> timeList, 
			DateTime curCalDate, 
			int userId, 
			DataTable objectTable, 
			DataTable resultTable, 
			int freeTimeCounter,
			int fromMinute,
			int toMinute,
			CalendarHelper calendarHelper,
			bool mergeBreaks,
			bool strictBorder,
			bool sticked)
        {
            // we should extend to left the first work item
            bool extendToLeft = (mergeBreaks && curCalDate.Date < calendarHelper.FromCalDate.Date) ? true : false;

            foreach (DataRow row in objectTable.Rows)
            {
                // ObjectId, ObjectTypeId, ObjectName, PriorityId, StartDate (UTC), FinishDate (UTC),
                // CreationDate (UTC), TaskTime, PercentCompleted, TaskTimeLeft, FinishDateLeft (UTC)

                int duration = (int)row["TaskTimeLeft"];
                int originalDuration = duration;
                int objectId = (int)row["ObjectId"];
                int objectTypeId = (int)row["ObjectTypeId"];
                int taskTimeLeft = (int)row["TaskTimeLeft"];
                string objectName = row["ObjectName"].ToString();
                int percentCompleted = (int)row["PercentCompleted"];
                int priorityId = (int)row["PriorityId"];
                int stateId = (int)row["StateId"];
                bool isNewMessage = (bool)row["IsNewMessage"];
                bool isOverdue = (bool)row["IsOverdue"];
                DateTime finishDate = Security.CurrentUser.CurrentTimeZone.ToLocalTime((DateTime)row["FinishDate"]);
                string assignmentId = row["AssignmentId"].ToString();
                string assignmentName = row["AssignmentName"].ToString();
                string projectTitle = string.Empty;
                if (row["ProjectTitle"] != DBNull.Value)
                    projectTitle = row["ProjectTitle"].ToString();

                int realStartMinute = -1;	// the position of the first minute allocation

                TimeType curType;
                if (!sticked)
                {
                    switch (priorityId)
                    {
                        case (int)Priority.Urgent:
                            curType = TimeType.WorkUrgent;
                            break;
                        case (int)Priority.VeryHigh:
                            curType = TimeType.WorkVeryHigh;
                            break;
                        case (int)Priority.High:
                            curType = TimeType.WorkHigh;
                            break;
                        case (int)Priority.Low:
                            curType = TimeType.WorkLow;
                            break;
                        default:
                            curType = TimeType.WorkNormal;
                            break;
                    }
                }
                else
                {
                    curType = TimeType.WorkPinnedUp;
                }

                DateTime objectStartDate = calendarHelper.GetCalendarDateFromUtc((DateTime)row["StartDate"]);
                if (objectStartDate < curCalDate.Date)
                    objectStartDate = curCalDate.Date;
                TimeSpan ts = objectStartDate.Subtract(curCalDate.Date);
                int minStart = (int)ts.TotalMinutes;

                bool continueFlag = false;

                int startMinute = -1;
                int endMinute;
                for (int i = minStart; i < calendarHelper.IntervalDuration; i++)
                {
                    // we should find free time
                    if (timeList[i] == TimeType.Free)
                    {
                        if (realStartMinute == 0)	// total start
                            realStartMinute = i;

                        if (startMinute < 0)	// start after some breaks
                            startMinute = i;

                        if (originalDuration <= 0)	// sticked objects can have 0 duration
                        {
                            AddRow(resultTable, calendarHelper.HighlightedItems, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(startMinute), curType, objectId, objectTypeId, objectName, taskTimeLeft, percentCompleted, priorityId, stateId, finishDate, assignmentId, assignmentName, projectTitle, mergeBreaks, isNewMessage, isOverdue);
                            continueFlag = true;
                            break;
                        }

                        timeList[i] = curType;
                        duration--;
                        freeTimeCounter--;

                        if (duration == 0 || freeTimeCounter == 0)
                        {
                            endMinute = i + 1;

                            if (startMinute < toMinute && endMinute > fromMinute)
                            {
                                startMinute = CalculateStartMinute(startMinute, realStartMinute, fromMinute, calendarHelper, timeList, ref extendToLeft, mergeBreaks, strictBorder);
                                endMinute = CalculateEndMinute(endMinute, toMinute, calendarHelper, timeList, duration, mergeBreaks, strictBorder);

                                if (startMinute < endMinute)
                                {
                                    AddRow(resultTable, calendarHelper.HighlightedItems, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), curType, objectId, objectTypeId, objectName, taskTimeLeft, percentCompleted, priorityId, stateId, finishDate, assignmentId, assignmentName, projectTitle, mergeBreaks, isNewMessage, isOverdue);
                                }
                            }
                            startMinute = -1;
                            break;
                        }
                    }
                    else // free interval break
                    {
                        if (startMinute >= 0)
                        {
                            endMinute = i;

                            if (startMinute < toMinute && endMinute > fromMinute)
                            {
                                startMinute = CalculateStartMinute(startMinute, realStartMinute, fromMinute, calendarHelper, timeList, ref extendToLeft, mergeBreaks, strictBorder);
                                endMinute = CalculateEndMinute(endMinute, toMinute, calendarHelper, timeList, duration, mergeBreaks, strictBorder);

                                if (startMinute < endMinute)
                                {
                                    AddRow(resultTable, calendarHelper.HighlightedItems, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), curType, objectId, objectTypeId, objectName, taskTimeLeft, percentCompleted, priorityId, stateId, finishDate, assignmentId, assignmentName, projectTitle, mergeBreaks, isNewMessage, isOverdue);
                                }
                            }
                            startMinute = -1;
                        }
                    }
                }

                if (continueFlag)
                    continue;

                // last interval
                if (startMinute >= 0)
                {
                    endMinute = calendarHelper.IntervalDuration;

                    if (startMinute < toMinute && endMinute > fromMinute)
                    {
                        startMinute = CalculateStartMinute(startMinute, realStartMinute, fromMinute, calendarHelper, timeList, ref extendToLeft, mergeBreaks, strictBorder);
                        endMinute = CalculateEndMinute(endMinute, toMinute, calendarHelper, timeList, duration, mergeBreaks, strictBorder);
                        if (startMinute < endMinute)
                        {
                            AddRow(resultTable, calendarHelper.HighlightedItems, userId, calendarHelper.GetUserDate(startMinute), calendarHelper.GetUserDate(endMinute), curType, objectId, objectTypeId, objectName, taskTimeLeft, percentCompleted, priorityId, stateId, finishDate, assignmentId, assignmentName, projectTitle, mergeBreaks, isNewMessage, isOverdue);
                        }
                    }
                }

                if (freeTimeCounter == 0)
                {
                    break;
                }
            }
        }