...

Обращение к блоку в контексте процесса из другого процесса

Тема в разделе "Проблемы/ошибки", создана пользователем r.kiyamov, 12 апр 2018.

  1. r.kiyamov

    r.kiyamov Member

    Есть 2 процесса проценка доставки и доставка. Проценок бывает несколько (разные способы доставки) и в конце определяестя как именно везём и запускается доставка. Данные по доставке (что откуда куда и как) все есть в проценке. Задача - выбрать при старте доставки все проценки (экземпляры процесса проценка по сделке), дать пользователю возможность выбрать нужную, и из контексат выбранной проценки из 3 блоков (что откуда куда везём) портировать информацию в 3 подобных блока в запускаемом процессе доставка. Процессы фильтрую приекрасно но немогу докопаться до блоков в контексте отфилтрованных процессов.
    Код:
        if (context.Sale != null) {
                context.Contractor = context.Sale.Contractor;
                var header = ProcessHeaderManager.Instance.Load(750);
                    var contextFilterType = Locator.GetServiceNotNull<WorkflowInstanceContextService>().GetInstanceContextFilterType(header.Published);
                    var filter = InterfaceActivator.Create<WorkflowInstanceFilter>();
                    List<WorkflowInstanceStatus> statuses = new List<WorkflowInstanceStatus>();
                    statuses.Add(WorkflowInstanceStatus.Completed);
                    filter.Statuses = statuses;
                    filter.GeneralStatus = WorkflowInstanceGeneralStatus.Completed;
                    filter.ProcessHeader = header;
                    dynamic fl = Activator.CreateInstance(contextFilterType);
                    if (context.Sale != null)
                    {
                        fl.Sale = context.Sale;
                        filter.ContextFilter = fl;
                        filter.ProcessHeader = header;
                        var process = WorkflowInstanceManager.Instance.FindUsingContext(filter, null);
                        if (process.Count() > 0)
                        {
                            foreach (var item in process)
                            {
                                dynamic ProcessInstance = item.AsDynamic().WorkflowInstance.Context;
                                foreach(var element in (Iesi.Collections.ISet)ProcessInstance.Positions)
                                {
                                    addBloc.InstanceName = ProcessInstance.WorkflowInstance.Name;
                        if (ProcessInstance.Positions.Count > 0)
                        {
                            var positions = ProcessInstance.Positions;
                            foreach (var posEl in positions)
                            {
                                var addBloc = InterfaceActivator.Create<P_DeliveryReqest_Process>();
                                addBloc.Transport = posEl.AsDynamic.Transport;
                                addBloc.TimeStr = posEl.AsDynamic.TimeStr;
                                addBloc.PriceTo = posEl.AsDynamic.PriceTo;
                                addBloc.PriceFrom = posEl.AsDynamic.PriceFrom;
                                context.Process.Add(addBloc); //добавляем элемент в блок
                            }
                        }
                                }
                            }
                        }
                    }
    Как правильно обратиться к блоку в процессе? Статьи из базы знаний не помогают либо я не понимаю как их применить. Need Help!!
     
  2. r.kiyamov

    r.kiyamov Member

    код немного путанный главная проблема не удаётся пойти циклом по блоку в контесте. Главное в студии в отладке я вижу что он есть но так как это динамик не удаётся пустить цикл по блоку
    Код:
    dynamic ProcessInstance = item.AsDynamic().WorkflowInstance.Context;
                                foreach(var element in (Iesi.Collections.ISet)ProcessInstance.Positions)
                                {
    такое нашёл в KB но всё равно падает
     
  3. arkarimov

    arkarimov Member

    Не понимаю как этот код мог скомпилироваться
    переменная addBloc сначала идет обращение, потом создание
    AsDynamic это функция, а к ней обращаетесь как к свойству без скобок.
    Зачем то к одному и тому же блоку идет двойное обращение под разными именами (подозреваю тут и скрыта ошибка)
    Код:
    //сначала
    foreach(var element in (Iesi.Collections.ISet)ProcessInstance.Positions)
    чуть позже в этом цикле
    var positions = ProcessInstance.Positions;
    foreach (var posEl in positions)
    В целом же идея правильная что-то вроде
    Код:
    dynamic ProcessInstance = item.AsDynamic().WorkflowInstance.Context;
    foreach(var element in (Iesi.Collections.ISet)ProcessInstance.Positions)
    {
                var addBloc = InterfaceActivator.Create<P_DeliveryReqest_Process>();
                addBloc.Transport = element.AsDynamic().Transport;
                addBloc.TimeStr = element.AsDynamic().TimeStr;
                addBloc.PriceTo = element.AsDynamic().PriceTo;
                addBloc.PriceFrom = element.AsDynamic().PriceFrom;
                context.Process.Add(addBloc); //добавляем элемент в блок
    }
    
    Еще могут быть грабли с Transport если это элемент справочника, то надо его загружать типа EntityManager<Transport>.Instance.Load(element.AsDynamic().Transport.Id);
     
  4. r.kiyamov

    r.kiyamov Member

    В пример код малость кривавтый там просто было мое экспериментов и ничего не работало. Оно имено падает на строке
    Код:
    foreach(var element in (Iesi.Collections.ISet)ProcessInstance.Positions)
    {
    при попытке приведения типа
     
  5. r.kiyamov

    r.kiyamov Member

    как системе правильно донести что этот dynamic это коллекция и по ней надо идти циклом.
    что интересно в дебаге там данные то видны но оно не хочет по им идти циклом.
     
  6. r.kiyamov

    r.kiyamov Member

    это само собой тут Transport это строка это не проблема. Отдельные перемененные я выдёргивать научился.
    Подскажите как корректно запустит цикл по блоку.
     
  7. arkarimov

    arkarimov Member

    А, тогда проблема тут
    dynamic ProcessInstance = item.AsDynamic().WorkflowInstance.Context;
    Надо избежать перевода в DynamicObject
    Я это делал при помощи рефлексии
    Код:
    var q = (IWorkflowInstance)proc.GetType ().GetProperty ("WorkflowInstance").GetValue (proc, null);
    if (q != null) {
       
    }
    Но позже отказался от поиска экземпляров при помощи FindUsingContext, проще нарисовать EQL запрос и искать им используя стандартный менеджер WorkflowInstanceManager
     
  8. r.kiyamov

    r.kiyamov Member

    WorkflowInstanceManager сможет искать по контексту? Можно пример выборки процессов по значению контекстной переменной с помощью WorkflowInstanceManager?
     
  9. arkarimov

    arkarimov Member

    Он в методе Find принимает EQL запрос в том числе, а при помощи EQL немного вывихнув мозг можно найти искомые процессы хоть по контексту хоть как.
    Пример поиска в стандартном процессе улучшение
    Код:
    var instances=WorkflowInstanceManager.Instance.Find("Id In (From P_Uluchshenie SELECT WorkflowInstance where ProcessOwner= CurrentUser())");
    var instancesAll=WorkflowInstanceManager.Instance.Find("Id In (From P_Uluchshenie SELECT WorkflowInstance where Id>0)");
    Console.WriteLine(instances.Count().ToString());
    Console.WriteLine(instancesAll.Count().ToString());
    Вывод консоли
    109
    533
     
  10. r.kiyamov

    r.kiyamov Member

    Решил проблему на основе ответа от техподдержки
    Код:
    context.Contractor = context.Sale.Contractor;
                    var header = ProcessHeaderManager.Instance.Load(750);
                    var contextFilterType = Locator.GetServiceNotNull<WorkflowInstanceContextService>().GetInstanceContextFilterType(header.Published);
                    var filter = InterfaceActivator.Create<WorkflowInstanceFilter>();
                    List<WorkflowInstanceStatus> statuses = new List<WorkflowInstanceStatus>();
                    statuses.Add(WorkflowInstanceStatus.Completed);
                    filter.Statuses = statuses;
                    filter.GeneralStatus = WorkflowInstanceGeneralStatus.Completed;
                    filter.ProcessHeader = header;
                        var process = PublicAPI.Processes.WorkflowInstance.Find(filter, null);
                      
                        //context.Process.Clear();
                        if (process.Count() > 0)
                        {
                            foreach (var item in process)
                            {
                                var cnt = item.Context;
                                var saleProp = cnt.GetType().GetProperty("Sale");
                                if (saleProp != null)//Проверка на существование свойства
                                {
                                    var salePropValue = saleProp.GetValue(cnt, null);
                                    if (salePropValue != null)
                                    {
                                        var salePropValueData = salePropValue as Sale;
                                        if (salePropValueData == context.Sale)
                                        {
                                            var prop = cnt.GetType().GetProperty("Positions");
                                            if (prop != null)//Проверка на существование свойства
                                            {
                                                var rez = prop.GetValue(cnt, null);
                                                //получаем значение свойства
                                                if (rez != null)//проверка на существование значения
                                                {
                                                    var da = rez as Iesi.Collections.ISet;
                                                    //приводим объект к коллекции
                                                    foreach (var element in da)
                                                    {
                                                        dynamic newBlock1 = element;//получаем экземпляр блока для работы
                                                        var addBloc = InterfaceActivator.Create<P_DeliveryReqest_Process>();
                                                        addBloc.InstanceName = item;
                                                        addBloc.Transport = newBlock1.Transport;
                                                        addBloc.TimeStr = newBlock1.TimeStr;
                                                        addBloc.PriceTo = newBlock1.PriceTo;
                                                        addBloc.PriceFrom = newBlock1.PriceFrom;
                                                        context.Process.Add(addBloc); //добавляем элемент в блок
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
     
  11. r.kiyamov

    r.kiyamov Member

    По контексту найти вывихнув мозг не смог. саппорт подсказал метод вывиха мозга такой
    Код:
    var process = PublicAPI.Processes.WorkflowInstance.Find(filter, null);
                     
                        //context.Process.Clear();
                        if (process.Count() > 0)
                        {
                            foreach (var item in process)
                            {
                                var cnt = item.Context;
                                var saleProp = cnt.GetType().GetProperty("Sale");
                                if (saleProp != null)//Проверка на существование свойства
                                {
                                    var salePropValue = saleProp.GetValue(cnt, null);
                                    if (salePropValue != null)
                                    {
                                        var salePropValueData = salePropValue as Sale;
                                        if (salePropValueData == context.Sale)
                                        {
     
  12. r.kiyamov

    r.kiyamov Member

    Это поиск по контекстной переменной
     
  13. r.kiyamov

    r.kiyamov Member

    А это доступ к содержимому блока в контексте
    Код:
    var prop = cnt.GetType().GetProperty("Positions");
                                            if (prop != null)//Проверка на существование свойства
                                            {
                                                var rez = prop.GetValue(cnt, null);
                                                //получаем значение свойства
                                                if (rez != null)//проверка на существование значения
                                                {
                                                    var da = rez as Iesi.Collections.ISet;
                                                    //приводим объект к коллекции
                                                    foreach (var element in da)
                                                    {
                                                        dynamic newBlock1 = element;//получаем экземпляр блока для работы
    
     
  14. r.kiyamov

    r.kiyamov Member

    ключевой момент
    Код:
    var da = rez as Iesi.Collections.ISet;
                                                    //приводим объект к коллекции
                                                    foreach (var element in da)
                                                    {
                                                        dynamic newBlock1 = element;//получаем экземпляр блока для работы
     
  15. r.kiyamov

    r.kiyamov Member

    спасибо всем кто пытался помочь
     

Поделиться: