Отвечай на вопросы, используя следующий контекст:
switch (decision)
                {
                    case KaskoSasCheckProcessConstants.KaskoSasCheckAccept:
                        if (isSensitiveDataChanged && (
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.Accepted || 
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.AcceptedWithLimits ||
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.RequiredExtraInfo))
                        {
                            SetExternalBasketUrmAprovalStatus(deal, externalBasketUrmAprovalStatus);
                        }
                        else
                        {
                            UrmHelper.SetUrmApprovalNotRequired(deal);
                        }

                        exitBranch = ExitBranch_TargetedSegment;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckUrm:
                        UrmApprovalStatusHelper.SetURMApprovalStatus(basket, false, comment); // возможно не нужен этот вызов, поресерчить
                        FixUrm(deal, requestGuid, processContext, integrationLoginName, logger, decision, isSensitiveDataChanged, externalBasketUrmAprovalStatus);
                        exitBranch = ExitBranch_NotTargetedSegment_CorrData;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckNoDecision:
                        UrmApprovalStatusHelper.SetURMApprovalStatus(basket, false, comment); // возможно не нужен этот вызов, поресерчить
                        FixUrm(deal, requestGuid, processContext, integrationLoginName, logger, decision, isSensitiveDataChanged, externalBasketUrmAprovalStatus);
                        exitBranch = ExitBranch_NotTargetedSegment_CorrData;
                        break;
                    case KaskoSasCheckProcessConstants.KaskoSasCheckReject:
                    default:
                        SetUrmStatus(deal, UrmApprovalStatusCodes.Rejected, requestGuid, decision);
                        AddValidationError(validationResultsAggregator);
                        exitBranch = ExitBranch_NotTargetedSegment_Reject;
                        break;
                }

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

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

                AddValidationError(validationResultsAggregator);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return basket;
        }

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

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

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

            return basket;
        }

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

            return basket;
        }

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

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

            return autoDeal;
        }

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

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

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

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

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

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

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

            return deal;
        }

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

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

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

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

            return deal;
        }

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

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

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

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

            return deal;
        }
    }
}

using iRIS.Framework.Common;
using iRIS.Framework.Cqrs.Interfaces;
using iRIS.InsuranceCore.Code.Constants;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.InsuranceCore.Infrastructure.Constants;
using iRIS.InsuranceCore.OSS.Code.Constants;
using iRIS.KaskoCore.Code.Queries;
using iRIS.PostProcessingClient.Auto.Code.Client;
using iRIS.PostProcessingClient.Auto.Code.Interfaces;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using AntiTheftSystemModel = iRIS.PostProcessingClient.Auto.Code.Client.AntiTheftSystemModel;
using AutoModel = iRIS.PostProcessingClient.Auto.Code.Client.AutoModel;
using InsuranceObjectTypeCodes = iRIS.InsuranceCore.Code.Constants.InsuranceObjectTypeCodes;

namespace iRIS.KaskoLink2.Code.PostProcessing
{
    public class PostProcessingBasketMapper : IPostProcessingBasketMapper<Basket>
    {
        private readonly IQueryBank _queryBank;
        private readonly ILogger _logger;
private void InitializeFillBasketProductsIfNotExists(ProcedureModel model)
        {
            model.Identifier = "FillBasketProductsIfNotExists";
            model.Name = "Заполнение продуктов Корзины, если они пустые";
            model.Description = @"Заполнение продуктов Корзины, если они пустые";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _setDealsDateFirstCalculation;
            model.ExceptionNextStep = _segmentationForm;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.InsuranceCore.Code.InsuranceCoreProcedures.FillBasketProductsIfNotExists),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializeDiKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache(CustomProcessModel model)
        {
            model.Identifier = "DiKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache";
            model.Name = "Сохранение данных водителей с сегментации в кэш";
            model.Description = @"Сохранение данных водителей с сегментации в кэш";
            model.ImplementationTypeName = typeof(iRIS.KaskoOsago.Code.CustomProcesses.DiKaskoQuestionnaireSaveSegmentationDriversDataProcessToCache).AssemblyQualifiedName;
            model.DataTypeName = null;
            model.DefaultNextStep = _defaultExitPoint;
            model.ExceptionNextStep = null;
            model.InputArguments = new List<CustomProcessInputArgument>();
            model.InputArguments.Add(new CustomProcessInputArgument
            {
                Name = "Basket",
                TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                Expression = @"Basket",
            });
            model.OutputArguments = new List<CustomProcessOutputArgument>();
            model.CustomExitPoints = new List<ProcessExitPoint>();
        }

