Отвечай на вопросы, используя следующий контекст:
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>();
        }
foreach (var proposal in proposals)
            {
                var dealConditionsStructIdsForProposal = dealConditionsStructIds;
                if (loadDefaultConditions != true
                    && (dealConditionsStructIds == null || dealConditionsStructIds.Count == 0)
                    && deal.Proposals.Any()
                    && selectedProposal != null
                    && selectedProposal.Offer_Id == proposal.Offer_Id)
                {
                    dealConditionsStructIdsForProposal = _dealManager.GetCondtionsStructIdsForDeal(deal);
                }

                var dealConditions = CreateDealConditionsByProposal(deal, allProductConfigs, proposal, dealConditionsStructIdsForProposal, useDrafts, loadDefaultConditions);
                allDealConditions.Add(dealConditions);
            }

            return allDealConditions;
        }

        public List<DealConditionsDto> CreateDealConditionsByProposals(
            Deal deal,
            List<Proposal> proposals,
            ToggledCondition toggledCondition,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            List<StructIdAndSum> dealConditionsStructIdsFromTopGroup,
            List<StructIdAndSum> dealConditionsStructIds,
            bool? useDrafts)
        {
            var allDealConditions = new List<DealConditionsDto>();

            InitSumManagerSums(deal);

            // Отбрасываем офферы (предложения) которые не содержат все выбранные условия из верхней групп
            var unsuitableDeals = GetUnsuitableProposals(deal, proposals, dealConditionsStructIdsFromTopGroup, allProductConfigs, useDrafts);
            RemoveUnsuitableProposals(proposals, unsuitableDeals);

            foreach (var proposal in proposals)
            {
                var dealConditions = CreateDealConditionsByProposal(deal, allProductConfigs, proposal, toggledCondition, dealConditionsStructIdsFromTopGroup, dealConditionsStructIds, useDrafts);
                if (dealConditions != null)
                {
                    allDealConditions.Add(dealConditions);
                }
            }

            return allDealConditions;
        }

        /// <summary>
        /// Получаем сделки, которые не содержат все выбранные условия из верхней группы.
        /// </summary>
        /// <param name="deal">Сделка.</param>
        /// <param name="proposals">Исходный список предложений.</param>
        /// <param name="dealConditionsStructIdsFromTopGroup">Условия из верхней группы.</param>
        /// <returns>Предложения, которые не содержат все выбранные условия из верхней группы.</returns>
        private List<Proposal> GetUnsuitableProposals(
            Deal deal,
            IEnumerable<Proposal> proposals,
            List<StructIdAndSum> dealConditionsStructIdsFromTopGroup,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            bool? useDrafts)
        {
            List<Proposal> proposalsToRemove = new List<Proposal>();
            foreach (var proposal in proposals)
            {
                var dealOffers = _queryOffer.GetOffers(new int?[] { proposal.Offer_Id }, deal.DateActual ?? DT.Now, useDrafts).ToList();
                var dealOfferStructs = dealOffers.SelectMany(o => o.OfferStructs);

                foreach (var structIdAndSum in dealConditionsStructIdsFromTopGroup)
                {
                    bool structIdAndSumInDeal = false;

                    foreach (var offerStruct in dealOfferStructs)
                    {
                        if (!allProductConfigs.ContainsKey(offerStruct.Id))
                        {
                            break;
                        }

                        var productConfiguration = allProductConfigs[offerStruct.Id];
                        var sum = _sumManager.GetSumForProductConfiguration(productConfiguration, deal: deal);

                        if (offerStruct.StructId == structIdAndSum.StructId && sum == structIdAndSum.Sum)
                        {
                            structIdAndSumInDeal = true;
                            break;
                        }
                    }

                    // Если не нашли в сделке хоть одно условие  суммой, то сделку удалять
                    if (!structIdAndSumInDeal)
                    {
                        proposalsToRemove.Add(proposal);
                        break;
                    }
                }
            }

            return proposalsToRemove;
        }

        private void RemoveUnsuitableProposals(List<Proposal> proposals, List<Proposal> proposalsToDelete)
        {
            foreach (var proposalToDelete in proposalsToDelete)
            {
                proposals.Remove(proposalToDelete);
            }
        }

        private DealConditionsDto CreateDealConditionsByProposal(
            Deal deal,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            Proposal proposal,
            List<StructIdAndSum> dealConditionsStructIds,
            bool? useDrafts,
            bool? loadDefaultConditions = null)
        {
            var dealConditions = new DealConditionsDto
            {
                Deal = deal,
                Proposal = proposal
            };

            var conditionsFilter = CreateConditionsFilter(proposal.Offer_Id, deal, allProductConfigs, useDrafts);

            var loadDefaultConditionsForDeal =
                    loadDefaultConditions == true &&
                    conditionsFilter
                        .NeedLoadDefaultConditions(
                            dealConditionsStructIds
                            .Select(x => new StructIdAndSum(x.StructId, x.Sum))
                            .ToList(),
                            _sumManager,
                            deal);

            dealConditions.StructId = conditionsFilter.GetDealStructId();
            dealConditions.ProductId = deal.Product_Id;
            dealConditions.DealConditionBlock = deal.ConditionBlock.Copy();
            dealConditions.DealConditionGroups = new List<DealConditionGroup>();
            dealConditions.InsuranceObjects = new List<InsuranceObject>(deal.InsuranceObjects);

            FillDealConditions(dealConditions, deal, allProductConfigs, conditionsFilter, dealConditionsStructIds, new List<int>(), null, loadDefaultConditionsForDeal);

            ClearDealConditionsFromUnsuitableInsuranceObjects(dealConditions);

            return dealConditions;
        }

        private DealConditionsDto CreateDealConditionsByProposal(
            Deal deal,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            Proposal proposal,
            ToggledCondition toggledCondition,
            List<StructIdAndSum> dealConditionsStructIdsFromTopGroup,
            List<StructIdAndSum> dealConditionsStructIds,
            bool? useDrafts)
        {
            var dealConditions = new DealConditionsDto
            {
                Deal = deal,
                Proposal = proposal
            };

            var conditionsFilter = CreateConditionsFilter(proposal.Offer_Id, deal, allProductConfigs, useDrafts);

            dealConditions.StructId = conditionsFilter.GetDealStructId();
            dealConditions.ProductId = deal.Product_Id;
            dealConditions.DealConditionBlock = deal.ConditionBlock.Copy();
            dealConditions.DealConditionGroups = new List<DealConditionGroup>();
            dealConditions.InsuranceObjects = new List<InsuranceObject>(deal.InsuranceObjects);
            FillSingleDealConditionByConditionsStructIdsFromTopGroup(dealConditions, deal, conditionsFilter, toggledCondition, dealConditionsStructIdsFromTopGroup, dealConditionsStructIds);

            if (FillDealConditions(
                dealConditions,
                deal,
                allProductConfigs,
                toggledCondition,
                conditionsFilter,
                dealConditionsStructIds))
            {
                return null;
            }

            ClearDealConditionsFromUnsuitableInsuranceObjects(dealConditions);

            return dealConditions;
        }

        private void InitSumManagerSums(Deal deal)
        {
            _sumManager.SetSumsForPercents(deal?.InsuranceObjects?.FirstOrDefault()?.InsuranceSumm);
        }

        /// <summary>
        /// Удаляет InsuranceObject со сделки, если для них нет соотвествующего InsuranceObjectCondition в сделке.
        /// </summary>
        /// <param name="dealConditions">Условия сделки.</param>
        private void ClearDealConditionsFromUnsuitableInsuranceObjects(DealConditionsDto dealConditions)
        {
            var insuranceObjectsToDelete = new List<InsuranceObject>();

            var insuranceObjectsFromIOC = dealConditions.DealConditionGroups
                .SelectMany(x => x.InsuranceObjectConditions)
                .Select(x => x.InsuranceObject)
                .ToList();

            foreach (var insuranceObject in dealConditions.InsuranceObjects)
            {
                if (!insuranceObjectsFromIOC.Contains(insuranceObject))
                {
                    insuranceObjectsToDelete.Add(insuranceObject);
                }
            }

            foreach (var io in insuranceObjectsToDelete)
            {
                dealConditions.InsuranceObjects.Remove(io);
            }
        }

        private void FillDealConditions(
            DealConditionsDto dealConditions,
            Deal deal,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            ToggledCondition toggledCondition,
            bool? loadDefaultConditions = null)
        {
            List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();
            bool loadDefaultConditionsFlag = loadDefaultConditions ?? toggledCondition == null;

            MakeEmptyConditionBlockIfNull(dealConditions);
            AddOCFConditionsToBlock(dealConditions.StructId.Value, dealConditions.DealConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);

            //проставялем периоды страхования
            var insurancePeriodTemplates = allProductConfigs.Select(x => x.Value).Where(x => x.ParentStructId == dealConditions.StructId).Where(x => x.InsurancePeriodTemplate != null);
            var dealPeriod = dealConditions.DealConditionBlock.DealPeriods?.FirstOrDefault();

            if (dealPeriod == null)
            {
                dealPeriod = new Period();
                dealConditions.DealConditionBlock.DealPeriods.Add(dealPeriod);
            }

            dealPeriod.InsurancePeriodTemplate = dealPeriod.InsurancePeriodTemplate ?? insurancePeriodTemplates.FirstOrDefault()?.InsurancePeriodTemplate;

            FillDealConditionGroupsAndAddInsuranceObjectCondition(dealConditions, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, dealConditionsStructIds, toggledCondition, loadDefaultConditionsFlag);
            FillInsuranceObjectConditionAndAddCoverage(dealConditions, deal, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, dealConditionsStructIds, toggledCondition, loadDefaultConditionsFlag);
            FillCoverageAndAddRisk(dealConditions, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, dealConditionsStructIds, toggledCondition, loadDefaultConditionsFlag);
            FillRisk(dealConditions, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);

            dealConditions.DealPaymentSchedule = conditionsFilter.GetPaymentScheduleConfiguration(deal.PaymentSchedule_Id ?? dealConditions.DealPaymentSchedule?.Id, loadDefaultConditionsFlag, toggledCondition)?.PaymentSchedule;
        }

        private void FillSingleDealConditionByConditionsStructIdsFromTopGroup(
            DealConditionsDto dealConditions,
            Deal deal,
            KaskoConditionsFilter conditionsFilter,
            ToggledCondition toggledCondition,
            List<StructIdAndSum> dealConditionsStructIdsFromTopGroup,
            List<StructIdAndSum> dealConditionsStructIds)
        {
            foreach (var structIdAndSum in dealConditionsStructIdsFromTopGroup)
            {
                var productConfiguration = conditionsFilter.GetProductConfigurationByStructId(structIdAndSum.StructId);

                if (productConfiguration.IsMain())
                {
                    // найти все родительские условия для structId
                    List<ProductConfiguration> parentConfigurations = conditionsFilter.GetParentProductConfigurationsFor(structIdAndSum.StructId);
                    parentConfigurations.Add(productConfiguration);

                    FillConditionUp(dealConditions, deal, parentConfigurations, dealConditionsStructIds);
                    dealConditionsStructIds.Remove(structIdAndSum);
                }
                else
                {
                    AddProductConfigurationToDeal(dealConditions, productConfiguration, deal, toggledCondition);
                    dealConditionsStructIds.Remove(structIdAndSum);
                }
            }
        }

        // реализация заполения сделки по изменяемому условию toggledCondition
        private bool FillDealConditions(
            DealConditionsDto dealConditions,
            Deal deal,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            ToggledCondition toggledCondition,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums)
        {
            List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();

            // Пройти вверх со стартовой точки и запомнить StructId всех проставленных вверх условий                
            bool needToRemove = FillDealConditionsUp(dealConditions, deal, allProductConfigs, toggledCondition, conditionsFilter, dealConditionsStructIdsAndSums);
            if (needToRemove)
            {
                return true;
            }

            // Пройти вниз от стартовой точки и проставить все обязательные вниз и запомнить все проставленные условия
            List<int> pastStructIdsAfterDown;
            FillDealConditionsDown(dealConditions, deal, toggledCondition, conditionsFilter, dealConditionsStructIds, out pastStructIdsAfterDown);

            // Пройти от корня вниз обычным обходом с игнором того, что уже проставили;
            FillDealConditions(dealConditions, deal, allProductConfigs, conditionsFilter, dealConditionsStructIdsAndSums, pastStructIdsAfterDown, toggledCondition);

            // Удаляем со сделки условия, у которых не заполнены дочерние элементы
            ClearDealConditionsFromIncorrectConditions(dealConditions);

            return false;
        }

        private bool FillDealConditionsUp(
            DealConditionsDto dealConditions,
            Deal deal,
            Dictionary<int, ProductConfiguration> allProductConfigs,
            ToggledCondition toggledCondition,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums)
        {
            if (toggledCondition.StructIds.Count == 0)
            {
                return false;
            }

            if (toggledCondition.IsChecked || toggledCondition.IsDropDown)
            {
                foreach (var structId in toggledCondition.StructIds)
                {
                    // найти все родительские условия для toggledCondition, чтобы проставить или снять их
                    var parentConfigurations = conditionsFilter.GetParentProductConfigurationsFor(structId);

                    // проставить все родительские условия
                    FillConditionUp(dealConditions, deal, parentConfigurations, dealConditionsStructIdsAndSums);
                }
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;
                        }
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);
        }
