コード例 #1
0
        public DealMilestoneWrapper CreateDealMilestone(
            String title,
            String description,
            String color,
            int successProbability,
            DealMilestoneStatus stageType)
        {

            if (String.IsNullOrEmpty(title))
                throw new ArgumentException();

            if (successProbability < 0)
                successProbability = 0;

            var dealMilestone = new DealMilestone
                                    {
                                        Title = title,
                                        Color = color,
                                        Description = description,
                                        Probability = successProbability,
                                        Status = stageType
                                    };

            dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone);

            return ToDealMilestoneWrapper(dealMilestone);

        }
コード例 #2
0
        public DealMilestoneWrapper CreateDealMilestone(
            string title,
            string description,
            string color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException();

            if (string.IsNullOrEmpty(title)) throw new ArgumentException();

            if (successProbability < 0) successProbability = 0;

            var dealMilestone = new DealMilestone
                {
                    Title = title,
                    Color = color,
                    Description = description,
                    Probability = successProbability,
                    Status = stageType
                };

            dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone);
            MessageService.Send(Request, MessageAction.OpportunityStageCreated, dealMilestone.Title);

            return ToDealMilestoneWrapper(dealMilestone);
        }
コード例 #3
0
        public DealMilestoneWrapper CreateDealMilestone(
            String title,
            String description,
            String color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (String.IsNullOrEmpty(title))
            {
                throw new ArgumentException();
            }

            if (successProbability < 0)
            {
                successProbability = 0;
            }

            var dealMilestone = new DealMilestone
            {
                Title       = title,
                Color       = color,
                Description = description,
                Probability = successProbability,
                Status      = stageType
            };

            dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone);

            return(ToDealMilestoneWrapper(dealMilestone));
        }
コード例 #4
0
        public DealMilestoneWrapper UpdateDealMilestone(
            int id,
            string title,
            string description,
            string color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (!(CRMSecurity.IsAdmin))
            {
                throw CRMSecurity.CreateSecurityException();
            }

            if (id <= 0 || string.IsNullOrEmpty(title))
            {
                throw new ArgumentException();
            }

            if (successProbability < 0)
            {
                successProbability = 0;
            }

            var curDealMilestoneExist = DaoFactory.GetDealMilestoneDao().IsExist(id);

            if (!curDealMilestoneExist)
            {
                throw new ItemNotFoundException();
            }

            var dealMilestone = new DealMilestone
            {
                Title       = title,
                Color       = color,
                Description = description,
                Probability = successProbability,
                Status      = stageType,
                ID          = id
            };

            DaoFactory.GetDealMilestoneDao().Edit(dealMilestone);
            MessageService.Send(Request, MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title);

            return(ToDealMilestoneWrapper(dealMilestone));
        }
コード例 #5
0
        public DealMilestoneWrapper UpdateDealMilestone(
            int id,
            String title,
            String description,
            String color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (id <= 0)
            {
                throw new ArgumentException();
            }

            if (successProbability < 0)
            {
                successProbability = 0;
            }

            var curDealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id);

            if (curDealMilestone == null)
            {
                throw new ItemNotFoundException();
            }

            var dealMilestone = new DealMilestone
            {
                Title       = title,
                Color       = color,
                Description = description,
                Probability = successProbability,
                Status      = stageType,
                ID          = id
            };

            DaoFactory.GetDealMilestoneDao().Edit(dealMilestone);

            return(ToDealMilestoneWrapper(dealMilestone));
        }
コード例 #6
0
        public DealMilestoneWrapper CreateDealMilestone(
            string title,
            string description,
            string color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (!(CRMSecurity.IsAdmin))
            {
                throw CRMSecurity.CreateSecurityException();
            }

            if (string.IsNullOrEmpty(title))
            {
                throw new ArgumentException();
            }

            if (successProbability < 0)
            {
                successProbability = 0;
            }

            var dealMilestone = new DealMilestone
            {
                Title       = title,
                Color       = color,
                Description = description,
                Probability = successProbability,
                Status      = stageType
            };

            dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone);
            MessageService.Send(Request, MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title);

            return(ToDealMilestoneWrapper(dealMilestone));
        }