        private void InitializeDefaultExitPoint(ExitPointModel model)
        {
            model.Identifier = "DefaultExitPoint";
            model.Name = "Сегментация пройдена";
            model.Description = @"Сегментация пройдена";
            model.ReturnParameters = new List<ParameterModel>();
        }
    }
}

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

using System;
using System.Collections.Generic;

using iRIS.Framework.Workflow.Process;
using iRIS.Framework.Workflow.Process.AuthorizationModel;
using iRIS.Framework.Workflow.Process.CustomProcessModel;
using iRIS.Framework.Workflow.Process.Data;
using iRIS.Framework.Workflow.UserData;

namespace iRIS.KaskoB2B.Generated.Processes.B2bKaskoQuestionnaireProcess.Draft
{
    public class B2bKaskoQuestionnaireProcess : FlowProcessModel
    {
        public const string ExitPoint_ContinueExit = "Анкета заполнена";

        private readonly ProcedureModel _prepareDocsForKaskoBasket;
        private readonly ProcedureModel _initializeAddressesForDriver;
        private readonly NestedProcessModel _checkStartDateOfCalculate;
        private readonly ProcedureModel _initializeAddressesForInsurant;
        private readonly FormDataModel _diKaskoQuestionnaireFormStep;
        private readonly InputModel _issue;
        private readonly ExitPointModel _continueExit;
        private readonly FormDataModel _dateStartMessageInfo;
        private readonly VersionPublisherModel _saveDraftBasketBlockAfterBuy;

        public B2bKaskoQuestionnaireProcess()
        {
            _prepareDocsForKaskoBasket = new ProcedureModel();
            _initializeAddressesForDriver = new ProcedureModel();
            _checkStartDateOfCalculate = new NestedProcessModel();
            _initializeAddressesForInsurant = new ProcedureModel();
            _diKaskoQuestionnaireFormStep = new FormDataModel();
            _issue = new InputModel();
            _continueExit = new ExitPointModel();
            _dateStartMessageInfo = new FormDataModel();
            _saveDraftBasketBlockAfterBuy = new VersionPublisherModel();

            InitializeB2bKaskoQuestionnaireProcess(this);

            InitializePrepareDocsForKaskoBasket(_prepareDocsForKaskoBasket);
            InitializeInitializeAddressesForDriver(_initializeAddressesForDriver);
            InitializecheckStartDateOfCalculate(_checkStartDateOfCalculate);
            InitializeInitializeAddressesForInsurant(_initializeAddressesForInsurant);
            InitializeDiKaskoQuestionnaireFormStep(_diKaskoQuestionnaireFormStep);
            Initializeissue(_issue);
            InitializeContinueExit(_continueExit);
            InitializedateStartMessageInfo(_dateStartMessageInfo);
            InitializeSaveDraftBasketBlockAfterBuy(_saveDraftBasketBlockAfterBuy);
        }

        private void InitializeB2bKaskoQuestionnaireProcess(FlowProcessModel model)
        {
            model.Identifier = "B2bKaskoQuestionnaireProcess";
            model.Name = "Анкета КАСКО";
            model.Description = @"Анкета КАСКО";
            model.Version = "Draft";
            model.IsPrivate = true;
            model.ProcessResumeAccessRules = new List<FlowProcessSecurity>();
            model.ProcessStartAccessRules = new List<FlowProcessSecurity>();
            model.VariableModelInfoList = new List<ProcessVariableDefinition>();
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "Basket",
                TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "DiAccountNumberIn",
                TypeName = typeof(string).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "FillIntouchInternal",
                TypeName = typeof(bool).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "policyIssuedByCallCenter",
                TypeName = typeof(bool).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.Start = _prepareDocsForKaskoBasket;
            model.NavigationStartPoints = new List<NavigationStartModel>();
            model.NavigationStartPoints.Add(new NavigationStartModel
            {
                Identifier = "DiKaskoQuestionnaireStep",
                NextStep = _prepareDocsForKaskoBasket,
            });
        }

