Обновление поля через рабочие процессы, лучший подход?

Меня попросили создать представление, включающее объекты, соответствующие диапазону дат. Таким образом, если поле new_date1 сущности меньше, чем сегодня, а его поле new_date2 больше, чем сегодня, сущность должна появиться во вложенной сетке в форме.

К сожалению, вы не можете сделать это с простыми представлениями, так как FetchXML не поддерживает вычисления и операторы, которые могли бы вернуть сегодняшнюю дату.

Мне пришла в голову идея создать поле Active для объекта, а затем установить правила javascript для этого поля в зависимости от введенного диапазона дат.

Затем представление может использовать поле Active в качестве критерия фильтрации.

Проблема заключается в том, что если форма объекта не открывается в течение некоторого времени, объект может стать неактивным (например, сегодняшняя дата больше date1 и date2), но если пользователи не открывают форму объекта, поле не будет обновляться. себя, и в представлении неактивные объекты будут отображаться как активные.

Поэтому я подумал о том, чтобы запланированный рабочий процесс собирал все объекты, которые должны быть активными или неактивными, а затем этот рабочий процесс запускает дочерние рабочие процессы, которые либо устанавливают флаг Active в значение да, либо нет.

Вот немного кода:

private void LaunchUpdateOpportunityWorkflow(IOrganizationService service, ITracingService tracingService, DataCollection<Entity> collection, bool active)
{

        foreach (Entity entity in collection)
        {
            //launch a different workflow, depending on whether we want it active or inactive...
            Guid wfId = (active) ? setActiveWorkflowId : setInactiveWorkflowId;
            ExecuteWorkflowRequest execRequest = new ExecuteWorkflowRequest();
            execRequest.WorkflowId = wfId;
            execRequest.EntityId = (Guid)entity["opportunityid"];

            try
            {
                CrmServiceExtensions.ExecuteWithRetry<ExecuteWorkflowResponse>(service, execRequest);
            }
            catch (Exception ex)
            {
                tracingService.Trace(string.Format("Error executing workflow for opportunity {0}: {1}", entity["opportunityid"], ex.Message));
            }
        }

}

Процесс сбора соответствующих DataCollection осуществляется с помощью простых RetrieveMultipleRequest запросов.

Проблема с этим подходом заключается в том, что если сервер перезагружается, кто-то должен пойти и запустить рабочий процесс, который запускает приведенный выше код.

Есть ли лучший подход к этому? Я использую MS CRM 2016.


person Francis Ducharme    schedule 24.05.2016    source источник
comment
какая у вас точная версия CRM?   -  person Guido Preite    schedule 25.05.2016
comment
@GuidoPreite 2016, отредактировал мой вопрос.   -  person Francis Ducharme    schedule 25.05.2016


Ответы (2)


В дополнение к ответу Джеймса, если критерии фильтрации усложняются, когда их нельзя достичь с помощью fetchxml, вы всегда можете использовать плагин.

Зарегистрируйте плагин на сообщение «RetrieveMultiple».

var queryExpression = PluginExecutionContext.InputParameters["Query"];
if(queryExpression == null || !queryExpression.EntityName.equals("yourentityname", StringComparison.InvariantCultureIgnoreCase) return;

Добавьте условие, уникальное для расширенного поиска, потому что нет способа отфильтровать, какой расширенный поиск запускает плагин для вашей сущности, самый простой способ добиться этого — добавить атрибут и использовать его в запросе расширенного поиска. .

Проверьте условие, если оно найдено, пользователь пытается запустить расширенный поиск, который вы настроили:

if (queryExpression.Criteria == null || queryExpression.Criteria.Conditions == null ||
!queryExpression.Criteria.Conditions.Any()) return;

Найдите соответствующее условие, чтобы удалить его и добавить условия, по которым вы хотите отфильтровать данные:

 var matchContidion = queryExpression.Criteria.Conditions.FirstOrDefault(c => c.AttributeName == "yourflagattribute");
 if (matchContidion == null) return;

Удалите фиктивные критерии соответствия и добавьте свои собственные критерии:

queryExpression.Criteria.Conditions.Remove(matchContidion);
queryExpression.Criteria.Conditions.Add(new ConditionExpression("new_date1", ConditionOperator.LessThan, DateTime.Now));
queryExpression.Criteria.Conditions.Add(new ConditionExpression("new_field2", ConditionOperator.Equals, "Some complex value which cannot be set using fetchxml")); //for example, based on certain values, you might want to call a webservice to get the filter value. 
person dynamicallyCRM    schedule 24.05.2016

Я думаю, вы, вероятно, можете добиться этого с помощью FetchXML.

new_date1 поле меньше, чем сегодня

Это старше 24 часов.

new_date2 поле больше, чем сегодня

Это любая дата в будущем, поэтому, предполагая, что ваши даты не далее 100 лет в будущем, вы можете использовать «Следующие X лет».

введите здесь описание изображения

Как заметил Даррен Льюис, старше 24 часов может быть и не вчерашний день, в зависимости от вашего определения вчерашнего дня. В этом случае попробуйте использовать Last X Years.

введите здесь описание изображения

person James Wood    schedule 24.05.2016
comment
Просто имейте в виду, что это не даст вам все записи со вчерашнего дня, которые, как я полагаю, ищет OP на основе их критериев меньше, чем сегодня. - person Darren Lewis; 25.05.2016
comment
@DarrenLewis, о да, я думаю, что Last X Years добьются цели, - person James Wood; 25.05.2016