コード例 #7
0
        public IEnumerable<OpportunityWrapper> DeleteBatchDeals(
            Guid responsibleid,
            int opportunityStagesid,
            IEnumerable<string> tags,
            int contactid,
            DealMilestoneStatus? stageType,
            bool? contactAlsoIsParticipant,
            ApiDateTime fromDate,
            ApiDateTime toDate)
        {
            var deals = DaoFactory.GetDealDao().GetDeals(_context.FilterValue,
                                                         responsibleid,
                                                         opportunityStagesid,
                                                         tags,
                                                         contactid,
                                                         stageType,
                                                         contactAlsoIsParticipant,
                                                         fromDate, toDate, 0, 0, null);

            if (!deals.Any()) return Enumerable.Empty<OpportunityWrapper>();

            deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals);
            MessageService.Send(Request, MessageAction.OpportunitiesDeleted, deals.Select(d => d.ID.ToString(CultureInfo.InvariantCulture)));

            return ToListOpportunityWrapper(deals);
        }
コード例 #8
0
        public IEnumerable<OpportunityWrapper> DeleteBatchDeals(
                                                                Guid responsibleid,
                                                                int opportunityStagesid,
                                                                IEnumerable<String> tags,
                                                                int contactid,
                                                                DealMilestoneStatus? stageType,
                                                                bool? contactAlsoIsParticipant,
                                                                ApiDateTime fromDate,
                                                                ApiDateTime toDate)
        {
            var deals = DaoFactory.GetDealDao().GetDeals(_context.FilterValue,
                                             responsibleid,
                                             opportunityStagesid,
                                             tags,
                                             contactid,
                                             stageType,
                                             contactAlsoIsParticipant,
                                             fromDate, toDate, 0, 0, null);

            if (!deals.Any()) return Enumerable.Empty<OpportunityWrapper>();


            var result = ToListOpportunityWrapper(deals);

            DaoFactory.GetDealDao().DeleteBatchDeals(deals);

            return result;
        }
コード例 #9
0
ファイル: DealDao.cs プロジェクト: haoasqui/ONLYOFFICE-Server
        private List<Deal> GetCrudeDeals(
                                   String searchText,
                                   Guid responsibleID,
                                   int milestoneID,
                                   IEnumerable<String> tags,
                                   int contactID,
                                   DealMilestoneStatus? stageType,
                                   bool? contactAlsoIsParticipant,
                                   DateTime fromDate,
                                   DateTime toDate,
                                   int from,
                                   int count,
                                   OrderBy orderBy)
        {
            var sqlQuery = GetDealSqlQuery(null);

            var withParams = !(String.IsNullOrEmpty(searchText) &&
                           responsibleID == Guid.Empty &&
                           milestoneID <= 0 &&
                           (tags == null || !tags.Any()) &&
                           contactID <= 0 &&
                           stageType == null &&
                           contactAlsoIsParticipant == null &&
                           fromDate == DateTime.MinValue &&
                           toDate == DateTime.MinValue);

            var whereConditional = WhereConditional(new List<int>(),
                                                    searchText,
                                                    responsibleID,
                                                    milestoneID,
                                                    tags,
                                                    contactID,
                                                    stageType,
                                                    contactAlsoIsParticipant);



            if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue)
                sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)));
            else if (withParams && whereConditional == null)
                return new List<Deal>();

            sqlQuery.Where(whereConditional);

            if (0 < from && from < int.MaxValue)
                sqlQuery.SetFirstResult(from);

            if (0 < count && count < int.MaxValue)
                sqlQuery.SetMaxResults(count);

            if (orderBy != null && Enum.IsDefined(typeof(DealSortedByType), orderBy.SortedBy))
                switch ((DealSortedByType)orderBy.SortedBy)
                {
                    case DealSortedByType.Title:
                        sqlQuery.OrderBy("tblDeal.title", orderBy.IsAsc);
                        break;
                    case DealSortedByType.BidValue:
                        sqlQuery.OrderBy("tblDeal.bid_value", orderBy.IsAsc);
                        break;
                    case DealSortedByType.Responsible:

                        sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc)
                                .OrderBy("tblDM.sort_order", orderBy.IsAsc)
                                .OrderBy("tblDeal.contact_id", true)
                                .OrderBy("tblDeal.actual_close_date", false)
                                .OrderBy("tblDeal.expected_close_date", true)
                                .OrderBy("tblDeal.title", true);

                        break;
                    case DealSortedByType.Stage:
                        sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc)
                                .OrderBy("tblDeal.contact_id", true)
                                .OrderBy("tblDeal.actual_close_date", false)
                                .OrderBy("tblDeal.expected_close_date", true)
                                .OrderBy("tblDeal.title", true);
                        break;
                    case DealSortedByType.DateAndTime:
                        sqlQuery.OrderBy("close_date", orderBy.IsAsc);
                        break;
                    default:
                        throw new ArgumentException();
                }
            else
                sqlQuery.OrderBy("tblDM.sort_order", true)
                    .OrderBy("tblDeal.contact_id", true)
                    .OrderBy("tblDeal.title", true);

            using (var db = GetDb())
            {
                return db.ExecuteList(sqlQuery).ConvertAll(ToDeal);
            }
        }
