Отвечай на вопросы, используя следующий контекст:
/// <summary>
        /// Установка статуса УРМ.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="sendMailOPKKK">Признак отправки письма в ОПККК.</param>
        public void SetURMApprovalStatus(Basket basket, bool sendMailOPKKK)
        {
            UrmApprovalStatusHelper.SetURMApprovalStatus(basket, sendMailOPKKK);
        }

        /// <summary>
        /// Установка признака повторного запроса в УРМ.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void SetURMApprovalIsRepeated(Basket basket)
        {
            var kaskoDeal = basket.GetKaskoDeal();

            if (kaskoDeal.IsInBasket != true)
            {
                return;
            }

            var approval = kaskoDeal.AutoDeal.GetLastUrmApproval();

            approval.IsRepeated = true;
        }

        /// <summary>
        /// Смена статуса проверок андеррайтера на статус "В работе".
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void SetDIUnderwriterApprovalStatusInWork(Basket basket)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            foreach (var approval in kaskoDeal.AutoDeal.DIUnderwriterApprovals)
            {
                if (approval.StatusCode == DiUnderwriterApprovalStatusCodes.Required || approval.StatusCode == DiUnderwriterApprovalStatusCodes.RequiredExtraInfo || string.IsNullOrEmpty(approval.StatusCode))
                {
                    approval.StatusCode = DiUnderwriterApprovalStatusCodes.InWork;
                    approval.RequestCreateDate ??= DT.Now;
                }
            }
        }

        /// <summary>
        /// Смена флага покупки полиса под клиентом.
        /// </summary>
        public void SetConfirmedByClient(Basket basket, bool value, bool forEPolicy)
        {
            var kasko = basket.GetDealByProductDictCode(ProductDictCodes.Kasko);
            var osago = basket.GetDealByProductDictCode(ProductDictCodes.Osago);

            if ((kasko?.IsEPolicy == true || osago?.IsEPolicy == true) && forEPolicy != true)
            {
                return;
            }

            basket.ConfirmedByClient = value;
        }

        /// <summary>
        /// Проверить наличие одинаковых водителей (В процессе КАСКО проверяется только для ОСАГО, так как в КАСКО нет точных полей ФИО + Д.Р.).
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <returns>Флаг наличия одинаковых водителей.</returns>
        public bool CheckDublicateDriversForKaskoProcess(Basket basket)
        {
            return false;

            var kaskoDeal = basket.GetKaskoDeal();

            if (kaskoDeal == null || kaskoDeal.AutoDeal == null || kaskoDeal.AutoDeal.IsMultidrive.GetValueOrDefault(false))
            {
                return false;
            }

            var drivers = kaskoDeal.AutoDeal.Drivers;

            var driversGroups = drivers.GroupBy(i => new
            {
                i.DriverLicenseSeries,
                i.DriverLicenseNumber,
                i.Subject.IndividualEntity.Person.Name,
                i.Subject.IndividualEntity.Person.LastName,
                i.Subject.IndividualEntity.Person.MiddleName,
                i.Subject.IndividualEntity.Person.DriveExperience,
                i.Subject.IndividualEntity.Person.DateOfBirth
            });

            return drivers.Count() != driversGroups.Count();
        }

        /// <summary>
        /// Проверить доступность оформления полиса без осмотра через мобильное приложение.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <returns>true, если нет ПСО и нет ни одной проверки.</returns>
        public bool CheckDealWithoutInspection(Basket basket)
        {
            var checkManager = ServiceProvider.GetService<ICheckInspectionManager>();
            var isWithoutInspection = checkManager.DealWithoutInspection(basket);
            var kaskoDeal = basket.GetKaskoDeal();

            bool underwriterApprovalsAdded = kaskoDeal.AutoDeal.DIUnderwriterApprovals
                 .Any(o => o.StatusCode == DiUnderwriterApprovalStatusCodes.Required);

            bool otaApprovalsAdded = kaskoDeal.AutoDeal.OtaApproval
                .Any(o => o.OtaApprovalStatusCode == OtaApprovalStatusCodes.Required);

            bool urmApprovalsAdded = kaskoDeal.AutoDeal.URMApproval
                .Any(o => o.URMApprovalStatusCode == UrmApprovalStatusCodes.Required);

            return isWithoutInspection && !underwriterApprovalsAdded && !otaApprovalsAdded && !urmApprovalsAdded;
        }

        /// <summary>
        /// Проверка необходима ли проверка полиса Каско в SAS для корзины.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="authorizationData">Данные авторизации.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsSasRequired(Basket basket, AuthorizationData authorizationData)
        {
            if (!authorizationData.IsAuthenticated)
            {
                return false;
            }

            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);
            var settingsManager = (IEntitySettingsManager)ServiceProvider.GetService(typeof(IEntitySettingsManager));

            //  запрос в САС требуется для всех случаев, кроме пролонгации, так же может быть выключен именованной настройкой
            if (IsNotProlongation(basket) &&
                settingsManager.TryGetSettingValue<bool>(
                    KaskoSasCheckProcessConstants.KaskoSasCheckProcessSettings,
                    out var checkKaskoSasRequired,
                    x => x.Where(c => c.Code == KaskoSasCheckProcessConstants.KaskoSasCheckProcessDefault)))
            {
                log.Information($"CheckIsSasRequired. EntitySetting value is {checkKaskoSasRequired}");
                return checkKaskoSasRequired;
            }

            return false;
        }

        /// <summary>
        /// Проверка возможности вызова BSI.
        /// </summary>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsAllowedToUseBSI(string integrationLogin)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.IsAllowedToUseBSI,
                KaskoEntitySettingCodes.IsAllowedToUseBSIDefault,
                KaskoEntitySettingCodes.IsAllowedToUseBSIByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false);
        }

        /// <summary>
        /// Проверка возможности обращения в Comissions.
        /// </summary>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsAllowedToGetComissions(string integrationLogin)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            var log = ServiceProvider.GetRequiredService<ILogger>();

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.IsAllowedToGetComissionsOnCalculate,
                KaskoEntitySettingCodes.IsAllowedToGetComissionsOnCalculateDefault,
                KaskoEntitySettingCodes.IsAllowedToGetComissionsOnCalculateByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false,
                log);
        }

        /// <summary>
        /// Проверка признака партнера B2C.
        /// </summary>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsB2CPartner(string integrationLogin, int entityId)
        {
            var entitySettingsManager = ServiceProvider.GetService<IEntitySettingsManager>();

            if (!string.IsNullOrEmpty(integrationLogin))
            {
                return entitySettingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.IsB2CPartner,
                KaskoEntitySettingCodes.IsB2CPartnerDefault,
                KaskoEntitySettingCodes.IsB2CPartnerByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false);
            }

            var permissionManager = ServiceProvider.GetService<IPermissionManager>();
            var queryIntegrationLogin = ServiceProvider.GetService<IQueryIntegrationLogin>();

            var userId = permissionManager.GetUserIdByRelationForObject(PermissionConstants.Relation.Creator, nameof(Basket), entityId);
            var creator = queryIntegrationLogin.GetIntegrationLoginByUserId(userId.Value);

            string integrationLoginName = creator.IntegrationLoginName;

            return CheckIsB2CPartnerHelper.CheckIsB2CPartner(entitySettingsManager, integrationLoginName);
        }

        public bool CheckIsSasRequestExecuted(Basket basket)
        {
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);
            var autoDeal = basket.GetKaskoDeal().AutoDeal;
            log.Information($"CheckIsSasRequestExecuted. Current SasApprovalStatus {autoDeal.SASApproval[0].SASApprovalStatusCode}");
            return !string.IsNullOrWhiteSpace(autoDeal.SASApproval[0].SASApprovalStatusCode);
        }

        /// <summary>
        /// Устанавливаем по умолчанию коэффицеинт САС. IRIS-103112.
        /// </summary>
        /// <param name="basket">basket.</param>
        public void SetDefaultSas(Basket basket)
        {
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);
            var deal = basket.GetKaskoDeal();

            if (deal.AutoDeal.SasCoefficient == null || deal.AutoDeal.SasCoefficient == 0)
            {
                var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
                var sasCoefficientHelper = ServiceProvider.GetRequiredService<SasCoefficientHelper>();
                if (settingsManager.TryGetSettingValue<decimal>("KaskoDefaultSasCoefficientValueSetting", out var settingsValue))
                {
                    sasCoefficientHelper.SetSasCoefficientToDeal(deal, basket.ExternalTagList.UseDrafts, settingsValue, 2);
                }

                log.Information($"Установка deal.AutoDeal.SasCoefficient. Значение: {settingsValue}");
            }
        }

        /// <summary>
        /// Проверка необходима ли проверка полиса Каско в SAS для корзины из Link2.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="authorizationData">Данные авторизации.</param>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsSasRequiredForLink2(Basket basket, AuthorizationData authorizationData, string integrationLoginName)
        {
            if (!authorizationData.IsAuthenticated)
            {
                return false;
            }

            var link2Invoker = ServiceProvider.GetRequiredService<Link2FunctionsInvoker>();
            var settingsManager = (IEntitySettingsManager)ServiceProvider.GetRequiredService(typeof(IEntitySettingsManager));
            var basketCreatorIsLink2Partner = link2Invoker.BasketCreatorIsLink2PartnerOrDiAgent(basket);
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);

            if (!basketCreatorIsLink2Partner)
            {
                return false;
            }

            if (basket.IsLead == true)
            {
                settingsManager.TryGetSettingValue<string[]>(KaskoEntitySettingCodes.GetSasCoefficientOnCalculateForLead, out var partnersWithSasRequestForLead);

                if (!partnersWithSasRequestForLead.Contains(integrationLoginName))
                {
                    return false;
                }
            }

            var deal = basket.GetKaskoDeal();

            var intermediary = deal
                ?.DealIntermediaries
                ?.FirstOrDefault(x => x.Intermediary?.InteractionTypeCode == InteractionTypeEnum.Agent.ToString())
                ?.Intermediary ?? deal.GetMainIntermediary();

            var autoDeal = deal?.AutoDeal;

            if (intermediary == null || (autoDeal?.IsSubscription == true && !string.IsNullOrEmpty(autoDeal?.PreviousPolicyNumber)) || IsLink2Upsale(basket) || !IsNotProlongation(basket))
            {
                return false;
            }

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessSettings,
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessDefault,
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessByIntermediary,
                intermediary,
                true,
                log);
        }

        /// <summary>
        /// Проверка необходима ли проверка полиса Каско в SAS для корзины из Link2.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="authorizationData">Данные авторизации.</param>
        /// <param name="defaultSasRequired">Проверка SAS по умолчанию.</param>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        [Obsolete("Устарел, использовать CheckIsSasRequiredForLink2(Basket, AuthorizationData, string)")]
        public bool CheckIsSasRequiredForLink2(Basket basket, AuthorizationData authorizationData, bool defaultSasRequired, string integrationLoginName)
        {
            if (!authorizationData.IsAuthenticated)
            {
                return false;
            }

            var link2Invoker = ServiceProvider.GetRequiredService<Link2FunctionsInvoker>();
            var settingsManager = (IEntitySettingsManager)ServiceProvider.GetRequiredService(typeof(IEntitySettingsManager));
            var basketCreatorIsLink2Partner = link2Invoker.BasketCreatorIsLink2PartnerOrDiAgent(basket);

            if (!basketCreatorIsLink2Partner)
            {
                return false;
            }

            if (basket.IsLead == true)
            {
                settingsManager.TryGetSettingValue<string[]>(KaskoEntitySettingCodes.GetSasCoefficientOnCalculateForLead, out var partnersWithSasRequestForLead);

                if (!partnersWithSasRequestForLead.Contains(integrationLoginName))
                {
                    return false;
                }
            }

            var deal = basket.GetKaskoDeal();

            var intermediary = deal
                ?.DealIntermediaries
                ?.FirstOrDefault(x => x.Intermediary?.InteractionTypeCode == InteractionTypeEnum.Agent.ToString())
                ?.Intermediary;

            var autoDeal = deal?.AutoDeal;

            if (intermediary == null || (autoDeal?.IsSubscription == true && !string.IsNullOrEmpty(autoDeal?.PreviousPolicyNumber)) || IsLink2Upsale(basket))
            {
                return false;
            }

            // проверка необходимсоти отправки в сас по посреднику
            if (settingsManager.TryGetSettingValue<bool>(
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessSettings,
                intermediary,
                out var checkKaskoSasRequired,
                x => x.Where(c => c.Code == KaskoSasCheckProcessConstants.KaskoSasCheckProcessByIntermediary)))
            {
                return checkKaskoSasRequired;
            }

            return defaultSasRequired;
        }