        private void InitializePrepareDocsForKaskoBasket(ProcedureModel model)
        {
            model.Identifier = "PrepareDocsForKaskoBasket";
            model.Name = "Подготовка файловых блоков";
            model.Description = @"Подготовка файловых блоков";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _diKaskoQuestionnaireFormStep;
            model.ExceptionNextStep = null;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.KaskoB2B.Code.Procedures.B2bKaskoInsuranceProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.KaskoB2B.Code.Procedures.B2bKaskoInsuranceProcedures.PrepareDocsForKaskoBasket),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializeInitializeAddressesForDriver(ProcedureModel model)
        {
            model.Identifier = "InitializeAddressesForDriver";
            model.Name = "Инициализация сущности Address у водителя";
            model.Description = @"Инициализация сущности Address у водителя";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _issue;
            model.ExceptionNextStep = null;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.KaskoOsago.Code.Procedures.DiKaskoQuestionnaireProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.KaskoOsago.Code.Procedures.DiKaskoQuestionnaireProcedures.InitializeAddressesForDrivers),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializecheckStartDateOfCalculate(NestedProcessModel model)
        {
            model.Identifier = "checkStartDateOfCalculate";
            model.Name = "Проверка даты создания расчета";
            model.Description = string.Empty;
            model.FlowProcessIdentifier = "CheckStartDateOfPolicyProcess";
            model.FlowProcessVersion = "Draft";
            model.DataTypeName = null;
            model.ExceptionNextStep = null;
            model.InputParameters = new List<ParameterNestedModel>();
            model.InputParameters.Add(new ParameterNestedModel
            {
                Name = "Basket",
                ExpressionType = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                InExpression = @"Basket",
            });
            model.ReturnParameters = new List<ProcedureModelOutput>();
            model.NextSteps = new List<ProcessExitPoint>();
            model.NextSteps.Add(new ProcessExitPoint
            {
                Name = "Exit_Failed",
                NextStep = _dateStartMessageInfo,
            });
            model.NextSteps.Add(new ProcessExitPoint
            {
                Name = "Exit_Sucess",
                NextStep = _continueExit,
            });
        }

        private void InitializeInitializeAddressesForInsurant(ProcedureModel model)
        {
            model.Identifier = "InitializeAddressesForInsurant";
            model.Name = "Инициализация сущности Address у страхователя";
            model.Description = @"Инициализация сущности Address у страхователя";
            model.DataTypeName = null;
            model.IsAsync = false;
            model.NextStep = _initializeAddressesForDriver;
            model.ExceptionNextStep = null;
            model.Functions = new List<ProcedureModelFunction>();
            model.Functions.Add(new ProcedureModelFunction
            {
                ContainerTypeName = typeof(iRIS.KaskoOsago.Code.Procedures.DiKaskoQuestionnaireProcedures).AssemblyQualifiedName,
                Function = nameof(iRIS.KaskoOsago.Code.Procedures.DiKaskoQuestionnaireProcedures.InitializeAddressesForInsurant),
                Parameters = new List<FunctionParameter>
                {
                    new FunctionParameter
                    {
                        Name = "basket",
                        TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                        Expression = @"Basket",
                    },
                },
            });
            model.Outputs = new List<ProcedureModelOutput>();
        }

        private void InitializeDiKaskoQuestionnaireFormStep(FormDataModel model)
        {
            model.Identifier = "DiKaskoQuestionnaireFormStep";
            model.Name = "Отрисовка формы – анкета.";
            model.Description = @"Отрисовка формы – анкета.";
            model.FormDataType = FormDataType.Form;
            model.FormName = "DiKaskoQuestionnaireStep";
            model.FormNameExpression = null;
            model.VersionManagementActions = new List<VersionManagementAction>();
            model.VersionManagementActions.Add(VersionManagementAction.ResetCurrentChange);
            model.VersionManagementActions.Add(VersionManagementAction.LoadTechnicalVersion);
            model.VersionManagementActions.Add(VersionManagementAction.LoadUserVersion);
            model.VersionManagementActions.Add(VersionManagementAction.LoadCallCenterVersion);
            model.NotSaveDraft = false;
            model.FormNestedEntities = new List<FormNestedEntity>();
            model.NextStep = _initializeAddressesForInsurant;
        }