コード例 #10
0
ファイル: CRMApi.Tag.cs プロジェクト: vipwan/CommunityServer
        public string AddTagToBatchDeals(
            Guid responsibleid,
            int opportunityStagesid,
            IEnumerable<string> tags,
            int contactid,
            DealMilestoneStatus? stageType,
            bool? contactAlsoIsParticipant,
            ApiDateTime fromDate,
            ApiDateTime toDate,
            string tagName)
        {
            var deals = DaoFactory
                .GetDealDao()
                .GetDeals(
                    _context.FilterValue,
                    responsibleid,
                    opportunityStagesid,
                    tags,
                    contactid,
                    stageType,
                    contactAlsoIsParticipant,
                    fromDate, toDate, 0, 0, null).Where(CRMSecurity.CanAccessTo).ToList();

            foreach (var deal in deals)
            {
                AddTagTo("opportunity", deal.ID, tagName);
            }
            return tagName;
        }
コード例 #11
0
ファイル: DealDao.cs プロジェクト: haoasqui/ONLYOFFICE-Server
        public int GetDealsCount(String searchText,
                                  Guid responsibleID,
                                  int milestoneID,
                                  IEnumerable<String> tags,
                                  int contactID,
                                  DealMilestoneStatus? stageType,
                                  bool? contactAlsoIsParticipant,
                                  DateTime fromDate,
                                  DateTime toDate)
        {
            var cacheKey = TenantID.ToString() +
                        "deals" +
                        SecurityContext.CurrentAccount.ID.ToString() +
                        searchText +
                        responsibleID +
                        milestoneID +
                        contactID;

            if (tags != null)
                cacheKey += String.Join("", tags.ToArray());

            if (stageType.HasValue)
                cacheKey += stageType.Value;

            if (contactAlsoIsParticipant.HasValue)
                cacheKey += contactAlsoIsParticipant.Value;

            if (fromDate != DateTime.MinValue)
                cacheKey += fromDate.ToString();

            if (toDate != DateTime.MinValue)
                cacheKey += toDate.ToString();

            var fromCache = _cache.Get(cacheKey);

            if (fromCache != null) return Convert.ToInt32(fromCache);

            var withParams = !(String.IsNullOrEmpty(searchText) &&
                               responsibleID == Guid.Empty &&
                               milestoneID <= 0 &&
                               (tags == null || !tags.Any()) &&
                               contactID <= 0 &&
                               stageType == null &&
                               contactAlsoIsParticipant == null &&
                               fromDate == DateTime.MinValue &&
                               toDate == DateTime.MinValue);

            ICollection<int> exceptIDs = CRMSecurity.GetPrivateItems(typeof(Deal)).ToList();

            int result;

            using (var db = GetDb())
            {
                if (withParams)
                {


                    var whereConditional = WhereConditional(exceptIDs, searchText, responsibleID, milestoneID, tags,
                                                            contactID, stageType, contactAlsoIsParticipant);


                    var sqlQuery = GetDealSqlQuery(whereConditional);

                    if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue)
                    {
                        sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)));

                        result = db.ExecuteList(sqlQuery).Count;

                    }
                    else if (whereConditional == null)
                    {
                        result = 0;
                    }
                    else
                    {
                        result = db.ExecuteList(sqlQuery).Count;
                    }

                }
                else
                {

                    var countWithoutPrivate = db.ExecuteScalar<int>(Query("crm_deal").SelectCount());
                    var privateCount = exceptIDs.Count;

                    if (privateCount > countWithoutPrivate)
                    {
                        _log.Error("Private deals count more than all deals");

                        privateCount = 0;
                    }

                    result = countWithoutPrivate - privateCount;
                }
            }
            if (result > 0)
                _cache.Insert(cacheKey, result, new CacheDependency(null, new[] { _dealCacheKey }), Cache.NoAbsoluteExpiration,
                                      TimeSpan.FromSeconds(30));

            return result;

        }