AddRiskToDeal(dealCoverage, risk);
                }
            }
        }

        private void FillRisk(
            DealConditionsDto dealConditions,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            bool loadDefaultConditionsFlag)
        {
            foreach (var dealRisk in dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages).SelectMany(x => x.DealRisks))
            {
                MakeEmptyConditionBlockIfNull(dealRisk);
                AddOCFConditionsToBlock(dealRisk.StructId.Value, dealRisk.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealRisk, dealRisk.ConditionBlock);
            }
        }

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

            //найти соответствие с "Объектом страхования в сделке"
            var insuranceObjectsInDeal = dealConditions.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()
                };

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

        private void AddCoverageToDeal(InsuranceObjectCondition insuranceObjectCondition, ProductConfigurationAndSum covProdConf, ToggledCondition toggledCondition = null, Deal deal = null)
        {
            if (covProdConf == null)
            {
                return;
            }

            if (insuranceObjectCondition.StructId == covProdConf.ProductConfiguration.ParentStructId)
            {
                var setSums = _sumManager.GetSumsForProductConfiguration(covProdConf.ProductConfiguration, out var defaultSetSum);

                var isSumCalculated = covProdConf.ProductConfiguration.ProductCoverage.SetSums
                    .Any(s => s.SumTypeCode == SumTypeEnum.CalculatedSum.ToString());

                decimal? sum =
                    IsSumContains(covProdConf.Sum, setSums, defaultSetSum) && covProdConf.Sum > 0 && !isSumCalculated
                        ? covProdConf.Sum
                        : _sumManager.GetSumForProductConfiguration(covProdConf.ProductConfiguration, toggledCondition, deal: deal);

                var dealCoverage = new DealCoverage
                {
                    StructId = covProdConf.ProductConfiguration.StructId,
                    ProductCoverage = covProdConf.ProductConfiguration.ProductCoverage,
                    ProductCoverage_Id = covProdConf.ProductConfiguration.ProductCoverage.Id,
                    Sum = sum
                };

                dealCoverage.ProductCoverage.SetSums.ForEach(s => s.SetReadonlyState(false));
                dealCoverage.ProductCoverage.DefaultSetSum?.SetReadonlyState(false);

                if (insuranceObjectCondition.DealCoverages == null)
                {
                    insuranceObjectCondition.DealCoverages = new ObservableList<DealCoverage>();
                }

                var foundCoverage = insuranceObjectCondition.DealCoverages?.SingleOrDefault(dc => dc.StructId == covProdConf.ProductConfiguration.StructId);
                if (foundCoverage == null)
                {
                    insuranceObjectCondition.DealCoverages.Add(dealCoverage);
                }
                else
                {
                    dealCoverage = foundCoverage;
                }
            }
        }

        private void AddRiskToDeal(DealCoverage dealCoverage, ProductConfigurationAndSum riskProdConf, ToggledCondition toggledCondition = null)
        {
            if (riskProdConf == null)
            {
                return;
            }

            if (dealCoverage.DealRisks == null)
            {
                dealCoverage.DealRisks = new ObservableList<DealRisk>();
            }

            if (dealCoverage.DealRisks?.Any(dr => dr.StructId == riskProdConf.ProductConfiguration.StructId) != true)
            {
                var setSums = _sumManager.GetSumsForProductConfiguration(riskProdConf.ProductConfiguration, out var defaultSetSum);

                decimal? sum =
                    IsSumContains(riskProdConf.Sum, setSums, defaultSetSum) && riskProdConf.Sum > 0
                        ? riskProdConf.Sum
                        : _sumManager.GetSumForProductConfiguration(riskProdConf.ProductConfiguration, toggledCondition);

                var dealRisk = new DealRisk
                {
                    StructId = riskProdConf.ProductConfiguration.StructId,
                    ProductRisk_Id = riskProdConf.ProductConfiguration.ProductRisk.Id,
                    ProductRisk = riskProdConf.ProductConfiguration.ProductRisk,
                    Sum = sum
                };

                dealRisk.ProductRisk.SetSums.ForEach(s => s.SetReadonlyState(false));
                dealRisk.ProductRisk.DefaultSetSum?.SetReadonlyState(false);

                dealCoverage.DealRisks.Add(dealRisk);
            }
        }

        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);
        }

        private void MakeEmptyConditionBlockIfNull(object condition)
        {
            _ = condition switch
            {
                DealConditionsDto dealConditions => dealConditions.DealConditionBlock ??= new ConditionBlock(),
                DealConditionGroup dealconditionGroup => dealconditionGroup.ConditionBlock ??= new ConditionBlock(),
                InsuranceObjectCondition insuranceObjectCondition => insuranceObjectCondition.ConditionBlock ??= new ConditionBlock(),
                DealCoverage dealCoverage => dealCoverage.ConditionBlock ??= new ConditionBlock(),
                DealRisk dealRisk => dealRisk.ConditionBlock ??= new ConditionBlock(),
                _ => throw new NotImplementedException($"Не удалось создать ConditionBlock для типа {condition.GetType().Name}")
            };
        }

        private void AddOCFConditionsToBlock(int parenstStructId, ConditionBlock conditionBlock, KaskoConditionsFilter conditionsFilter, List<StructIdAndSum> dealConditionsStructIdsAndSums, List<int> structIdsToIgnore, bool loadDefaultConditions)
        {
            List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();

            var options = conditionsFilter.GetOptionsConfigurations(parenstStructId, loadDefaultConditions, dealConditionsStructIds);
            options = options.Where(x => !structIdsToIgnore.Contains(x.StructId.Value)).ToList();
            var oprionsAndSums = GetProductConfigurationsAndSums(options, dealConditionsStructIdsAndSums);
            AddOptionsToBlocks(conditionBlock, oprionsAndSums, false);

            var franchises = conditionsFilter.GetFranchiseConfigurations(parenstStructId, loadDefaultConditions, dealConditionsStructIds);
            franchises = franchises.Where(x => !structIdsToIgnore.Contains(x.StructId.Value)).ToList();
            var franchisesAndSums = GetProductConfigurationsAndSums(franchises, dealConditionsStructIdsAndSums);
            AddFranchiseToBlocks(conditionBlock, franchisesAndSums, false);

            var compensationOptions = conditionsFilter.GetCompesationOptionsConfigurations(parenstStructId, loadDefaultConditions, dealConditionsStructIds);
            compensationOptions = compensationOptions.Where(x => !structIdsToIgnore.Contains(x.StructId.Value)).ToList();
            var compensationOptionsAndSums = GetProductConfigurationsAndSums(compensationOptions, dealConditionsStructIdsAndSums);
            AddCompensationOptionsToBlocks(conditionBlock, compensationOptionsAndSums, false);
        }

        private List<ProductConfigurationAndSum> GetProductConfigurationsAndSums(List<ProductConfiguration> productConfigurations, List<StructIdAndSum> structIdsAndSums)
        {
            List<ProductConfigurationAndSum> result = new List<ProductConfigurationAndSum>();

            foreach (var pc in productConfigurations)
            {
                decimal? sum = structIdsAndSums.SingleOrDefault(x => x.StructId == pc.StructId)?.Sum;
                ProductConfigurationAndSum pcAndSum = new ProductConfigurationAndSum(pc, sum);
                result.Add(pcAndSum);
            }

            return result;
        }

        /// <summary>
        /// Добавляет список опций в блок. Если передан флаг deleteOthers, удаляет другие опции в блоке.
        /// </summary>
        /// <param name="block">Блок условий.</param>
        /// <param name="optionsConfigs">Настройки для опции.</param>
        /// <param name="deleteOther">Флаг удаления других опций в блоке.</param>
        /// <param name="toggledCondition">Переключаемое условие.</param>
        private void AddOptionsToBlocks(ConditionBlock block, List<ProductConfigurationAndSum> optionsConfigs, bool deleteOther, ToggledCondition toggledCondition = null)
        {
            MakeEmptyCollectionIfNull(block.DealOptions);

            foreach (var optionConfig in optionsConfigs)
            {
                if (block.DealOptions.FirstOrDefault(x => x.StructId == optionConfig.ProductConfiguration.StructId) != null)
                {
                    return;
                }

                var setSums = _sumManager.GetSumsForProductConfiguration(optionConfig.ProductConfiguration, out var defaultSetSum);

                decimal? sum =
                    (IsSumContains(optionConfig.Sum, setSums, defaultSetSum) ||
                     IsSelectValueContains(optionConfig.Sum, optionConfig.ProductConfiguration.ProductOption)) &&
                    optionConfig.Sum > 0
                        ? optionConfig.Sum
                        : _sumManager.GetSumForProductConfiguration(optionConfig.ProductConfiguration, toggledCondition);

                int? selectValue = KaskoConditionManager.GetProductOptionSelectValue(optionConfig.ProductConfiguration.ProductOption, toggledCondition?.NewSumValue ?? (int?)sum);

                var option = new DealOption
                {
                    StructId = optionConfig.ProductConfiguration.StructId,
                    ProductOption = optionConfig.ProductConfiguration.ProductOption,
                    ProductOption_Id = optionConfig.ProductConfiguration.ProductOption.Id
                };

                if (selectValue.HasValue)
                {
                    option.SelectValue = selectValue;
                }
                else
                {
                    option.Sum = sum;
                }

                option.ProductOption.SetSums.ForEach(s => s.SetReadonlyState(false));
                option.ProductOption.DefaultSetSum?.SetReadonlyState(false);

                block.DealOptions.Add(option);
            }

            if (deleteOther)
            {
                // Удяляем все опции, кроме тех, которые добавили
                block.DealOptions = block.DealOptions.Where(x => optionsConfigs.Select(c => c.ProductConfiguration.StructId).Contains(x.StructId)).ToList();
            }
        }

        /// <summary>
        /// Добавляет список франшиз в блок. Если передан флаг deleteOthers, удаляет другие франшизы в блоке.
        /// </summary>
        /// <param name="block">Блок условий.</param>
        /// <param name="francisesConfigs">Настройки для фрашиз.</param>
        /// <param name="deleteOther">Флаг удаления других франшиз в блоке.</param>
        /// <param name="toggledCondition">Переключаемое условие.</param>
        private void AddFranchiseToBlocks(ConditionBlock block, List<ProductConfigurationAndSum> francisesConfigs, bool deleteOther, ToggledCondition toggledCondition = null)
        {
            MakeEmptyCollectionIfNull(block.DealFranchises);

            foreach (var franchiseConfig in francisesConfigs)
            {
                if (block.DealFranchises.FirstOrDefault(x => x.StructId == franchiseConfig.ProductConfiguration.StructId) != null)
                {
                    return;
                }

                var setSums = _sumManager.GetSumsForProductConfiguration(franchiseConfig.ProductConfiguration, out var defaultSetSum);

                decimal? sum =
                    IsSumContains(franchiseConfig.Sum, setSums, defaultSetSum) && franchiseConfig.Sum > 0
                        ? franchiseConfig.Sum
                        : _sumManager.GetSumForProductConfiguration(franchiseConfig.ProductConfiguration, toggledCondition);

                var franchise = new DealFranchise
                {
                    StructId = franchiseConfig.ProductConfiguration.StructId,
                    ProductFranchise_Id = franchiseConfig.ProductConfiguration.ProductFranchise_Id,
                    ProductFranchise = franchiseConfig.ProductConfiguration.ProductFranchise,
                    Sum = sum
                };

                franchise.ProductFranchise.SetSums.ForEach(s => s.SetReadonlyState(false));
                franchise.ProductFranchise.DefaultSetSum?.SetReadonlyState(false);

                block.DealFranchises.Add(franchise);
            }

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

        /// <summary>
        /// Добавляет список CompensationOptions в блок. Если передан флаг deleteOthers, удаляет другие CompensationOptions в блоке.
        /// </summary>
        /// <param name="block">Блок условий.</param>
        /// <param name="compensationOptionsConfigs">Настройки для CompensationOptions.</param>
        /// <param name="deleteOther">Флаг удаления других CompensationOptions в блоке.</param>
        /// <param name="toggledCondition">Переключаемое условие.</param>
        private void AddCompensationOptionsToBlocks(ConditionBlock block, List<ProductConfigurationAndSum> compensationOptionsConfigs, bool deleteOther, ToggledCondition toggledCondition = null)
        {
            MakeEmptyCollectionIfNull(block.DealCompensationOptions);
как создать новый productRisk