        private void Initializeissue(InputModel model)
        {
            model.Identifier = "issue";
            model.Name = "Вызов действия «Отправить»";
            model.Description = @"Вызов действия «Отправить»";
            model.PermissionType = "actionIssue";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.FullModel;
            model.ValidationGroups = new List<string>();
            model.ValidationGroups.Add("DiKaskoQuestionnaireDelivery");
            model.ValidationGroups.Add("Address");
            model.ValidationGroups.Add("DIUnderwriterApprovalFromCallcenter");
            model.ValidationGroups.Add("DiKaskoQuestionnaire");
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = null;
            model.NextStep = _saveDraftBasketBlockAfterBuy;
        }

        private void InitializeContinueExit(ExitPointModel model)
        {
            model.Identifier = "ContinueExit";
            model.Name = "Анкета заполнена";
            model.Description = @"Продолжить оформление";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializedateStartMessageInfo(FormDataModel model)
        {
            model.Identifier = "dateStartMessageInfo";
            model.Name = "DateStartMessageInfo";
            model.Description = string.Empty;
            model.FormDataType = FormDataType.Message;
            model.MessageExpression = @"Дата начала срока действия расчета не валидна";
            model.NotificationType = iRIS.Framework.Common.Notifications.NotificationType.Error;
            model.Caption = "Дата начала срока действия расчета";
            model.NextStep = null;
        }

        private void InitializeSaveDraftBasketBlockAfterBuy(VersionPublisherModel model)
        {
            model.Identifier = "SaveDraftBasketBlockAfterBuy";
            model.Name = "Сохранение черновика корзины";
            model.Description = @"F1. Сохранение черновика корзины";
            model.VersionAction = VersionAction.SaveDraft;
            model.RelationType = RelationType.Draft;
            model.NextStep = _checkStartDateOfCalculate;
            model.ExceptionNextStep = null;
        }
    }
}


using iRIS.Framework.Common;
using iRIS.Framework.Cqrs.Interfaces;
using iRIS.InsuranceCore.Code.ConstructorCore.Models;
using iRIS.InsuranceCore.Code.CustomProcesses.BasketPreparationProcess.Enums;
using iRIS.InsuranceCore.Code.Queries;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.KaskoCore.Code.Interfaces;
using iRIS.KaskoCore.CreateOn.Code.OssKaskoOptionsProcessor;
using iRIS.KaskoCore.CreateOn.Code.Utilities;
using iRIS.KaskoLink2.Code.Constructor;
using iRIS.KaskoLink2.Code.CreateOn.DealInitialization;
using iRIS.KaskoLink2.Code.CreateOn.Extension;
using iRIS.KaskoLink2.Code.CreateOn.Utilities;
using Serilog;
using System.Collections.Generic;
using System.Linq;

namespace iRIS.KaskoLink2.Code.CreateOn.OssKaskoOptionsProcessor
{
    internal sealed class OssKaskoOptionsProcessor : IOssKaskoOptionsProcessor
    {
        private readonly ICqrsMediator _mediator;
        private readonly ILogger _logger;
        private readonly IOssKaskoOptionsRulesRunner _ossKaskoOptionsRulesRunner;
        private readonly IOssKaskoOptionsEnricher _ossKaskoOptionsEnricher;
        private readonly IKaskoConstructorOfferGetter _constructorOfferGetter;
        private readonly IDiKaskoConditionsProcessor _diKaskoConditionsProcessor;
        private readonly IDiKaskoDealManager _diKaskoDealManager;

        private Dictionary<int, ProductConfiguration> _productConfigurations;

        public OssKaskoOptionsProcessor(
            ICqrsMediator mediator,
            ILogger logger,
            IOssKaskoOptionsRulesRunner ossKaskoOptionsRulesRunner,
            IOssKaskoOptionsEnricher ossKaskoOptionsEnricher,
            IKaskoConstructorOfferGetter constructorOfferGetter,
            IDiKaskoConditionsProcessor diKaskoConditionsProcessor,
            IDiKaskoDealManager diKaskoDealManager)
        {
            _mediator = mediator;
            _logger = logger;
            _ossKaskoOptionsRulesRunner = ossKaskoOptionsRulesRunner;
            _ossKaskoOptionsEnricher = ossKaskoOptionsEnricher;
            _constructorOfferGetter = constructorOfferGetter;
            _diKaskoConditionsProcessor = diKaskoConditionsProcessor;
            _diKaskoDealManager = diKaskoDealManager;
        }