コード例 #12
0
ファイル: DealDao.cs プロジェクト: haoasqui/ONLYOFFICE-Server
        public List<Deal> GetDeals(
                                  String searchText,
                                  Guid responsibleID,
                                  int milestoneID,
                                  IEnumerable<String> tags,
                                  int contactID,
                                  DealMilestoneStatus? stageType,
                                  bool? contactAlsoIsParticipant,
                                  DateTime fromDate,
                                  DateTime toDate,
                                  int from,
                                  int count,
                                  OrderBy orderBy)
        {

            if (CRMSecurity.IsAdmin)
                return GetCrudeDeals(searchText,
                                     responsibleID,
                                     milestoneID,
                                     tags,
                                     contactID,
                                     stageType,
                                     contactAlsoIsParticipant,
                                     fromDate,
                                     toDate,
                                     from,
                                     count,
                                     orderBy);

            var crudeDeals = GetCrudeDeals(searchText,
                                     responsibleID,
                                     milestoneID,
                                     tags,
                                     contactID,
                                     stageType,
                                     contactAlsoIsParticipant,
                                      fromDate,
                                      toDate,
                                      0,
                                      from + count,
                                      orderBy);

            if (crudeDeals.Count == 0) return crudeDeals;

            if (crudeDeals.Count < from + count) return crudeDeals.FindAll(CRMSecurity.CanAccessTo).Skip(from).ToList();

            var result = crudeDeals.FindAll(CRMSecurity.CanAccessTo);

            if (result.Count == crudeDeals.Count) return result.Skip(from).ToList();

            var localCount = count;
            var localFrom = from + count;

            while (true)
            {
                crudeDeals = GetCrudeDeals(searchText,
                                              responsibleID,
                                              milestoneID,
                                              tags,
                                              contactID,
                                              stageType,
                                              contactAlsoIsParticipant,
                                              fromDate,
                                              toDate,
                                              localFrom,
                                              localCount,
                                              orderBy);

                if (crudeDeals.Count == 0) break;

                result.AddRange(crudeDeals.Where(CRMSecurity.CanAccessTo));

                if ((result.Count >= count + from) || (crudeDeals.Count < localCount)) break;

                localFrom += localCount;
                localCount = localCount * 2;
            }

            return result.Skip(from).Take(count).ToList();
        }
