public Subtask ChangeStatus(Task task, Subtask subtask, TaskStatus newStatus)
        {
            if (subtask == null) throw new Exception("subtask.Task");
            if (task == null) throw new ArgumentNullException("task");
            if (task.Status == TaskStatus.Closed) throw new Exception("task can't be closed");

            if (subtask.Status == newStatus) return subtask;

            ProjectSecurity.DemandEdit(task, subtask);
           
            subtask.Status = newStatus;
            subtask.LastModifiedBy = SecurityContext.CurrentAccount.ID;
            subtask.LastModifiedOn = TenantUtil.DateTimeNow();
            subtask.StatusChangedOn = TenantUtil.DateTimeNow();

            if (subtask.Responsible.Equals(Guid.Empty))
                subtask.Responsible = SecurityContext.CurrentAccount.ID;

            var senders = GetSubscribers(task);

            if (task.Status != TaskStatus.Closed && newStatus == TaskStatus.Closed && !factory.DisableNotifications && senders.Count != 0)
                NotifyClient.Instance.SendAboutSubTaskClosing(senders, task, subtask);

            if (task.Status != TaskStatus.Closed && newStatus == TaskStatus.Open && !factory.DisableNotifications && senders.Count != 0)
                NotifyClient.Instance.SendAboutSubTaskResumed(senders, task, subtask);

            return subtaskDao.Save(subtask);
        }
 public override Subtask Save(Subtask subtask)
 {
     if (subtask != null)
     {
         ResetCache(subtask.ID);
     }
     return base.Save(subtask);
 }
 public SubtaskWrapper(Subtask subtask, Task task)
 {
     Id = subtask.ID;
     Title = subtask.Title;
     Status = (int)subtask.Status;
     if (subtask.Responsible != Guid.Empty)
     {
         Responsible = EmployeeWraper.Get(subtask.Responsible);
     }
     Created = (ApiDateTime)subtask.CreateOn;
     CreatedBy = EmployeeWraper.Get(subtask.CreateBy);
     Updated = (ApiDateTime)subtask.LastModifiedOn;
     if (subtask.CreateBy != subtask.LastModifiedBy)
     {
         UpdatedBy = EmployeeWraper.Get(subtask.LastModifiedBy);
     }
     CanEdit = ProjectSecurity.CanEdit(task, subtask);
 }
        public Subtask ChangeStatus(Task task, Subtask subtask, TaskStatus newStatus)
        {
            if (subtask == null) throw new Exception("subtask.Task");
            if (task == null) throw new ArgumentNullException("task");
            if (task.Status == TaskStatus.Closed) throw new Exception("task can't be closed");

            if (subtask.Status == newStatus) return subtask;

            ProjectSecurity.DemandEdit(task, subtask);
           
            switch (newStatus)
            {
                case TaskStatus.Closed:
                    TimeLinePublisher.Subtask(subtask, task, EngineResource.ActionText_Closed, UserActivityConstants.ActivityActionType, UserActivityConstants.ImportantActivity);
                    break;

                case TaskStatus.Open:
                    TimeLinePublisher.Subtask(subtask, task, subtask.Status == TaskStatus.Closed ? EngineResource.ActionText_Reopen : EngineResource.ActionText_Accept, UserActivityConstants.ActivityActionType, UserActivityConstants.SmallActivity);
                    break;
            }

            subtask.Status = newStatus;
            subtask.LastModifiedBy = SecurityContext.CurrentAccount.ID;
            subtask.LastModifiedOn = TenantUtil.DateTimeNow();
            subtask.StatusChangedOn = TenantUtil.DateTimeNow();

            if (subtask.Responsible.Equals(Guid.Empty))
                subtask.Responsible = SecurityContext.CurrentAccount.ID;

            var objectID = task.UniqID + "_" + task.Project.ID;
            var senders = NotifySource.Instance.GetSubscriptionProvider().GetRecipients(NotifyConstants.Event_NewCommentForTask, objectID).ToList();
            senders.RemoveAll(r => r.ID == SecurityContext.CurrentAccount.ID.ToString());

            if (task.Status != TaskStatus.Closed && newStatus == TaskStatus.Closed && !_factory.DisableNotifications && senders.Count != 0)
                NotifyClient.Instance.SendAboutSubTaskClosing(senders, task, subtask);

            if (task.Status != TaskStatus.Closed && newStatus == TaskStatus.Open && !_factory.DisableNotifications && senders.Count != 0)
                NotifyClient.Instance.SendAboutSubTaskResumed(senders, task, subtask);

            return _subtaskDao.Save(subtask);
        }
        private void NotifySubtask(Task task, Subtask subtask, List<IRecipient> recipients, bool isNew)
        {
            //Don't send anything if notifications are disabled
            if (_factory.DisableNotifications) return;

            if (isNew && recipients.Any())
            {
                NotifyClient.Instance.SendAboutSubTaskCreating(recipients, task, subtask);
            }

            if (subtask.Responsible.Equals(Guid.Empty) || subtask.Responsible.Equals(SecurityContext.CurrentAccount.ID)) return;

            if (!_factory.GetTaskEngine().IsUnsubscribedToTask(task, subtask.Responsible.ToString()))
                NotifyClient.Instance.SendAboutResponsibleBySubTask(subtask, task);
        }
        public Subtask SaveOrUpdate(Subtask subtask, Task task)
        {
            if (subtask == null) throw new Exception("subtask.Task");
            if (task == null) throw new ArgumentNullException("task");
            if (task.Status == TaskStatus.Closed) throw new Exception("task can't be closed");

            var isNew = subtask.ID == default(int); //Task is new

            subtask.LastModifiedBy = SecurityContext.CurrentAccount.ID;
            subtask.LastModifiedOn = TenantUtil.DateTimeNow();

            if (isNew)
            {
                if (subtask.CreateBy == default(Guid)) subtask.CreateBy = SecurityContext.CurrentAccount.ID;
                if (subtask.CreateOn == default(DateTime)) subtask.CreateOn = TenantUtil.DateTimeNow();

                ProjectSecurity.DemandEdit(task);
                subtask = _subtaskDao.Save(subtask);
                TimeLinePublisher.Subtask(subtask, task, EngineResource.ActionText_Create,
                                          UserActivityConstants.ContentActionType, UserActivityConstants.NormalContent);
            }
            else
            {
                //changed task
                ProjectSecurity.DemandEdit(task, GetById(subtask.ID));
                subtask = _subtaskDao.Save(subtask);
                TimeLinePublisher.Subtask(subtask, task, EngineResource.ActionText_Update,
                                          UserActivityConstants.ActivityActionType, UserActivityConstants.NormalActivity);
            }

            var objectID = task.UniqID + "_" + task.Project.ID;
            var recipients = NotifySource.Instance.GetSubscriptionProvider().GetRecipients(NotifyConstants.Event_NewCommentForTask, objectID)
                .Where(r => r.ID != SecurityContext.CurrentAccount.ID.ToString() && r.ID != subtask.Responsible.ToString() && r.ID != subtask.CreateBy.ToString())
                .ToList();

            NotifySubtask(task, subtask, recipients, isNew);

            var senders = new HashSet<Guid> { subtask.Responsible, subtask.CreateBy };
            senders.Remove(Guid.Empty);

            foreach (var sender in senders)
            {
                _factory.GetTaskEngine().SubscribeToTask(task, sender);
            }

            return subtask;
        }
 public static void DemandEdit(Task task, Subtask subtask)
 {
     if (!CanEdit(task, subtask)) throw CreateSecurityException();
 }
        public static bool CanEdit(Task task, Subtask subtask)
        {
            if (!Can(subtask)) return false;
            if (CanEdit(task)) return true;

            return IsInTeam(task.Project) &&
                   (subtask.CreateBy == CurrentUserId ||
                    subtask.Responsible == CurrentUserId);
        }
 public static bool CanRead(Subtask subtask)
 {
     if (!IsProjectsEnabled(CurrentUserId)) return false;
     if (subtask == null) return false;
     return subtask.Responsible == CurrentUserId;
 }
        public void SendAboutSubTaskEditing(List<IRecipient> recipients, Task task, Subtask subtask)
        {
            var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), ""));
            client.AddInterceptor(interceptor);

            try
            {
                client.SendNoticeToAsync(
                    NotifyConstants.Event_SubTaskEdited,
                    task.NotifyId,
                    recipients.ToArray(),
                    true,
                    new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
                    new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
                    new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
                    new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
                    new TagValue(NotifyConstants.Tag_EntityID, task.ID),
                    new TagValue(NotifyConstants.Tag_Responsible,
                                 !subtask.Responsible.Equals(Guid.Empty)
                                     ? ToRecipient(subtask.Responsible).Name
                                     : PatternResource.subtaskWithoutResponsible),
                    ReplyToTagProvider.Comment("project.task", task.ID.ToString(CultureInfo.InvariantCulture)));
            }
            finally
            {
                client.RemoveInterceptor(interceptor.Name);
            }
        }
        public SubtaskWrapper AddSubtask(int taskid, Guid responsible, string title)
        {
            if (string.IsNullOrEmpty(title)) throw new ArgumentException(@"title can't be empty", "title");
            var task = EngineFactory.GetTaskEngine().GetByID(taskid).NotFoundIfNull();

            if (task.Status == TaskStatus.Closed) throw new ArgumentException(@"task can't be closed");

            var subtask = new Subtask
                {
                    Responsible = responsible,
                    Task = task.ID,
                    Status = TaskStatus.Open,
                    Title = title
                };

            subtask = EngineFactory.GetSubtaskEngine().SaveOrUpdate(subtask, task);
            MessageService.Send(Request, MessageAction.SubtaskCreated, task.Project.Title, task.Title, subtask.Title);

            return new SubtaskWrapper(subtask, task);
        }