        public IReadOnlyList<PreviousOssOption> SetOssKaskoOptions(Basket basket, string integrationLogin)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            InitServices(basket, kaskoDeal);

            var ossKaskoOptions = kaskoDeal.AutoDeal.PreviousOssOptions.Select(s => s.CloneWithoutStructId()).ToList();

            _ossKaskoOptionsRulesRunner.RunRules(basket, kaskoDeal, ossKaskoOptions, _productConfigurations.Select(v => v.Value).ToList(), integrationLogin);

            _ossKaskoOptionsEnricher.EnrichStructIds(ossKaskoOptions);

            FillDealsConditions(basket, kaskoDeal, _ossKaskoOptionsEnricher.ParentStructIds, ossKaskoOptions);

            UpdateStructId(ossKaskoOptions, kaskoDeal.AutoDeal.PreviousOssOptions);

            return ossKaskoOptions;
        }

        private void FillDealsConditions(Basket basket, Deal deal, IReadOnlyList<int> parentStructtIds, IReadOnlyList<PreviousOssOption> ossKaskoOptions)
        {
            var deals = new List<Deal>() { deal };
            var addedProposal = DealInitializationHelper.AddProposal(deal, _constructorOfferGetter.GetConstructorOfferId(basket));

            deal.DealConditionGroups.Clear();
            deal.ConditionBlock = null;
            deal.PaymentSchedule = null;
            deal.PaymentSchedule_Id = null;

            var dealConditions = _diKaskoConditionsProcessor.CreateDealConditionsForProposals(deal, _productConfigurations, GetStructIdAndSums(parentStructtIds, ossKaskoOptions), null, false);
            _diKaskoDealManager.ApplyDealsCondition(new Deal[] { deal }, dealConditions);

            var paymentSchedule = ossKaskoOptions.Single(p => p.Type == ProductConfigurationType.PaymentSchedule.ToString());
            var prConfSchedule = _productConfigurations.Select(v => v.Value).Single(p => p.StructId == paymentSchedule.StructId);
            deal.PaymentSchedule_Id = prConfSchedule.PaymentSchedule_Id;
            deal.PaymentSchedule = prConfSchedule.PaymentSchedule;

            deal.Proposals.Remove(addedProposal);
        }

        private List<StructIdAndSum> GetStructIdAndSums(IReadOnlyList<int> parentStructIds, IReadOnlyList<PreviousOssOption> ossKaskoOptions)
        {
            var structIdAndSum = new List<StructIdAndSum>(parentStructIds.Count + ossKaskoOptions.Count);
            structIdAndSum.AddRange(parentStructIds.Select(s => new StructIdAndSum(s)));
            structIdAndSum.AddRange(ossKaskoOptions
                .Where(s => s.IsFoundProductConfiguration())
                .Select(s => new StructIdAndSum(s.StructId.Value, s.Sum)));

            return structIdAndSum;
        }

        private void UpdateStructId(IReadOnlyList<PreviousOssOption> sources, IReadOnlyList<PreviousOssOption> targets)
        {
            var comparer = new OssKaskoOptionsComparer();
            foreach (var source in sources)
            {
                var target = targets.SingleOrDefault(t => comparer.Equals(t, source));
                if (target != null)
                {
                    target.StructId = source.StructId;
                }
            }
        }

        private void InitServices(Basket basket, Deal deal)
        {
            var queryOffer = _mediator.ResolveQuery<IQueryOffer>();
            var offers = queryOffer.GetOffers(new int?[] { _constructorOfferGetter.GetConstructorOfferId(basket) }, DT.Now, null);
            var productConfigurations = _mediator.ResolveQuery<IQueryProductConfiguration>().GetProductConfigurationForOffers(offers, DT.Now, null);
            _productConfigurations = productConfigurations;

            _ossKaskoOptionsEnricher.Init(_productConfigurations.Select(v => v.Value).ToList());
        }