コード例 #13
0
ファイル: DealDao.cs プロジェクト: haoasqui/ONLYOFFICE-Server
        private Exp WhereConditional(
                                  ICollection<int> exceptIDs,
                                  String searchText,
                                  Guid responsibleID,
                                  int milestoneID,
                                  IEnumerable<String> tags,
                                  int contactID,
                                  DealMilestoneStatus? stageType,
                                  bool? contactAlsoIsParticipant)
        {
            var conditions = new List<Exp>();

            var ids = new List<int>();

            if (!String.IsNullOrEmpty(searchText))
            {
                searchText = searchText.Trim();

                var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray();

                if (keywords.Length > 0)
                    if (FullTextSearch.SupportModule(FullTextSearch.CRMDealsModule))
                    {
                        ids = FullTextSearch.Search(searchText, FullTextSearch.CRMDealsModule)
                            .GetIdentifiers()
                            .Select(item => Convert.ToInt32(item.Split('_')[1])).Distinct().ToList();

                        if (ids.Count == 0) return null;

                    }
                    else
                        conditions.Add(BuildLike(new[] { "tblDeal.title", "tblDeal.description" }, keywords));
            }

            if (tags != null && tags.Any())
            {
                ids = SearchByTags(EntityType.Opportunity, ids.ToArray(), tags);

                if (ids.Count == 0) return null;
            }

            if (contactID > 0)
            {
                if (contactAlsoIsParticipant.HasValue && contactAlsoIsParticipant.Value)
                {
                    var relativeContactsID = GetRelativeToEntity(contactID, EntityType.Opportunity, null).ToList();

                    if (relativeContactsID.Count == 0)
                    {
                        conditions.Add(Exp.Eq("tblDeal.contact_id", contactID));
                    }
                    else
                    {
                        if (ids.Count > 0)
                        {
                            ids = relativeContactsID.Intersect(ids).ToList();

                            if (ids.Count == 0) return null;
                        }
                        else
                        {
                            ids = relativeContactsID;
                        }
                    }
                }
                else
                {
                    conditions.Add(Exp.Eq("tblDeal.contact_id", contactID));
                }
            }

            if (0 < milestoneID && milestoneID < int.MaxValue)
            {
                conditions.Add(Exp.Eq("tblDeal.deal_milestone_id", milestoneID));
            }

            if (responsibleID != Guid.Empty)
            {
                conditions.Add(Exp.Eq("tblDeal.responsible_id", responsibleID));
            }

            if (stageType != null)
            {
                conditions.Add(Exp.Eq("tblDM.status", (int)stageType.Value));
            }

            if (ids.Count > 0)
            {
                if (exceptIDs.Count > 0)
                {
                    ids = ids.Except(exceptIDs).ToList();
                    if (ids.Count == 0) return null;
                }

                conditions.Add(Exp.In("tblDeal.id", ids));
            }
            else if (exceptIDs.Count > 0)
            {
                conditions.Add(!Exp.In("tblDeal.id", exceptIDs.ToArray()));
            }

            if (conditions.Count == 0) return null;

            return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j);
        }