/// <summary>
        /// Создаёт файловые блоки для документов сделок.
        /// Проверки осаго на null необходимы для процесса б2б каско.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void PrepareDocsForKaskoBasket(Basket basket)
        {
            var processDataService = (IProcessDataService)ServiceProvider.GetRequiredService(typeof(IProcessDataService));
            var dictionaryDate = processDataService.GetDictionaryDate(basket.RelatedProcessKey ?? basket.Number, 1);
            var kaskoDeal = basket.Deals.Single(x => x.Product.ProductDictCode == ProductDictCodes.Kasko);
            var osagoDeal = basket.Deals.SingleOrDefault(x => x.Product.ProductDictCode == ProductDictCodes.Osago);
            var eosagoDeal = basket.Deals.SingleOrDefault(x => x.Product.ProductDictCode == ProductDictCodes.EOsago);

            var fileBlockBuilder = (IFileBlockBuilder)ServiceProvider.GetRequiredService(typeof(IFileBlockBuilder));
            var fileBlockStructureProvider = (IFileBlockStructureProvider)ServiceProvider.GetRequiredService(typeof(IFileBlockStructureProvider));

            if (eosagoDeal == null)
            {
                // инициализация полей каско при отсутствии
                var autoKasko = kaskoDeal.GetAuto();
                var ownerKasko = kaskoDeal.GetOwner();
                kaskoDeal.AutoDeal.TsIdentityCard ??= new TsIdentityCard();
                kaskoDeal.Insurant.IdentityDocument ??= new IdentityDocument();
                ownerKasko.IdentityDocument ??= new IdentityDocument();
                autoKasko.DiagnosticCard ??= new DiagnosticCard();
                kaskoDeal.OtherInsuranceCompanyPolicy ??= new OtherInsuranceCompanyPolicy();

                // создаём файловые блоки
                if (kaskoDeal.AutoDeal.Drivers.Any(dr => dr.DriverLicenseScan is null))
                {
                    //при переходе между анкетой и сегментацией количество водителей может менятся и надо каждый раз инициализировать файловые блоки
                    fileBlockBuilder.BuildFileBlock(
                        basket,
                        fileBlockStructureProvider.GetFileBlockStructure("DriverLicense", dictionaryDate),
                        "Deals.Where(Product.InsuranceTypeCode == \"KASKO\").AutoDeal.Drivers.DriverLicenseScan");
                }

                if (kaskoDeal.AutoDeal.TsIdentityCard.FileBlock is null || kaskoDeal.AutoDeal.TsIdentityCard.FileBlock.FileGroups.Count == 0)
                {
                    fileBlockBuilder.BuildFileBlock(
                        basket,
                        fileBlockStructureProvider.GetFileBlockStructure(nameof(TsIdentityCard), dictionaryDate),
                        "Deals.Where(Product.InsuranceTypeCode == \"KASKO\").AutoDeal.TsIdentityCard.FileBlock");

                    if (kaskoDeal.AutoDeal.TsIdentityCard.OwnershipProof is null || kaskoDeal.AutoDeal.TsIdentityCard.OwnershipProof.FileGroups.Count == 0)
                    {
                        fileBlockBuilder.BuildFileBlock(
                             basket,
                             fileBlockStructureProvider.GetFileBlockStructure("OwnershipProof", dictionaryDate),
                             "Deals.Where(Product.InsuranceTypeCode == \"KASKO\").AutoDeal.TsIdentityCard.OwnershipProof");
                    }
                }

                if (kaskoDeal.Insurant.IdentityDocument.FileBlock is null || kaskoDeal.Insurant.IdentityDocument.FileBlock.FileGroups.Count == 0)
                {
                    fileBlockBuilder.BuildFileBlock(
                        basket,
                        fileBlockStructureProvider.GetFileBlockStructure(nameof(IdentityDocument), dictionaryDate),
                        "Deals.Where(Product.InsuranceTypeCode == \"KASKO\").Insurant.IdentityDocument.FileBlock");
                }

                if (ownerKasko.IdentityDocument.FileBlock is null)
                {
                    fileBlockBuilder.BuildFileBlock(
                        basket,
                        fileBlockStructureProvider.GetFileBlockStructure(nameof(IdentityDocument), dictionaryDate),
                        "Deals.Where(Product.ProductDictCode == \"KASKO\").InsuranceObjects.Where(InsuranceObjectTypeCode == \"Auto\").Owners[0].IdentityDocument.FileBlock");
                }

                if (kaskoDeal.OtherInsuranceCompanyPolicy.FileBlock is null)
                {
                    fileBlockBuilder.BuildFileBlock(
                        basket,
                        fileBlockStructureProvider.GetFileBlockStructure(nameof(OtherInsuranceCompanyPolicy), dictionaryDate),
                        "Deals.Where(Product.ProductDictCode == \"KASKO\").OtherInsuranceCompanyPolicy.FileBlock");
                }

                if (osagoDeal != null)
                {
                    // инициализация полей осаго при отсутствии
                    var autoOsago = osagoDeal?.GetAuto();
                    osagoDeal.AutoDeal.TsIdentityCard ??= new TsIdentityCard();
                    osagoDeal.Insurant.IdentityDocument ??= new IdentityDocument();
                    osagoDeal.GetOwner().IdentityDocument ??= new IdentityDocument();
                    osagoDeal.OtherInsuranceCompanyPolicy ??= new OtherInsuranceCompanyPolicy();
                    autoOsago.DiagnosticCard ??= new DiagnosticCard();

                    // перенос файловых блоков из каско в осаго
                    foreach (var kaskoDriver in kaskoDeal.AutoDeal.Drivers)
                    {
                        var osagoDriver = osagoDeal.AutoDeal.Drivers.SingleOrDefault(x => x == kaskoDriver);

                        if (osagoDriver != null)
                        {
                            osagoDriver.DriverLicenseScan = kaskoDriver.DriverLicenseScan;
                        }
                    }

                    osagoDeal.AutoDeal.TsIdentityCard.FileBlock = kaskoDeal.AutoDeal.TsIdentityCard.FileBlock;
                    osagoDeal.AutoDeal.TsIdentityCard.OwnershipProof = kaskoDeal.AutoDeal.TsIdentityCard.OwnershipProof;
                    osagoDeal.Insurant.IdentityDocument.FileBlock = kaskoDeal.Insurant.IdentityDocument.FileBlock;
                    osagoDeal.GetOwner().IdentityDocument.FileBlock = ownerKasko.IdentityDocument.FileBlock;
                    autoOsago.DiagnosticCard.FileBlock = autoKasko.DiagnosticCard.FileBlock;
                    osagoDeal.OtherInsuranceCompanyPolicy.FileBlock = kaskoDeal.OtherInsuranceCompanyPolicy.FileBlock;
                }
            }
        }

        /// <summary>
        /// Заполняет дату первого расчета у сделок по подписке соответствующим значением предыдущей сделки.
        /// Если значение уже задано, оно остается без изменений.
        /// </summary>
        /// <param name="basket">корзина</param>
        public void SetSubscriptionDealsDateFirstCalculation(Basket basket)
        {
            if (basket == null)
            {
                throw new ArgumentNullException(nameof(basket));
            }

            var deals = basket.Deals.Where(d => d.AutoDeal.IsSubscription == true);

            foreach (var deal in deals)
            {
                var prevNumber = deal.AutoDeal.PreviousPolicyNumber;

                if (!string.IsNullOrEmpty(prevNumber) && !deal.DateFirstCalculation.HasValue)
                {
                    var queryService = (ICachedQueryServiceInvoker)ServiceProvider.GetService(typeof(ICachedQueryServiceInvoker));
                    var prevDeal = queryService.GetByExpression<Deal>(x => x.Where(d => d.PolicyNumber == prevNumber && d.State == Framework.Data.VersionState.Current)).FirstOrDefault();

                    deal.DateFirstCalculation = prevDeal?.DateFirstCalculation;
                }
            }
        }

        /// <summary>
        /// Заполнить значения по умолчанию.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void InitDefaultValues(Basket basket)
        {
            SetDealInsuranceType(basket);
            SetMultidrive(basket);
            SetDriver(basket);
        }

        /// <summary>
        /// Получение значения настройки KaskoProlongationSendToSiebel.
        /// </summary>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Значение настройки KaskoProlongationSendToSiebel</returns>
        public bool GetKaskoProlongationSendToSiebel(string integrationLoginName)
        {
            if (string.IsNullOrEmpty(integrationLoginName))
            {
                return false;
            }

            var entitySettingsManager = ServiceProvider.GetService<IEntitySettingsManager>();
            var queryServiceInvoker = (ICachedQueryServiceInvoker)ServiceProvider.GetRequiredService(typeof(ICachedQueryServiceInvoker));
            var integrationLogin = queryServiceInvoker.GetByExpression<IntegrationLogin>(x => x.Where(u => u.IntegrationLoginName == integrationLoginName)).FirstOrDefault();
            var logger = ServiceProvider.GetRequiredService<ILogger>();

            return entitySettingsManager.GetSettingForDefaultOrPartnerConfiguration<bool>(
                EntitySettingCodes.KaskoProlongationSendToSiebel,
                EntitySettingCodes.KaskoProlongationSendToSiebelDefault,
                EntitySettingCodes.KaskoProlongationSendToSiebelPartner,
                integrationLogin,
                false,
                logger);
        }

        [Obsolete("Использовать SetBranchCodeByKladrForLink2(Basket basket, string integrationLoginName)")]
        public void SetBranchCodeByKladrForLink2(Basket basket)
        {
            SetBranchCodeByKladrForLink2(basket, null);
        }

        /// <summary>
        /// Задать филиал по региону использования авто для b2c партнера, и из филиала посредника для б2п.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="integrationLoginName"></param>
        public void SetBranchCodeByKladrForLink2(Basket basket, string integrationLoginName)
        {
            var deal = basket.GetKaskoDeal();
            
            if (deal.EntityContext.TryGetValue(
                    Link2Parameters.SetDefaultBranchCode, 
                    out bool setDefaultBranchCode) 
                && basket.IsLegal == true 
                && !setDefaultBranchCode)
            {
                return;
            }

            var cacheManager = (IDictionariesCacheManager)ServiceProvider.GetRequiredService(typeof(IDictionariesCacheManager));
            var versionIdDealSource = cacheManager.GetDictionaryVersion(nameof(BranchDictionariesVersion), deal.DictionaryDate ?? DT.Now).Id;
            var branches = cacheManager.GetItems<Branch>(versionIdDealSource).ToList();

            var entitySettingsManager = ServiceProvider.GetService<IEntitySettingsManager>();
            var isB2CPartner = CheckIsB2CPartnerHelper.CheckIsB2CPartner(entitySettingsManager, integrationLoginName);
            if (!isB2CPartner) 
            {
                var intermediary = deal
                   ?.DealIntermediaries
                   ?.FirstOrDefault(x => x.Intermediary?.InteractionTypeCode == InteractionTypeEnum.Agent.ToString())
                   ?.Intermediary ?? deal.GetMainIntermediary();

                if (intermediary.ReninsUnit != null)
                {
                    deal.Branch = branches.FirstOrDefault(x => x.Code.Equals(intermediary.ReninsUnit.BranchCode, StringComparison.OrdinalIgnoreCase));
                    deal.BranchCode = intermediary.ReninsUnit.BranchCode;
                    return;
                }
            }

            var codeKladrRegion = deal.GetAutoRegionOfUsingCodeKladr();
            var branchByCodeKladr = branches.FirstOrDefault(b => b.CodeKladrRegion?.Split(';').Any(c => c.Equals(codeKladrRegion)) == true);

            if (branchByCodeKladr != null)
            {
                deal.Branch = branchByCodeKladr;
                deal.BranchCode = branchByCodeKladr.Code;
            }            
        }

        /// <summary>
        /// Заполнить тип полиса по умолчанию Каско.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        private static void SetDealInsuranceType(Basket basket)
        {
            if (basket.Deals.Any(d => d.IsInBasket == true))
            {
                return;
            }

            var kaskoDeal = basket.Deals
                .SingleOrDefault(d => d.Product.ProductDictCode == ProductDictCodes.Kasko);

            if (kaskoDeal == null)
            {
                return;
            }

            kaskoDeal.IsInBasket = true;
        }

        /// <summary>
        /// Заполнить мультидрайв равным false.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        private void SetMultidrive(Basket basket)
        {
            if (basket.Deals.All(d => d.AutoDeal != null && d.AutoDeal.IsMultidrive == null))
            {
                basket.Deals.ForEach(d => d.AutoDeal.IsMultidrive = false);
            }
        }

        /// <summary>
        /// Заполнить одного водителя.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        private static void SetDriver(Basket basket)
        {
            if (basket.Deals.All(d =>
                d.AutoDeal != null 
                && d.AutoDeal.Drivers != null
                && d.AutoDeal.Drivers.Count == 0
                && d.AutoDeal.IsMultidrive == false))
            {
                var driver = new Driver
                {
                    UniqueId = Guid.NewGuid(),
                    Subject = new Subject
                    {
                        IndividualEntity = new IndividualEntity
                        {
                            Person = new Person { }
                        }
                    },
                };

                basket.Deals.ForEach(d => d.AutoDeal.Drivers.Add(driver));
            }
        }

        /// <summary>
        /// Обновляет дату первого расчета для сделки каско, если выполнен перерасчет корзины.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="isUseNewTariffs">Использовать новые тарифы для перерасчёта.</param>
        /// <param name="isBasketRecalculated">Флаг, указывающий, был ли выполнен перерасчет корзины.</param>
        /// <returns>Сообщение.</returns>
        public string SetKaskoDealDateFirstCalculation(Basket basket, bool isUseNewTariffs, bool isBasketRecalculated)
        {
            if (!isBasketRecalculated)
            {
                return null;
            }

            var deal = basket.GetKaskoDeal();

            var dateUtcNow = DT.UtcNow;
            var dateFirstCalculation = deal?.DateFirstCalculation;
            var hasOldTariffDaysExpired = dateUtcNow - dateFirstCalculation > TimeSpan.FromDays(7);

            if (!isUseNewTariffs && hasOldTariffDaysExpired)
            {
                deal.DateFirstCalculation = dateUtcNow;
                return "Перерасчёт произведён по актуальному тарифу";
            }
            else if (isUseNewTariffs && deal.IsProlongation.HasValue && deal.IsProlongation.Value)
            {
                return "Перерасчёт произведён по тарифу, актуальному на дату создания котировки";
            }
            else if (isUseNewTariffs)
            {
                deal.DateFirstCalculation = dateUtcNow;
            }

            return null;
        }
    }
}


