示例#1
0
        protected override void ExecuteLogic()
        {
            var xrmContext = new XrmServiceContext(Service)
            {
                MergeOption = MergeOption.NoTracking
            };

            // get the triggering record
            var target = (Entity)Context.InputParameters["Target"];

            Log.SetRegarding(Context.PrimaryEntityName, target.Id);

            var config = CrmHelpers.GetGenericConfig(Service, Context.OrganizationId.ToString()).ToEntity <CommonConfiguration>();

            if (config.JobsPlatform != CommonConfiguration.JobsPlatformEnum.CRM)
            {
                throw new InvalidPluginExecutionException($"Cannot queue the job because target platform is not set to CRM"
                                                          + $" (current: {config.JobsPlatform}).");
            }

            Log.Log("Fetching job records ...");
            var jobRecordsQuery =
                from job in xrmContext.CustomJobSet
                where ((job.TargetDate == null || job.TargetDate < DateTime.UtcNow) &&
                       (job.StatusReason == CustomJob.StatusReasonEnum.Waiting ||
                        job.StatusReason == CustomJob.StatusReasonEnum.Retry)) ||
                (job.ModifiedOn < DateTime.UtcNow.AddMinutes(-config.JobTimeout.GetValueOrDefault(20)) &&
                 (job.StatusReason == CustomJob.StatusReasonEnum.Running ||
                  job.StatusReason == CustomJob.StatusReasonEnum.Queued))
                select new
            {
                job.CustomJobId,
                job.StatusReason
            };

            var maxJobsPerRun = xrmContext.CustomJobEngineSet.Select(engine => engine.MaxJobsPerRun).FirstOrDefault();

            if (maxJobsPerRun > 0)
            {
                jobRecordsQuery = jobRecordsQuery.Take(maxJobsPerRun.Value);
            }

            var jobRecords = jobRecordsQuery.ToList();

            Log.Log($"Fetched job records '{jobRecords.Count}'.");

            Log.Log("Fetching parent job records ...");

            var parentQuery = new FetchExpression(
                $@"
<fetch no-lock='true'>
  <entity name='ldv_customjob'>
    <attribute name='ldv_customjobid' />
    <attribute name='statuscode' />
    <filter>
      <condition attribute='statuscode' operator='eq' value='{CustomJob.StatusReasonEnum.WaitingOnSubJobs}' />
      <condition entityname='subjob' attribute='ldv_customjobid' operator='null' />
    </filter>
    <link-entity name='ldv_customjob' from='ldv_parentjobid' to='ldv_customjobid' link-type='outer' alias='subjob' >
      <filter>
        <condition attribute='statecode' operator='eq' value='0' />
      </filter>
    </link-entity>
  </entity>
</fetch>");
            var parentJobs = Service.RetrieveMultiple(parentQuery).Entities;

            Log.Log($"Fetched parent job records '{jobRecords.Count}'.");

            jobRecords = jobRecords
                         .Union(parentJobs
                                .Select(j => j.ToEntity <CustomJob>())
                                .Select(j => new { j.CustomJobId, j.StatusReason }))
                         .Where(j => j.CustomJobId.HasValue).ToList();

            Log.Log($"Fetched" +
                    $" {jobRecords.Count(job => new [] { CustomJob.StatusReasonEnum.Queued, CustomJob.StatusReasonEnum.Running, CustomJob.StatusReasonEnum.WaitingOnSubJobs }.Contains(job.StatusReason.GetValueOrDefault()))}"
                    + $" stalled job records.");

            if (jobRecords.Any())
            {
                foreach (var jobRecord in jobRecords)
                {
                    Service.Update(
                        new CustomJob
                    {
                        Id           = jobRecord.CustomJobId.GetValueOrDefault(),
                        StatusReason = CustomJob.StatusReasonEnum.Queued,
                        RunTrigger   = new Random().Next(11111, 999999).ToString()
                    });
                }

                Log.Log(new LogEntry("Queue Information",
                                     information: jobRecords.Select(record => record.ToString()).Aggregate((r1, r2) => r1 + "\r\n" + r2)));
            }

            Log.Log("Fetching date-corrupted records ...");
            var corruptJobs =
                (from job in xrmContext.CustomJobSet
                 where job.TargetDate > new DateTime(2099, 1, 1) && job.StatusReason == CustomJob.StatusReasonEnum.Waiting &&
                 job.RecurrentJob == true
                 select job.CustomJobId).ToArray().Where(id => id.HasValue).Select(id => id.GetValueOrDefault()).ToArray();

            Log.Log($"Fetched {corruptJobs.Length} date-corrupted records.");

            if (corruptJobs.Any())
            {
                Log.Log("Triggering recurrence recalculation of records ...");
                foreach (var jobId in corruptJobs)
                {
                    Service.Update(
                        new CustomJob
                    {
                        Id = jobId,
                        RecurrenceUpdatedTrigger = new Random().Next(111111, 99999999).ToString()
                    });
                    Log.Log($"Triggered recurrence recalculation of '{jobId}'.");
                }
                Log.Log("Finished triggering recurrence recalculation of records.");
            }
        }
示例#2
0
        protected override void ExecuteLogic()
        {
            // get the triggering record
            var target = Target;
            NotificationMessage message = null;

            var isEnabled = CrmHelpers
                            .GetGenericConfig(Service, Context.OrganizationId).ToEntity <CommonConfiguration>()?
                            .NotificationsCentreEnabled == true;

            if (!isEnabled)
            {
                return;
            }

            switch (target.LogicalName)
            {
            case Email.EntityLogicalName:
                var email = target.ToEntity <Email>();
                var body  = email.Description;

                // no message
                if (string.IsNullOrEmpty(body))
                {
                    return;
                }

                if (body.Contains("<html>"))
                {
                    var doc = new XmlDocument();
                    doc.LoadXml(body);
                    body = doc.SelectSingleNode("body")?.InnerXml;
                }

                // html has no body to display
                if (string.IsNullOrEmpty(body))
                {
                    return;
                }

                var users = email.To
                            .Select(e => e.Party)
                            .Where(a => a.LogicalName == User.EntityLogicalName)
                            .Select(a =>
                                    new NotificationMessageUser
                {
                    User = a.Id
                }).ToArray();

                // no users to notify
                if (!users.Any())
                {
                    return;
                }

                message =
                    new NotificationMessage
                {
                    Title              = email.Subject,
                    Message            = body,
                    RegardingTypeCode  = Email.EntityTypeCode,
                    RegardingID        = target.Id.ToString(),
                    MessageUsers       = users,
                    NotificationSource = GlobalEnums.NotificationSource.Email
                };

                break;

            case Task.EntityLogicalName:
                var task = target.ToEntity <Task>();
                message =
                    new NotificationMessage
                {
                    Title             = task.Subject,
                    Message           = task.Description,
                    RegardingTypeCode = Task.EntityTypeCode,
                    RegardingID       = target.Id.ToString()
                };

                var owner = task.Owner;

                switch (owner.LogicalName)
                {
                case User.EntityLogicalName:
                    message.MessageUsers =
                        new[]
                    {
                        new NotificationMessageUser
                        {
                            User = owner.Id
                        }
                    };
                    break;

                case Team.EntityLogicalName:
                    message.MessageTeams =
                        new[]
                    {
                        new NotificationMessageTeam
                        {
                            Team = owner.Id
                        }
                    };
                    break;
                }

                message.NotificationSource = GlobalEnums.NotificationSource.Task;

                break;
            }

            if (message != null)
            {
                message.StatusReason = NotificationMessage.StatusReasonEnum.Open;
                Service.Create(message);
            }
        }