Exemple #12
0
        public void SendAboutSubTaskDeleting(List<IRecipient> recipients, Task task, Subtask subtask)
        {
            client.SendNoticeToAsync(
                NotifyConstants.Event_SubTaskDeleted,
                task.NotifyId,
                recipients.ToArray(),
                GetDefaultSenders(recipients.FirstOrDefault()),
                null,
                new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
                new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
                new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
                new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
                new TagValue(NotifyConstants.Tag_EntityID, task.ID),
                new TagValue(NotifyConstants.Tag_AdditionalData, new Hashtable { { "TaskDescription", HttpUtility.HtmlEncode(task.Description) } }),
                ReplyToTagProvider.Comment("project.task", task.ID.ToString()));

        }
        public static void Subtask(Subtask subtask, Task task, String actionText, int actionType, int businessValue)
        {
            //DropProjectActivitiesCache(task.Project);
            UserActivityPublisher.Publish<TimeLinePublisher>(new TimeLineUserActivity(actionText, actionType, businessValue)
            {

                ContentID = (task != null) ? task.ToString() : String.Empty,
                ContainerID = task.Project.ID.ToString(),
                Title = subtask.Title,
                URL = String.Concat(VirtualPathUtility.ToAbsolute(ConfigurationManager.BaseVirtualPath + "tasks.aspx").Replace("api/", ""), String.Format("?prjID={0}&id={1}", task.Project.ID, task.ID)),
                AdditionalData = String.Format(AdditionalDataPattern, EntityType.SubTask, (task != null) ? task.Title : String.Empty, task.Project.Title),
                SecurityId = string.Format(SecurityDataPattern, EntityType.SubTask, task.ID, task.Project.ID),
                HtmlPreview = null
            });
        }
 public void SendAboutResponsibleBySubTask(Subtask subtask, Task task)
 {
     var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), ""));
     client.AddInterceptor(interceptor);
     try
     {
         var recipient = ToRecipient(subtask.Responsible);
         if (recipient != null)
         {
             client.SendNoticeToAsync(
                 NotifyConstants.Event_ResponsibleForSubTask,
                 task.NotifyId,
                 new[] { recipient },
                 true,
                 new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
                 new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
                 new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
                 new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
                 new TagValue(NotifyConstants.Tag_EntityID, task.ID),
                 new TagValue(NotifyConstants.Tag_AdditionalData, new Hashtable { { "TaskDescription", HttpUtility.HtmlEncode(task.Description) } }),
                 ReplyToTagProvider.Comment("project.task", task.ID.ToString(CultureInfo.InvariantCulture)),
                 new AdditionalSenderTag("push.sender"),
                 new TagValue(PushConstants.PushItemTagName, new PushItem(PushItemType.Subtask, subtask.ID.ToString(), subtask.Title)),
                 new TagValue(PushConstants.PushParentItemTagName, new PushItem(PushItemType.Task, task.ID.ToString(), task.Title)),
                 new TagValue(PushConstants.PushModuleTagName, PushModule.Projects),
                 new TagValue(PushConstants.PushActionTagName, PushAction.Assigned));
         }
     }
     finally
     {
         client.RemoveInterceptor(interceptor.Name);
     }
 }
        public void Delete(Subtask subtask, Task task)
        {
            if (subtask == null) throw new ArgumentNullException("subtask");
            if (task == null) throw new ArgumentNullException("task");

            ProjectSecurity.DemandEdit(task, subtask);
            subtaskDao.Delete(subtask.ID);

            var recipients = GetSubscribers(task);

            if (recipients.Any())
            {
                NotifyClient.Instance.SendAboutSubTaskDeleting(recipients, task, subtask);
            }
        }
        private void NotifySubtask(Task task, Subtask subtask, bool isNew, Guid oldResponsible)
        {
            //Don't send anything if notifications are disabled
            if (factory.DisableNotifications) return;

            var recipients = GetSubscribers(task);

            if (!subtask.Responsible.Equals(Guid.Empty) && (isNew || !oldResponsible.Equals(subtask.Responsible)))
            {
                NotifyClient.Instance.SendAboutResponsibleBySubTask(subtask, task);
                recipients.RemoveAll(r => r.ID.Equals(subtask.Responsible.ToString()));
            }

            if (isNew)
            {
                NotifyClient.Instance.SendAboutSubTaskCreating(recipients, task, subtask);
            }
            else
            {
                NotifyClient.Instance.SendAboutSubTaskEditing(recipients, task, subtask);
            }
        }
        public Subtask SaveOrUpdate(Subtask subtask, Task task)
        {
            if (subtask == null) throw new Exception("subtask.Task");
            if (task == null) throw new ArgumentNullException("task");
            if (task.Status == TaskStatus.Closed) throw new Exception("task can't be closed");

            // check guest responsible
            if (ProjectSecurity.IsVisitor(subtask.Responsible))
            {
                ProjectSecurity.CreateGuestSecurityException();
            }

            var isNew = subtask.ID == default(int); //Task is new
            var oldResponsible = Guid.Empty;

            subtask.LastModifiedBy = SecurityContext.CurrentAccount.ID;
            subtask.LastModifiedOn = TenantUtil.DateTimeNow();

            if (isNew)
            {
                if (subtask.CreateBy == default(Guid)) subtask.CreateBy = SecurityContext.CurrentAccount.ID;
                if (subtask.CreateOn == default(DateTime)) subtask.CreateOn = TenantUtil.DateTimeNow();

                ProjectSecurity.DemandEdit(task);
                subtask = subtaskDao.Save(subtask);
            }
            else
            {
                var oldSubtask = subtaskDao.GetById(new[] { subtask.ID }).First();

                if (oldSubtask == null) throw new ArgumentNullException("subtask");

                oldResponsible = oldSubtask.Responsible;

                //changed task
                ProjectSecurity.DemandEdit(task, oldSubtask);
                subtask = subtaskDao.Save(subtask);
            }

            NotifySubtask(task, subtask, isNew, oldResponsible);

            var senders = new HashSet<Guid> { subtask.Responsible, subtask.CreateBy };
            senders.Remove(Guid.Empty);

            foreach (var sender in senders)
            {
                taskEngine.Subscribe(task, sender);
            }

            return subtask;
        }
        public void SendAboutSubTaskResumed(List<IRecipient> recipients, Task task, Subtask subtask)
        {
            var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), ""));
            client.AddInterceptor(interceptor);

            try
            {
                client.SendNoticeToAsync(
                    NotifyConstants.Event_SubTaskResumed,
                    task.NotifyId,
                    recipients.ToArray(),
                    true,
                    new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
                    new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
                    new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
                    new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
                    new TagValue(NotifyConstants.Tag_EntityID, task.ID),
                    ReplyToTagProvider.Comment("project.task", task.ID.ToString(CultureInfo.InvariantCulture)),
                    new AdditionalSenderTag("push.sender"),
                    new TagValue(PushConstants.PushItemTagName, new PushItem(PushItemType.Subtask, subtask.ID.ToString(CultureInfo.InvariantCulture), subtask.Title)),
                    new TagValue(PushConstants.PushParentItemTagName, new PushItem(PushItemType.Task, task.ID.ToString(CultureInfo.InvariantCulture), task.Title)),
                    new TagValue(PushConstants.PushModuleTagName, PushModule.Projects),
                    new TagValue(PushConstants.PushActionTagName, PushAction.Resumed));
            }
            finally
            {
                client.RemoveInterceptor(interceptor.Name);
            }
        }
        public void Delete(Subtask subtask, Task task)
        {
            if (subtask == null) throw new ArgumentNullException("subtask");
            if (task == null) throw new ArgumentNullException("task");

            ProjectSecurity.DemandEdit(task, subtask);
            _subtaskDao.Delete(subtask.ID);

            TimeLinePublisher.Subtask(subtask, task, EngineResource.ActionText_Delete, UserActivityConstants.ActivityActionType, UserActivityConstants.NormalActivity);

            var objectID = task.UniqID + "_" + task.Project.ID;
            var recipients = NotifySource.Instance.GetSubscriptionProvider().GetRecipients(NotifyConstants.Event_NewCommentForTask, objectID)
                            .Where(r => r.ID != SecurityContext.CurrentAccount.ID.ToString()).ToList();

            if (recipients.Any())
            {
                NotifyClient.Instance.SendAboutSubTaskDeleting(recipients, task, subtask);
            }
        }