using iRIS.Framework.Entity.Dictionary.ABTests;
using iRIS.Framework.Workflow.Activities;
using iRIS.InsuranceCore.Entities;
using System;
using System.Activities;
using System.Linq;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.KaskoLink2.Code.Helpers;

namespace iRIS.KaskoLink2.Code.Procedures
{
    [Serializable]
    public class DIKaskoCreateActivityProcedures : ActivityProcedures
    {
        public DIKaskoCreateActivityProcedures()
            : base(null)
        {
        }

        public DIKaskoCreateActivityProcedures(ActivityContext activityContext)
            : base(activityContext)
        {
        }
//только в случае если нет Риска Ущерб (5016) и есть Ущерб только на условиях полная гибель (5029)
                if (dealHelper.DealRisks.Exists(x => x.StructId == 5029) &&
                    !dealHelper.DealRisks.Exists(x => x.StructId == 5016))
                {
                    dealHelper.DealRisks.First(x => x.StructId == 5029).Sum = autoCost;
                }

                // если в сделке есть риск "Ущерб. ДТП со 2 участником"
                var dmgSecPartRisk = dealHelper.DealRisks.SingleOrDefault(x => x.ProductRisk.RiskCode == RiskCodes.DMGSECPART);
                if (dmgSecPartRisk != null)
                {
                    dmgSecPartRisk.Sum = autoCost;
                    if (dealHelper.DealOptions.Any(x => x.ProductOption.OptionCode == OptionCodes.FDREPAIRFIX))
                    {
                        dmgSecPartRisk.Sum = 500000m;
                    }
                }

