Отвечай на вопросы, используя следующий контекст:
return false;
            }
            else
            {
                List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();
                return toggledCondition.StructIds.All(structId => UncheckConditionUp(dealConditions, allProductConfigs, conditionsFilter, structId, dealConditionsStructIds));
            }
        }

        // Заполняет условия в поддереве, начиная с условия toogledStructId и вниз
        private void FillDealConditionsDown(
            DealConditionsDto dealConditions,
            Deal deal,
            ToggledCondition toggledCondition,
            KaskoConditionsFilter conditionsFilter,
            List<int> dealConditionsStructIds,
            out List<int> pastStructIds)
        {
            pastStructIds = new List<int>();

            if (toggledCondition.StructIds.Count == 0)
            {
                return;
            }

            if (toggledCondition.IsChecked || toggledCondition.IsDropDown)
            {
                // Получить дочерние условия + изменяемое условие как список (изменяемое условие делаю первым в списке для дальнейше обработки)
                var childConfigurations = conditionsFilter.GetRequiredChildProductConfigurationsFor(toggledCondition.StructIds, dealConditionsStructIds);
                var toogledProductConfigurations = conditionsFilter.GetProductConfigurationByStructIds(toggledCondition.StructIds);
                childConfigurations.InsertRange(0, toogledProductConfigurations);

                // проставить все дочерние условия
                foreach (var childConfiguration in childConfigurations)
                {
                    AddProductConfigurationToDeal(dealConditions, childConfiguration, deal, toggledCondition, false);
                    pastStructIds.Add(childConfiguration.StructId.Value);
                }
            }
            else
            {
                var childsProductConfigurationsToRemove = conditionsFilter.GetChildProductConfigurationsFor(toggledCondition.StructIds, dealConditionsStructIds);
                var toogledProductConfigurations = conditionsFilter.GetProductConfigurationByStructIds(toggledCondition.StructIds);
                if (toogledProductConfigurations.Count > 0)
                {
                    childsProductConfigurationsToRemove.AddRange(toogledProductConfigurations);
                }

                var structIdsToRemove = childsProductConfigurationsToRemove.Select(x => x.StructId.Value);

                dealConditionsStructIds.RemoveAll(x => structIdsToRemove.Contains(x));

                pastStructIds.AddRange(structIdsToRemove);
            }
        }

        /// <summary>
        /// Очищаем сделку от условий, у которых не заполнены дочерние элементы.
        /// </summary>
        /// <param name="dealConditions">Условия сделки.</param>
        private void ClearDealConditionsFromIncorrectConditions(DealConditionsDto dealConditions)
        {
            var coverages = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages).ToList();
            foreach (var coverage in coverages)
            {
                if (coverage.DealRisks == null || coverage.DealRisks.Count == 0)
                {
                    var conditionBlock = coverage.ConditionBlock;

                    if (conditionBlock == null || conditionBlock.DealOptions == null || conditionBlock.DealOptions.Count == 0)
                    {
                        var iocs = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).ToList();
                        foreach (var ioc in iocs)
                        {
                            if (ioc.DealCoverages.Contains(coverage))
                            {
                                ioc.DealCoverages.Remove(coverage);
                            }
                        }
                    }
                }
            }

            var insuranceObjectConditions = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).ToList();
            foreach (var ioc in insuranceObjectConditions)
            {
                if (ioc.DealCoverages == null || ioc.DealCoverages.Count == 0)
                {
                    var conditionGroups = dealConditions.DealConditionGroups;
                    foreach (var dealCondtionGroup in conditionGroups)
                    {
                        if (dealCondtionGroup.InsuranceObjectConditions.Contains(ioc))
                        {
                            dealCondtionGroup.InsuranceObjectConditions.Remove(ioc);
                        }
                    }
                }
            }

            var dealConditionsGroups = dealConditions.DealConditionGroups.ToList();
            foreach (var dealConditionGroup in dealConditionsGroups)
            {
                if (dealConditionGroup.InsuranceObjectConditions == null || dealConditionGroup.InsuranceObjectConditions.Count == 0)
                {
                    if (dealConditions.DealConditionGroups.Contains(dealConditionGroup))
                    {
                        dealConditions.DealConditionGroups.Remove(dealConditionGroup);
                    }
                }
            }

            if (dealConditions.DealConditionGroups == null || dealConditions.DealConditionGroups.Count == 0)
            {
                _log.Warning($"При построении условий сделки для предложения офера =  {dealConditions.Proposal.Offer_Id} были удалены все DealConditionGroups");
            }
        }

        private void FillConditionUp(
            DealConditionsDto dealConditions,
            Deal deal,
            List<ProductConfiguration> parentConfigurations,
            List<StructIdAndSum> dealConditionsStructIdsAndSums)
        {
            var conditionGroupConfig = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.ConditionGroup.ToString());
            if (conditionGroupConfig == null)
            {
                return;
            }

            AddConditionGroupToDeal(dealConditions, new ProductConfigurationAndSum(conditionGroupConfig));
            var dealConditionGroup = dealConditions.DealConditionGroups.SingleOrDefault(x => x.StructId == conditionGroupConfig.StructId);
            CorrectDealConditionGroupSum(dealConditionGroup, dealConditionsStructIdsAndSums);

            var insuranceObjectType = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.TypeIOInProduct.ToString());
            if (insuranceObjectType == null)
            {
                return;
            }

            AddInsuranceObjectConditionToDeal(dealConditions, dealConditionGroup, insuranceObjectType);
            var dealInsuranceObjectConditions = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).Where(x => x.StructId == insuranceObjectType.StructId);

            foreach (var dealInsuranceObjectCondition in dealInsuranceObjectConditions)
            {
                var coverage = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Coverage.ToString());
                if (coverage == null)
                {
                    return;
                }

                AddCoverageToDeal(dealInsuranceObjectCondition, new ProductConfigurationAndSum(coverage), deal: deal);
                var dealCoverage = dealInsuranceObjectCondition.DealCoverages.SingleOrDefault(x => x.StructId == coverage.StructId);

                var risk = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Risk.ToString());
                if (risk != null)
                {
                    AddRiskToDeal(
                        dealCoverage,
                        new ProductConfigurationAndSum(
                            risk,
                            dealConditionsStructIdsAndSums.FirstOrDefault(s => s.StructId == risk.StructId)?.Sum));
                }
            }

            return;
        }

        private bool UncheckConditionUp(
            DealConditionsDto dealConditions,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            KaskoConditionsFilter conditionsFilter,
            int toggledStructId,
            List<int> dealConditionsStructIds)
        {
            // найти все родительские условия для toggledCondition, чтобы проставить или снять их
            List<ProductConfiguration> parentConfigurations = conditionsFilter.GetParentProductConfigurationsFor(toggledStructId);
            bool isRequired = false;

            var currentNode = conditionsFilter.GetProductConfigurationByStructId(toggledStructId);

            // Берем из списка всех родительсикх условий (настроек продукта) Покрытие
            var coverage = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Coverage.ToString());

            // Если Покрытие условие существует, то проверим, сколько у него дочерних услоий может быть по структуре. Если нет ни одного или оно обязательное - удаляем покрытие
            if (coverage != null)
            {
                var dealCoverages = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions.SelectMany(ioc => ioc.DealCoverages)).Where(x => x.StructId == coverage.StructId).ToList();

                foreach (var dealCoverage in dealCoverages)
                {
                    var hasMoreThanOneChild = allProductConfigs.Values.Where(x => x.ParentStructId == coverage.StructId).Count() > 1;
                    isRequired = currentNode.IsRequired();
                    bool isMainCondition = currentNode.IsMain();

                    if (dealCoverage != null && ((!hasMoreThanOneChild && isMainCondition) || isRequired))
                    {
                        // Находим все условия объекта страхования, где есть такое покрытие и удаляем его из этих условий объекта страхования
                        var insuranceObjectConditions = dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).Where(x => x.DealCoverages.Contains(dealCoverage)).ToList();
                        foreach (var insuranceObjectCondition in insuranceObjectConditions)
                        {
                            insuranceObjectCondition.DealCoverages.Remove(dealCoverage);
                            dealConditionsStructIds.Remove(dealCoverage.StructId.Value);
                        }

                        currentNode = coverage;
                    }
                    else
                    {
                        return false;
                    }
                }
            }

            // Берем из списка всех родительсикх условий (настроек продукта) Тип ОС
            var ioType = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.TypeIOInProduct.ToString());

            // Если Тип ОС условие существует, то проверим, сколько у него дочерних услоий. Если нет ни одного - удаляем
            if (ioType != null)
            {
                var insuranceObjectConditionsStructIds = dealConditionsStructIds.Where(x => x == ioType.StructId).ToList();

                foreach (var insuranceObjectConditionStructId in insuranceObjectConditionsStructIds)
                {
                    var hasMoreThanOneChild = allProductConfigs.Values.Where(x => x.ParentStructId == ioType.StructId).Count() > 1;
                    isRequired = currentNode.IsRequired();
                    bool isMainCondition = currentNode.IsMain();

                    if ((!hasMoreThanOneChild && isMainCondition) || isRequired)
                    {
                        dealConditionsStructIds.Remove(insuranceObjectConditionStructId);

                        currentNode = ioType;
                    }
                    else
                    {
                        return false;
                    }
                }
            }

            // Берем из списка всех родительсикх условий (настроек продукта) группу условий
            var conditionGroup = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.ConditionGroup.ToString());

            // Если группа условий существует, то проверим, сколько у него дочерних услоий. Если нет ни одного - удаляем
            if (conditionGroup != null)
            {
                var dealConditionGroup = dealConditions.DealConditionGroups.SingleOrDefault(x => x.StructId == conditionGroup.StructId);
                var hasMoreThanOneChild = allProductConfigs.Values.Where(x => x.ParentStructId == conditionGroup.StructId).Count() > 1;
                isRequired = currentNode.IsRequired();
                bool isMainCondition = currentNode.IsMain();

                if ((!hasMoreThanOneChild && isMainCondition) || isRequired)
                {
                    if (dealConditionGroup != null)
                    {
                        dealConditions.DealConditionGroups.Remove(dealConditionGroup);
                    }

                    dealConditionsStructIds.Remove(conditionGroup.StructId.Value);
                }

                currentNode = conditionGroup;
            }

            var product = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Product.ToString());

            // Если продукт существует, то проверим, сколько у него дочерних услоий. Если нет ни одного - удаляем
            if (product != null)
            {
                var dealProduct = dealConditions.StructId;
                var hasMoreThanOneChild = allProductConfigs.Values.Where(x => x.ParentStructId == dealConditions.StructId).Count() > 1;
                isRequired = currentNode.IsRequired();
                bool isMainCondition = currentNode.IsMain();

                if (dealProduct != null && ((!hasMoreThanOneChild && isMainCondition) || isRequired))
                {
                    return true;
                }
            }

            return false;
        }

        private void AddProductConfigurationToDeal(
            DealConditionsDto dealConditions,
            ProductConfiguration productConfiguration,
            Deal deal,
            ToggledCondition toggledCondition,
            bool deleteOther = true)
        {
            if (productConfiguration.ParentStructId == dealConditions.StructId)
            {
                switch (productConfiguration.ProductConfigurationChildType.Name)
                {
                    case nameof(ProductConfigurationType.ConditionGroup):
                        {
                            AddConditionGroupToDeal(dealConditions, new ProductConfigurationAndSum(productConfiguration), toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.Option):
                        {
                            MakeEmptyConditionBlockIfNull(dealConditions);
                            AddOptionsToBlocks(dealConditions.DealConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.CompensationOption):
                        {
                            MakeEmptyConditionBlockIfNull(dealConditions);
                            AddCompensationOptionsToBlocks(dealConditions.DealConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                            break;
                        }
foreach (var compensationOptionConfig in compensationOptionsConfigs)
            {
                if (block.DealCompensationOptions.FirstOrDefault(x => x.StructId == compensationOptionConfig.ProductConfiguration.StructId) != null)
                {
                    return;
                }

                decimal? sum = _sumManager.GetSumForProductConfiguration(compensationOptionConfig.ProductConfiguration, toggledCondition);

                var compensationOption = new DealCompensationOptions
                {
                    StructId = compensationOptionConfig.ProductConfiguration.StructId,
                    ProductCompensationOption_Id = compensationOptionConfig.ProductConfiguration.ProductCompensationOption.Id,
                    ProductCompensationOption = compensationOptionConfig.ProductConfiguration.ProductCompensationOption,
                    Sum = sum
                };

                compensationOption.ProductCompensationOption.SetSums.ForEach(s => s.SetReadonlyState(false));
                compensationOption.ProductCompensationOption.DefaultSetSum?.SetReadonlyState(false);

                block.DealCompensationOptions.Add(compensationOption);
            }

            if (deleteOther)
            {
                // Удяляем все франшизы, кроме тех, которые добавили
                block.DealCompensationOptions = block.DealCompensationOptions.Where(x => compensationOptionsConfigs.Select(c => c.ProductConfiguration.StructId).Contains(x.StructId)).ToList();
            }
        }

        private void AddConditionGroupToDeal(DealConditionsDto dealConditions, ProductConfigurationAndSum conditionGroupConfig, ToggledCondition toggledCondition = null)
        {
            if (conditionGroupConfig == null)
            {
                return;
            }

            var resultConditionGroup = dealConditions.DealConditionGroups?.SingleOrDefault(cg => cg.StructId == conditionGroupConfig.ProductConfiguration.StructId);

            if (resultConditionGroup == null)
            {
                decimal? sum = _sumManager.GetSumForProductConfiguration(conditionGroupConfig.ProductConfiguration, toggledCondition);

                var dealConditionGroup = new DealConditionGroup
                {
                    StructId = conditionGroupConfig.ProductConfiguration.StructId,
                    ProductConditionGroup_Id = conditionGroupConfig.ProductConfiguration.ProductConditionGroup_Id,
                    ProductConditionGroup = conditionGroupConfig.ProductConfiguration.ProductConditionGroup,
                    Sum = sum
                };

                dealConditionGroup.ProductConditionGroup.SetSums.ForEach(s => s.SetReadonlyState(false));
                dealConditionGroup.ProductConditionGroup.DefaultSetSum?.SetReadonlyState(false);

                dealConditions.DealConditionGroups.Add(dealConditionGroup);
            }
        }

        private void RemoveEmptyConditionBlock(object condition, ConditionBlock conditionBlock)
        {
            if (!conditionBlock.DealOptions.Any() && !conditionBlock.DealFranchises.Any()
                && !conditionBlock.DealCompensationOptions.Any() && !conditionBlock.DealPeriods.Any())
            {
                _ = condition switch
                {
                    Deal deal => deal.ConditionBlock = null,
                    DealConditionGroup dealconditionGroup => dealconditionGroup.ConditionBlock = null,
                    InsuranceObjectCondition insuranceObjectCondition => insuranceObjectCondition.ConditionBlock = null,
                    DealCoverage dealCoverage => dealCoverage.ConditionBlock = null,
                    DealRisk dealRisk => dealRisk.ConditionBlock = null,
                    _ => throw new Exception($"Невозможно очистить ConditionBlock для типа {condition.GetType().Name}.")
                };
            }
        }

        private KaskoConditionsFilter CreateConditionsFilter(int? offerId, Deal deal, Dictionary<int, ProductConfiguration> allProductConfifurations, bool? useDrafts)
        {
            var offerIds = new int?[] { offerId };
            var dealOffers = _queryOffer.GetOffers(offerIds, deal.DateActual ?? DT.Now, useDrafts).ToList();
            return new KaskoConditionsFilter(deal, dealOffers, allProductConfifurations, offerIds);
        }

        private void MakeEmptyCollectionIfNull<T>(ObservableList<T> collection)
        {
            if (collection == null)
            {
                collection = new ObservableList<T>();
            }
        }

        private bool IsSumContains(decimal? configurationSum, IEnumerable<SetSum> setSums, decimal? defaultSum = null)
        {
            return setSums != null
                   && (setSums.Any(ss => ss.SumTypeCode == SumTypeEnum.Manual.ToString())
                       || setSums.Any(ss => ss.SumMin == configurationSum)
                       || (!setSums.Any() && defaultSum != null));
        }

        private bool IsSelectValueContains(decimal? selectValue, ProductOption productOption)
        {
            return productOption.ProductOptionSelectValues.Any(sv => sv.Value == selectValue);
        }
    }
}

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by IRIS.Designer.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using iRIS.Framework.Workflow.Process;
using iRIS.Framework.Workflow.Process.AuthorizationModel;
using iRIS.Framework.Workflow.Process.CustomProcessModel;
using iRIS.Framework.Workflow.Process.Data;
using iRIS.Framework.Workflow.UserData;

namespace iRIS.KaskoB2B.Generated.Processes.B2bKaskoSegmentationProcess.Draft
{
    public class B2bKaskoSegmentationProcess : FlowProcessModel
    {
        public const string ExitPoint_DefaultExitPoint = "Сегментация пройдена";

        private readonly ProcedureModel _setDealsDateFirstCalculation;
        private readonly CustomProcessModel _calculateBasketProcess;
        private readonly NestedProcessModel _segmentationForm;
        private readonly ProcedureModel _fillBasketSegmentsAndOffers;
        private readonly ProcedureModel _fillBasketProductsIfNotExists;
        private readonly CustomProcessModel _diKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache;
        private readonly ExitPointModel _defaultExitPoint;

        public B2bKaskoSegmentationProcess()
        {
            _setDealsDateFirstCalculation = new ProcedureModel();
            _calculateBasketProcess = new CustomProcessModel();
            _segmentationForm = new NestedProcessModel();
            _fillBasketSegmentsAndOffers = new ProcedureModel();
            _fillBasketProductsIfNotExists = new ProcedureModel();
            _diKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache = new CustomProcessModel();
            _defaultExitPoint = new ExitPointModel();

            InitializeB2bKaskoSegmentationProcess(this);

            InitializeSetDealsDateFirstCalculation(_setDealsDateFirstCalculation);
            InitializeCalculateBasketProcess(_calculateBasketProcess);
            InitializeSegmentationForm(_segmentationForm);
            InitializeFillBasketSegmentsAndOffers(_fillBasketSegmentsAndOffers);
            InitializeFillBasketProductsIfNotExists(_fillBasketProductsIfNotExists);
            InitializeDiKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache(_diKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache);
            InitializeDefaultExitPoint(_defaultExitPoint);
        }

        private void InitializeB2bKaskoSegmentationProcess(FlowProcessModel model)
        {
            model.Identifier = "B2bKaskoSegmentationProcess";
            model.Name = "Сегментация для процесса Авто";
            model.Description = @"1. Сегментация для процесса Авто";
            model.Version = "Draft";
            model.IsPrivate = true;
            model.EntityLoaderTypeName = typeof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures).AssemblyQualifiedName;
            model.ProcessResumeAccessRules = new List<FlowProcessSecurity>();
            model.ProcessStartAccessRules = new List<FlowProcessSecurity>();
            model.VariableModelInfoList = new List<ProcessVariableDefinition>();
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "Basket",
                TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.Start = _segmentationForm;
            model.NavigationStartPoints = new List<NavigationStartModel>();
        }

        private void InitializeSetDealsDateFirstCalculation(ProcedureModel model)
        {
            model.Identifier = "SetDealsDateFirstCalculation";
            model.Name = "Устанавливаем дату первого расчета";
            model.Description = @"Заполняет дату первого расчета у сделок.
        Если значение уже задано, оно остается без изменений.";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _diKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache;
            model.ExceptionNextStep = _segmentationForm;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures.SetDealsDateFirstCalculation),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializeCalculateBasketProcess(CustomProcessModel model)
        {
            model.Identifier = "CalculateBasketProcess";
            model.Name = "D8. Расчет и сохранение стоимости корзины (Рутовая корзина)";
            model.Description = @"D8. Расчет и сохранение стоимости корзины (Рутовая корзина)";
            model.ImplementationTypeName = typeof(iRIS.InsuranceCore.Code.CustomProcesses.CalculateBasketProcess).AssemblyQualifiedName;
            model.DataTypeName = typeof(iRIS.InsuranceCore.Generated.Processes.CalculationResultChanged).AssemblyQualifiedName;
            model.DefaultNextStep = _fillBasketProductsIfNotExists;
            model.ExceptionNextStep = null;
            model.InputArguments = new List<CustomProcessInputArgument>();
            model.InputArguments.Add(new CustomProcessInputArgument
            {
                Name = "Basket",
                TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                Expression = @"Basket",
            });
            model.OutputArguments = new List<CustomProcessOutputArgument>();
            model.OutputArguments.Add(new CustomProcessOutputArgument
            {
                Name = "IsCalculationResultChanged",
                TypeName = typeof(bool).AssemblyQualifiedName,
            });
            model.CustomExitPoints = new List<ProcessExitPoint>();
        }

        private void InitializeSegmentationForm(NestedProcessModel model)
        {
            model.Identifier = "SegmentationForm";
            model.Name = "Форма сегментации для процесса Авто";
            model.Description = @"1. Форма сегментации для процесса Авто";
            model.FlowProcessIdentifier = "B2bKaskoSegmentationFormProcess";
            model.FlowProcessVersion = "Draft";
            model.DataTypeName = null;
            model.ExceptionNextStep = null;
            model.InputParameters = new List<ParameterNestedModel>();
            model.InputParameters.Add(new ParameterNestedModel
            {
                Name = "Basket",
                ExpressionType = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                InExpression = @"Basket",
            });
            model.ReturnParameters = new List<ProcedureModelOutput>();
            model.NextSteps = new List<ProcessExitPoint>();
            model.NextSteps.Add(new ProcessExitPoint
            {
                Name = "Форма сегментации заполнена",
                NextStep = _fillBasketSegmentsAndOffers,
            });
        }

        private void InitializeFillBasketSegmentsAndOffers(ProcedureModel model)
        {
            model.Identifier = "FillBasketSegmentsAndOffers";
            model.Name = "Запись сегментов и офферов в Корзину";
            model.Description = @"Запись сегментов и офферов в Корзину";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _calculateBasketProcess;
            model.ExceptionNextStep = _segmentationForm;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures.FillBasketSegmentsAndOffers),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializeFillBasketProductsIfNotExists(ProcedureModel model)
        {
            model.Identifier = "FillBasketProductsIfNotExists";
            model.Name = "Заполнение продуктов Корзины, если они пустые";
            model.Description = @"Заполнение продуктов Корзины, если они пустые";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _setDealsDateFirstCalculation;
            model.ExceptionNextStep = _segmentationForm;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures.FillBasketProductsIfNotExists),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }
exitBranch = ExitBranch_TargetedSegment;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckUrm:
                        UrmApprovalStatusHelper.SetURMApprovalStatus(basket, false, comment); // возможно не нужен этот вызов, поресерчить
                        FixUrm(deal, requestGuid, processContext, integrationLoginName, logger, decision, isSensitiveDataChanged, externalBasketUrmAprovalStatus);
                        exitBranch = ExitBranch_NotTargetedSegment_CorrData;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckNoDecision:
                        UrmApprovalStatusHelper.SetURMApprovalStatus(basket, false, comment); // возможно не нужен этот вызов, поресерчить
                        FixUrm(deal, requestGuid, processContext, integrationLoginName, logger, decision, isSensitiveDataChanged, externalBasketUrmAprovalStatus);
                        exitBranch = ExitBranch_NotTargetedSegment_CorrData;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckReject:
                    default:
                        SetUrmStatus(deal, UrmApprovalStatusCodes.Rejected, requestGuid, decision);
                        AddValidationError(validationResultsAggregator);
                        exitBranch = ExitBranch_NotTargetedSegment_Reject;
                        break;
                }

                processContext.SetExitBranch(exitBranch);
                logger?.ForContext("BasketNumber", basket.Number).Information($"Переход на {exitBranch}", sw.ElapsedMilliseconds);

                var dataServiceInvoker = processContext.ServiceProvider.GetRequiredService<IDataServiceInvoker>();
                dataServiceInvoker.Publish(deal.AutoDeal, _aggregateName);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"Ошибка в работе блока {GetType().Name}");

                AddValidationError(validationResultsAggregator);

                processContext.SetExitBranch(ExitBranch_NotTargetedSegment_Reject);
                logger?.ForContext("BasketNumber", basket.Number)
                                .Information($"Переход на {ExitBranch_NotTargetedSegment_Reject}");
            }
        }

        private void SetExternalBasketUrmAprovalStatus(Deal deal, string externalBasketUrmAprovalStatus)
        {
            var lastApproval = deal.AutoDeal?.URMApproval?.LastOrDefault();
            if (lastApproval != null) 
            {
                lastApproval.URMApprovalStatusCode = externalBasketUrmAprovalStatus;
            } 
        }

        private void SetUrmStatus(Deal deal, string urmApprovalStatus, string requestGuid, string sasDecision)
        {
            var lastApproval = deal.AutoDeal.URMApproval.LastOrDefault();
            if (lastApproval != null)
            {
                lastApproval.URMApprovalComment = $"Проверка через SAS. {sasDecision}";
                lastApproval.URMApprovalStatusCode = urmApprovalStatus;
                lastApproval.ApprovalId = requestGuid;
            }
        }

        private void UpdateSasApprovalInDeal(Deal deal, string sasApprovalStatus, decimal? sasCoefficient)
        {
            if (!deal.AutoDeal.SASApproval.Any())
            {
                deal.AutoDeal.SASApproval.Add(new SASApproval { SASApprovalStatusCode = sasApprovalStatus, SasCoefficient = sasCoefficient });
            }
            else
            {
                var approval = deal.AutoDeal.SASApproval.Last();

                approval.SASApprovalStatusCode = sasApprovalStatus;
                approval.SasCoefficient = sasCoefficient;
            }
        }

        private void AddValidationError(IValidationResultsAggregator validationResultsAggregator)
        {
            validationResultsAggregator.AppendValidationErrors(new ValidationError()
            {
                ErrorMessage = "Код: 300019.Оформление невозможно",
                CriticalLevel = ValidationCriticalLevel.CantContProc
            });
        }

        /// <summary>
        /// Добавление УРМ в сделку для случая, когда объекта еще нет, и включена настройка.
        /// Установка статуса NotRequired, когда настройка выключена.
        /// </summary>
        /// <param name="deal">Сделка.</param>
        /// <param name="requestGuid">Идентификатор запроса.</param>
        /// <param name="context">Контекст процесса.</param>
        /// <param name="integrationLoginName">Имя пользователя для интеграции.</param>
        /// <param name="logger">Логгер для записи логов.</param>
        /// <param name="decision">Решение сас, принятое по сделке.</param>
        /// <param name="isSensitiveDataChanged">Чувствительные изменения при перерасчете.</param>
        /// <param name="externalBasketUrmAprovalStatus">Urm статус до перерасчета.</param>
        private void FixUrm(
            Deal deal, 
            string requestGuid, 
            IProcessContext context, 
            string integrationLoginName, 
            ILogger logger, 
            string decision, 
            bool isSensitiveDataChanged, 
            string externalBasketUrmAprovalStatus)
        {
            if (decision == KaskoSasCheckProcessConstants.KaskoSasCheckUrm && isSensitiveDataChanged && (externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.Accepted || externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.AcceptedWithLimits))
            {
                //Создаем новую заявку required
                UrmHelper.AddUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, requestGuid);
                return;
            }

            if (decision == KaskoSasCheckProcessConstants.KaskoSasCheckUrm && isSensitiveDataChanged && externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.RequiredExtraInfo)
            {
                UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, requestGuid);
                return;
            }

            bool needCheckUrm = NeedCheckUrm(decision, deal, context, integrationLoginName, logger);

            if (needCheckUrm)
            {
                UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, requestGuid);
            }
            else
            {
                UrmHelper.SetUrmApprovalNotRequired(deal);
            }
        }

        private bool NeedCheckUrm(string decision, Deal deal, IProcessContext context, string integrationLoginName, ILogger logger)
        {
            bool canSkipUrm = UrmHelper.CanSkipUrm(deal);
            bool needCheckUrmSetting = GetNeedCheckUrmKASKOSetting(context, integrationLoginName, logger);
            bool isWithoutUrmIndicatorOrNoSegments = UrmHelper.UrmCheckForWithoutURMIndicatorOrNoSegments(deal);

            return decision == KaskoSasCheckProcessConstants.KaskoSasCheckNoDecision
                ? !canSkipUrm && needCheckUrmSetting && !isWithoutUrmIndicatorOrNoSegments
                : !canSkipUrm && needCheckUrmSetting;
        }

        private bool GetNeedCheckUrmKASKOSetting(IProcessContext context, string integrationLoginName, ILogger logger)
        {
            var settingsManager = context.ServiceProvider.GetRequiredService<IEntitySettingsManager>();

            var needCheckUrmKASKOSetting = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                EntitySettingCodes.NeedCheckUrmKASKOSetting,
                EntitySettingCodes.NeedCheckUrmKASKOSettingDefault,
                EntitySettingCodes.NeedCheckUrmKASKOSettingByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLoginName },
                true,
                logger);

            return needCheckUrmKASKOSetting;
        }
    }
}
using iRIS.Framework.Data;
using iRIS.Framework.Security.Entities;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.InsuranceCore.Infrastructure.Constants;
using iRIS.KaskoCore.Code.Constants;
using iRIS.KaskoOsago.Code.Implementations.DIUnderwriterManager;
using System;
using System.Linq;

