Beispiel #1
0
        public IEnumerable <TimeBox> ArrangeSeat(Entity site, int bufferLength, bool isMatchingRank,
                                                 IgnoreAgentPriority agentPriorityMethodology, DateTime start, DateTime end, SeatingEngineStatus engineStatus)
        {
            _status         = engineStatus;
            _isMatchingRank = isMatchingRank;
            _bufferLength   = bufferLength;

            _employeeSeatOccupationRegister = new Dictionary <ISimpleEmployee, List <List <SeatArrangement> > >();
            _employeeAssignmentRegister     = new Dictionary <TimeBox, List <Fork> >();
            _termOccupationRegister         = new Dictionary <ISeatingTerm, List <List <SeatArrangement> > >();

            IEnumerable <List <SeatArrangement> > occupationList;
            IEnumerable <ISeat> seatList;

            #region StatusMessage

            int   temp1 = 0;
            int[] occupationData;
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EngineGeatherInfo", DateTime.Now);
            #endregion

            #region // Prepare Data //

            var getSeat =
                new Func <string, Seat>(seat => _seatBoxSet.ContainsKey(seat) ? _seatBoxSet[seat].Seat : default(Seat));
            var addSeatArrangement =
                new Func <string, SeatArrangement, bool>(
                    (seat, seatArrangement) => _seatBoxSet[seat].AddOccupation(seatArrangement));

            foreach (var timeBox in _agentsOnSeat)
            {
                timeBox.GetAllTerm <Term>(start, end).GenSeatArrangements(timeBox.Agent, getSeat, addSeatArrangement);
            }

            foreach (var timeBox in _participaters)
            {
                var filteredTerms = timeBox.GetAllTermWithoutOffWork <Term>(start, end, o =>
                {
                    return(o.GetLowestTerm().If <ISeatingTerm>(x => x.ArrangeSeatYet() && x.StartIsCoverd(start, end)));
                }).ToArray();

                timeBox.GetAllTerm <Term>(start, end).GenSeatArrangements(timeBox.Agent, getSeat, addSeatArrangement);

                var    prv = default(Term);
                var    seatArrangementGroup = new List <SeatArrangement>();
                var    occupationGroup      = new List <List <SeatArrangement> >();
                Action finalStep            = () => { };

                var agent = timeBox.Agent;

                filteredTerms.SliceOccupied((dateRange, term) =>
                {
                    if (term == null || !term.IsNeedSeat)
                    {
                        prv = term;
                        return(default(SeatArrangement));
                    }

                    if (prv != null && !ReferenceEquals(prv, term) && prv.Level == 0 && term.Level == 0)
                    {
                        prv = null;
                    }

                    var source = default(Term);
                    TermExt.X(prv, term, ref source);

                    var instance = default(SeatArrangement);

                    if (source.If(o => o.SeatIsEmpty()) == true)
                    {
                        instance = new SeatArrangement(source, agent, dateRange.Start, dateRange.End)
                        {
                            Remark = "ByEngine"
                        };

                        var isOccupiedUnlaoredSubevent = new Func <Term, bool>(o => o.GetIsNeedSeatField() && o is UnlaboredSubEvent);

                        if (isOccupiedUnlaoredSubevent(source) || (source.Level > 1 && source.SeatIsEmpty() && isOccupiedUnlaoredSubevent(source.Bottom)))
                        {
                            seatArrangementGroup.Add(instance);
                        }
                        else
                        {
                            var key = (Term)term.GetLowestTerm();
                            if (!_termOccupationRegister.ContainsKey(key))
                            {
                                _termOccupationRegister[key] = new List <List <SeatArrangement> >();
                            }
                            _termOccupationRegister[key].Add(seatArrangementGroup);

                            if (seatArrangementGroup.Count > 0)
                            {
                                occupationGroup.Add(seatArrangementGroup);
                            }

                            if (term is IAssignment)
                            {
                                _status.AssignmentAmount += 1;
                            }
                            seatArrangementGroup = new List <SeatArrangement>(new[] { instance });
                            finalStep            = () =>
                            {
                                _termOccupationRegister[key].Add(seatArrangementGroup);
                                occupationGroup.Add(seatArrangementGroup);
                            };
                        }
                    }

                    prv = term;
                    return(instance);
                }, t => t.IsNeedSeat);

                finalStep();

                _employeeSeatOccupationRegister.Add(timeBox.Agent, occupationGroup);
                _employeeAssignmentRegister.Add(timeBox, filteredTerms.GetFork());
            }

            //TODO: load exist occupations

            _seatOccupationRegister = _seatBoxSet.Values
                                      .ToDictionary(o => o.Seat as ISeatingSeat, o => o.Occupations.ToList());

            #region StatusMessage
            _status.EmployeeAmount = _employeeAssignmentRegister.Count;
            //foreach (List<Fork> fkList in _employeeAssignmentRegister.Values)
            //    temp1 += fkList.Count;
            //_status.AssignmentAmount = 0;
            temp1 = 0;
            foreach (List <List <SeatArrangement> > soList in _employeeSeatOccupationRegister.Values)
            {
                foreach (List <SeatArrangement> sooList in soList)
                {
                    temp1 += sooList.Count;
                }
            }
            _status.SeatArrangementAmount = temp1;
            _status.TextMessage          += "\n";
            _status.TextMessage          += string.Format("{0} : EngineStartSeating", DateTime.Now);
            #endregion
            #endregion

            #region // Consolidation Rule  Active //

            foreach (var consolidationRule in _seatConsolidationRepository.GetByStie(site))
            {
                if (!_seatsMap.Keys.Contains(consolidationRule.TargetSeat.Area))
                {
                    continue;
                }
                seatList       = GetSeatByRule(consolidationRule, _seatsMap[consolidationRule.TargetSeat.Area], true);
                occupationList = GetOccupationByConsolidationRule(consolidationRule);
                foreach (var seat in seatList)
                {
                    foreach (var seatArrangement in occupationList)
                    {
                        SetOccupationSeat(seatArrangement, seat);
                    }
                }
            }
            // debug
            //Console.WriteLine("=============================");
            // debug
            #region StatusMessage
            _status.Process = 0.25;
            occupationData  = getState();

            _status.Stage1ArrangedAmount    = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage1ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage1ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount       = occupationData[2];
            _status.TotalContinueAssignmentPercentage   = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount       = occupationData[1];
            _status.ArrangedSeatArrangementPercentage   = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount     = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.TextMessage += "\n";
            _status.TextMessage += String.Format("{0} : EngineConsolidationFinish", DateTime.Now);

            #endregion

            #endregion

            #region // Seat Priority Employee Active //

            int priorityEmployeeIndexMax = Math.Min(4 - (int)agentPriorityMethodology, 3);
            for (int priorityEmployeeIndex = 0; priorityEmployeeIndex < priorityEmployeeIndexMax; priorityEmployeeIndex++)
            {
                foreach (var item in _priorityEmployeeSet)
                {
                    var priorityEmployeeConut = item.Value.Count;

                    if (priorityEmployeeIndex >= priorityEmployeeConut)
                    {
                        continue;
                    }

                    occupationList = GetOccupationByEmployee(item.Value[priorityEmployeeIndex].Object);
                    foreach (List <SeatArrangement> iso in occupationList)
                    {
                        SetOccupationSeat(iso, item.Key);
                    }
                }

                #region StatusMessage
                _status.Process = 0.25 + 0.25 * priorityEmployeeIndex / 3;
                occupationData  = getState();
                _status.Stage2ArrangedAmount[priorityEmployeeIndex]     = occupationData[1] - _status.ArrangedSeatArrangementAmount;
                _status.Stage2ArrangedPercentage[priorityEmployeeIndex] = 100 * (double)_status.Stage2ArrangedAmount[priorityEmployeeIndex] / (double)_status.SeatArrangementAmount;
                //_status.Stage2ArrangedAmount = _status.Stage2ArrangedAmount;
                //_status.Stage2ArrangedPercentage = _status.Stage2ArrangedPercentage;

                _status.TotalContinueAssignmentAmount       = occupationData[2];
                _status.TotalContinueAssignmentPercentage   = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
                _status.ArrangedSeatArrangementAmount       = occupationData[1];
                _status.ArrangedSeatArrangementPercentage   = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
                _status.UnArrangedSeatArrangementAmount     = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
                _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;

                _status.TextMessage += "\n";
                _status.TextMessage += string.Format("{0} : EnginePriorityEmployee {1} Finish", DateTime.Now, priorityEmployeeIndex);

                #endregion
            }
            #endregion

            #region // Seat Priority Organization Active //

            foreach (var area in _seatsMap)
            {
                foreach (var seat in area.Value)
                {
                    if (seat.PriorityOrganization == null)
                    {
                        continue;
                    }

                    //var seatRank = seat.Rank;
                    occupationList = GetOccupationByOrganization(seat.PriorityOrganization,
                                                                 rank => true, skills => true, o => true);

                    foreach (List <SeatArrangement> occupation in occupationList)
                    {
                        SetOccupationSeat(occupation, seat);
                    }
                }
            }

            #region StatusMessage
            _status.Process = 0.75;
            occupationData  = getState();
            _status.Stage3ArrangedAmount    = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage3ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage3ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount       = occupationData[2];
            _status.TotalContinueAssignmentPercentage   = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount       = occupationData[1];
            _status.ArrangedSeatArrangementPercentage   = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount     = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EnginePriorityOrgFinish", DateTime.Now);

            #endregion
            #endregion

            #region // Area Priority Organization Active //

            OrganizationSeatingArea organizationSeatingRule;

            int priorityOrganizationIndexMax = _organizationSeatingAreaSet.Values.Max(o => o.Length);


            for (int index = 0; index < priorityOrganizationIndexMax; index++)
            {
                foreach (var item in _organizationSeatingAreaSet.OrderBy(o => o.Key.SaftyGetProperty <int, IIndexable>(i => i.Index)))
                {
                    if (index >= item.Value.Length)
                    {
                        continue;
                    }
                    organizationSeatingRule = item.Value[index];
                    seatList = GetSeatByRule(organizationSeatingRule, _seatsMap[item.Key], false);

                    occupationList = GetOccupationByOrganization(organizationSeatingRule.Object,
                                                                 rank => true,
                                                                 skill => true, o => true);
                    foreach (var seat in seatList)
                    {
                        //var seatRank = seat.Rank;
                        foreach (List <SeatArrangement> iso in occupationList)
                        {
                            SetOccupationSeat(iso, seat);
                        }
                    }
                }
            }
            #endregion

            #region // Clear Partial Assignment and ReAssign AssignmentWise //
            //foreach (var kvp in _termOccupationRegister)
            //{
            //    if (CheckAssignmentState(kvp.Key) == AssignmentSeatingState.Partial)
            //    {
            //        foreach (var iso in kvp.Value)
            //        {
            //            if (iso.Seat != default(ISeat))
            //            {
            //                _seatOccupationRegister[iso.Seat].Remove(iso);
            //                iso.Seat = default(ISeat);
            //            }
            //        }
            //    }
            //}
            //for (int index = 0; index < priorityOrganizationIndexMax; index++)
            //{
            //    foreach (var item in _seatsMap)
            //    {
            //        var area = item.Key;

            //        if (index >= _organizationSeatingAreaSet[area].Length)
            //            continue;

            //        var orderedServiceOrganizations = _organizationSeatingAreaSet[area];

            //        organizationSeatingRule = orderedServiceOrganizations[index];

            //        // try arrange Assignment-wise
            //        foreach (ISeatingTerm isa in GetAssignmentByOrganization(organizationSeatingRule.Object, rank => true))
            //        {
            //            var seatArrangementList = _termOccupationRegister.ContainsKey(isa) ? _termOccupationRegister[isa] : null;

            //            if (seatArrangementList == null)
            //                continue;

            //            bool isAssignmentSuccess = true;
            //            foreach (var iso in seatArrangementList)
            //            {
            //                bool isOccupationSuccess = false;
            //                seatList = GetSeatByRule(organizationSeatingRule, item.Value, false);
            //                foreach (var iss in seatList.Where(st => _isMatchingRank ? st.Rank <= iso.Agent.Rank : true))
            //                {
            //                    if (SetOccupationSeat(iso, iss))
            //                    {
            //                        isOccupationSuccess = true;
            //                        break;
            //                    }
            //                }
            //                if (!isOccupationSuccess)
            //                {
            //                    isAssignmentSuccess = false;
            //                    break;
            //                }
            //            }
            //            // fail to Arrange Whole Assignment cancel Assignment
            //            if (!isAssignmentSuccess)
            //            {
            //                foreach (SeatArrangement iso in seatArrangementList)
            //                {
            //                    if (iso.Seat != default(ISeat))
            //                    {
            //                        _seatOccupationRegister[iso.Seat].Remove(iso);
            //                        iso.Seat = default(ISeat);
            //                    }
            //                }
            //            }
            //        }

            //    }
            //}
            #endregion

            #region StatusMessage
            _status.Process = 1;
            occupationData  = getState();
            _status.Stage4ArrangedAmount    = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage4ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage4ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount       = occupationData[2];
            _status.TotalContinueAssignmentPercentage   = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount       = occupationData[1];
            _status.ArrangedSeatArrangementPercentage   = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount     = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;

            _status.SeatUsageRate = GetSeatUsageRate((end - start).TotalMinutes);
            _status.TextMessage  += "\n";
            _status.TextMessage  += string.Format("{0} : EngineAreaOrgFinsish", DateTime.Now);

            #endregion

            foreach (var kvp in _termOccupationRegister)
            {
                foreach (var arrangementList in kvp.Value)
                {
                    foreach (var arrangement in arrangementList.Where(o => o.Seat != null))
                    {
                        _seatBoxSet[arrangement.Seat.Id.ToString()].AddOccupation(arrangement);
                    }
                }
            }

            //foreach (var kvp in _termOccupationRegister)
            //{
            //    var assignment = ((AssignmentBase)kvp.Key);

            //    AssignmentSeatingState checkState = CheckAssignmentState(assignment);
            //    if (checkState == AssignmentSeatingState.Empty)
            //    {
            //        assignment.OccupyStatus = "W";
            //    }
            //    else if (checkState == AssignmentSeatingState.Full)
            //    {
            //        assignment.OccupyStatus = "C";
            //    }
            //    else if (checkState == AssignmentSeatingState.FullButSeprate)
            //    {
            //        assignment.OccupyStatus = "S";
            //    }
            //    else
            //    {
            //        //throw new Exception("SeatingEngine inner exception: There is partial assignment in result.");
            //    }
            //}
            //_timeBoxRepository.Clear();
            return(_employeeAssignmentRegister.Keys);
        }