                foreach (var mappingSum in mappingSumDictionary)
                {
                    var option = dealHelper.DealOptions.FirstOrDefault(x => x.StructId == mappingSum.Key);
                    if (option != null)
                    {
                        option.Sum = mappingSum.Value;
                        continue;
                    }

                    var risk = dealHelper.DealRisks.FirstOrDefault(x => x.StructId == mappingSum.Key);
                    if (risk != null)
                    {
                        risk.Sum = mappingSum.Value;
                        continue;
                    }

                    var coverage = dealHelper.DealCoverages.FirstOrDefault(x => x.StructId == mappingSum.Key);
                    if (coverage != null)
                    {
                        coverage.Sum = mappingSum.Value;
                    }
                }

                return true;
            }

            bool ossMapper()
            {
                var dealCoverages = new DealHelper(deal).DealCoverages;
                foreach (var coverage in dealCoverages)
                {
                    var franchisesWithPercentInsuranceSum = coverage.DealRisks
                       .Where(risk => risk.ConditionBlock != null)
                       .SelectMany(risk => risk.ConditionBlock.DealFranchises
                              .Where(x => x.ProductFranchise.SetSums
                                   .Where(y => y.PercentInsuranceSum != null).Any()));

                    foreach (var dealRisk in coverage.DealRisks.Where(d => d.Sum.HasValue))
                    {
                        coverage.Sum = dealRisk.Sum;

                        var dealFranchises = dealRisk.ConditionBlock?.DealFranchises?.Where(x =>
                        x != null
                        && x.ProductFranchise != null
                        && x.ProductFranchise.SetSums != null
                        && x.ProductFranchise.SetSums
                                   .Where(y => y != null && y.PercentInsuranceSum != null).Any());

                        if (dealFranchises != null)
                        {
                            foreach (var franchise in dealFranchises)
                            {
                                franchise.Sum = dealRisk.Sum * franchise.ProductFranchise.SetSums.Single().PercentInsuranceSum.Value;
                            }
                        }
                    }

                    if (coverage.ProductCoverage.CoverageCode.Equals(CoverageCodes.ADDCOSTS, StringComparison.OrdinalIgnoreCase))
                    {
                        var options = coverage.DealRisks
                            .Select(dr => dr.ConditionBlock)
                            .SelectMany(x => x.DealOptions)
                            .Where(x => x != null)
                            .GroupBy(o => o.Id).Select(g => g.First())
                            .Where(d => d.Sum.HasValue);

                        coverage.Sum = options.Sum(o => o.Sum.Value);
                    }
                }

                return true;
            }