namespace iRIS.KaskoOsago.Tests.HelperData
{
    public static class EntityFactory
    {
        public static Basket CreateBasket(params string[] products)
        {
            var basket = new Basket
            {
                Deals = new ObservableList<Deal>()
                {
                    CreateDeal("OSAGO", products.Contains("OSAGO")),
                    CreateDeal("KASKO", products.Contains("KASKO"))
                }
            };

            return basket;
        }

        public static Deal CreateDeal(string productDictCode, bool? isInBasket = null)
        {
            return new Deal
            {
                IsInBasket = isInBasket,
                Product = new Product
                {
                    ProductDictCode = productDictCode
                }
            };
        }

        public static DIUnderwriterApproval CreateDIUnderwriterApproval(
            Guid uniqueId = default,
            bool? isClosed = null,
            string statusCode = "",
            string themeCode = "",
            decimal? autoCostApproval = default)
        {
            return new DIUnderwriterApproval()
            {
                IsClosed = isClosed,
                UniqueId = uniqueId,
                StatusCode = statusCode,
                ThemeCode = themeCode,
                AutoCostApproval = autoCostApproval
            };
        }

        public static Basket CreateBasketWithDIUnderwriterApprovals(ObservableList<DIUnderwriterApproval> diUnderwriterApprovals)
        {
            var basket = CreateBasket("KASKO");
            var kaskoDeal = basket.GetKaskoDeal();
            kaskoDeal.AutoDeal = new AutoDeal()
            {
                DIUnderwriterApprovals = diUnderwriterApprovals
            };
            kaskoDeal.InsuranceObjects.Add(new InsuranceObject { Auto = new Auto() });

            return basket;
        }