        public IReadOnlyList<PreviousOssOption> SetOssKaskoOptionsForKaskoProlongationLogic(Basket basket)
        {
            return new List<PreviousOssOption>();
        }
    }
}
using iRIS.Framework.Data.Services.Client;
using iRIS.Framework.Entity.Dictionary.EntitySettings;
using iRIS.Framework.Entity.Metadata;
using iRIS.Framework.Link2;
using iRIS.Framework.Security.Entities;
using iRIS.Framework.Validation;
using iRIS.Framework.Workflow.Process.CustomProcessModel;
using iRIS.InsuranceCore.Code.Implementations.Comparison;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.Custom;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.InsuranceCore.Entities.Enums;
using iRIS.KaskoCore.Code.Constants;
using iRIS.KaskoCore.Code.Helpers;
using iRIS.KaskoLink2.Code.Constants;
using iRIS.KaskoLink2.Code.Constants.ConstantsHelpers;
using iRIS.KaskoLink2.Code.Helpers;
using iRIS.KaskoLink2.Code.Implementations.AutoCostCalculator;
using Microsoft.Extensions.DependencyInjection;
using SasClient.Code.CheckKaskoUpProjectService;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using EntitySettingCodes = iRIS.KaskoLink2.Implementations.Code.Constants.EntitySettingCodes;

namespace iRIS.KaskoLink2.Code.CustomProcesses
{
    /// <summary>
    /// Подпроцесс проверки Kasko корзины в SAS.
    /// </summary>
    public class KaskoSasCheckProcessForLink2 : ICustomProcess, IAsyncCustomProcess
    {
        private string _aggregateName = Link2AggregateNames.Link2AutoDealWithURMAndSasDetailed;

        /// <summary>
        /// Переход ЦС.
        /// </summary>
        public const string ExitBranch_TargetedSegment = "TargetedSegment";

        /// <summary>
        /// Переход Не ЦС. Reject.
        /// </summary>
        public const string ExitBranch_NotTargetedSegment_Reject = "NotTargetedSegment_Reject";

        /// <summary>
        /// Переход Не ЦС. CorrData.
        /// </summary>
        public const string ExitBranch_NotTargetedSegment_CorrData = "NotTargetedSegment_CorrData";

        /// <summary>
        /// Сделка.
        /// </summary>
        public const string InputArgument_Deal = nameof(Deal);

        /// <summary>
        /// Корзина.
        /// </summary>
        public const string InputArgument_Basket = nameof(Basket);

        /// <summary>
        /// Имеются чувствительные данные при перерасчете.
        /// </summary>
        public const string InputArgument_IsSensitiveDataChanged = "IsSensitiveDataChanged";

        /// <summary>
        /// Проверки urm до перерасчета.
        /// </summary>
        public const string InputArgument_ExternalBasketUrmAproval = "ExternalBasketUrmAproval";

        /// <summary>
        /// Ошибки от SAS.
        /// </summary>
        public const string OutpuArgument_Value = nameof(Value);

        /// <summary>
        /// Входной параметр - Cделка.
        /// </summary>
        public InputArgument<Deal> Deal { get; } = new InputArgument<Deal>(InputArgument_Deal);

        /// <summary>
        /// Входной параметр - Корзина.
        /// </summary>
        public InputArgument<Basket> Basket { get; } = new InputArgument<Basket>(InputArgument_Basket);

        /// <summary>
        /// Входной параметр - Наименование процесса.
        /// </summary>
        [Obsolete("Не используется с 09.09.21")]
        public InputArgument<string> ProcessName { get; } = new InputArgument<string>("ProcessName");

        /// <summary>
        /// Выходоной параметр - сообщение об ошибке.
        /// </summary>
        /// <output/>
        public OutputArgument<string> Value { get; } = new OutputArgument<string>(OutpuArgument_Value);

        /// <summary>
        /// Входной параметр - Чувствительные изменения при перерасчете.
        /// </summary>
        public InputArgument<bool> IsSensitiveDataChanged { get; } = new InputArgument<bool>(InputArgument_IsSensitiveDataChanged);

        /// <summary>
        /// Входной параметр - Проверки URM корзины до перерасчета.
        /// </summary>
        public InputArgument<URMApproval> ExternalBasketUrmAproval { get; } = new InputArgument<URMApproval>(InputArgument_ExternalBasketUrmAproval);

        /// <inheritdoc />
        public void Execute(IProcessContext processContext)
        {
            ExecuteAsync(processContext).GetAwaiter().GetResult();
        }