            TryDoSomethingAndWriteLogIfItsCrash(funcMapper, "Ошибка маппинга страховых сумм сделки Каско для расчета с тарификатором.");
            TryDoSomethingAndWriteLogIfItsCrash(ossMapper, "Ошибка маппинга для ОСС.");
        }

        public int GetSelectedOfferId(Deal deal)
        {
            var proposal = deal.GetSelectedProposal();
            return proposal.Offer_Id.Value;
        }

        public List<PsoInspectionFileDescriptionModel> CreateInspectionFileDescriptionModel(Basket basket)
        {
            var deal = basket.GetKaskoDeal();
            var queryPrintingStores = ServiceProvider.GetService<IQueryPrintingStores>();
            var printingStores = queryPrintingStores.GetPrintStoresForDeal(deal);

            var document = new PrintingActivityHelper().PrintDocument(ServiceProvider, printingStores, basket, false, null);

            var result = new List<PsoInspectionFileDescriptionModel>
            {
                new PsoInspectionFileDescriptionModel()
                {
                    FileContent = document,
                    FileName = printingStores.First(t => t.PrintingOrder == printingStores.Min(subt => subt.PrintingOrder)).PrintingGroupNameRu,
                    FileExtension = "pdf"
                }
            };

            if (TryGetSettingsForIntermediary<bool>(deal, "KaskoUploadOtherInsuranceCompanyPolicyDocumentsToPso"))
            {
                result.AddRange(DownloadOtherInsuranceCompanyPolicyDocuments(deal).Select(x => new PsoInspectionFileDescriptionModel()
                {
                    FileContent = x.Content,
                    FileName = $"Предыдущий полис {Path.GetFileNameWithoutExtension(x.FileName)}",
                    FileExtension = Path.GetExtension(x.FileName)?.Replace(".", string.Empty)
                }));
            }

            return result;
        }

        internal T TryGetSettingsForIntermediary<T>(Deal deal, string settingsKey, T defaultValue = default)
        {
            var intermediary = deal.GetMainIntermediary();

            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            if (settingsManager.TryGetSettingValue<T>(settingsKey, intermediary, out var settingsValue))
            {
                return settingsValue;
            }

            return defaultValue;
        }

        internal List<(string FileName, byte[] Content)> DownloadOtherInsuranceCompanyPolicyDocuments(Deal deal)
        {
            var documents = new List<(string FileName, byte[] Content)>();
            var logger = ServiceProvider.GetService<ILogger>();
            var fileStorageServiceClient = ServiceProvider.GetService<IFileStorageServiceClient>();

            if (deal.OtherInsuranceCompanyPolicy?.FileBlock?.FileGroups?.Any(fg => fg.FileInfos != null && fg.FileInfos.Any(fi => fi.FileGuid != null)) == true)
            {
                foreach (var fileInfo in deal.OtherInsuranceCompanyPolicy.FileBlock.FileGroups.SelectMany(x => x.FileInfos))
                {
                    if (fileInfo.FileGuid == null)
                    {
                        continue;
                    }

                    byte[] documentData = null;
                    try
                    {
                        documentData = fileStorageServiceClient.DownloadFileContent(fileInfo.FileGuid.ToString());
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, $"Ошибка скачивания файла {fileInfo.FileName} {fileInfo.FileGuid} предыдущего полиса для отправки в ПСО.");
                        continue;
                    }

                    if (documentData != null)
                    {
                        documents.Add((fileInfo.FileName, documentData));
                    }
                }
            }

            return documents;
        }

        /// <summary>
        /// Устанавливаем текст особых условий для сделки каско
        /// https://jira.renins.com/browse/IRIS-98443. Перенести в маппинг ОСС KaskoOssMapper.GetSpecialNotes.
        /// </summary>
        /// <param name="deal"></param>
        public void SetSpecialNotes(Deal deal)
        {
            deal.SpecialNotes = GetSpecialNotes(deal);
        }

        /// <summary>
        /// возвращает текст особых условий для сделки каско
        /// </summary>
        /// <param name="deal"></param>
        public string GetSpecialNotes(Deal deal)
        {
            if (deal?.Product?.ProductDictCode != ProductDictCodes.Kasko)
            {
                return null;
            }

            var scManager = ServiceProvider.GetRequiredService<ISpecialClausesBankManager>();

            var sb = new StringBuilder();
            var specialConditions = scManager.GetSpecialClauses(deal);

            if (!string.IsNullOrEmpty(specialConditions))
            {
                sb.Append(specialConditions);
                sb.Append(Environment.NewLine);
            }

            sb.Append("При отказе Страхователя от Полиса до даты начала срока страхования, Страховщик возвращает Страхователю страховую премию в полном объеме. При отказе Страхователя от Полиса после даты начала срока страхования и до 14 календарного дня с даты заключения Полиса включительно, Страхователь имеет право получить часть уплаченной страховой премии, рассчитанной пропорционально сроку действия страхования. Возврат уплаченной страховой премии осуществляется Страхователю при отсутствии в период страхования событий с признаками страхового случая. Денежные средства возвращаются Страхователю в течение десяти рабочих дней с даты получения Страховщиком заявления Страхователя об отказе от Договора. При отказе Страхователя от Полиса в иных случаях применяется пункт 7.8.3 Правил.");
            if (KaskoOsagoPrintingMapperFunctions.HasRisk(deal, RiskCodes.CARJACKING))
            {
                sb.Append(Environment.NewLine);
                sb.Append(
                    "Страховщик на свое усмотрение имеет право осуществить страховую выплату по риску «Угон/Хищение» до предоставления Страхователем (Выгодоприобретателем, Застрахованными лицами) Постановления о прекращении уголовного дела.");
            }

            if (deal.InsuranceObjects[0].CheckNecessityCode != CheckNecessityCodes.InspecYes)
            {
                sb.Append("Принимая настоящий Полис и оплачивая страховую премию, Страхователь подтверждает, что застрахованное ТС является новым, ранее не эксплуатировалось и на дату начала срока страхования находится в салоне официального дилера. Дата передачи ТС Страхователю (дата начала эксплуатации ТС), устанавливаемая на основании договора купли-продажи, акта приема-передачи ТС или отметки в " + deal.AutoDeal.TsIdentityCard.TsIdentityCardType.Name + ", должна совпадать или быть позже даты начала срока страхования по настоящему Полису. В ином случае Договор страхования считается не вступившим в силу и действие срока страхования не начинается до подписания между Страховщиком и Страхователем Акта осмотра ТС.");
                sb.Append(Environment.NewLine);
            }

            sb.Append("Правила страхования");

            if (deal.InsuranceObjects[0].CheckNecessityCode != CheckNecessityCodes.InspecYes)
            {
                sb.Append(", Акт осмотра ТС");
            }

            sb.Append(" являются неотъемлемой частью настоящего Полиса. Принимая настоящий Полис и оплачивая страховую премию, Страхователь подтверждает, что Правила получил, ознакомлен и согласен с их условиями, а также с условиями настоящего Полиса и его приложений в полном объеме. Дополнительно с Правилами страхования можно ознакомиться на официальном сайте Страховщика renins.ru.");
            sb.Append(Environment.NewLine);
            sb.Append("Принимая настоящий полис и оплачивая страховую премию, Страхователь подтверждает, что все сведения, указанные в настоящем Полисе и в его приложениях, являются полными и достоверными. Стороны пришли к соглашению, что настоящий Полис и любые документы в рамках настоящего Полиса могут быть подписаны Страховщиком с использованием факсимиле или электронной подписи уполномоченного представителя Страховщика. В случае разночтений между условиями настоящего Полиса и Правилами приоритет будут иметь условия настоящего Полиса.");
            sb.Append(Environment.NewLine);
            sb.Append("Принимая настоящий полис и оплачивая страховую премию, Страхователь подтверждает, что он не является иностранными публичным должностным лицом и / или его родственником, должностным лицом публичной международной организации, а также лицом, замещающим(занимающим) государственную должность РФ, должность члена Совета Директоров ЦБ РФ, должность федеральной государственной службы, назначение и освобождение от которой осуществляется Президентом РФ или Правительством РФ, должность в ЦБ РФ, государственных корпорациях и иных организациях, созданных РФ на основании федеральных законов, включенную в перечни должностей, определяемые Президентом РФ.В ином случае Страхователь обязуется предоставить документы, подтверждающие должность / наименование и адрес работодателя / степень родства / статус(супруг или супруга).Также Страхователь подтверждает, что не имеет регистрации, места жительства / нахождения, счета в банке в государстве(на территории), которое(-ая) не выполняет рекомендации ФАТФ.Страхователь подтверждает, что не ограничен в дееспособности, а также его действия по иным основаниям не контролирует иное физическое лицо(бенефициарный владелец).");
            sb.Append(Environment.NewLine);
            sb.Append("Принимая настоящий Полис и оплачивая страховую премию Страхователь выражает Страховщику согласие на обработку персональных данных физических лиц, содержащихся в настоящем Полисе и в иных документах, передаваемых Страховщику для исполнения обязательств по данному Полису, а также в целях продвижения товаров, работ, услуг на рынке путем осуществления Страховщиком прямых контактов с помощью связи.");
            sb.Append(Environment.NewLine);
            sb.Append("Принимая настоящий Полис и оплачивая страховую премию Страхователь подтверждает, что в полном объеме получил информацию, предусмотренную пунктом 2.1.2. Базового стандарта защиты прав и интересов физических и юридических лиц — получателей финансовых услуг, оказываемых членами саморегулируемых организаций, объединяющих страховые организации, утв. Решением КФН ЦБ РФ, Протокол от 09.08.18 № КФНП-24. Принимая настоящий Полис и оплачивая страховую премию Страхователь выражает согласие осуществлять взаимодействие со Страховщиком путем обращения в офисы Страховщика, посредствам почтовой и телефонной связи, а также иными способами в случаях, специально предусмотренных Правилами страхования. Принимая настоящий Полис и оплачивая страховую премию Страхователь выражает согласие получать сообщения и уведомления от Страховщика, в том числе в электронной форме, по адресам, телефонам, указанным в настоящем Полисе. Информация об адресах офисов Страховщика, в которых осуществляется прием документов при наступлении страховых случаев и иных обращений, а также о случаях и порядке приема документов в электронной форме, размещена на официальном сайте Страховщика и может быть получена при обращении по телефонам Страховщика, указанным в настоящем Полисе.");
            return sb.ToString();
        }

        public List<PsoAdditionalFieldModel> CreatePsoAdditionalFields(Basket basket)
        {
            var deal = basket.GetKaskoDeal();
            var auto = deal.GetInsObjectAuto();

            var result = new List<PsoAdditionalFieldModel>
            {
                CreatePsoAdditionalFieldValueModel("policy_number", deal.PolicyNumber),
                CreatePsoAdditionalFieldValueModel("marka_model", string.Join(", ", auto.AutoBrandName, auto.AutoModelName)),
                CreatePsoAdditionalFieldValueModel("VIN", auto.Vin),
                CreatePsoAdditionalFieldValueModel("rate_num", basket.Number),
                CreatePsoAdditionalFieldValueModel("GRZ", auto.RegistrationNumber)
            };

            return result.Where(x => x != null).ToList();
        }