        public static Basket CreateBasketWithAutoCostAndHasMileage(decimal? autoCost, bool? hasMileage = null)
        {
            var basket = CreateBasket("KASKO");
            var kaskoDeal = basket.GetKaskoDeal();
            kaskoDeal.InsuranceObjects = new ObservableList<InsuranceObject>()
            {
                new InsuranceObject()
                {
                    Auto = new Auto
                    {
                        AutoCost = autoCost,
                        HasMileage = hasMileage
                    }
                }
            };

            return basket;
        }

        public static AutoDeal CreateAutoDealWithDIUnderwriterApprovals(string[] themeCodes, decimal? autoCostApproval = null, string status = "accepted", bool isClosed = true)
        {
            var autoDeal = new AutoDeal
            {
                DIUnderwriterApprovals = new ObservableList<DIUnderwriterApproval>()
            };

            foreach (var themeCode in themeCodes)
            {
                autoDeal.DIUnderwriterApprovals.Add(new DIUnderwriterApproval
                {
                    ThemeCode = themeCode,
                    AutoCostApproval = autoCostApproval,
                    StatusCode = status,
                    IsClosed = true
                });
            }

            return autoDeal;
        }

        public static DIUnderwriterCheckingRuleResult CreateDIUnderwriterCheckingRuleResult(string approvalThemeCode, bool isSucceded)
        {
            return new DIUnderwriterCheckingRuleResult
            {
                ApprovalThemeCode = approvalThemeCode,
                IsSucceded = isSucceded
            };
        }