        /// <inheritdoc />
        public async Task ExecuteAsync(IProcessContext processContext)
        {
            var logger = processContext.ServiceProvider.GetService<ILogger>()?.ForContext<KaskoSasCheckProcess>();

            var deal = Deal.Get(processContext);
            var basket = Basket.Get(processContext);
            IsSensitiveDataChanged.TryGet(processContext, out var isSensitiveDataChanged);
            ExternalBasketUrmAproval.TryGet(processContext, out var externalBasketUrmAproval);

            var checkKaskoUpProjectServiceAdapter = processContext.ServiceProvider.GetService<ICheckKaskoUpProjectServiceAdapter<Basket, Deal>>();
            var autoCostCalculator = processContext.ServiceProvider.GetService<IAutoCostCalculator>();
            var validationResultsAggregator = processContext.ServiceProvider.GetRequiredService<IValidationResultsAggregator>();
            var priceMax = await SasRequestResultHelper.GetMaxPriceAsync(autoCostCalculator, deal);

            var integrationLoginName = processContext.GetCustomVariable(Link2Constants.IntegrationLoginKey) as string;

            string externalBasketUrmAprovalStatus = externalBasketUrmAproval?.URMApprovalStatusCode;

            if (externalBasketUrmAproval != null)
            {
                string sensitiveChangeMessage = isSensitiveDataChanged
                    ? "Чувствительные изменения при перерасчете обнаружены"
                    : "Чувствительные изменения при перерасчете не обнаружены";

                logger?.Information($"{sensitiveChangeMessage}, статус URM до перерасчета: {externalBasketUrmAprovalStatus}");
            }

            if (!isSensitiveDataChanged && (
                externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.Accepted || 
                externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.AcceptedWithLimits ||
                externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.RequiredExtraInfo))
            { 
                SetExternalBasketUrmAprovalStatus(deal, externalBasketUrmAprovalStatus);
                return;
            }

            try
            {
                var sw = Stopwatch.StartNew();

                var requestGuid = Guid.NewGuid().ToString();
                if (deal.AutoDeal.IsSasCoefficientOutdate != false)
                {
                    var firstCheckResult = await checkKaskoUpProjectServiceAdapter.FirstCheckBasketAsync(basket, deal, priceMax, requestGuid);

                    AutoCheckResultHelper.CreateKaskoRtdmAutoCheckResult(deal, firstCheckResult);
                }

                var secondCheckResult = await checkKaskoUpProjectServiceAdapter.SecondCheckBasketAsync(basket, deal, requestGuid);
                var decision = secondCheckResult.FinDecision?.ToLower();

                sw.Stop();

                logger?.ForContext("BasketNumber", basket.Number)
                    .Information("Блок проверки Check Kasko Project SAS: {TotalTime} ms", sw.ElapsedMilliseconds);

                AutoCheckResultHelper.CreateKaskoRtdmPassportCheckAutoCheckResult(deal, secondCheckResult);

                var comment = $"Проверка через SAS. {decision}";

                logger?.ForContext("BasketNumber", basket.Number)
                    .Information(comment, sw.ElapsedMilliseconds);

                if (secondCheckResult.Inspection || (decision is KaskoSasCheckProcessConstants.KaskoSasCheckNoDecision && deal.GetAuto().HasMileage == true))
                {
                    deal.EntityContext[PsoEntityValuesConstants.IsInspectionForPartnerBySasDecision] = true;
                }

                UpdateSasApprovalInDeal(deal, SASApprovalStatusCodeHelper.GetSASStatusCode(decision), secondCheckResult.SasCoefficient);
                string exitBranch = string.Empty;               

                switch (decision)
                {
                    case KaskoSasCheckProcessConstants.KaskoSasCheckAccept:
                        if (isSensitiveDataChanged && (
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.Accepted || 
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.AcceptedWithLimits ||
                            externalBasketUrmAprovalStatus == UrmApprovalStatusCodes.RequiredExtraInfo))
                        {
                            SetExternalBasketUrmAprovalStatus(deal, externalBasketUrmAprovalStatus);
                        }
                        else
                        {
                            UrmHelper.SetUrmApprovalNotRequired(deal);
                        }
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);
какой structId у риска тоталь?