private void Copy(TicketPart source, ContentItemPermissionPart sourcePermissionPart, task destination, TicketContext context)
        {
            destination.name     = source.Record.Title.Length > 50 ? source.Record.Title.Substring(0, 50) : source.Record.Title;
            destination.date_due = source.Record.DueDate;

            // status
            if (source.Record.StatusRecord != null)
            {
                var status = context.StatusList.FirstOrDefault(c => c.Id == source.Record.StatusRecord.Id);
                if (status != null)
                {
                    destination.status = status.Name;
                }
            }

            // priority
            if (source.Record.PriorityRecord != null)
            {
                var priority = context.Priorities.FirstOrDefault(c => c.Id == source.Record.PriorityRecord.Id);
                if (priority != null)
                {
                    destination.priority = priority.Name;
                }
            }

            CommonPart commonPart = source.As <CommonPart>();

            if (commonPart != null && commonPart.ModifiedUtc.HasValue)
            {
                destination.date_modified = commonPart.ModifiedUtc;
            }

            destination.assigned_user_id = this.GetAssigneeUserExternalId(sourcePermissionPart);
            destination.created_by       = this.GetOwnerUserExternalId(commonPart);
        }
        private void CopySuiteCRMTasksToOrchardTickets(TicketContext context, CopyOrchardProjectToSuiteViewModel.ProjectIdentifiers syncSettings)
        {
            if (syncSettings.OrchardCollaborationProjectId == null)
            {
                throw new ArgumentNullException("OrchardCollaborationProjectId must not be null");
            }

            if (string.IsNullOrEmpty(syncSettings.SuiteCRMId))
            {
                throw new ArgumentNullException("SuiteCRMId must not be null");
            }

            List <project_task> suiteCRMTasks = context.ProjectTaskUnitOfWork.GetProjectTasks(syncSettings.SuiteCRMId).ToList();
            var orchardTickets = this.searchTicketService.SearchByDatabase(
                new PagerParametersWithSortFields()
            {
                PageSize = 0
            },
                new PostedTicketSearchViewModel {
                ProjectId = syncSettings.OrchardCollaborationProjectId
            })
                                 .Select(c => c.As <SuiteCRMTaskPart>())
                                 .Where(c => c != null)
                                 .ToList();

            foreach (var suiteCRMTask in suiteCRMTasks)
            {
                var     orchardTicket  = orchardTickets.FirstOrDefault(c => c.ExternalId == suiteCRMTask.id);
                dynamic ticketSnapshot = null;

                ContentItem ticketContentItem = null;
                bool        isNew             = false;
                if (orchardTicket == null)
                {
                    isNew             = true;
                    ticketContentItem = this.services.ContentManager.Create("Ticket");
                }
                else
                {
                    ticketContentItem = orchardTicket.ContentItem;
                    ticketSnapshot    = this.streamService.TakeSnapshot(ticketContentItem);
                }

                TicketPart          ticketPart          = ticketContentItem.As <TicketPart>();
                SuiteCRMTaskPart    taskPart            = ticketContentItem.As <SuiteCRMTaskPart>();
                AttachToProjectPart attachToProjectPart = ticketContentItem.As <AttachToProjectPart>();

                // the values will be overridde in case user doesn't care about update time (item.DoNotOverrideNewerValues == false) or
                // the target modified date is less than source modified date
                DateTime?  lastSuiteCRMChangeDate = suiteCRMTask.date_modified ?? suiteCRMTask.date_entered;
                CommonPart commonPart             = ticketPart.As <CommonPart>();
                if (!syncSettings.DoNotOverrideNewerValues ||
                    isNew ||
                    (lastSuiteCRMChangeDate.HasValue && commonPart.ModifiedUtc <= lastSuiteCRMChangeDate.Value))
                {
                    if (attachToProjectPart != null)
                    {
                        attachToProjectPart.Record.Project = new ProjectPartRecord {
                            Id = syncSettings.OrchardCollaborationProjectId.Value
                        };
                    }

                    this.Copy(suiteCRMTask, ticketPart, context);
                    this.services.ContentManager.Publish(ticketContentItem);
                    this.streamService.WriteChangesToStreamActivity(ticketContentItem, ticketSnapshot, null);
                }

                taskPart.ExternalId   = suiteCRMTask.id;
                taskPart.LastSyncTime = DateTime.UtcNow;
                taskPart.TaskType     = SuiteCRMTaskPart.SuiteCRMProjectTaskTypeValue;
            }
        }
        private void CopyOrchardTicketsToSuiteCRM(TicketContext context, CopyOrchardProjectToSuiteViewModel.ProjectIdentifiers syncSettings)
        {
            if (syncSettings.OrchardCollaborationProjectId == null)
            {
                throw new ArgumentNullException("OrchardCollaborationProjectId must not be null");
            }

            if (string.IsNullOrEmpty(syncSettings.SuiteCRMId))
            {
                throw new ArgumentNullException("SuiteCRMId must not be null");
            }

            var orchardTickets = this.searchTicketService.SearchByDatabase(new PagerParametersWithSortFields()
            {
                PageSize = 0
            }, new PostedTicketSearchViewModel {
                ProjectId = syncSettings.OrchardCollaborationProjectId
            });
            List <project_task> suiteCRMTasks = new List <project_task>();

            if (!string.IsNullOrEmpty(syncSettings.SuiteCRMId))
            {
                suiteCRMTasks.AddRange(context.ProjectTaskUnitOfWork.GetProjectTasks(syncSettings.SuiteCRMId));
            }

            foreach (var ticket in orchardTickets)
            {
                var suiteCRMTaskPart = ticket.As <SuiteCRMTaskPart>();

                if (suiteCRMTaskPart == null)
                {
                    continue;
                }

                TicketPart ticketPart = ticket.As <TicketPart>();
                ContentItemPermissionPart permissionPart = ticket.As <ContentItemPermissionPart>();

                if (ticketPart == null)
                {
                    continue;
                }

                if (!syncSettings.SyncSubTasks && ticketPart.Record.Parent != null)
                {
                    continue;
                }

                project_task suiteCRMProjectTask = null;

                if (!string.IsNullOrEmpty(suiteCRMTaskPart.ExternalId))
                {
                    suiteCRMProjectTask = suiteCRMTasks.FirstOrDefault(c => c.id == suiteCRMTaskPart.ExternalId);
                }

                if (suiteCRMProjectTask == null)
                {
                    suiteCRMProjectTask            = new project_task();
                    suiteCRMProjectTask.project_id = syncSettings.SuiteCRMId;
                    context.ProjectTaskUnitOfWork.Add(suiteCRMProjectTask);
                }

                CommonPart commonPart = ticketPart.As <CommonPart>();
                DateTime?  lastOrchardTicketChangeDate = commonPart.ModifiedUtc ?? commonPart.CreatedUtc;
                if (!syncSettings.DoNotOverrideNewerValues ||
                    suiteCRMProjectTask.date_modified == null ||
                    (lastOrchardTicketChangeDate.HasValue &&
                     suiteCRMProjectTask.date_modified.Value <= lastOrchardTicketChangeDate.Value))
                {
                    this.Copy(ticketPart, permissionPart, suiteCRMProjectTask, context);
                    context.ProjectTaskUnitOfWork.Save();
                }

                suiteCRMTaskPart.ExternalId   = suiteCRMProjectTask.id;
                suiteCRMTaskPart.LastSyncTime = DateTime.UtcNow;
                suiteCRMTaskPart.TaskType     = SuiteCRMTaskPart.SuiteCRMProjectTaskTypeValue;
                this.services.ContentManager.Publish(ticket.ContentItem);
            }
        }
        public IEnumerable <SuiteCRMTaskDetailViewModel> CopyOrchardTicketsToSuite(CopyOrchardTasksToSuiteViewModel model)
        {
            List <SuiteCRMTaskDetailViewModel> returnValue = new List <SuiteCRMTaskDetailViewModel>();

            using (var connection = Helper.GetConnection(this.services, this.Logger))
                using (SuiteCRMTaskUnitOfWork taskRepository = new SuiteCRMTaskUnitOfWork(connection))
                    using (SuiteCRMEmailAddressBeanUnitOfWork suiteCRMEmailAddressBeanUnitOfWork = new SuiteCRMEmailAddressBeanUnitOfWork(taskRepository))
                        using (SuiteCRMEmailAddressUnitOfWork suiteCRMEmailAddressUnitOfWork = new SuiteCRMEmailAddressUnitOfWork(taskRepository))
                            using (SuiteCRMProjectTaskUnitOfWork projectTasksRepository = new SuiteCRMProjectTaskUnitOfWork(taskRepository))
                                using (var suiteCRMTransaction = taskRepository.BeginTransaction())
                                {
                                    TicketContext context = new TicketContext();
                                    context.ProjectTaskUnitOfWork = projectTasksRepository;
                                    context.Priorities            = this.priorityRepository.Table.ToList();
                                    context.StatusList            = this.statusRepository.Table.ToList();

                                    try
                                    {
                                        var taskIds           = model.Tasks.Where(c => !string.IsNullOrEmpty(c.SuiteCRMId)).Select(c => c.SuiteCRMId).ToArray();
                                        var suiteTasks        = taskRepository.GetTasks(taskIds);
                                        var suiteProjectTasks = projectTasksRepository.GetTasks(taskIds);
                                        var orchardTickets    = this.services
                                                                .ContentManager
                                                                .GetMany <SuiteCRMTaskPart>(
                                            model.Tasks.Where(c => c.OrchardCollaborationTicketId.HasValue).Select(c => c.OrchardCollaborationTicketId.Value),
                                            VersionOptions.Published,
                                            new QueryHints().ExpandParts <TicketPart>());

                                        foreach (var item in model.Tasks)
                                        {
                                            if (item.OrchardCollaborationTicketId == null)
                                            {
                                                continue;
                                            }

                                            var ticket = orchardTickets.FirstOrDefault(c => c.Id == item.OrchardCollaborationTicketId.Value);

                                            var        suiteCRMTaskPart = ticket.As <SuiteCRMTaskPart>();
                                            TicketPart ticketPart       = ticket.As <TicketPart>();
                                            ContentItemPermissionPart permissionPart      = ticket.As <ContentItemPermissionPart>();
                                            AttachToProjectPart       attachToProjectPart = ticket.As <AttachToProjectPart>();
                                            SuiteCRMProjectPart       projectPart         = null;

                                            if (!this.IsSyncingTicketValid(item, ticket, out projectPart))
                                            {
                                                continue;
                                            }

                                            project_task suiteCRMProjectTask = null;
                                            task         suiteCRMTask        = null;

                                            if (!string.IsNullOrEmpty(suiteCRMTaskPart.ExternalId) && item.IsProjectTask)
                                            {
                                                suiteCRMProjectTask = suiteProjectTasks.FirstOrDefault(c => c.id == suiteCRMTaskPart.ExternalId);
                                            }

                                            if (!string.IsNullOrEmpty(suiteCRMTaskPart.ExternalId) && !item.IsProjectTask)
                                            {
                                                suiteCRMTask = suiteTasks.FirstOrDefault(c => c.id == suiteCRMTaskPart.ExternalId);
                                            }

                                            if (suiteCRMProjectTask == null && item.IsProjectTask)
                                            {
                                                suiteCRMProjectTask            = new project_task();
                                                suiteCRMProjectTask.project_id = item.SuiteCRMId;
                                                projectTasksRepository.Add(suiteCRMProjectTask);
                                            }

                                            if (suiteCRMTask == null && !item.IsProjectTask)
                                            {
                                                suiteCRMTask = new task();
                                                taskRepository.Add(suiteCRMTask);
                                            }

                                            CommonPart commonPart = ticketPart.As <CommonPart>();
                                            DateTime?  lastOrchardTicketChangeDate = commonPart.ModifiedUtc ?? commonPart.CreatedUtc;
                                            if (suiteCRMProjectTask != null &&
                                                (
                                                    !item.DoNotOverrideNewerValues ||
                                                    suiteCRMProjectTask.date_modified == null ||
                                                    (lastOrchardTicketChangeDate.HasValue &&
                                                     suiteCRMProjectTask.date_modified.Value <= lastOrchardTicketChangeDate.Value)
                                                ))
                                            {
                                                this.Copy(ticketPart, permissionPart, suiteCRMProjectTask, context);
                                                suiteCRMProjectTask.project_id = projectPart.ExternalId;
                                                projectTasksRepository.Save();
                                            }

                                            if (suiteCRMTask != null &&
                                                (
                                                    !item.DoNotOverrideNewerValues ||
                                                    suiteCRMTask.date_modified == null ||
                                                    (lastOrchardTicketChangeDate.HasValue &&
                                                     suiteCRMTask.date_modified.Value <= lastOrchardTicketChangeDate.Value)
                                                ))
                                            {
                                                this.Copy(ticketPart, permissionPart, suiteCRMTask, context);

                                                // set  contact
                                                if (string.IsNullOrEmpty(suiteCRMTask.created_by) && commonPart.Owner != null)
                                                {
                                                    var emailAddress = suiteCRMEmailAddressUnitOfWork.GetByEmail(commonPart.Owner.Email);
                                                    if (emailAddress != null)
                                                    {
                                                        var contact = suiteCRMEmailAddressBeanUnitOfWork.GetBeanIdOfEmailAddress(Helper.ContactsModuleName, new[] { emailAddress.id }).FirstOrDefault();

                                                        if (contact != null)
                                                        {
                                                            suiteCRMTask.parent_id   = contact.id;
                                                            suiteCRMTask.parent_type = Helper.ContactsModuleName;
                                                        }
                                                    }
                                                }

                                                projectTasksRepository.Save();
                                            }

                                            suiteCRMTaskPart.ExternalId   = item.IsProjectTask ? suiteCRMProjectTask.id : suiteCRMTask.id;
                                            suiteCRMTaskPart.LastSyncTime = DateTime.UtcNow;
                                            suiteCRMTaskPart.TaskType     = item.IsProjectTask ? SuiteCRMTaskPart.SuiteCRMProjectTaskTypeValue : SuiteCRMTaskPart.SuiteCRMTaskTypeValue;
                                            this.services.ContentManager.Publish(ticket.ContentItem);

                                            SuiteCRMTaskDetailViewModel returnValueItem = new SuiteCRMTaskDetailViewModel();
                                            returnValueItem.OrchardCollaborationTicket = ticket.ContentItem;
                                            returnValueItem.IsSync         = true;
                                            returnValueItem.IsProjectTask  = item.IsProjectTask;
                                            returnValueItem.LastSyncTime   = suiteCRMTaskPart.LastSyncTime;
                                            returnValueItem.SuiteCRMTaskId = suiteCRMTaskPart.ExternalId;
                                            returnValue.Add(returnValueItem);
                                        }

                                        suiteCRMTransaction.Commit();
                                    }
                                    catch (Exception ex)
                                    {
                                        suiteCRMTransaction.Rollback();
                                        throw ex;
                                    }
                                }

            return(returnValue);
        }
        public override IEnumerable <LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext)
        {
            TicketPart ticketPart = workflowContext.Content.As <TicketPart>();

            if (!workflowContext.Tokens.ContainsKey("Permission"))
            {
                this.Logger.Debug("There is no Permission among the tokens");
                return(new[] { T("Failed") });
            }

            ContentItemPermissionDetailRecord permission = (ContentItemPermissionDetailRecord)workflowContext.Tokens["Permission"];

            if (permission == null)
            {
                this.Logger.Debug("There is no Permission among the tokens");
                return(new[] { T("Failed") });
            }

            if (ticketPart == null)
            {
                this.Logger.Debug("ContentItem mismatch: Expexting TicketPart");
                return(new[] { T("Failed") });
            }

            // setup tokenizer
            Dictionary <string, object> temp = new Dictionary <string, object>();

            temp.Add(ActivityTokenProvider.PermissionDetailKey, permission);
            var titlePart = ticketPart.As <TitlePart>();

            if (titlePart != null)
            {
                temp.Add(ActivityTokenProvider.TitkeKey, titlePart);
            }

            CRMCommentPart commentPart = workflowContext.Content.As <CRMCommentPart>();

            if (commentPart != null)
            {
                temp.Add(ActivityTokenProvider.CRMCommentKey, commentPart);
            }

            string emailTemplateIdString = activityContext.GetState <string>(EmailTemplateActivityForm.EmailTemplateIdFieldName);
            int    emailTemplateId;

            if (!int.TryParse(emailTemplateIdString, out emailTemplateId))
            {
                this.Logger.Debug("There is no email Template for new Tickets");
                return(new[] { T("Failed") });
            }

            var ticketEmailTemplate = this.emailTemplateRepository.Table.First(c => c.Id == emailTemplateId);

            if (ticketEmailTemplate == null)
            {
                this.Logger.Debug("There is no email Template for new Tickets");
                return(new[] { T("Failed") });
            }

            var queued   = activityContext.GetState <bool>("Queued");
            var priority = activityContext.GetState <int>("Priority");

            var recipients = this.GetRecipients(permission);

            foreach (var recipient in recipients.Where(c => !string.IsNullOrEmpty(c.Email)))
            {
                temp.Add(ActivityTokenProvider.UserKey, recipient);
                string body    = this.tokenizer.Replace(ticketEmailTemplate.Body, temp);
                string subject = this.tokenizer.Replace(ticketEmailTemplate.Subject, temp);
                this.SendEmail(subject, body, recipient.Email, queued, priority);
            }

            return(new[] { T("Done") });
        }
        public override IEnumerable <LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext)
        {
            TicketPart                ticketPart      = workflowContext.Content.As <TicketPart>();
            CRMCommentPart            commentPart     = workflowContext.Content.As <CRMCommentPart>();
            ContentItemPermissionPart permissionsPart = workflowContext.Content.As <ContentItemPermissionPart>();

            if (ticketPart == null)
            {
                if (commentPart == null)
                {
                    this.Logger.Debug("ContentItem mismatch: Expexting TicketPart");
                    return(new[] { T("Failed") });
                }
                else
                {
                    var contentPart = this.contentManager.Get(commentPart.Record.CRMCommentsPartRecord.ContentItemRecord.Id);
                    ticketPart      = contentPart.As <TicketPart>();
                    permissionsPart = contentPart.As <ContentItemPermissionPart>();
                }
            }

            if (permissionsPart == null)
            {
                this.Logger.Debug("ContentItem mismatch: Expexting ContentItemPermissionPart ");
                return(new[] { T("Failed") });
            }

            // setup tokenizer
            Dictionary <string, object> temp = new Dictionary <string, object>();

            temp.Add("Content", workflowContext.Content);
            var titlePart = ticketPart.As <TitlePart>();

            // read email template Id
            string emailTemplateIdString = activityContext.GetState <string>(EmailTemplateActivityForm.EmailTemplateIdFieldName);
            int    emailTemplateId;

            if (!int.TryParse(emailTemplateIdString, out emailTemplateId))
            {
                this.Logger.Debug("There is no email Template for new Tickets");
                return(new[] { T("Failed") });
            }

            bool sendToRequestingUser  = this.GetBooleanValue(activityContext, EmailTemplateActivityForm.SentToRequestingUserFieldName);
            bool sendToOwner           = this.GetBooleanValue(activityContext, EmailTemplateActivityForm.SentToOwnerFieldName);
            bool sendToSharedWithUsers = this.GetBooleanValue(activityContext, EmailTemplateActivityForm.SentToSharedUsersFieldName);

            var ticketEmailTemplate = this.emailTemplateRepository.Table.First(c => c.Id == emailTemplateId);

            if (ticketEmailTemplate == null)
            {
                this.Logger.Debug("There is no email Template for new Tickets");
                return(new[] { T("Failed") });
            }

            var queued   = activityContext.GetState <bool>("Queued");
            var priority = activityContext.GetState <int>("Priority");

            List <UserPartRecord> recipients = new List <UserPartRecord>();

            if (permissionsPart.Record.Items != null)
            {
                foreach (var permission in permissionsPart.Record.Items)
                {
                    if (permission.AccessType == ContentItemPermissionAccessTypes.Assignee && sendToOwner)
                    {
                        recipients.AddRange(this.GetRecipients(permission));
                    }
                    else if (sendToSharedWithUsers)
                    {
                        recipients.AddRange(this.GetRecipients(permission));
                    }
                }
            }

            if (sendToRequestingUser)
            {
                var record = ticketPart.Record;
                if (record.RequestingUser != null)
                {
                    recipients.Add(record.RequestingUser);
                }
                else if (record.SourceId == TicketSourceTypes.Email &&
                         !string.IsNullOrEmpty(record.SourceData))
                {
                    dynamic sender = JObject.Parse(record.SourceData);
                    string  email  = sender.Email;
                    string  name   = sender.Name;
                    recipients.Add(new UserPartRecord {
                        Email = email, UserName = name
                    });
                }
            }

            // filter the redundent items
            recipients = recipients.GroupBy(c => c.Id).Select(c => c.First()).ToList();

            foreach (var recipient in recipients.Where(c => !string.IsNullOrEmpty(c.Email)))
            {
                temp[ActivityTokenProvider.UserKey] = recipient;
                string body    = this.tokenizer.Replace(ticketEmailTemplate.Body, temp);
                string subject = this.tokenizer.Replace(ticketEmailTemplate.Subject, temp);
                this.SendEmail(subject, body, recipient.Email, queued, priority);
            }

            return(new[] { T("Done") });
        }