        public static User CreateUser(string userGroup = UserGroups.CallCenter)
        {
            return new User
            {
                Groups = new ObservableList<UserGroup>
                {
                    new UserGroup
                    {
                        Name = userGroup
                    }
                }
            };
        }

        public static Deal CreateDeal(bool damageInDeal, bool totalInDeal, bool carjackingInDeal = true, bool kaskoNoPolicyInDeal = false)
        {
            var deal = new Deal
            {
                DealConditionGroups = new ObservableList<DealConditionGroup>
                {
                    new DealConditionGroup
                    {
                        StructId = 5000,
                        InsuranceObjectConditions = new ObservableList<InsuranceObjectCondition>
                        {
                            new InsuranceObjectCondition
                            {
                                StructId = 5001,
                                DealCoverages = new ObservableList<DealCoverage>
                                {
                                    new DealCoverage
                                    {
                                        StructId = 5015,
                                        DealRisks = new ObservableList<DealRisk>()
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5030,
                                        DealRisks = new ObservableList<DealRisk>()
                                    }
                                }
                            }
                        }
                    }
                }
            };

            if (damageInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5016 // Ущерб
                    });
            }

            if (totalInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5029 // Тотал
                    });
            }

            if (carjackingInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[1].DealRisks.Add(
                new DealRisk
                {
                    StructId = 5031 // Тотал
                });
            }

            if (kaskoNoPolicyInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[1].DealRisks.Add(
                new DealRisk
                {
                    StructId = 5528 // КАСКО от бесполисных
                });
            }

            return deal;
        }