/// <summary>
        /// Проверка возможности оформления отложенного ПСО.
        /// </summary>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsPostponedPso(string integrationLoginName)
        {
            if (!string.IsNullOrEmpty(integrationLoginName))
            {
                var postponedPsoHelper = (IPostponedPsoHelper)ServiceProvider.GetRequiredService(typeof(IPostponedPsoHelper));
                var isPostponedPso = postponedPsoHelper.IsPostponedPso(integrationLoginName);

                return isPostponedPso;
            }

            return false;
        }

        /// <summary>
        /// Получение отложенного осмотра для сделки Каско.
        /// </summary>
        /// <returns>Осмотры для сделки Каско.</returns>
        public Inspection GetPostponedInspectionForKaskoDeal(Basket basket)
        {
            var mediator = ServiceProvider.GetService<ICqrsMediator>();
            var inspection = mediator.ResolveQuery<IQueryKaskoInspection>().GetInspectionByDealEntityId(basket.GetKaskoDeal().EntityId);

            inspection.PostponedInspection = true;

            return inspection;
        }

        /// <summary>
        /// Установить версию справочников.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void SetDictionariyVersions(Basket basket)
        {
            if (basket == null)
            {
                return;
            }

            if (!basket.DictionaryDate.HasValue)
            {
                basket.DictionaryDate = DT.Now;
            }

            var dictionaryProcessor = new DictionaryProcessor();
            dictionaryProcessor.SetDictionariyVersions(ServiceProvider, basket, basket.DictionaryDate.Value);
        }

        /// <summary>
        /// Проверка возможности пропуска публикации корзины.
        /// </summary>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsAllowedSkipPublishBasket(string integrationLogin)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.IsAllowedToSkipPublishBasket,
                KaskoEntitySettingCodes.IsAllowedToSkipPublishBasketDefault,
                KaskoEntitySettingCodes.IsAllowedToSkipPublishBasketByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false);
        }

        /// <summary>
        /// Проверка возможности пропуска публикации корзины на расчете.
        /// </summary>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsAllowedCalcSkipPublishBasket(string integrationLogin)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.IsAllowedToSkipCalcPublishBasket,
                KaskoEntitySettingCodes.IsAllowedToSkipPublishBasketDefault,
                KaskoEntitySettingCodes.IsAllowedToSkipCalcPublishBasketByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false);
        }

        /// <summary>
        /// Проверка возможности использования дефолтного коэффициента SAS.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="integrationLogin">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckCanUseDefaultSasCoefficient(string integrationLogin)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration<bool>(
                KaskoEntitySettingCodes.CanUseDefaultSasCoefficient,
                KaskoEntitySettingCodes.CanUseDefaultSasCoefficientDefault,
                KaskoEntitySettingCodes.CanUseDefaultSasCoefficientByIntegrationLogin,
                new IntegrationLogin { IntegrationLoginName = integrationLogin },
                false);
        }

        /// <summary>
        /// Проверка, необходим ли вызов SAS для получения коэффициента.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Результат проверки.</returns>
        public bool CheckIsSasOnCalculateRequiredForLink2(Basket basket, string integrationLoginName)
        {
            if (basket.IsLink2Process != true || basket.GetKaskoDeal()?.IsSubscription() == true || IsLink2Upsale(basket) || basket.GetKaskoDeal()?.IsProlongation == true)
            {
                return false;
            }

            var settingsManager = (IEntitySettingsManager)ServiceProvider.GetRequiredService(typeof(IEntitySettingsManager));
            var queryServiceInvoker = (ICachedQueryServiceInvoker)ServiceProvider.GetRequiredService(typeof(ICachedQueryServiceInvoker));
            var integrationLogin = queryServiceInvoker.GetByExpression<IntegrationLogin>(x => x.Where(u => u.IntegrationLoginName == integrationLoginName)).FirstOrDefault();

            if (basket.IsLead == true)
            {
                settingsManager.TryGetSettingValue<string[]>(KaskoEntitySettingCodes.GetSasCoefficientOnCalculateForLead, out var partnersWithSasRequestForLead);

                if (!partnersWithSasRequestForLead.Contains(integrationLogin?.IntegrationLoginName))
                {
                    return false;
                }
            }

            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);

            return settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.GetSasCoefficientOnCalculate,
                KaskoEntitySettingCodes.GetSasCoefficientOnCalculateDefault,
                KaskoEntitySettingCodes.GetSasCoefficientOnCalculatePartner,
                integrationLogin,
                false,
                log);
        }

        /// <summary>
        /// Необходим ли пропуск всех проверок.
        /// </summary>
        /// <param name="basket">Корзина.</param>        
        /// <returns>Результат проверки.</returns>
        public bool AllKaskoChecksMustBeSkipped(Basket basket)
        {
            var deal = basket?.GetKaskoDeal();

            if (deal?.IsSubscription() == true)
            {
                return !string.IsNullOrEmpty(deal.AutoDeal.PreviousPolicyNumber);
            }

            var selectedOffer = deal?.GetSelectedProposal()?.Offer;
            if (selectedOffer == null)
            {
                return false;
            }

            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            if (settingsManager.TryGetSettingValue(
                KaskoSasCheckProcessConstants.SkipKaskoAllChecksSettingName,
                out List<int> specialOfferEntityIds))
            {
                return specialOfferEntityIds != null && specialOfferEntityIds.Contains(selectedOffer.EntityId);
            }

            return false;
        }

        /// <summary>
        /// Необходим ли пропуск ПСО для специальной кредитной машины.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <returns>Признак необходимости пропуска ПСО.</returns>
        public bool PsoMustBeSkippedForSpecialCreditAuto(Basket basket, string integrationLoginName)
        {
            try
            {
                var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
                var conditions = settingsManager.GetSettingValue<SpecialCreditAutoConditionsDto>("KaskoSpecialCrediAutoConditions");

                return SpecialCreditAutoPsoSkipHelper.IsCreditAutoWithSuitablePrice(conditions, basket)
                    && SpecialCreditAutoPsoSkipHelper.IsCorrectCreditBank(conditions, basket)
                    && SpecialCreditAutoPsoSkipHelper.HasCorrectFranchise(conditions, basket, ServiceProvider.GetService<IEntityIterator>())
                    && SpecialCreditAutoPsoSkipHelper.HasPreviousPolicy(conditions, basket)
                    && SpecialCreditAutoPsoSkipHelper.HasEntitySetting(integrationLoginName, settingsManager);
            }
            catch (Exception ex)
            {
                var log = (ILogger)ServiceProvider.GetService(typeof(ILogger));
                log.Error(ex, $"Ошибка при проверке возможности пропуска ПСО для кредитного автомобиля.");
            }

            return false;
        }

        /// <summary>
        /// Устанавливает подтверждение УРМ без выполнения проверок.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void SetFakeKaskoUrmApprove(Basket basket)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            var urmApprovalCollection = kaskoDeal?.AutoDeal?.URMApproval;
            if (urmApprovalCollection != null && !urmApprovalCollection.Any())
            {
                kaskoDeal.AutoDeal.URMApproval.Add(new URMApproval
                {
                    ApprovalId = Guid.Empty.ToString(),
                    URMApprovalStatusCode = UrmApprovalStatusCodes.Accepted,
                    URMApprovalComment = $"Пропуск проверки УРМ/SAS."
                });
            }
            else if (urmApprovalCollection != null)
            {
                var actualApproval = UrmApprovalStatusHelper.GetActualApproval(kaskoDeal);
                actualApproval.URMApprovalComment = $"Пропуск проверки УРМ/SAS.";
                actualApproval.URMApprovalStatusCode = UrmApprovalStatusCodes.Accepted;
            }
        }

        private bool IsNotProlongation(Basket basket)
        {
            var deal = basket.GetKaskoDeal();
            return deal.IsProlongation != true;
        }

        public string GetBasketLink(Basket basket) => basket.KaskoBasketLink(ServiceProvider);

        public Dictionary<string, object> GetUserCreationMessageParameters(Basket basket)
        {
            return new Dictionary<string, object>
            {
                { "KaskoBasketLink", basket.KaskoBasketLink(ServiceProvider) },
            };
        }

        /// <summary>
        /// Фильтрация офферов Атисресса Каско согласно АБтестам.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void FilterAntistressOffersByABTestsByIris(Basket basket)
        {
            var config = ServiceProvider.GetRequiredService<IOptions<KaskoLink2ModuleConfiguration>>().Value;

            var abTestVariantOfferCodes = config.AbTestAntistressOffers.ABTestCodeVariants.Split(',')
                .Select((item, index) => new { Item = item, Index = index }).ToList();

            var abTestOfferToShow = GetOfferVariantByAbTest(config, abTestVariantOfferCodes.Select(v => v.Item).ToList(), basket);
            if (string.IsNullOrEmpty(abTestOfferToShow))
            {
                return;
            }

            // Id офферов для выбора
            var offerVariantIds = config.AbTestAntistressOffers.OfferIdVariants.Split(',').Select(s => int.Parse(s)).ToArray();

            // выбранный offerId
            var antistressOfferId = offerVariantIds[abTestVariantOfferCodes.Where(v => v.Item == abTestOfferToShow).First().Index];

            // Фильтрация оферов и сегментов
            var offersToExclude = offerVariantIds.Except(new int[] { antistressOfferId }).ToArray();

            ExcludeOffers(basket, offersToExclude);
        }

        /// <summary>
        /// Фильтрация офферов Каско согласно флагу isIrisCalculation.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="isIrisCalculation">Флаг способа расчёта</param>
        [Obsolete("Флаг isIrisCalculation удален. Для поддержки старых версий.")]
        public void FilterOffersByIsIrisCalculation(Basket basket, bool isIrisCalculation)
            => ExcludeOffers(basket, isIrisCalculation ? DiKaskoOfferIds.DiCalculationOfferIds : DiKaskoOfferIds.IrisCalculationOfferIds);

        /// <summary>
        /// Фильтрация офферов Каско.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void FilterOffers(Basket basket)
            => ExcludeOffers(basket, DiKaskoOfferIds.DiCalculationOfferIds);

        /// <summary>
        /// Исключение оферов из корзины и из сегментов.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="offersToExclude">Список Id оферов для исключения.</param>
        public void ExcludeOffers(Basket basket, IEnumerable<int> offersToExclude)
        {
            basket.Offers = basket.Offers.Where(o => !offersToExclude.Contains(o.Id)).ToList();

            foreach (var segment in basket.Segments)
            {
                segment.Offers = segment.Offers.Where(o => !offersToExclude.Contains(o.Id)).ToList();
            }
        }

        /// <summary>
        /// Фильтрация офферов Каско согласно выставленным условиям в запросе Link2.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        public void FilterOffersByLink2Conditions(Basket basket)
        {
            var link2FilterConditionsManager = ServiceProvider.GetRequiredService<IDiKaskoLink2FilterConditionsManager>();
            link2FilterConditionsManager.FilterOffers(basket);
        }

        /// <summary>
        /// Маппинг страховых сумм сделки Каско для расчета с тарификатором.
        /// </summary>
        /// <param name="deal">Сделка каско.</param>
        public void MapSumForIrisCalculation(Deal deal)
        {
            if (deal == null
                || deal.Product.ProductDictCode != ProductDictCodes.Kasko)
            {
                return;
            }

            var log = ServiceProvider.GetService<ILogger>();
            var context = ServiceProvider.GetService<PipelineExecutionContext>();

            log.ForContext("BasketNumber", context.GetBasketNumber())
                .Information("Маппинг страховых сумм сделки Каско для расчета с тарификатором.");

            var autoCost = deal.GetAuto().AutoCost.GetValueOrDefault();

            // словарь StructId - страховая умма
            var mappingSumDictionary = new Dictionary<int, decimal>()
            {
                [5031] = autoCost, // Угон/хищение
                [5004] = 10000, // Эвакуация
                [5005] = 2000, // Такси
                [5006] = 3000, // Тех. Помощь
                [5007] = 10000, // Автоконсьерж
                [5008] = 50000, // Отмена франшизы Каршеринга
                [5011] = 10000, // Аренда автомобиля
                [5012] = 10000, // Аварком 2 и более
                [5013] = 10000, // Аварком на все 
                [5036] = autoCost, // GAP страхование
                [5093] = autoCost, // ФД ремонт динамич
                [5092] = 500000 // ФД ремонт статич
            };

            bool funcMapper()
            {
                var dealHelper = new DealHelper(deal);

                //Если одновременно выбраны риски Ущерб (5016) и Ущерб только на условиях полная гибель (5029),
                //то записать Страховую сумму для Покрытия Ущерб (5015) = Стоимости автомобиля
                if (new List<int> { 5016, 5029 }.All(x => dealHelper.DealRisks.Exists(risk => risk.StructId == x)))
                {
                    var coverage = dealHelper.DealCoverages.FirstOrDefault(x => x.StructId == 5015);
                    if (coverage != null)
                    {
                        coverage.Sum = autoCost;
                    }
                }
/// <summary>
        /// Регион использования относится к конверсионным 
        /// </summary>
        /// <param name="basket">Корзина</param>
        /// <returns>True, если относится; False для всех остальных случаев</returns>
        public bool GetIsConversionRegion(Basket basket)
        {
            var autoRegionOfUsing = basket.Deals.First(d => d.IsInBasket == true)?.InsuranceObjects[0]?.Auto?.RegionOfUsingCode;

            switch (autoRegionOfUsing)
            {
                case "Moskva":
                case "Ekaterinburg":
                    return true;
                default:
                    return false;
            }
        }
    }
}