コード例 #14
0
        public IEnumerable<OpportunityWrapper> GetDeals(
            Guid responsibleid,
            int opportunityStagesid,
            IEnumerable<string> tags,
            int contactid,
            DealMilestoneStatus? stageType,
            bool? contactAlsoIsParticipant,
            ApiDateTime fromDate,
            ApiDateTime toDate)
        {
            DealSortedByType dealSortedByType;

            IEnumerable<OpportunityWrapper> result;

            var searchString = _context.FilterValue;

            OrderBy dealsOrderBy;

            if (Web.CRM.Classes.EnumExtension.TryParse(_context.SortBy, true, out dealSortedByType))
            {
                dealsOrderBy = new OrderBy(dealSortedByType, !_context.SortDescending);
            }
            else if (string.IsNullOrEmpty(_context.SortBy))
            {
                dealsOrderBy = new OrderBy(DealSortedByType.Stage, true);
            }
            else
            {
                dealsOrderBy = null;
            }

            var fromIndex = (int)_context.StartIndex;
            var count = (int)_context.Count;

            if (dealsOrderBy != null)
            {
                result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals(
                    searchString,
                    responsibleid,
                    opportunityStagesid,
                    tags,
                    contactid,
                    stageType,
                    contactAlsoIsParticipant,
                    fromDate,
                    toDate,
                    fromIndex,
                    count,
                    dealsOrderBy)).ToList();

                _context.SetDataPaginated();
                _context.SetDataFiltered();
                _context.SetDataSorted();
            }
            else
            {
                result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals(
                    searchString,
                    responsibleid,
                    opportunityStagesid,
                    tags,
                    contactid,
                    stageType,
                    contactAlsoIsParticipant,
                    fromDate,
                    toDate,
                    0, 0, null)).ToList();
            }


            int totalCount;

            if (result.Count() < count)
            {
                totalCount = fromIndex + result.Count();
            }
            else
            {
                totalCount = DaoFactory
                    .GetDealDao()
                    .GetDealsCount(searchString,
                                   responsibleid,
                                   opportunityStagesid,
                                   tags,
                                   contactid,
                                   stageType,
                                   contactAlsoIsParticipant,
                                   fromDate,
                                   toDate);
            }

            _context.SetTotalCount(totalCount);

            return result.ToSmartList();
        }
コード例 #15
0
        public IEnumerable<OpportunityWrapper> SetAccessToBatchDeal(
            Guid responsibleid,
            int opportunityStagesid,
            IEnumerable<string> tags,
            int contactid,
            DealMilestoneStatus? stageType,
            bool? contactAlsoIsParticipant,
            ApiDateTime fromDate,
            ApiDateTime toDate,
            bool isPrivate,
            IEnumerable<Guid> accessList
            )
        {
            var result = new List<Deal>();
            var deals = DaoFactory.GetDealDao()
                                  .GetDeals(_context.FilterValue,
                                            responsibleid,
                                            opportunityStagesid,
                                            tags,
                                            contactid,
                                            stageType,
                                            contactAlsoIsParticipant,
                                            fromDate, toDate, 0, 0, null);
            if (!deals.Any()) return Enumerable.Empty<OpportunityWrapper>();

            foreach (var deal in deals)
            {
                if (deal == null) throw new ItemNotFoundException();

                if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue;

                SetAccessToDeal(deal.ID, isPrivate, accessList);
                result.Add(deal);
            }

            return ToListOpportunityWrapper(result);
        }
コード例 #16
0
        public DealMilestoneWrapper UpdateDealMilestone(
            int id,
            String title,
            String description,
            String color,
            int successProbability,
            DealMilestoneStatus stageType)
        {

            if (id <= 0)
                throw new ArgumentException();

            if (successProbability < 0)
                successProbability = 0;

            var curDealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id);

            if (curDealMilestone == null)
                throw new ItemNotFoundException();

            var dealMilestone = new DealMilestone
            {
                Title = title,
                Color = color,
                Description = description,
                Probability = successProbability,
                Status = stageType,
                ID = id
            };

            DaoFactory.GetDealMilestoneDao().Edit(dealMilestone);

            return ToDealMilestoneWrapper(dealMilestone);

        }
コード例 #17
0
        public DealMilestoneWrapper UpdateDealMilestone(
            int id,
            string title,
            string description,
            string color,
            int successProbability,
            DealMilestoneStatus stageType)
        {
            if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException();

            if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException();

            if (successProbability < 0) successProbability = 0;

            var curDealMilestoneExist = DaoFactory.GetDealMilestoneDao().IsExist(id);
            if (!curDealMilestoneExist) throw new ItemNotFoundException();

            var dealMilestone = new DealMilestone
                {
                    Title = title,
                    Color = color,
                    Description = description,
                    Probability = successProbability,
                    Status = stageType,
                    ID = id
                };

            DaoFactory.GetDealMilestoneDao().Edit(dealMilestone);
            MessageService.Send(Request, MessageAction.OpportunityStageUpdated, dealMilestone.Title);

            return ToDealMilestoneWrapper(dealMilestone);
        }