public static Deal CreateConstructorDeal1(bool damageInDeal, bool totalInDeal, bool carjackingInDeal)
        {
            var deal = new Deal
            {
                DealConditionGroups = new ObservableList<DealConditionGroup>
                {
                    new DealConditionGroup
                    {
                        StructId = 5000,
                        InsuranceObjectConditions = new ObservableList<InsuranceObjectCondition>
                        {
                            new InsuranceObjectCondition
                            {
                                StructId = 5001,
                                DealCoverages = new ObservableList<DealCoverage>
                                {
                                    new DealCoverage
                                    {
                                        StructId = 5015, // Ущерб
                                        DealRisks = new ObservableList<DealRisk>()
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5030, // Угон
                                        DealRisks = new ObservableList<DealRisk>()
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5002, // Доп расходы
                                        DealRisks = new ObservableList<DealRisk>
                                        {
                                            new DealRisk
                                            {
                                                StructId = 5003, // Доп расходы
                                                ProductRisk = new ProductRisk { RiskCode = RiskCodes.ADDCOSTS },
                                                ConditionBlock = new ConditionBlock
                                                {
                                                    DealOptions = new ObservableList<DealOption>
                                                    {
                                                        new DealOption
                                                        {
                                                            ProductOption = new ProductOption { OptionCode = OptionCodes.TECHHELP },
                                                        },
                                                        new DealOption
                                                        {
                                                            ProductOption = new ProductOption { OptionCode = OptionCodes.TAXI },
                                                        },
                                                        new DealOption
                                                        {
                                                            ProductOption = new ProductOption { OptionCode = OptionCodes.AVARCOMACCIDENT },
                                                        },
                                                    }
                                                }
                                            }
                                        },
                                        ConditionBlock = new ConditionBlock
                                        {
                                                DealOptions = new ObservableList<DealOption>
                                                {
                                                    new DealOption
                                                    {
                                                        ProductOption = new ProductOption { OptionCode = OptionCodes.RENT },
                                                    }
                                                }
                                        }
                                    },
                                }
                            }
                        }
                    }
                }
            };

            if (damageInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5016, // Ущерб
                        ProductRisk = new ProductRisk { RiskCode = RiskCodes.DAMAGE },
                        ConditionBlock = new ConditionBlock
                        {
                            DealOptions = new ObservableList<DealOption> 
                            { 
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.TECHCENTER },
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = KaskoOptionCodes.Limit_Loss },
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.GLASS1T },
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.BODY3P1T },
                                }
                            },
                            DealFranchises = new ObservableList<DealFranchise>
                            { 
                                new DealFranchise 
                                {
                                    ProductFranchise = new ProductFranchise { Code = FranchiseCode.CAUSER },
                                    Sum = 50000
                                }
                            }
                        }
                    });
            }

            if (totalInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5029, // Тотал
                        ProductRisk = new ProductRisk { RiskCode = RiskCodes.TOTAL }
                    });
            }

            if (carjackingInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[1].DealRisks.Add(
                new DealRisk
                {
                    StructId = 5031, // Угон
                    ProductRisk = new ProductRisk { RiskCode = RiskCodes.CARJACKING }
                });
            }

            return deal;
        }

        public static Deal CreateConstructorDeal2(bool damageInDeal, bool totalInDeal, bool carjackingInDeal)
        {
            var deal = new Deal
            {
                DealConditionGroups = new ObservableList<DealConditionGroup>
                {
                    new DealConditionGroup
                    {
                        StructId = 5000,
                        InsuranceObjectConditions = new ObservableList<InsuranceObjectCondition>
                        {
                            new InsuranceObjectCondition
                            {
                                StructId = 5001,
                                DealCoverages = new ObservableList<DealCoverage>
                                {
                                    new DealCoverage
                                    {
                                        StructId = 5015, // Ущерб
                                        DealRisks = new ObservableList<DealRisk>()
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5030, // Угон
                                        DealRisks = new ObservableList<DealRisk>()
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5035, // GAP
                                        DealRisks = new ObservableList<DealRisk>
                                        {
                                            new DealRisk
                                            {
                                                StructId = 5036,
                                                ProductRisk = new ProductRisk { RiskCode = RiskCodes.GAP }
                                            }
                                        }
                                    },
                                    new DealCoverage
                                    {
                                        StructId = 5002, // Доп расходы
                                        DealRisks = new ObservableList<DealRisk>
                                        {
                                            new DealRisk
                                            {
                                                StructId = 5003, // Доп расходы
                                                ProductRisk = new ProductRisk { RiskCode = RiskCodes.ADDCOSTS },
                                                ConditionBlock = new ConditionBlock
                                                {
                                                    DealOptions = new ObservableList<DealOption>
                                                    {
                                                        new DealOption
                                                        {
                                                            ProductOption = new ProductOption { OptionCode = OptionCodes.TECHHELP },
                                                        },
                                                        new DealOption
                                                        {
                                                            ProductOption = new ProductOption { OptionCode = OptionCodes.AVARCOM2PAR },
                                                        },
                                                    }
                                                }
                                            }
                                        }
                                    },
                                }
                            }
                        }
                    },
                    new DealConditionGroup
                    {
                        StructId = 5037, // ГО
                        InsuranceObjectConditions = new ObservableList<InsuranceObjectCondition>
                        {
                            new InsuranceObjectCondition
                            {
                                StructId = 5038, // ГО
                                DealCoverages = new ObservableList<DealCoverage>
                                {
                                    new DealCoverage
                                    {
                                        StructId = 5039, // ГО
                                        DealRisks = new ObservableList<DealRisk>
                                        {
                                            new DealRisk
                                            {
                                                StructId = 5040, // ГО
                                                ProductRisk = new ProductRisk { RiskCode = RiskCodes.CIVILLIABILITY },
                                                Sum = 750000
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    new DealConditionGroup
                    {
                        StructId = 5041, // НС
                        InsuranceObjectConditions = new ObservableList<InsuranceObjectCondition>
                        {
                            new InsuranceObjectCondition
                            {
                                StructId = 5042, // НС
                                DealCoverages = new ObservableList<DealCoverage>
                                {
                                    new DealCoverage
                                    {
                                        StructId = 5043, // НС
                                        DealRisks = new ObservableList<DealRisk>
                                        {
                                            new DealRisk
                                            {
                                                StructId = 5044, // НС
                                                ProductRisk = new ProductRisk { RiskCode = RiskCodes.ACCIDENT }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            if (damageInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5016, // Ущерб
                        ProductRisk = new ProductRisk { RiskCode = RiskCodes.DAMAGE },
                        ConditionBlock = new ConditionBlock
                        {
                            DealOptions = new ObservableList<DealOption>
                            {
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.DEALERTECHCENTER },
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.MileLimit },
                                    SelectValue = 10000
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.GLASSMANY },
                                },
                                new DealOption
                                {
                                    ProductOption = new ProductOption { OptionCode = OptionCodes.BODY5P2T },
                                }
                            },
                            DealFranchises = new ObservableList<DealFranchise>
                            {
                                new DealFranchise
                                {
                                    ProductFranchise = new ProductFranchise { Code = FranchiseCode.INSEVENT2 },
                                    Sum = 50000
                                }
                            }
                        }
                    });
            }

            if (totalInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[0].DealRisks.Add(
                    new DealRisk
                    {
                        StructId = 5029, // Тотал
                        ProductRisk = new ProductRisk { RiskCode = RiskCodes.TOTAL }
                    });
            }

            if (carjackingInDeal)
            {
                deal.DealConditionGroups[0].InsuranceObjectConditions[0].DealCoverages[1].DealRisks.Add(
                new DealRisk
                {
                    StructId = 5031, // Угон
                    ProductRisk = new ProductRisk { RiskCode = RiskCodes.CARJACKING }
                });
            }

            return deal;
        }
    }
}
var dealConditionsGroups = deal.DealConditionGroups.ToList();
            foreach (var dealConditionGroup in dealConditionsGroups)
            {
                if (dealConditionGroup.InsuranceObjectConditions == null || dealConditionGroup.InsuranceObjectConditions.Count == 0)
                {
                    if (deal.DealConditionGroups.Contains(dealConditionGroup))
                    {
                        deal.DealConditionGroups.Remove(dealConditionGroup);
                    }
                }
            }

            if (deal.DealConditionGroups == null || deal.DealConditionGroups.Count == 0)
            {
                _log.Warning($"Для сделки с Id =  {deal.Id} были удалены все DealConditionGroups");
            }
        }

        private void AddProductConfigurationToDeal(ProductConfiguration productConfiguration, Deal deal, ToggledCondition toggledCondition, bool deleteOther = true)
        {
            if (productConfiguration.ParentStructId == deal.StructId)
            {
                switch (productConfiguration.ProductConfigurationChildType.Name)
                {
                    case nameof(ProductConfigurationType.ConditionGroup):
                        {
                            AddConditionGroupToDeal(deal, new ProductConfigurationAndSum(productConfiguration), toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.Option):
                        {
                            MakeEmptyConditionBlockIfNull(deal);
                            AddOptionsToBlocks(deal.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.CompensationOption):
                        {
                            MakeEmptyConditionBlockIfNull(deal);
                            AddCompensationOptionsToBlocks(deal.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.Franchise):
                        {
                            MakeEmptyConditionBlockIfNull(deal);
                            AddFranchiseToBlocks(deal.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                            break;
                        }

                    case nameof(ProductConfigurationType.PaymentSchedule):
                        {
                            AddPaymentScheduleToDeal(deal, new ProductConfigurationAndSum(productConfiguration));
                            break;
                        }

                    case nameof(ProductConfigurationType.PeriodTemplate):
                        {
                            MakeEmptyConditionBlockIfNull(deal);
                            AddPeriodTemlateToConditionBlock(deal.ConditionBlock, new ProductConfigurationAndSum(productConfiguration));
                            break;
                        }
                }
            }

            foreach (var dealConditionGroup in deal.DealConditionGroups)
            {
                if (productConfiguration.ParentStructId == dealConditionGroup.StructId)
                {
                    if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.TypeIOInProduct.ToString())
                    {
                        AddInsuranceObjectConditionToDeal(deal, dealConditionGroup, productConfiguration);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Option.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealConditionGroup);
                        AddOptionsToBlocks(dealConditionGroup.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.CompensationOption.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealConditionGroup);
                        AddCompensationOptionsToBlocks(dealConditionGroup.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Franchise.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealConditionGroup);
                        AddFranchiseToBlocks(dealConditionGroup.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                }
            }

            foreach (var insuranceOBjectCondition in deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions))
            {
                if (productConfiguration.ParentStructId == insuranceOBjectCondition.StructId)
                {
                    if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Coverage.ToString())
                    {
                        AddCoverageToDeal(insuranceOBjectCondition, new ProductConfigurationAndSum(productConfiguration), toggledCondition, deal: deal);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Option.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(insuranceOBjectCondition);
                        AddOptionsToBlocks(insuranceOBjectCondition.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.CompensationOption.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(insuranceOBjectCondition);
                        AddCompensationOptionsToBlocks(insuranceOBjectCondition.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Franchise.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(insuranceOBjectCondition);
                        AddFranchiseToBlocks(insuranceOBjectCondition.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                }
            }

            foreach (var dealCoverage in deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages))
            {
                if (productConfiguration.ParentStructId == dealCoverage.StructId)
                {
                    if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Risk.ToString())
                    {
                        AddRiskToDeal(dealCoverage, new ProductConfigurationAndSum(productConfiguration), toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Option.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealCoverage);
                        AddOptionsToBlocks(dealCoverage.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.CompensationOption.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealCoverage);
                        AddCompensationOptionsToBlocks(dealCoverage.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Franchise.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealCoverage);
                        AddFranchiseToBlocks(dealCoverage.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                }
            }

            foreach (var dealRisk in deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages).SelectMany(x => x.DealRisks))
            {
                if (productConfiguration.ParentStructId == dealRisk.StructId)
                {
                    if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Option.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealRisk);
                        AddOptionsToBlocks(dealRisk.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.CompensationOption.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealRisk);
                        AddCompensationOptionsToBlocks(dealRisk.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                    else if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.Franchise.ToString())
                    {
                        MakeEmptyConditionBlockIfNull(dealRisk);
                        AddFranchiseToBlocks(dealRisk.ConditionBlock, new List<ProductConfigurationAndSum>() { new ProductConfigurationAndSum(productConfiguration) }, deleteOther, toggledCondition);
                    }
                }
            }
        }

        private void AddConditionGroupToDeal(Deal deal, ProductConfigurationAndSum conditionGroupConfig, ToggledCondition toggledCondition = null)
        {
            if (conditionGroupConfig == null)
            {
                return;
            }

            if (deal.DealConditionGroups == null)
            {
                deal.DealConditionGroups = new ObservableList<DealConditionGroup>();
            }

            var resultConditionGroup = deal.DealConditionGroups?.SingleOrDefault(cg => cg.StructId == conditionGroupConfig.ProductConfiguration.StructId);

            if (resultConditionGroup == null)
            {
                decimal? sum = _sumManager.GetSumForProductConfiguration(conditionGroupConfig.ProductConfiguration, toggledCondition);

                var dealConditionGroup = new DealConditionGroup
                {
                    StructId = conditionGroupConfig.ProductConfiguration.StructId,
                    ProductConditionGroup_Id = conditionGroupConfig.ProductConfiguration.ProductConditionGroup_Id,
                    ProductConditionGroup = conditionGroupConfig.ProductConfiguration.ProductConditionGroup,
                    Sum = sum
                };

                dealConditionGroup.ProductConditionGroup.SetSums.ForEach(s => s.SetReadonlyState(false));
                dealConditionGroup.ProductConditionGroup.DefaultSetSum?.SetReadonlyState(false);

                deal.DealConditionGroups.Add(dealConditionGroup);
            }
        }

        private void AddInsuranceObjectConditionToDeal(Deal deal, DealConditionGroup dealConditionGroup, ProductConfiguration iotConfig)
        {
            if (iotConfig == null)
            {
                return;
            }

            //найти соответствие с "Объектом страхования в сделке"
            var insuranceObjectsInDeal = deal.InsuranceObjects.Where(o =>
                                        o.InsuranceObjectTypeCode == iotConfig.ProductInsuranceObjectType.InsuranceObjectTypeCode);

            if (insuranceObjectsInDeal.Any())
            {
                // Если еще не добавили такого insuranceObjectCondition
                if (!dealConditionGroup.InsuranceObjectConditions.Any(x => x.StructId == iotConfig.StructId))
                {
                    foreach (var insuranceObject in insuranceObjectsInDeal)
                    {
                        CreateInsuranceObjectCondition(dealConditionGroup, iotConfig, insuranceObject);
                    }
                }
            }

            //TODO: вернуть проверку на флаг вызова из конструтора  //if (callFromConstructor)
            else
            {
                // не найдено
                // создаем объект страхования в сделке
                var newInsuranceObject = new InsuranceObject
                {
                    InsuranceObjectType = iotConfig.ProductInsuranceObjectType.InsuranceObjectType,
                    InsuranceObjectTypeCode = iotConfig.ProductInsuranceObjectType.InsuranceObjectTypeCode,
                    UniqueId = Guid.NewGuid()
                };

                CreateInsuranceObjectEntity(newInsuranceObject, iotConfig);
                CreateInsuranceObjectCondition(dealConditionGroup, iotConfig, newInsuranceObject);
                deal.InsuranceObjects.Add(newInsuranceObject);
            }
        }

        private void CreateInsuranceObjectEntity(InsuranceObject io, ProductConfiguration pc)
        {
            string entityName = pc.ProductInsuranceObjectType?.IsuranceObjectEntityName;

            if (string.IsNullOrWhiteSpace(entityName))
            {
                return;
            }

            switch (entityName)
            {
                case "Traveller":
                    // создаем путешественника
                    if (io.Traveller == null)
                    {
                        io.Traveller = new Traveller();
                    }

                    break;
                case "Flat":
                    if (io.Flat == null)
                    {
                        io.Flat = new Flat();
                    }

                    break;

                case "Property":
                    if (io.Property == null)
                    {
                        io.Property = new Property();
                    }

                    break;

                case "Luggage":
                    if (io.Luggage == null)
                    {
                        io.Luggage = new Luggage();
                    }

                    break;

                case "Pet":
                    if (io.Pet == null)
                    {
                        io.Pet = new Pet();
                    }

                    break;
            }
        }

        private void CreateInsuranceObjectCondition(DealConditionGroup dealConditionGroup, ProductConfiguration iotConfig, InsuranceObject insuranceObject)
        {
            var insuranceObjectCondition = new InsuranceObjectCondition
            {
                InsuranceObject = insuranceObject,
                StructId = iotConfig.StructId,
                /*ProductInsuranceObjectType = iotConfig.ProductInsuranceObjectType*/
                ProductInsuranceObjectType_Id = iotConfig.ProductInsuranceObjectType_Id
            };

            dealConditionGroup.InsuranceObjectConditions.Add(insuranceObjectCondition);
        }
какой structId у риска дтп со вторым участником?