Exemple #20
0
 public void SendAboutSubTaskResumed(List<IRecipient> recipients, Task task, Subtask subtask)
 {
     client.SendNoticeToAsync(
         NotifyConstants.Event_SubTaskResumed,
         task.NotifyId,
         recipients.ToArray(),
         GetDefaultSenders(recipients.FirstOrDefault()),
         null,
         new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
         new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
         new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
         new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
         new TagValue(NotifyConstants.Tag_EntityID, task.ID),
         ReplyToTagProvider.Comment("project.task", task.ID.ToString()));
 }
 public static bool CanRead(Subtask subtask)
 {
     if (subtask == null) return false;
     return subtask.Responsible == SecurityContext.CurrentAccount.ID;
 }
Exemple #22
0
 public void SendAboutResponsibleBySubTask(Subtask subtask, Task task)
 {
     var recipient = ToRecipient(subtask.Responsible);
     if (recipient != null)
     {
         client.SendNoticeToAsync(
             NotifyConstants.Event_ResponsibleForSubTask,
             task.NotifyId,
             new[] { recipient },
             GetDefaultSenders(recipient),
             null,
             new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
             new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
             new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
             new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
             new TagValue(NotifyConstants.Tag_EntityID, task.ID),
             new TagValue(NotifyConstants.Tag_AdditionalData, new Hashtable { { "TaskDescription", HttpUtility.HtmlEncode(task.Description) } }),
             ReplyToTagProvider.Comment("project.task", task.ID.ToString()));
     }
 }
 public void SendAboutSubTaskDeleting(List<IRecipient> recipients, Task task, Subtask subtask)
 {
     var description = !string.IsNullOrEmpty(task.Description) ? HttpUtility.HtmlEncode(task.Description) : "";
     var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), ""));
     client.AddInterceptor(interceptor);
     try
     {
         client.SendNoticeToAsync(
             NotifyConstants.Event_SubTaskDeleted,
             task.NotifyId,
             recipients.ToArray(),
             true,
             new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
             new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
             new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
             new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
             new TagValue(NotifyConstants.Tag_EntityID, task.ID),
             new TagValue(NotifyConstants.Tag_AdditionalData, new Hashtable { { "TaskDescription", description } }),
             ReplyToTagProvider.Comment("project.task", task.ID.ToString(CultureInfo.InvariantCulture)),
             new AdditionalSenderTag("push.sender"),
             new TagValue(PushConstants.PushItemTagName, new PushItem(PushItemType.Subtask, subtask.ID.ToString(CultureInfo.InvariantCulture), subtask.Title)),
             new TagValue(PushConstants.PushParentItemTagName, new PushItem(PushItemType.Task, task.ID.ToString(CultureInfo.InvariantCulture), task.Title)),
             new TagValue(PushConstants.PushModuleTagName, PushModule.Projects),
             new TagValue(PushConstants.PushActionTagName, PushAction.Deleted));
     }
     finally
     {
         client.RemoveInterceptor(interceptor.Name);
     }
 }