using iRIS.Framework.Link2.AppServices;
using iRIS.Framework.Workflow.Activities;
using iRIS.InsuranceCore.Code.Interfaces;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.Enums;
using iRIS.KaskoLink2.Code.Constructor.Interfaces;
using iRIS.KaskoLink2.Code.Constructor.Models;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using System.Activities;
using System.Collections.Generic;
using System.Linq;

namespace iRIS.KaskoLink2.Code.Procedures
{
    public class DiKaskoCalculationProcedures : ActivityProcedures
    {
        private ILogger _logger;

        public DiKaskoCalculationProcedures(ActivityContext activityContext)
            : base(activityContext)
        {
            if (ServiceProvider != null)
            {
                _logger = ServiceProvider.GetRequiredService<ILogger>().ForContext<DiKaskoCalculationProcedures>();
            }
        }

        /// <summary>
        /// Добавление флага возможности скидки по КВ в сделку.
        /// </summary>
        public void HasKvDiscountToDeal(IEnumerable<DealConditions> dealConditions)
        {
            if (dealConditions == null)
            {
                _logger?.Warning($"dealConditions are null in the Method={nameof(HasKvDiscountToDeal)}");
                return;
            }

            var partnerSettingsService = ServiceProvider.GetRequiredService<IPartnerSettingsService>();

            var deals = dealConditions.Select(dc => dc.Deal).Distinct();

            foreach (var deal in deals)
            {
                var intermediaryName = deal.
                    DealIntermediaries?
                    .FirstOrDefault()?
                    .Intermediary?
                    .IntermediaryInternalName;

                deal.HasKvDiscount = string.IsNullOrWhiteSpace(intermediaryName) ? false : partnerSettingsService.HasKvDiscount(intermediaryName);
            }
        }

        public void SetDiscountPromocode(Basket basket, IEnumerable<DealConditions> dealConditions)
        {
            if (basket.PromoCode == null)
            {
                return;
            }

            var promocodeManager = ServiceProvider.GetRequiredService<IPromocodeManager>();
            var discountApplier = ServiceProvider.GetRequiredService<IDiscountApplier>();

            var deals = dealConditions.Select(dc => dc.Deal).Distinct();

            foreach (var dealCondition in dealConditions)
            {
                //только сделки каско
                if (dealCondition.Deal.Product.ProductDictCode != ProductDictCodes.Kasko)
                {
                    continue;
                }

                var promocode = promocodeManager.GetActualPromocode(basket.PromoCode.Id, dealCondition.Deal.Product.Id);

                //промкод протух
                if (promocode == null)
                {
                    _logger.Error($"Ошибка получения промокода для сделки {dealCondition.Deal.Product.ProductDictCode}");
                    continue;
                }

                discountApplier.ApplyPromocode(dealCondition, promocode, basket.ExternalTagList.UseDrafts);
            }
        }
    }
}


