Отвечай на вопросы, используя следующий контекст:
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;
                        }

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

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

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

            foreach (var dealConditionGroup in dealConditions.DealConditionGroups)
            {
                if (productConfiguration.ParentStructId == dealConditionGroup.StructId)
                {
                    if (productConfiguration.ProductConfigurationChildType.Name == ProductConfigurationType.TypeIOInProduct.ToString())
                    {
                        AddInsuranceObjectConditionToDeal(dealConditions, 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 dealConditions.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 dealConditions.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 dealConditions.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 AddPaymentScheduleToDeal(DealConditionsDto dealConditions, ProductConfigurationAndSum conditionGroupConfig)
        {
            if (conditionGroupConfig == null)
            {
                return;
            }

            dealConditions.DealPaymentSchedule = conditionGroupConfig.ProductConfiguration.PaymentSchedule;
        }

        private void AddPeriodTemlateToConditionBlock(ConditionBlock block, ProductConfigurationAndSum conditionGroupConfig)
        {
            if (conditionGroupConfig == null)
            {
                return;
            }

            var period = block.DealPeriods?.FirstOrDefault();

            if (period == null)
            {
                period = new Period();
                block.DealPeriods.Add(period);
            }

            period.InsurancePeriodTemplate = conditionGroupConfig.ProductConfiguration.InsurancePeriodTemplate;
            period.InsurancePeriodTemplate_Id = conditionGroupConfig.ProductConfiguration.InsurancePeriodTemplate.Id;

            CalculatePeriodDateEnd(period);
        }

        private void CalculatePeriodDateEnd(Period period)
        {
            if (!period.DateStart.HasValue)
            {
                return;
            }

            var functionForCalculatingDateEnd = period.DateStart.Value.GetAddTimeFunc(period.InsurancePeriodTemplate.AgreementFullTermMeasureCode);

            if (functionForCalculatingDateEnd != default)
            {
                period.DateEnd = functionForCalculatingDateEnd(period.InsurancePeriodTemplate.AgreementFullTerm.Value);
            }
        }

        private void CorrectDealConditionGroupSum(DealConditionGroup dealConditionGroup, List<StructIdAndSum> dealConditionsStructIdsAndSums)
        {
            var dealConditionGroupSum =
                dealConditionsStructIdsAndSums.FirstOrDefault(s => s.StructId == dealConditionGroup.StructId)?.Sum;

            if (dealConditionGroupSum != null)
            {
                dealConditionGroup.Sum = dealConditionGroupSum;
            }
        }

        private void FillDealConditionGroupsAndAddInsuranceObjectCondition(
            DealConditionsDto dealConditions,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            List<int> dealConditionsStructIds,
            ToggledCondition toggledCondition,
            bool loadDefaultConditionsFlag)
        {
            // Получить все обязательные и по умолчанию Группы
            var conditionGroups = conditionsFilter.GetConditionGroupsConfigurations(loadDefaultConditionsFlag, dealConditions.StructId, dealConditionsStructIds, toggledCondition);
            var conditionGroupsAndSums = GetProductConfigurationsAndSums(conditionGroups, dealConditionsStructIdsAndSums);

            // Добавить группы в сделку
            foreach (var conditionGroup in conditionGroupsAndSums)
            {
                if (structIdsToIgnore.Contains(conditionGroup.ProductConfiguration.StructId.Value))
                {
                    continue;
                }

                AddConditionGroupToDeal(dealConditions, conditionGroup);
            }

            foreach (var dealConditionGroup in dealConditions.DealConditionGroups)
            {
                MakeEmptyConditionBlockIfNull(dealConditionGroup);
                AddOCFConditionsToBlock(dealConditionGroup.StructId.Value, dealConditionGroup.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealConditionGroup, dealConditionGroup.ConditionBlock);

                var ioTypeConditions =
                    conditionsFilter.GetInsuranceObjectTypeConfiguarations(
                        dealConditionGroup.StructId.Value,
                        loadDefaultConditionsFlag,
                        dealConditionsStructIds,
                        toggledCondition);

                foreach (var ioTypeCondition in ioTypeConditions)
                {
                    if (structIdsToIgnore.Contains(ioTypeCondition.StructId.Value))
                    {
                        continue;
                    }

                    AddInsuranceObjectConditionToDeal(dealConditions, dealConditionGroup, ioTypeCondition);
                }
            }
        }

        private void FillInsuranceObjectConditionAndAddCoverage(
            DealConditionsDto dealConditions,
            Deal deal,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            List<int> dealConditionsStructIds,
            ToggledCondition toggledCondition,
            bool loadDefaultConditionsFlag)
        {
            foreach (var dealInsuranceObjectCondition in dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions))
            {
                MakeEmptyConditionBlockIfNull(dealInsuranceObjectCondition);
                AddOCFConditionsToBlock(dealInsuranceObjectCondition.StructId.Value, dealInsuranceObjectCondition.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealInsuranceObjectCondition, dealInsuranceObjectCondition.ConditionBlock);

                var coverages = conditionsFilter.GetCoveragesConfigurations(dealInsuranceObjectCondition.StructId.Value, loadDefaultConditionsFlag, dealConditionsStructIds, toggledCondition);
                var coveragesAndSums = GetProductConfigurationsAndSums(coverages, dealConditionsStructIdsAndSums);
                foreach (var coverage in coveragesAndSums)
                {
                    if (structIdsToIgnore.Contains(coverage.ProductConfiguration.StructId.Value))
                    {
                        continue;
                    }

                    AddCoverageToDeal(dealInsuranceObjectCondition, coverage, deal: deal);
                }
            }
        }

        private void FillCoverageAndAddRisk(
            DealConditionsDto dealConditions,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            List<int> dealConditionsStructIds,
            ToggledCondition toggledCondition,
            bool loadDefaultConditionsFlag)
        {
            foreach (var dealCoverage in dealConditions.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages))
            {
                MakeEmptyConditionBlockIfNull(dealCoverage);
                AddOCFConditionsToBlock(dealCoverage.StructId.Value, dealCoverage.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealCoverage, dealCoverage.ConditionBlock);
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);
        }

        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 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 void RemoveEmptyConditionBlock(object condition, ConditionBlock conditionBlock)
        {
            if (!conditionBlock.DealOptions.Any() && !conditionBlock.DealFranchises.Any()
                && !conditionBlock.DealCompensationOptions.Any() && !conditionBlock.DealPeriods.Any())
            {
                switch (condition)
                {
                    case Deal deal:
                        deal.ConditionBlock = null;
                        break;
                    case DealConditionGroup dealconditionGroup:
                        dealconditionGroup.ConditionBlock = null;
                        break;
                    case InsuranceObjectCondition insuranceObjectCondition:
                        insuranceObjectCondition.ConditionBlock = null;
                        break;
                    case DealCoverage dealCoverage:
                        dealCoverage.ConditionBlock = null;
                        break;
                    case DealRisk dealRisk:
                        dealRisk.ConditionBlock = null;
                        break;
                }
            }
        }

        /// <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 (startStructId != null && startStructId.Value == productConfiguration.StructId)
                //{
                //    block.DealCompensationOptions.Clear();
                //    block.DealFranchises.Clear();
                //}
            }

            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 (startStructId != null && startStructId.Value == productConfiguration.StructId)
                //{
                //    block.DealCompensationOptions.Clear();
                //    block.DealFranchises.Clear();
                //}
            }

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

            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 (startStructId != null && startStructId.Value == productConfiguration.StructId)
                //{
                //    block.DealCompensationOptions.Clear();
                //    block.DealFranchises.Clear();
                //}
            }

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

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

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

        private void MakeEmptyConditionBlockIfNull(object condition)
        {
            string type = condition.GetType().Name;
            switch (type)
            {
                case nameof(Deal):
                    if (((Deal)condition).ConditionBlock == null)
                    {
                        ((Deal)condition).ConditionBlock = new ConditionBlock();
                    }
using iRIS.Framework.Common;
using iRIS.Framework.Data;
using iRIS.Framework.RequestPipeline.Extensions;
using iRIS.InsuranceCore.Code.ConstructorCore.Models;
using iRIS.InsuranceCore.Code.CustomProcesses.BasketPreparationProcess.Enums;
using iRIS.InsuranceCore.Code.Interfaces;
using iRIS.InsuranceCore.Code.Interfaces.ConstructorCore;
using iRIS.InsuranceCore.Code.Queries;
using iRIS.InsuranceCore.Code.TypeExtensions;
using iRIS.InsuranceCore.Entities;
using iRIS.KaskoCore.Code.Implementations;
using iRIS.KaskoLink2.Code.Constructor.Helpers.EntityExtensions;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;

namespace iRIS.KaskoLink2.Code.Constructor.FromInsuranceCore.ConstructorCore
{
    /// <summary>
    /// Обработчик условий в сделке (заполнение,  проставление).
    /// </summary>
    [Obsolete("Новая реализация в DiKaskoConditionsProcessor. (IRIS-163411)")]
    public class DealConditionsProcessor : IDealConditionsProcessor
    {
        private readonly Dictionary<int, ProductConfiguration> _allProductConfigs;
        private readonly ISumManager _sumManager;
        private readonly IProposalCurrencyDeterminator _currencyDeterminator;
        private readonly IQueryOffer _queryOffer;
        private readonly PipelineExecutionContext _context;
        private ILogger _log;

        public DealConditionsProcessor(
            Dictionary<int, ProductConfiguration> allProductConfigs,
            ILogger log,
            IQueryOffer queryOffer,
            ISumManager sumManager,
            IProposalCurrencyDeterminator currencyDeterminator,
            PipelineExecutionContext context = null)
        {
            _allProductConfigs = allProductConfigs;
            _queryOffer = queryOffer;
            _sumManager = sumManager;
            _currencyDeterminator = currencyDeterminator;
            _log = log;
            _context = context;
        }

        public void FillDealsConditions(List<Deal> deals, List<StructIdAndSum> dealConditionsStructIds, bool? useDrafts, bool? loadDefaultConditions = null)
        {
            foreach (var deal in deals)
            {
                var dealOfferIds = deal.Proposals.Select(x => x.Offer_Id).Distinct().ToArray();
                var dealOffers = _queryOffer.GetOffers(dealOfferIds, deal.DateActual ?? DT.Now, useDrafts).ToList();
                var conditionsFilter = new KaskoConditionsFilter(deal, dealOffers, _allProductConfigs);

                deal.StructId = conditionsFilter.GetDealStructId();

                FillSingleDealConditions(deal, conditionsFilter, dealConditionsStructIds, new List<int>(), null, loadDefaultConditions);

                // Удаляем InsuranceObject со сделки, если нет для них InsuranceObjectCondition в сделке
                ClearDealFromUnsuitableInsuranceObjects(deal);
            }

            _currencyDeterminator.DetermineCurrenciesForDealsAndConditions(deals);
        }

        public void FillDealsConditions(List<Deal> deals, ToggledCondition toggledCondition, List<StructIdAndSum> dealConditionsStructIdsFromTopGroup, List<StructIdAndSum> dealConditionsStructIds, bool? useDrafts)
        {
            List<Deal> dealsToDelete = new List<Deal>();

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

            foreach (var deal in deals)
            {
                var dealOfferIds = deal.Proposals.Select(x => x.Offer_Id).Distinct().ToArray();
                var dealOffers = _queryOffer.GetOffers(dealOfferIds, deal.DateActual ?? DT.Now, useDrafts).ToList();
                var conditionsFilter = new KaskoConditionsFilter(deal, dealOffers, _allProductConfigs);
                deal.StructId = conditionsFilter.GetDealStructId();

                //Проставляем условия из верхней группы (при этом удалим проставленные из dealConditionsStructIds)
                FillSingleDealConditionByConditionsStructIdsFromTopGroup(deal, conditionsFilter, toggledCondition, dealConditionsStructIdsFromTopGroup, dealConditionsStructIds);

                var needRemoveDeal = FillSingleDealConditions(deal, toggledCondition, conditionsFilter, dealConditionsStructIds);
                if (needRemoveDeal)
                {
                    dealsToDelete.Add(deal);
                }

                // Удаляем InsuranceObject со сделки, если нет для них InsuranceObjectCondition в сделке
                ClearDealFromUnsuitableInsuranceObjects(deal);
            }

            _currencyDeterminator.DetermineCurrenciesForDealsAndConditions(deals);

            //Отбрасываем сделки(офферы), которые не подходят из-за снятия условий в констр-ре
            RemoveUnsuitableDeals(deals, dealsToDelete);
        }

        private void FillSingleDealConditionByConditionsStructIdsFromTopGroup(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(deal, parentConfigurations, dealConditionsStructIds);
                    dealConditionsStructIds.Remove(structIdAndSum);
                }
                else
                {
                    AddProductConfigurationToDeal(productConfiguration, deal, toggledCondition);
                    dealConditionsStructIds.Remove(structIdAndSum);
                }
            }
        }

        private void RemoveUnsuitableDeals(List<Deal> deals, List<Deal> dealsToDelete)
        {
            foreach (var dealToDelete in dealsToDelete)
            {
                deals.Remove(dealToDelete);
            }
        }

        /// <summary>
        /// Получаем сделки, которые не содержат все выбранные условия из верхней группы
        /// </summary>
        /// <param name="deals">Исходный список сделок</param>
        /// <param name="dealConditionsStructIdsFromTopGroup">Условия из верхней группы</param>
        /// <returns>Сделки, которые не содержат все выбранные условия из верхней группы</returns>
        private List<Deal> GetUnsuitableDeals(List<Deal> deals, List<StructIdAndSum> dealConditionsStructIdsFromTopGroup, bool? useDrafts)
        {
            List<Deal> dealsToRemove = new List<Deal>();
            foreach (var deal in deals)
            {
                var dealOfferIds = deal.Proposals.Select(x => x.Offer_Id).Distinct().ToArray();
                var dealOffers = _queryOffer.GetOffers(dealOfferIds, 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)
                    {
                        dealsToRemove.Add(deal);
                        break;
                    }
                }
            }

            //var result = deals.Where(x => !dealConditionsStructIdsFromTopGroup.All(c => x.Proposals.Select(p => p.Offer).SelectMany(o => o.OfferStructs).Select(os => os.StructId).Contains(c.StructId))).ToList();
            return dealsToRemove;
        }

        // реализация по заполнения обязательными и дефолтными условиями
        private void FillSingleDealConditions(
            Deal deal,
            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(deal);
            AddOCFConditionsToBlock(deal.StructId.Value, deal.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);

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

            if (dealPeriod == null)
            {
                dealPeriod = new Period();
                deal.ConditionBlock.DealPeriods.Add(dealPeriod);
            }

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

            // Получить все обязательные и по умолчанию Группы           
            var conditionGroups = conditionsFilter.GetConditionGroupsConfigurations(loadDefaultConditionsFlag, deal.StructId, dealConditionsStructIds, toggledCondition);
            var conditionGroupsAndSums = GetProductConfigurationsAndSums(conditionGroups, dealConditionsStructIdsAndSums);

            // Добавить группы в сделку
            foreach (var conditionGroup in conditionGroupsAndSums)
            {
                if (structIdsToIgnore.Contains(conditionGroup.ProductConfiguration.StructId.Value))
                {
                    continue;
                }

                AddConditionGroupToDeal(deal, conditionGroup);
            }

            foreach (var dealConditionGroup in deal.DealConditionGroups)
            {
                MakeEmptyConditionBlockIfNull(dealConditionGroup);
                AddOCFConditionsToBlock(dealConditionGroup.StructId.Value, dealConditionGroup.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealConditionGroup, dealConditionGroup.ConditionBlock);

                var ioTypeConditions =
                    conditionsFilter.GetInsuranceObjectTypeConfiguarations(
                        dealConditionGroup.StructId.Value,
                        loadDefaultConditionsFlag,
                        dealConditionsStructIds,
                        toggledCondition);

                foreach (var ioTypeCondition in ioTypeConditions)
                {
                    if (structIdsToIgnore.Contains(ioTypeCondition.StructId.Value))
                    {
                        continue;
                    }

                    AddInsuranceObjectConditionToDeal(deal, dealConditionGroup, ioTypeCondition);
                }
            }

            foreach (var dealInsuranceObjectCondition in deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions))
            {
                MakeEmptyConditionBlockIfNull(dealInsuranceObjectCondition);
                AddOCFConditionsToBlock(dealInsuranceObjectCondition.StructId.Value, dealInsuranceObjectCondition.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealInsuranceObjectCondition, dealInsuranceObjectCondition.ConditionBlock);

                var coverages = conditionsFilter.GetCoveragesConfigurations(dealInsuranceObjectCondition.StructId.Value, loadDefaultConditionsFlag, dealConditionsStructIds, toggledCondition);
                var coveragesAndSums = GetProductConfigurationsAndSums(coverages, dealConditionsStructIdsAndSums);
                foreach (var coverage in coveragesAndSums)
                {
                    if (structIdsToIgnore.Contains(coverage.ProductConfiguration.StructId.Value))
                    {
                        continue;
                    }

                    AddCoverageToDeal(dealInsuranceObjectCondition, coverage, deal: deal);
                }
            }

            foreach (var dealCoverage in deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).SelectMany(x => x.DealCoverages))
            {
                MakeEmptyConditionBlockIfNull(dealCoverage);
                AddOCFConditionsToBlock(dealCoverage.StructId.Value, dealCoverage.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);
                RemoveEmptyConditionBlock(dealCoverage, dealCoverage.ConditionBlock);

                var risks = conditionsFilter.GetRisksConfigurations(dealCoverage.StructId.Value, loadDefaultConditionsFlag, dealConditionsStructIds, toggledCondition);
                var riskAndSums = GetProductConfigurationsAndSums(risks, dealConditionsStructIdsAndSums);
                foreach (var risk in riskAndSums)
                {
                    if (structIdsToIgnore.Contains(risk.ProductConfiguration.StructId.Value))
                    {
                        continue;
                    }

                    AddRiskToDeal(dealCoverage, risk);
                }
            }

            foreach (var dealRisk in deal.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);
            }

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

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

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

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

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

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

            return false;
        }

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

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

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

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

        private bool FillDealConditionsUp(Deal deal, 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(deal, parentConfigurations, dealConditionsStructIdsAndSums);
                }

                return false;
            }
            else
            {
                List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();
                return toggledCondition.StructIds.All(structId => UncheckConditionUp(deal, conditionsFilter, structId, dealConditionsStructIds));
            }
        }

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

            AddConditionGroupToDeal(deal, new ProductConfigurationAndSum(conditionGroupConfig));
            var dealConditionGroup = deal.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(deal, dealConditionGroup, insuranceObjectType);
            var dealInsuranceObjectConditions = deal.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 void CorrectDealConditionGroupSum(DealConditionGroup dealConditionGroup, List<StructIdAndSum> dealConditionsStructIdsAndSums)
        {
            var dealConditionGroupSum =
                dealConditionsStructIdsAndSums.FirstOrDefault(s => s.StructId == dealConditionGroup.StructId)?.Sum;

            if (dealConditionGroupSum != null)
            {
                dealConditionGroup.Sum = dealConditionGroupSum;
            }
        }

        private bool UncheckConditionUp(Deal deal, 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 = deal.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 = deal.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 = deal.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)
                    {
                        deal.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 = deal.StructId;
                var hasMoreThanOneChild = _allProductConfigs.Values.Where(x => x.ParentStructId == deal.StructId).Count() > 1;
                isRequired = currentNode.IsRequired();
                bool isMainCondition = currentNode.IsMain();

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

            return false;
        }

        // Заполняет условия в поддереве, начиная с условия toogledStructId и вниз
        private void FillDealConditionsDown(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(childConfiguration, deal, toggledCondition, false);
                    pastStructIds.Add(childConfiguration.StructId.Value);
                }
            }
            else
            {
                // var deletedStructIds = _dealManager.FillAllDealConditionsWhenUncheck(deal, toggledCondition.StructIds[0], _allProductConfigs.Values.ToList());
                //dealConditionsStructIds.RemoveAll(x => deletedStructIds.Contains(x));
                //pastStructIds = deletedStructIds;
                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="deal">Сделка</param>
        private void ClearDealFromIncorrectConditions(Deal deal)
        {
            var coverages = deal.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 = deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).ToList();
                        foreach (var ioc in iocs)
                        {
                            if (ioc.DealCoverages.Contains(coverage))
                            {
                                ioc.DealCoverages.Remove(coverage);
                            }
                        }
                    }
                }
            }

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

            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");
            }
        }
Как мне создать новый ProductRisk