Beispiel #2
0
        public IEnumerable<TimeBox> ArrangeSeat(Entity site, int bufferLength, bool isMatchingRank,
            IgnoreAgentPriority agentPriorityMethodology, DateTime start, DateTime end, SeatingEngineStatus engineStatus)
        {
            _status = engineStatus;
            _isMatchingRank = isMatchingRank;
            _bufferLength = bufferLength;

            _employeeSeatOccupationRegister = new Dictionary<ISimpleEmployee, List<List<SeatArrangement>>>();
            _employeeAssignmentRegister = new Dictionary<TimeBox, List<Fork>>();
            _termOccupationRegister = new Dictionary<ISeatingTerm, List<List<SeatArrangement>>>();

            IEnumerable<List<SeatArrangement>> occupationList;
            IEnumerable<ISeat> seatList;

            #region StatusMessage

            int temp1 = 0;
            int[] occupationData;
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EngineGeatherInfo", DateTime.Now);
            #endregion

            #region // Prepare Data //

            var getSeat =
                new Func<string, Seat>(seat => _seatBoxSet.ContainsKey(seat) ? _seatBoxSet[seat].Seat : default(Seat));
            var addSeatArrangement =
                new Func<string, SeatArrangement, bool>(
                    (seat, seatArrangement) => _seatBoxSet[seat].AddOccupation(seatArrangement));

            foreach (var timeBox in _agentsOnSeat)
                timeBox.GetAllTerm<Term>(start, end).GenSeatArrangements(timeBox.Agent, getSeat, addSeatArrangement);

            foreach (var timeBox in _participaters)
            {
                var filteredTerms = timeBox.GetAllTermWithoutOffWork<Term>(start, end, o =>
                   {
                       return o.GetLowestTerm().If<ISeatingTerm>(x=> x.ArrangeSeatYet() && x.StartIsCoverd(start, end));
                      
                   }).ToArray();

                timeBox.GetAllTerm<Term>(start, end).GenSeatArrangements(timeBox.Agent, getSeat, addSeatArrangement);

                var prv = default(Term);
                var seatArrangementGroup = new List<SeatArrangement>();
                var occupationGroup = new List<List<SeatArrangement>>();
                Action finalStep = () => { };

                var agent = timeBox.Agent;

                filteredTerms.SliceOccupied((dateRange, term) =>
                {
                    if (term == null || !term.IsNeedSeat)
                    {
                        prv = term;
                        return default(SeatArrangement);
                    }

                    if (prv != null && !ReferenceEquals(prv, term) && prv.Level == 0 && term.Level == 0)
                    {
                        prv = null;
                    }

                    var source = default(Term);
                    TermExt.X(prv, term, ref source);

                    var instance = default(SeatArrangement);

                    if (source.If(o => o.SeatIsEmpty()) == true)
                    {
                        instance = new SeatArrangement(source, agent, dateRange.Start, dateRange.End) { Remark = "ByEngine" };

                        var isOccupiedUnlaoredSubevent = new Func<Term, bool>(o => o.GetIsNeedSeatField() && o is UnlaboredSubEvent);

                        if (isOccupiedUnlaoredSubevent(source) || (source.Level > 1 && source.SeatIsEmpty() && isOccupiedUnlaoredSubevent(source.Bottom)))
                            seatArrangementGroup.Add(instance);
                        else
                        {
                            var key = (Term)term.GetLowestTerm();
                            if (!_termOccupationRegister.ContainsKey(key))
                                _termOccupationRegister[key] = new List<List<SeatArrangement>>();
                            _termOccupationRegister[key].Add(seatArrangementGroup);

                            if (seatArrangementGroup.Count > 0)
                                occupationGroup.Add(seatArrangementGroup);

                            if (term is IAssignment)
                                _status.AssignmentAmount += 1;
                            seatArrangementGroup = new List<SeatArrangement>(new[] { instance });
                            finalStep = () =>
                            {
                                _termOccupationRegister[key].Add(seatArrangementGroup);
                                occupationGroup.Add(seatArrangementGroup);
                            };
                        }
                    }

                    prv = term;
                    return instance;
                }, t => t.IsNeedSeat);

                finalStep();

                _employeeSeatOccupationRegister.Add(timeBox.Agent, occupationGroup);
                _employeeAssignmentRegister.Add(timeBox, filteredTerms.GetFork());
            }

            //TODO: load exist occupations

            _seatOccupationRegister = _seatBoxSet.Values
                .ToDictionary(o => o.Seat as ISeatingSeat, o => o.Occupations.ToList());

            #region StatusMessage
            _status.EmployeeAmount = _employeeAssignmentRegister.Count;
            //foreach (List<Fork> fkList in _employeeAssignmentRegister.Values)
            //    temp1 += fkList.Count;
            //_status.AssignmentAmount = 0;
            temp1 = 0;
            foreach (List<List<SeatArrangement>> soList in _employeeSeatOccupationRegister.Values)
            {
                foreach (List<SeatArrangement> sooList in soList)
                    temp1 += sooList.Count;
            }
            _status.SeatArrangementAmount = temp1;
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EngineStartSeating", DateTime.Now);
            #endregion
            #endregion

            #region // Consolidation Rule  Active //

            foreach (var consolidationRule in _seatConsolidationRepository.GetByStie(site))
            {
                if (!_seatsMap.Keys.Contains(consolidationRule.TargetSeat.Area))
                    continue;
                seatList = GetSeatByRule(consolidationRule, _seatsMap[consolidationRule.TargetSeat.Area], true);
                occupationList = GetOccupationByConsolidationRule(consolidationRule);
                foreach (var seat in seatList)
                {
                    foreach (var seatArrangement in occupationList)
                        SetOccupationSeat(seatArrangement, seat);
                }
            }
            // debug
            //Console.WriteLine("=============================");
            // debug
            #region StatusMessage
            _status.Process = 0.25;
            occupationData = getState();

            _status.Stage1ArrangedAmount = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage1ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage1ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount = occupationData[2];
            _status.TotalContinueAssignmentPercentage = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount = occupationData[1];
            _status.ArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.TextMessage += "\n";
            _status.TextMessage += String.Format("{0} : EngineConsolidationFinish", DateTime.Now);

            #endregion

            #endregion

            #region // Seat Priority Employee Active //

            int priorityEmployeeIndexMax = Math.Min(4 - (int)agentPriorityMethodology, 3);
            for (int priorityEmployeeIndex = 0; priorityEmployeeIndex < priorityEmployeeIndexMax; priorityEmployeeIndex++)
            {
                foreach (var item in _priorityEmployeeSet)
                {
                    var priorityEmployeeConut = item.Value.Count;

                    if (priorityEmployeeIndex >= priorityEmployeeConut)
                        continue;

                    occupationList = GetOccupationByEmployee(item.Value[priorityEmployeeIndex].Object);
                    foreach (List<SeatArrangement> iso in occupationList)
                    {
                        SetOccupationSeat(iso, item.Key);
                    }
                }

                #region StatusMessage
                _status.Process = 0.25 + 0.25 * priorityEmployeeIndex / 3;
                occupationData = getState();
                _status.Stage2ArrangedAmount[priorityEmployeeIndex] = occupationData[1] - _status.ArrangedSeatArrangementAmount;
                _status.Stage2ArrangedPercentage[priorityEmployeeIndex] = 100 * (double)_status.Stage2ArrangedAmount[priorityEmployeeIndex] / (double)_status.SeatArrangementAmount;
                //_status.Stage2ArrangedAmount = _status.Stage2ArrangedAmount;
                //_status.Stage2ArrangedPercentage = _status.Stage2ArrangedPercentage;

                _status.TotalContinueAssignmentAmount = occupationData[2];
                _status.TotalContinueAssignmentPercentage = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
                _status.ArrangedSeatArrangementAmount = occupationData[1];
                _status.ArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
                _status.UnArrangedSeatArrangementAmount = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
                _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;

                _status.TextMessage += "\n";
                _status.TextMessage += string.Format("{0} : EnginePriorityEmployee {1} Finish", DateTime.Now, priorityEmployeeIndex);

                #endregion
            }
            #endregion

            #region // Seat Priority Organization Active //

            foreach (var area in _seatsMap)
            {
                foreach (var seat in area.Value)
                {
                    if (seat.PriorityOrganization == null)
                        continue;

                    //var seatRank = seat.Rank;
                    occupationList = GetOccupationByOrganization(seat.PriorityOrganization,
                                                                   rank => true, skills => true, o => true);

                    foreach (List<SeatArrangement> occupation in occupationList)
                        SetOccupationSeat(occupation, seat);
                }
            }

            #region StatusMessage
            _status.Process = 0.75;
            occupationData = getState();
            _status.Stage3ArrangedAmount = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage3ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage3ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount = occupationData[2];
            _status.TotalContinueAssignmentPercentage = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount = occupationData[1];
            _status.ArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EnginePriorityOrgFinish", DateTime.Now);

            #endregion
            #endregion

            #region // Area Priority Organization Active //

            OrganizationSeatingArea organizationSeatingRule;

            int priorityOrganizationIndexMax = _organizationSeatingAreaSet.Values.Max(o => o.Length);


            for (int index = 0; index < priorityOrganizationIndexMax; index++)
            {
                foreach (var item in _organizationSeatingAreaSet.OrderBy(o=> o.Key.SaftyGetProperty<int,IIndexable>(i=> i.Index)))
                {
                    if (index >= item.Value.Length)
                        continue;
                    organizationSeatingRule = item.Value[index];
                    seatList = GetSeatByRule(organizationSeatingRule, _seatsMap[item.Key], false);

                    occupationList = GetOccupationByOrganization(organizationSeatingRule.Object,
                                                            rank => true,
                                                            skill => true, o => true);
                    foreach (var seat in seatList)
                    {
                        //var seatRank = seat.Rank;
                        foreach (List<SeatArrangement> iso in occupationList)
                            SetOccupationSeat(iso, seat);
                    }
                }
            }
            #endregion

            #region // Clear Partial Assignment and ReAssign AssignmentWise //
            //foreach (var kvp in _termOccupationRegister)
            //{
            //    if (CheckAssignmentState(kvp.Key) == AssignmentSeatingState.Partial)
            //    {
            //        foreach (var iso in kvp.Value)
            //        {
            //            if (iso.Seat != default(ISeat))
            //            {
            //                _seatOccupationRegister[iso.Seat].Remove(iso);
            //                iso.Seat = default(ISeat);
            //            }
            //        }
            //    }
            //}
            //for (int index = 0; index < priorityOrganizationIndexMax; index++)
            //{
            //    foreach (var item in _seatsMap)
            //    {
            //        var area = item.Key;

            //        if (index >= _organizationSeatingAreaSet[area].Length)
            //            continue;

            //        var orderedServiceOrganizations = _organizationSeatingAreaSet[area];

            //        organizationSeatingRule = orderedServiceOrganizations[index];

            //        // try arrange Assignment-wise
            //        foreach (ISeatingTerm isa in GetAssignmentByOrganization(organizationSeatingRule.Object, rank => true))
            //        {
            //            var seatArrangementList = _termOccupationRegister.ContainsKey(isa) ? _termOccupationRegister[isa] : null;

            //            if (seatArrangementList == null)
            //                continue;

            //            bool isAssignmentSuccess = true;
            //            foreach (var iso in seatArrangementList)
            //            {
            //                bool isOccupationSuccess = false;
            //                seatList = GetSeatByRule(organizationSeatingRule, item.Value, false);
            //                foreach (var iss in seatList.Where(st => _isMatchingRank ? st.Rank <= iso.Agent.Rank : true))
            //                {
            //                    if (SetOccupationSeat(iso, iss))
            //                    {
            //                        isOccupationSuccess = true;
            //                        break;
            //                    }
            //                }
            //                if (!isOccupationSuccess)
            //                {
            //                    isAssignmentSuccess = false;
            //                    break;
            //                }
            //            }
            //            // fail to Arrange Whole Assignment cancel Assignment
            //            if (!isAssignmentSuccess)
            //            {
            //                foreach (SeatArrangement iso in seatArrangementList)
            //                {
            //                    if (iso.Seat != default(ISeat))
            //                    {
            //                        _seatOccupationRegister[iso.Seat].Remove(iso);
            //                        iso.Seat = default(ISeat);
            //                    }
            //                }
            //            }
            //        }

            //    }
            //}
            #endregion

            #region StatusMessage
            _status.Process = 1;
            occupationData = getState();
            _status.Stage4ArrangedAmount = occupationData[1] - _status.ArrangedSeatArrangementAmount;
            _status.Stage4ArrangePercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.Stage4ArrangedAmount / (double)_status.SeatArrangementAmount;

            _status.TotalContinueAssignmentAmount = occupationData[2];
            _status.TotalContinueAssignmentPercentage = _status.AssignmentAmount == 0 ? 0 : 100 * (double)_status.TotalContinueAssignmentAmount / (double)_status.AssignmentAmount;
            _status.ArrangedSeatArrangementAmount = occupationData[1];
            _status.ArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.ArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;
            _status.UnArrangedSeatArrangementAmount = _status.SeatArrangementAmount - _status.ArrangedSeatArrangementAmount;
            _status.UnArrangedSeatArrangementPercentage = _status.SeatArrangementAmount == 0 ? 0 : 100 * (double)_status.UnArrangedSeatArrangementAmount / (double)_status.SeatArrangementAmount;

            _status.SeatUsageRate = GetSeatUsageRate((end - start).TotalMinutes);
            _status.TextMessage += "\n";
            _status.TextMessage += string.Format("{0} : EngineAreaOrgFinsish", DateTime.Now);

            #endregion

            foreach (var kvp in _termOccupationRegister)
            {
                foreach (var arrangementList in kvp.Value)
                {
                    foreach (var arrangement in arrangementList.Where(o => o.Seat != null))
                    {
                        _seatBoxSet[arrangement.Seat.Id.ToString()].AddOccupation(arrangement);
                    }
                }
            }

            //foreach (var kvp in _termOccupationRegister)
            //{
            //    var assignment = ((AssignmentBase)kvp.Key);

            //    AssignmentSeatingState checkState = CheckAssignmentState(assignment);
            //    if (checkState == AssignmentSeatingState.Empty)
            //    {
            //        assignment.OccupyStatus = "W";
            //    }
            //    else if (checkState == AssignmentSeatingState.Full)
            //    {
            //        assignment.OccupyStatus = "C";
            //    }
            //    else if (checkState == AssignmentSeatingState.FullButSeprate)
            //    {
            //        assignment.OccupyStatus = "S";
            //    }
            //    else
            //    {
            //        //throw new Exception("SeatingEngine inner exception: There is partial assignment in result.");
            //    }
            //}
            //_timeBoxRepository.Clear();
            return _employeeAssignmentRegister.Keys;
        }