Exemple #24
0
        public void SendAboutSubTaskCreating(List<IRecipient> recipients, Task task, Subtask subtask)
        {
            client.SendNoticeToAsync(
                NotifyConstants.Event_SubTaskCreated,
                task.NotifyId,
                recipients.ToArray(),
                GetDefaultSenders(recipients.FirstOrDefault()),
                null,
                new TagValue(NotifyConstants.Tag_ProjectID, task.Project.ID),
                new TagValue(NotifyConstants.Tag_ProjectTitle, task.Project.Title),
                new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
                new TagValue(NotifyConstants.Tag_SubEntityTitle, subtask.Title),
                new TagValue(NotifyConstants.Tag_EntityID, task.ID),
                new TagValue(NotifyConstants.Tag_Responsible, !subtask.Responsible.Equals(Guid.Empty) ? ToRecipient(subtask.Responsible).Name : "Nobody"),
                ReplyToTagProvider.Comment("project.task", task.ID.ToString())
                );

        }
        public virtual Subtask Save(Subtask subtask)
        {
            using (var db = new DbManager(DatabaseId))
            {
                using (var tr = db.Connection.BeginTransaction())
                {
                    var insert = Insert(SubtasksTable)
                        .InColumnValue("id", subtask.ID)
                        .InColumnValue("task_id", subtask.Task)
                        .InColumnValue("title", subtask.Title)
                        .InColumnValue("responsible_id", subtask.Responsible.ToString())
                        .InColumnValue("status", subtask.Status)
                        .InColumnValue("create_by", subtask.CreateBy.ToString())
                        .InColumnValue("create_on", TenantUtil.DateTimeToUtc(subtask.CreateOn))
                        .InColumnValue("last_modified_by", subtask.LastModifiedBy.ToString())
                        .InColumnValue("last_modified_on", TenantUtil.DateTimeToUtc(subtask.LastModifiedOn))
                        .InColumnValue("status_changed", TenantUtil.DateTimeToUtc(subtask.StatusChangedOn))
                        .Identity(1, 0, true);

                    subtask.ID = db.ExecuteScalar<int>(insert);

                    tr.Commit();


                    return subtask;

                }
            }
        }
 public SubtaskWrapperFull(Subtask subtask)
     : base(subtask, subtask.ParentTask)
 {
     ParentTask = new SimpleTaskWrapper(subtask.ParentTask);
 }
        public static bool CanEdit(Task task, Subtask subtask)
        {
            if (subtask == null) return false;

            if (CanEdit(task)) return true;

            return IsInTeam(task.Project) &&
                (subtask.CreateBy == SecurityContext.CurrentAccount.ID ||
                subtask.Responsible == SecurityContext.CurrentAccount.ID);
        }