using iRIS.Framework.Common;
using iRIS.Framework.CrossCutting.ClientCommunications.DigitalChannels.SmsTemplate;
using iRIS.Framework.CrossCutting.ClientCommunications.SMS;
using iRIS.Framework.Data.Services.Client;
using iRIS.Framework.RequestPipeline.Pipelines;
using iRIS.Framework.Workflow.Activities;
using iRIS.KaskoLink2.Code.Gazprom.Constants;
using iRIS.KaskoLink2.Code.Gazprom.Dto;
using iRIS.KaskoLink2.Code.Gazprom.Interfaces;
using iRIS.KaskoLink2.Code.Gazprom.Model;
using iRIS.KaskoLink2.Entities;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using System;
using System.Activities;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace iRIS.KaskoLink2.Code.Gazprom.Process
{
    public class GazpromProcedures : ActivityProcedures
    {
        public GazpromProcedures(ActivityContext activityContext)
            : base(activityContext)
        {
        }

        public bool Authorize()
        {
            SetStep(GazpromStep.Authorize);
            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();

            var authInfo = gazpromClient.Authorize().GetAwaiter().GetResult();
            if (authInfo == null)
            {
                LogWrite(LogEventLevel.Error, $"Неудачная попытка авторизоваться");
                return false;
            }

            LogWrite(LogEventLevel.Information, "Авторизация в начале процесса.");

            return true;
        }

        public bool SendPromocodeSms(string phoneNumber, string promocode, string dateEnd)
        {
            return SendSms(GetGazpromPromocodeAttachSmsTemplate(phoneNumber, promocode, dateEnd)); 
        }

        public bool SendAttachSms(string phoneNumber)
        {
            return SendSms(GetGazpromAttachSmsTemplate(phoneNumber));
        }

        public bool SendInviteSms(string phoneNumber, string inviteUrl)
        {
            return SendSms(GetSmsTemplate(phoneNumber, inviteUrl));
        }

        private bool SendSms(ISmsTemplate smsTemplate)
        {
            SetStep(GazpromStep.SendSms);

            var smsSender = ServiceProvider.GetRequiredService<ISmsSender>();

            try
            {
                var task = Task.Run(async () => await smsSender.SendSms(smsTemplate));
                return task.Result;
            }
            catch (Exception ex)
            {
                LogWrite(LogEventLevel.Error, "Ошибка при отправке SMS-сообщения.", ex);
            }

            return false;
        }

        public string GetTemplateId(int? cardSum)
        {
            SetStep(GazpromStep.GetTemplate);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();

            if (cardSum.HasValue)
            {
                if (cardSum == 2000)
                {
                    return gazpromClient.Setting.Template2000;
                }
                else if (cardSum == 4000)
                {
                    return gazpromClient.Setting.Template4000;
                }
            }

            return null;
        }

        private void LogWrite(LogEventLevel level, string messageTemplate, Exception ex = null)
        {
            var logger = ServiceProvider.GetRequiredService<ILogger>();
            logger.Write(level, $"Газпром: {messageTemplate}", ex);
        }

        private GazpromAttachSmsTemplate GetGazpromAttachSmsTemplate(string phoneNumber)
        {
            const string link = "https://opti24.page.link/app";

            var messageTemplate = new GazpromAttachSmsTemplate(GazpromConstants.GazpromAttachSmsTemplate, phoneNumber)
            {
                Link = link
            };

            return messageTemplate;
        }

        private GazpromSmsTemplate GetSmsTemplate(string phoneNumber, string inviteUrl)
        {
            var messageTemplate = new GazpromSmsTemplate(GazpromConstants.GazpromSmsTemplate, phoneNumber)
            {
                InviteUrl = inviteUrl
            };

            return messageTemplate;
        }

        private GazpromPromocodeAttachSmsTemplateNew GetGazpromPromocodeAttachSmsTemplate(string phoneNumber, string promocode, string dateEnd)
        {
            var messageTemplate = new GazpromPromocodeAttachSmsTemplateNew(GazpromConstants.GazpromPromocodeAttachSmsTemplateNew, phoneNumber)
            {
                Promocode = promocode,
                DateEnd = dateEnd
            };

            return messageTemplate;
        }

        public GazpromUsersDto GetUserByPhone(string insurantPhoneNumber)
        {
            SetStep(GazpromStep.GetUser);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var user = gazpromClient.GetUserByPhone(insurantPhoneNumber).GetAwaiter().GetResult();

            if (user.data.result == null)
            {
                LogWrite(LogEventLevel.Error, "Ошибка при получении пользователя");
                throw new NullReferenceException();
            }

            return user;
        }

        public List<string> CheckInvites(string insurantPhoneNumber)
        {
            SetStep(GazpromStep.CheckInvite);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var result = new List<string>();
            var invites = gazpromClient.CheckInvites(insurantPhoneNumber).GetAwaiter().GetResult();
            var invitesToDelete = invites.data.result
                    .Where(r => r.status == GazpromConstants.ActiveInviteStatus || r.status == GazpromConstants.ExpiredInviteStatus);

            if (invites.data.total_count != 0 && invitesToDelete.Any())
            {
                result.AddRange(invitesToDelete.Select(i => i.id));
            }

            return result;
        }

        public void DeleteInvites(List<string> invitesToDelete)
        {
            SetStep(GazpromStep.DeleteInvite);

            if (invitesToDelete?.Count > 0)
            {
                var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();

                foreach (var inviteId in invitesToDelete)
                {
                    gazpromClient.DeleteInvite(inviteId).GetAwaiter().GetResult();
                }
            }
        }

        public bool AttachContract(string userId, string templateId)
        {
            SetStep(GazpromStep.AttachContract);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var attachContract = gazpromClient.AttachContract(userId, templateId).GetAwaiter().GetResult();

            return attachContract?.data == false;
        }

        public GazpromCardDto CreateCard(GazpromPolicy policy, string templateId)
        {
            SetStep(GazpromStep.CreateCard);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var card = gazpromClient.CreateNewCard(templateId).GetAwaiter().GetResult();

            policy.CardNumber = card?.data?.number;

            return card;
        }

        public GazpromAttachCardDto AttachCard(string cardId, string userId)
        {
            SetStep(GazpromStep.AttachCard);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var attach = gazpromClient.AttachCard(cardId, userId).GetAwaiter().GetResult();

            return attach;
        }

        public string CreateInvite(GazpromPolicy policy, string cardId, string templateId, string phoneNumber)
        {
            SetStep(GazpromStep.Invite);

            var gazpromClient = ServiceProvider.GetRequiredService<IGazpromClient>();
            var invite = gazpromClient.CreateInvite(cardId, templateId, phoneNumber).GetAwaiter().GetResult();
            var inviteURL = invite?.data?.url;

            policy.InviteURL = inviteURL;

            return inviteURL;
        }

        public void SetPolicyDescriptionAndStatus(GazpromPolicy policy, GazpromPolicySetting setting)
        {
            var gazpromPoliciySaver = ServiceProvider.GetRequiredService<IGazpromPoliciySaver>();

            policy.AttemptCount++;
            policy.UpdateDate = DT.Now;

            if (policy.Status == (byte)GazpromPolicyStatus.Done)
            {
                if (policy.FuelCard != null)
                {
                    policy.FuelCard.Number = policy.CardNumber;
                    policy.FuelCard.Value = policy.CardValue;
                }

                policy.IsSmsSended = true;
                LogWrite(LogEventLevel.Information, $"Успешно выполнены все запросы. PolicyNumber: {policy.PolicyNumber}, PhoneNumber: {policy.InsurantPhoneNumber}");
            }
            else
            {
                SetPolicyDescription(policy);
                policy.Status = GetPolicyStatus(policy.Status);

                LogWrite(LogEventLevel.Information, $"Обработка запросов по полису завершилась с ошибкой. PolicyNumber: {policy?.PolicyNumber}, PhoneNumber: {policy?.InsurantPhoneNumber}");
                policy.IsSmsSended = false;
            }

            policy.EntityContext?.Clear();
            gazpromPoliciySaver.SaveGazpromPolicy(policy);

            int? GetPolicyStatus(int? status) => status switch
            {
                (byte)GazpromPolicyStatus.SmsDontSendInProgress =>
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.SmsDontSend,
                (byte)GazpromPolicyStatus.InviteSmsSendInProgress =>
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.InviteSmsDontSend,
                (byte)GazpromPolicyStatus.PromocodeSmsDontSendInInProgress =>
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.PromocodeSmsDontSend,
                (byte)GazpromPolicyStatus.PromocodeSmsDontSend =>
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.PromocodeSmsDontSend,
                (byte)GazpromPolicyStatus.PromocodeNotFound => 
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.PromocodeNotFound,
                _ =>
                    policy.AttemptCount >= setting.MaxCountAttempt ? (byte)GazpromPolicyStatus.Failed : (byte)GazpromPolicyStatus.Error
            };
        }

        public void SetPolicyStatus(GazpromPolicy policy, int status)
        {
            policy.Status = status;
        }

        public GazpromPromocode GetPromocode(GazpromPolicy policy)
        {
            SetStep(GazpromStep.GetPromocode);

            var promocodeQueryInvoker = ServiceProvider.GetRequiredService<IGazpromPromocodeQueryInvoker>();

            var promocode = promocodeQueryInvoker.GetPromocode(policy.CardValue.Value).GetAwaiter().GetResult();

            return promocode;
        }

        public void SavePromocode(GazpromPromocode promocode)
        {
            SetStep(GazpromStep.SavePromocode);

            if (promocode != null)
            {
                promocode.IsUsed = true;
                promocode.DateSend = DT.Now;

                var dataServiceInvoker = ServiceProvider.GetRequiredService<IDataServiceInvoker>();
                dataServiceInvoker.Publish(promocode, GazpromConstants.GazpromPromocodeDetailed);
            }
        }

        public void ApplyPromocode(GazpromPolicy policy, GazpromPromocode promocode)
        {
            SetStep(GazpromStep.ApplyPromocode);

            policy.GazpromPromocode_Id = promocode.Id;
            policy.GazpromPromocode = promocode;
        }

        private void SetStep(string step)
        {
            LogWrite(LogEventLevel.Information, $"Шаг обработки: {step}.");

            var context = ServiceProvider.GetRequiredService<ProcessApiContext>();
            context.PipelineSharedVariables.AddOrUpdate(nameof(GazpromStep), step);
        }
меня интересует справочник который может получить по коду риска его structId