Отвечай на вопросы, используя следующий контекст:
/// <summary>
        /// Обновляет статусы URM в сделке после отказа SAS.
        /// </summary>
        /// <param name="basket"></param>
        public void ProcessUrmApprovalSasReject(Basket basket)
        {
            var deal = basket.GetKaskoDeal();

            if (!deal.AutoDeal.URMApproval.Any())
            {
                deal.AutoDeal.URMApproval.Add(new URMApproval { URMApprovalStatusCode = "rejected" });
            }
            else
            {
                var urmApproval = deal.AutoDeal.URMApproval.Last();
                urmApproval.URMApprovalStatusCode = "rejected";
            }
        }

        /// <summary>
        /// Публикация обновленного AutoDeal.
        /// </summary>
        /// <param name="basket"></param>
        public void PublishAutoDealSasReject(Basket basket)
        {
            var deal = basket.GetKaskoDeal();

            // Очистка проинциализированого, но не заполненного паспорта ТС для избежания ошибки сохранения
            deal.AutoDeal.TsIdentityCard = null;

            var dataServiceInvoker = ServiceProvider.GetRequiredService<IDataServiceInvoker>();
            dataServiceInvoker.Publish(deal.AutoDeal, Link2AggregateNames.Link2AutoDealWithURMAndSasDetailed);
        }

        /// <summary>
        /// Приложены ли документы.
        /// </summary>
        /// <param name="basket"></param>
        /// <param name="preInsuranceCheck"></param>
        /// <param name="integrationLoginName"></param>
        /// <returns></returns>
        [Obsolete("Удалить после 30.12.2024")] 
        public bool IsDocumentsAttached(Basket basket, iRIS.KaskoLink2.Code.Implementations.PreInsuranceCheck.PreInsuranceCheckModel preInsuranceCheck, string integrationLoginName)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);

            var skipFileBlocksRequirement = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.SkipFileBlocksRequirement,
                KaskoEntitySettingCodes.SkipFileBlocksRequirementDefault,
                KaskoEntitySettingCodes.SkipFileBlocksRequirementPartner,
                new IntegrationLogin { IntegrationLoginName = integrationLoginName },
                false,
                log);

            if (skipFileBlocksRequirement)
            {
                return true;
            }

            var feFinder = ServiceProvider.GetRequiredService<IFileEntityFinder>();

            var commentHasBeenRead = preInsuranceCheck.CommentHasBeenRead || string.IsNullOrEmpty(preInsuranceCheck.Comment);

            if (preInsuranceCheck.Type == PreInsuranceCheckTypes.Urm)
            {
                return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForUrm(feFinder, basket) && commentHasBeenRead;
            }

            if (preInsuranceCheck.Type == PreInsuranceCheckTypes.Ota)
            {
                var queryInspection = ServiceProvider.GetRequiredService<IQueryInspection>();

                var inspection = queryInspection.GetLastInspectionInDeal(basket.GetKaskoDeal().EntityId);

                if (inspection != null && inspection.TraditionalInspection == true && inspection.PostponedInspection == false)
                {
                    return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForPso(feFinder, basket) && commentHasBeenRead;
                }

                return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForOta(feFinder, basket) && commentHasBeenRead;
            }

            return true;
        }

        /// <summary>
        /// Приложены ли документы.
        /// </summary>
        /// <param name="basket"></param>
        /// <param name="preInsuranceCheck"></param>
        /// <param name="integrationLoginName"></param>
        /// <returns></returns>
        public bool IsDocumentsAttached(Basket basket, iRIS.KaskoCore.Code.Implementations.PreInsuranceCheck.PreInsuranceCheckModel preInsuranceCheck, string integrationLoginName)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);

            var skipFileBlocksRequirement = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoEntitySettingCodes.SkipFileBlocksRequirement,
                KaskoEntitySettingCodes.SkipFileBlocksRequirementDefault,
                KaskoEntitySettingCodes.SkipFileBlocksRequirementPartner,
                new IntegrationLogin { IntegrationLoginName = integrationLoginName },
                false,
                log);

            if (skipFileBlocksRequirement)
            {
                return true;
            }

            var feFinder = ServiceProvider.GetRequiredService<IFileEntityFinder>();

            var commentHasBeenRead = preInsuranceCheck.CommentHasBeenRead || string.IsNullOrEmpty(preInsuranceCheck.Comment);

            if (preInsuranceCheck.Type == PreInsuranceCheckTypes.Urm)
            {
                return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForUrm(feFinder, basket) && commentHasBeenRead;
            }

            if (preInsuranceCheck.Type == PreInsuranceCheckTypes.Ota)
            {
                var queryInspection = ServiceProvider.GetRequiredService<IQueryInspection>();

                var inspection = queryInspection.GetLastInspectionInDeal(basket.GetKaskoDeal().EntityId);

                if (inspection != null && inspection.TraditionalInspection == true && inspection.PostponedInspection == false)
                {
                    return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForPso(feFinder, basket) && commentHasBeenRead;
                }

                return !PreInsuranceCheckFileHelper.CheckRequiredForFileBlocksForOta(feFinder, basket) && commentHasBeenRead;
            }

            return true;
        }

        public async Task AddOtaApprovalToDeal(Basket basket, string integrationLoginName)
        {
            if (basket.IsUpsale())
            {
                return;
            }

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

            var ignoreCheckOtaKASKOSetting = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                 KaskoEntitySettingCodes.IgnoreCheckOtaKASKOSetting,
                 KaskoEntitySettingCodes.IgnoreCheckOtaKASKOSettingDefault,
                 KaskoEntitySettingCodes.IgnoreCheckOtaKASKOSettingByIntegrationLogin,
                 new IntegrationLogin { IntegrationLoginName = integrationLoginName },
                 true,
                 log);

            if (ignoreCheckOtaKASKOSetting)
            {
                return;
            }

            var deal = basket.GetKaskoDeal();
            var otaHelper = ServiceProvider.GetRequiredService<IOtaHelper>();

            if (!await otaHelper.CanSkip(basket, deal))
            {
                deal.AutoDeal.OtaApproval.Add(new OtaApproval { OtaApprovalStatusCode = OtaApprovalStatusCodes.Required });
            }
        }

        [Obsolete("Удалить 01.01.2025")]
        public void AddUrmToDeal(Basket basket, string integrationLoginName)
        {
            AddUrmToDeal(basket, integrationLoginName, false, null);
        }

        /// <summary>
        /// Добавление URM если запрос в сас отключен.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="integrationLoginName">Интеграционный логин.</param>
        /// <param name="isSensitiveDataChanged">Изменение чувствительных данных при перерасчете.</param>
        /// <param name="externalBasketUrmAproval">Проверка URM корзины до перерасчета.</param>
        public void AddUrmToDeal(Basket basket, string integrationLoginName, bool isSensitiveDataChanged, URMApproval externalBasketUrmAproval)
        {
            var settingsManager = ServiceProvider.GetRequiredService<IEntitySettingsManager>();
            var log = ServiceProvider.GetRequiredService<ILogger>().ForContext("BasketNumber", basket.Number);

            var deal = basket.GetKaskoDeal();

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

            if (intermediary == null)
            {
                return;
            }

            var kaskoSasCheckProcess = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessSettings,
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessDefault,
                KaskoSasCheckProcessConstants.KaskoSasCheckProcessByIntermediary,
                intermediary,
                true,
                log);

            if (!kaskoSasCheckProcess || deal.IsAutoProlongation())
            {
                var needCheckUrmKASKO = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                    iRIS.KaskoLink2.Implementations.Code.Constants.EntitySettingCodes.NeedCheckUrmKASKOSetting,
                    iRIS.KaskoLink2.Implementations.Code.Constants.EntitySettingCodes.NeedCheckUrmKASKOSettingDefault,
                    iRIS.KaskoLink2.Implementations.Code.Constants.EntitySettingCodes.NeedCheckUrmKASKOSettingByIntegrationLogin,
                    new IntegrationLogin { IntegrationLoginName = integrationLoginName },
                    true,
                    log);

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

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

                var requiredBySegment = UrmHelper.RequiredByIndicatorSegment(deal) && !UrmHelper.CanSkipUrm(deal) && needCheckUrmKASKO;

                if (externalBasketUrmAproval != null &&
                    (externalBasketUrmAproval.URMApprovalStatusCode == UrmApprovalStatusCodes.Accepted ||
                     externalBasketUrmAproval.URMApprovalStatusCode == UrmApprovalStatusCodes.AcceptedWithLimits))
                {
                    if (!isSensitiveDataChanged)
                    {
                        UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, externalBasketUrmAproval.URMApprovalStatusCode, Guid.NewGuid().ToString());
                    }
                    else
                    {
                        if (requiredBySegment)
                        {
                            //Создаем новую заявку required
                            UrmHelper.AddUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, Guid.NewGuid().ToString());
                        }
                        else
                        {
                            UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, externalBasketUrmAproval.URMApprovalStatusCode, Guid.NewGuid().ToString());
                        }
                    }
                }
                else if (externalBasketUrmAproval != null &&
                         externalBasketUrmAproval.URMApprovalStatusCode == UrmApprovalStatusCodes.RequiredExtraInfo)
                {
                    if (!isSensitiveDataChanged)
                    {
                        UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, externalBasketUrmAproval.URMApprovalStatusCode, Guid.NewGuid().ToString());
                    }
                    else
                    {
                        if (requiredBySegment)
                        {
                            UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, Guid.NewGuid().ToString());
                        }
                        else
                        {
                            UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, externalBasketUrmAproval.URMApprovalStatusCode, Guid.NewGuid().ToString());
                        }
                    }
                }
                else
                {   
                    if (requiredBySegment)
                    {
                        UrmHelper.AddOrUpdateUrmApprovalToDeal(deal, UrmApprovalStatusCodes.Required, Guid.NewGuid().ToString());
                    }
                    else if (!kaskoSasCheckProcess)
                    {
                        UrmHelper.SetUrmApprovalNotRequired(deal);
                    }
                }
            }
        }

        /// <summary>
        /// Сохранение информации о добавленном ПСО в объект сделки.
        /// </summary>
        /// <param name="basket"></param>
        public void SetPsoEntityContext(Basket basket)
        {
            var deal = basket.GetKaskoDeal();

            deal.EntityContext[PsoEntityValuesConstants.IsPsoInWork] = true;
        }

        /// <summary>
        /// Начальная инициализация сделок в корзине.
        /// </summary>
        /// <param name="basket">Корзина для инициализации сделок.</param>
        public void InitializeDeals(Basket basket)
        {
            var productsId = GetProducts(basket);

            // TODO: после выхода полного переноса B2P процесса в текущий, нужно добавить в сегментоффер DI_Osago.
            if (productsId.Count == 1)
            {
                // Добавление осаго.
                productsId.Insert(0, 16);
            }

            var dealManager = (IDealManager)ServiceProvider.GetService(typeof(IDealManager));

            //Формируем список продуктов, по которым в корзине еще нет сделок
            var clearProductsId = dealManager.GetProducts(basket, productsId);

            //По списку продуктов формируем сделки
            dealManager.InitializeBasketDeals(basket, clearProductsId);
        }

        /// <summary>
        /// Установка значения скидки продавца.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <param name="irisDiscount">Значение коэфиициента.</param>
        public void SetIrisDiscount(Basket basket, string irisDiscount)
        {
            if (string.IsNullOrEmpty(irisDiscount))
            {
                return;
            }

            var deal = basket.GetKaskoDeal();
            var discountValue = decimal.Parse(irisDiscount);

            if (discountValue > 0)
            {
                foreach (var proposal in deal.Proposals)
                {
                    var selectedDiscountCombination = proposal.GetSelectedDiscountCombination();
                    var dealDiscount = selectedDiscountCombination.Discounts.SingleOrDefault(d =>
                        d.CalculationComponentCoefficient.Coefficient.Name.Equals(DiscountCoefficientNames.K_Iris, StringComparison.OrdinalIgnoreCase));

                    dealDiscount.DiscountSwitchOnOff = true;
                    dealDiscount.DiscountValue = 1 - (discountValue / 100);
                }
            }
        }

        public string GetUnderwriterApprovalStatus(Basket basket)
        {
            var underwriterApprovals = basket.GetKaskoDeal().AutoDeal.DIUnderwriterApprovals;

            if (underwriterApprovals.Any(ua => ua.StatusCode == DiUnderwriterApprovalStatusCodes.Rejected))
            {
                return DiUnderwriterApprovalStatusCodes.Rejected;
            }

            if (underwriterApprovals.Any(ua => ua.StatusCode == DiUnderwriterApprovalStatusCodes.RequiredExtraInfo))
            {
                return DiUnderwriterApprovalStatusCodes.RequiredExtraInfo;
            }
/// <summary>
    /// Тест-драйв
    /// </summary>
    public const string Testdrive = "TESTDRIVE";

    /// <summary>
    /// Коммерческая
    /// </summary>
    public const string Commerce = "COMMERCE";

    /// <summary>
    /// Доставка.
    /// </summary>
    public const string Delivery = "DELIVERY";

    /// <summary>
    /// Такси.
    /// </summary>
    public const string Taxi = PurposeOfUsingCodes.Taxi;

    /// <summary>
    /// Дорожные и специальные ТС.
    /// </summary>
    public const string Special = PurposeOfUsingCodes.Special;

    /// <summary>
    /// Аренда/прокат.
    /// </summary>
    public const string Rental = PurposeOfUsingCodes.Rental;

    /// <summary>
    /// Прочее.
    /// </summary>
    public const string Other = PurposeOfUsingCodes.Other;

    /// <summary>
    /// Перевозки опасных и легковоспламеняющихся грузов.
    /// </summary>
    public const string Danger = PurposeOfUsingCodes.Danger;

    /// <summary>
    /// Работы экстренных и коммунальных служб.
    /// </summary>
    public const string Municipal = PurposeOfUsingCodes.Municipal;

    /// <summary>
    /// Регулярных пассажирских перевозок или перевозок пассажиров по заказам.
    /// </summary>
    public const string Passenger = PurposeOfUsingCodes.Passenger;

    /// <summary>
    /// Учебной езды.
    /// </summary>
    public const string Learn = PurposeOfUsingCodes.Learn;

    /// <summary>
    /// Проверить валидность цели перевозки для юр.лиц.
    /// </summary>
    /// <param name="purposeOfUsing">Код цели перевозки.</param>
    /// <returns>Флаг валидности цели.</returns>
    public static bool Contains(string purposeOfUsing)
        => LegalPurposes.Any(x => x.Equals(purposeOfUsing, StringComparison.OrdinalIgnoreCase));

    private static readonly string[] LegalPurposes =
    [
        Encashment, 
        Ambulance, 
        Carsharing, 
        Testdrive, 
        Commerce, 
        Delivery,
        Rental,
        Special,
        Taxi,
        Danger,
        Municipal,
        Passenger,
        Learn,
        Other
    ];
}


# Code\Constants\RegistrationRegions.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public class RegistrationRegions
    {
        public const string Moskva = "Moskva";
        public const string SanktPeterburg = "SanktPeterburg";
        public const string Kazan = "Kazan";
        public const string NizhniNovgo = "NizhniNovgo";
        public const string CHelyabinsk = "CHelyabinsk";
        public const string Novosibirsk = "Novosibirsk";
        public const string Ekaterinburg = "Ekaterinburg";
        public const string RespuTatar = "RespuTatar";
        public const string Nizhegoblas = "Nizhegoblas";
        public const string CHelyaboblas = "CHelyaboblas";
        public const string Novosoblas = "Novosoblas";
        public const string Sverdoblas = "Sverdoblas";
    }
}


# Code\Constants\SalesChainNumbers.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    internal static class SalesChainNumbers
    {
        /// <summary>
        /// Цепочка продаж для Страховая касса.
        /// </summary>
        public const string StrahKassaSalesChainNumber = "39435";

        /// <summary>
        /// Цепочка продаж для МИКСТЕЛЛ.
        /// </summary>
        public const string MikstellSalesChainNumber = "36820";
    }
}


# Code\Constants\SasApprovalStatusCodes.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public static class SasApprovalStatusCodes
    {
        public const string Accepted = "accepted";
        public const string Rejected = "rejected";
        public const string Urm = "urm";
        public const string NoDecision = "noDecision";
    }
}

# Code\Constants\SasRequestSource.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public static class SasRequestSource
    {
        public const string Constructor = "Constructor";
        public const string Questionnaire = "Questionnaire";
    }
}


# Code\Constants\SexCodes.cs
﻿namespace iRIS.KaskoLink2.Code.Constants;

public class SexCodes
{
    /// <summary>
    /// Мужской.
    /// </summary>
    public const string M = "M";

    /// <summary>
    /// Женский.
    /// </summary>
    public const string F = "F";

    /// <summary>
    /// Трансгендер.
    /// </summary>
    public const string TG = "TG";

    public static readonly string[] AvailableSexCodes = { M, F };
}


# Code\Constants\SexNames.cs
﻿namespace iRIS.KaskoLink2.Code.Constants;

public class SexNames
{
    public const string M = "Мужской";
    public const string F = "Женский";
    public const string TG = "Трансгендер";
}


# Code\Constants\StructIdsCodes.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public static class StructIdsCodes
    {
        public const int AddEquipment = 5034;

        /// <summary>
        /// Аварийный комиссар: выезд на любое ДТП.
        /// </summary>
        public const int AvarcomAccident = 5013;

        /// <summary>
        /// Аварийный комиссар: выезд на любое страховое событие.
        /// </summary>
        public const int AvarcomAny = 5551;

        /// <summary>
        /// Аварийный комиссар: сбор справок.
        /// </summary>
        public const int AvarcomNote = 5014;

        /// <summary>
        /// Аварийный комиссар: выезд на ДТП с двумя и более участниками или пострадавшими по жизни и здоровью.
        /// </summary>
        public const int Avarcom2Par = 5012;

        /// <summary>
        /// Угон/хищение.
        /// </summary>
        public const int CarjackingCode = 5031;

        /// <summary>
        /// Ущерб.
        /// </summary>
        public const int Damage = 5016;

        /// <summary>
        /// Ремонт на СТОА дилера по направлению Страховщика.
        /// </summary>
        public const int DealerTechcenter = 5485;

        /// <summary>
        /// Эвакуация.
        /// </summary>
        public const int Evacuation = 5004;

        public const int FranchiseCauser = 5027;

        public const int FranchiseSecondIncEvent = 5028;

        /// <summary>
        /// GAP (страхование на полную стоимость).
        /// </summary>
        public const int Gap = 5036;

        /// <summary>
        /// Стекла без справок 1 раз в год.
        /// </summary>
        public const int Glass1T = 5018;

        /// <summary>
        /// Стекла без справок без ограничений.
        /// </summary>
        public const int GlassMany = 5019;

        public const int InstallmentPaymentsCode = 5096;

        /// <summary>
        /// Ремонт на СТОА по выбору Страхователя.
        /// </summary>
        public const int InsurantTechcenter = 5486;

        public const int Milelimit = 5023;

        public const int OneTimePaymentCode = 5097;

        /// <summary>
        /// Выплата без справок по кузовным деталям до 3% от страховой суммы один раз в год (BODY3P1T).
        /// </summary>
        public const int Percent3 = 5020;

        /// <summary>
        /// Выплата без справок по кузовным деталям до 5% от страховой суммы два раза в год (BODY5P2T).
        /// </summary>
        public const int Percent5 = 5021;

        public const int ProductKasko = 3042;

        /// <summary>
        /// Аренда автомобиля.
        /// </summary>
        public const int Rent = 5011;

        /// <summary>
        /// Такси.
        /// </summary>
        public const int Taxi = 5005;

        /// <summary>
        /// Ремонт на СТОА (кроме дилеров) по направлению Страховщика.
        /// </summary>
        public const int Techcenter = 5484;

        /// <summary>
        /// Техпомощь.
        /// </summary>
        public const int TechHelp = 5006;

        /// <summary>
        /// Ущерб только на условиях "Полная гибель".
        /// </summary>
        public const int TotalLoss = 5029;
    }
}


# Code\Constants\UrmApprovalThemeProlongationCodes.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public static class UrmApprovalThemeProlongationCodes
    {
        public const string ChangeOwner = "changeOwner";
        public const string ChangeInsurant = "changeInsurant";
        public const string Other = "other";
    }
}


# Code\Constants\UserGroupConstant.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    public class UserGroupConstant
    {
        public const string Nb_grs = "НБ ГРС";
        public const string Nb_intouch = "НБ Интач";
        public const string Nb_grs_supervizor = "НБ ГРС Супервайзер";
        public const string Nb_intouch_supervizor = "НБ Интач Супервайзер";
        public const string CallCenter = "CallCenter";
        public const string Delivery = "Delivery";
        public const string Clients = "Clients";
        public const string URM = "URM";
        public const string DIUnderwriter = "DIUnderwriter";
        public const string Link2Agents = "Link2Agents";
        public const string Administrators = "Administrators";
        public const string COK = "COK";
        public const string HelpDesk = "HelpDesk";
    }
}


# Code\Constants\UserModeCodes.cs
﻿namespace iRIS.KaskoLink2.Code.Constants
{
    internal class UserModeCodes
    {
        public const string CallCenter = "CallCenter";
        public const string Supervisor = "Supervisor";
    }
}


# Code\Constants\ConstantsHelpers\SASApprovalStatusCodeHelper.cs
﻿using iRIS.InsuranceCore.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace iRIS.KaskoLink2.Code.Constants.ConstantsHelpers
{
    public static class SASApprovalStatusCodeHelper
    {
        public static string GetSASStatusCode(string kaskoSasCheckProcessConstant)
        {
            switch (kaskoSasCheckProcessConstant)
            {
                case KaskoSasCheckProcessConstants.KaskoSasCheckAccept:
                    return SASApprovalStatusCodes.Accepted;
                case KaskoSasCheckProcessConstants.KaskoSasCheckUrm:
                    return SASApprovalStatusCodes.Urm;
                case KaskoSasCheckProcessConstants.KaskoSasCheckNoDecision:
                    return SASApprovalStatusCodes.NoDecision;
                case KaskoSasCheckProcessConstants.KaskoSasCheckReject:
                default:
                    return SASApprovalStatusCodes.Rejected;
            }
        }
    }
}


# Code\Constructor\ConstructorModule.cs
﻿using Autofac;
using iRIS.InsuranceCore.Code.Constructor;
using iRIS.KaskoCore.Code.Implementations;
using iRIS.KaskoCore.Code.Interfaces;
using iRIS.KaskoLink2.Code.Constructor.Implementations;
using iRIS.KaskoLink2.Code.Constructor.Implementations.CallCenterConstructor;
using iRIS.KaskoLink2.Code.Constructor.Implementations.ClientConstructor;
using iRIS.KaskoLink2.Code.Constructor.Interfaces;
using iRIS.KaskoLink2.ViewModels;

namespace iRIS.KaskoLink2.Code.Constructor
{
    public class ConstructorModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<ConstructorOfferGetter>().As<IConstructorOfferGetter>();
            builder.RegisterType<ConstructorCacheWrapper>().As<IConstructorCacheWrapper>();
            builder.RegisterType<ToggleConditionHandler>().As<IToggleConditionHandler>();
            builder.RegisterType<ConstructorSiebelWrapper>().As<IConstructorSiebelWrapper>();
            builder.RegisterType<KaskoDeltaProcessor>().As<IKaskoDeltaProcessor>();
            builder.RegisterType<CallcenterConstructorDataWrapper>().As<IConstructorDataWrapper<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<ClientConstructorDataWrapper>().As<IConstructorDataWrapper<DiKaskoClientConstructorStepViewModel>>();
            builder.RegisterType<CallcenterConstructorCalculator>().As<IConstructorCalculator<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<ClientConstructorCalculator>().As<IConstructorCalculator<DiKaskoClientConstructorStepViewModel>>();
            builder.RegisterType<ConstructorDiscountsLogic>().As<IConstructorDiscountsLogic<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<CallcenterConstructorLogic>().As<IConstructorLogic<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<ClientConstructorLogic>().As<IConstructorLogic<DiKaskoClientConstructorStepViewModel>>();
            builder.RegisterType<CallcenterConstructorModelUpdater>().As<IConstructorModelUpdater<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<ClientConstructorModelUpdater>().As<IConstructorModelUpdater<DiKaskoClientConstructorStepViewModel>>();
            builder.RegisterType<CallcenterConstructorViewModelUpdater>().As<IConstructorViewModelUpdater<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<ClientConstructorViewModelUpdater>().As<IConstructorViewModelUpdater<DiKaskoClientConstructorStepViewModel>>();
            builder.RegisterType<ConstructorDiscountModelUpdater>().As<IConstructorDiscountModelUpdater<DiKaskoConstructorStepViewModel>>();
            builder.RegisterType<KaskoDiscountApplier>().As<IDiscountApplier>().SingleInstance();
        }
    }
}


# Code\Constructor\KaskoConstructorOfferGetter.cs
﻿using iRIS.Framework.Cqrs.Interfaces;
using iRIS.Framework.Entity.Dictionary.EntitySettings;
using iRIS.InsuranceCore.Code.ExternalFunctions;
using iRIS.InsuranceCore.Code.Queries;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.KaskoCore.Code.Constants;
using iRIS.KaskoCore.Code.Extensions;
using iRIS.KaskoLink2.Code.Helpers;
using Serilog;
using System;

namespace iRIS.KaskoLink2.Code.Constructor
{
    public interface IKaskoConstructorOfferGetter
    {
        int GetConstructorOfferId(Basket basket, string loginName = null);
    }

    public class KaskoConstructorOfferGetter : IKaskoConstructorOfferGetter
    {
        public static int[] ConstructorOffers { get; set; } = new int[] 
        {
            DiKaskoOfferIds.Link2Constructor,
            DiKaskoOfferIds.Constructor,
            B2BKaskoOfferIds.KaskoKKP,
            B2BKaskoOfferIds.KaskoKKPProlongation
        };

        private readonly Link2FunctionsInvoker _invoker;
        private readonly ILogger _logger;
        private readonly IEntitySettingsManager _entitySettingsManager;
        private readonly ICqrsMediator _mediator;

        public KaskoConstructorOfferGetter(Link2FunctionsInvoker invoker, ILogger logger, IEntitySettingsManager entitySettingsManager, ICqrsMediator mediator)
        {
            _invoker = invoker;
            _logger = logger;
            _entitySettingsManager = entitySettingsManager;
            _mediator = mediator;
        }

        public int GetConstructorOfferId(Basket basket, string loginName = null)
        {
            int selectedConstructorOfferId;
            string intLoginName = loginName ?? GetLoginName(basket);

            try
            {
                if (_invoker.BasketCreatorIsLink2PartnerOrDiAgent(basket))
                {
                    if (CheckIsB2CPartnerHelper.CheckIsB2CPartner(_entitySettingsManager, intLoginName))
                    {
                        selectedConstructorOfferId = DiKaskoOfferIds.Link2Constructor;
                    }
                    else
                    {
                        selectedConstructorOfferId = basket.HasProlongationInBasket()
                            ? B2BKaskoOfferIds.KaskoKKPProlongation
                            : B2BKaskoOfferIds.KaskoKKP;
                    }
                }
                else
                {
                    selectedConstructorOfferId = DiKaskoOfferIds.Constructor;
                }
            }
            catch (Exception e)
            {
                _logger.Error(e, "Ошибка получения оффера для конструктора Link2");
                selectedConstructorOfferId = 0;
            }

            return selectedConstructorOfferId;
        }

        private string GetLoginName(Basket basket)
        {
            var basketCreator = _mediator.ResolveQuery<IQueryBasketCreator>().GetBasketCreatorDetailed(basket.EntityId, basket.Number, null);
            var integrationLogin = _mediator.ResolveQuery<IQueryIntegrationLogin>().GetIntegrationLoginByUserId(basketCreator.User.Id);
            
            return integrationLogin.IntegrationLoginName;
        }
    }
}
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();
        }

        public bool ReadConfigBooleanVariable(string variableName)
        {
            var configService = ServiceProvider.GetRequiredService<IConfigurationRoot>();
            return configService.GetValue<bool>(variableName);
        }

        public string ReadConfigStringVariable(string variableName)
        {
            var configService = ServiceProvider.GetRequiredService<IConfigurationRoot>();
            return configService.GetValue<string>(variableName);
        }

        public string GetUrlResumeProcessKaskoWithToken(AuthorizationData authorizationData, Basket basket)
        {
            return GetUrlResumeProcessKaskoWithToken(authorizationData, basket, false);
        }

        public string GetUrlResumeProcessKaskoWithToken(AuthorizationData authorizationData, Basket basket, bool isReusable)
        {
            // Из фрейма на сайте интача не получается сделать редирект из процесса оплаты обратно в процесс Каско
            if (basket.IsIntouchWeb())
            {
                return null;
            }

            var resumeProcessUrlGetter = ServiceProvider.GetRequiredService<IKaskoResumeProcessUrlGetter>();

            return resumeProcessUrlGetter.GetUrlResumeProcessKaskoWithToken(authorizationData.CurrentUserId, authorizationData.BrowserSessionId, basket, isReusable);
        }

        public void SelectConstructorProposal(Basket basket)
        {
            IKaskoConstructorOfferGetter constructorOfferGetter = ServiceProvider.GetService<IKaskoConstructorOfferGetter>();

            var deal = basket.GetKaskoDeal();
            var proposal = deal.Proposals.Single(p => p.Offer_Id == constructorOfferGetter.GetConstructorOfferId(basket));

            deal.SetSelectedProposal(proposal);
        }

        /// <summary>
        /// Блок по пересчету со скидкой. Копипаста из DiKaskoConstructorExtension.
        /// </summary>
        public async Task ApplyDiscount(Basket basket)
        {
            var discountCalculationHelper = ServiceProvider.GetRequiredService<DiscountCalculationHelper>();
            var calcData = discountCalculationHelper.GetCalcData(basket);

            var discountApplier = ServiceProvider.GetRequiredService<IDiscountApplier>();
            await discountApplier.CalculteWithAppliedDiscountsConsideringCombinationStatusAsync(calcData);
        }

        public void ApplyCostCenterByPromocode(Basket basket)
        {
            if (basket.PromoCode == null)
            {
                return;
            }

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

            if (!discountApplier.IsPromoCodeAppliedAtKaskoDeal(basket))
            {
                return;
            }

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

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

                //промкод протух
                if (promocode == null)
                {
                    continue;
                }

                discountApplier.SetDealCostCenterCodeByPromocode(deal, promocode);
            }
        }

        public bool ApplyPromocodeToDiscounts(Basket basket, Dictionary<string, string> inputModelContext)
        {
            var promocodeValue = string.Empty;
            if (inputModelContext != null && inputModelContext.ContainsKey("promocode"))
            {
                promocodeValue = inputModelContext["promocode"];
            }

            var result = ApplyPromo(basket, promocodeValue);

            // если пользователь сбросил промокод и промокод пришёл из url, то очищаем значение, принятое из url
            if (string.IsNullOrEmpty(promocodeValue) && !string.IsNullOrEmpty(basket.ExternalTagList?.PromoCode))
            {
                basket.ExternalTagList.PromoCode = string.Empty;
            }

            return result;
        }

        public bool ApplyPromocodeForLink2(Basket basket)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            var promocode = kaskoDeal?.PromoCode;
            var promocodeValue = promocode?.Code;
            if (string.IsNullOrEmpty(promocodeValue))
            {
                return false;
            }

            var result = ApplyPromo(basket, promocodeValue);

            return result;
        }

        public void CreateEmptyCourierDealIntermediary(Basket basket)
        {
            var dealsWithCourierDelivery = basket.Deals.Where(x =>
                x.IsInBasket == true
                && x.IsExternal != true
                && x.Deliveries.Any(del => del.DeliveryWayCode == DeliveryWayCodes.ByCourier));

            foreach (var deal in dealsWithCourierDelivery)
            {
                var courierDealIntermediary = deal.DealIntermediaries
                    .Where(x => x.InteractionTypeCode == InteractionTypeEnum.Courier.ToString()
                                || x.Intermediary?.InteractionTypeCode == InteractionTypeEnum.Courier.ToString())
                    .FirstOrDefault();

                if (courierDealIntermediary == null)
                {
                    var courierIntermediary = new Intermediary
                    {
                        InteractionTypeCode = InteractionTypeEnum.Courier.ToString(),
                        IntermediaryStatusCode = "IntActive",
                    };
                    courierIntermediary.EntityContext[KaskoCore.Siebel.Code.Constants.EntityContextKeys.PositionTypeKey] = KaskoCore.Siebel.Code.Constants.SiebelPositionTypeNames.DeliveryDepartment;
                    deal.DealIntermediaries.Add(new DealIntermediary
                    {
                        InteractionTypeCode = InteractionTypeEnum.Courier.ToString(),
                        Intermediary = courierIntermediary
                    });
                }
            }
        }

        private bool ApplyPromo(Basket basket, string promo)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            if (kaskoDeal == null)
            {
                return false;
            }

            if (string.IsNullOrWhiteSpace(promo))
            {
                ResetPromocode(basket);
                return true;
            }

            var promoCode = GetBestAvailablePromocode(promo, kaskoDeal);

            if (promoCode == null || !string.IsNullOrEmpty(promoCode.CallCenterName))
            {
                ResetPromocode(basket);

                return false;
            }

            basket.PromoCode = promoCode;

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

            discountApplier.ApplyPromocode(kaskoDeal, promoCode, basket.ExternalTagList.UseDrafts);

            if (discountApplier.IsPromoCodeAppliedAtKaskoDeal(basket))
            {
                discountApplier.SetDealCostCenterCodeByPromocode(kaskoDeal, promoCode);
                var osagodeal = basket.GetOsagoDealInBasket();
                if (osagodeal != null)
                {
                    discountApplier.SetDealCostCenterCodeByPromocode(osagodeal, promoCode);
                }
            }

            return true;
        }

        public async Task CalculateProposals(Basket basket)
        {
            await CalculateProposalsInternalAsync(basket, DiscountCalculationStrategy.CalculateForAgreedOrApproveNotRequiredDiscounts);
        }

        private async Task CalculateProposalsInternalAsync(Basket basket, DiscountCalculationStrategy? discountCalculationStrategy = null)
        {
            var kaskoCalculationWrapper = ServiceProvider.GetRequiredService<IKaskoCalculationWrapper>();
            await kaskoCalculationWrapper.CalculateAndApplyProposalsAsync(basket, discountCalculationStrategy, true);
        }

        public async Task CalculateProposalsForLink2WithPromocode(Basket basket)
        {
            var kaskoRater = ServiceProvider.GetRequiredService<IKaskoRater>();
            await kaskoRater.CalculateDealAsync(basket, basket.GetKaskoDeal());

            basket.UpdatePrice();
        }

        public void ActivatePromocode(Basket basket)
        {
            var kaskoDeal = basket.GetKaskoDeal();
            if (kaskoDeal != null &&
                basket.PromoCode != null &&
                basket.PromoCode.Code.Contains(ReninsPlusConstants.ReninsPlusPromocodePrefix))
            {
                var code = basket.PromoCode.Code.Replace(ReninsPlusConstants.ReninsPlusPromocodePrefix, string.Empty);
                var reninsPlusPromocodeService = ServiceProvider.GetRequiredService<IReninsPlusPromocodeService>();
                reninsPlusPromocodeService.ActivatePromocode(
                    code, kaskoDeal.PolicyNumber, PolicyType.Kasko);
            }
        }

        public void CorrectDeliveryDate(Basket basket, bool isProcessApiRequest)
        {
            if (isProcessApiRequest && basket.BasketStatusCode == "Registration")
            {
                var kaskoDeal = basket.GetKaskoDeal();

                var delivery = kaskoDeal?.GetLastDelivery();

                if (delivery?.Date?.Date <= DT.Now.Date && delivery?.DeliveryWayCode == DeliveryWayCodes.Email)
                {
                    delivery.Date = DT.Now.AddDays(1);
                }
            }
        }

        public void ApplyDealsConditions(List<Deal> deals, List<DealConditions> dealsConditions)
        {
            var kaskoDealManager = ServiceProvider.GetRequiredService<IDiKaskoDealManager>();
            kaskoDealManager.ApplyDealsCondition(deals, dealsConditions.Convert());
        }

        private void ResetPromocode(Basket basket)
        {
            var kaskoDeal = basket.Deals.SingleOrDefault(d => d.Product.ProductDictCode == ProductDictCodes.Kasko);
            if (kaskoDeal == null)
            {
                return;
            }

            //clear from discount
            var discountApplier = ServiceProvider.GetRequiredService<IDiscountApplier>();
            discountApplier.ClearPromocode(kaskoDeal, basket.ExternalTagList.UseDrafts);
            var constructorCacheWrapper = ServiceProvider.GetRequiredService<IConstructorCacheWrapper>();
            var constructorDeal = constructorCacheWrapper.GetDealFromCache(kaskoDeal.Id);
            if (constructorDeal != null)
            {
                discountApplier.ClearPromocode(constructorDeal, basket.ExternalTagList.UseDrafts);
                constructorCacheWrapper.SaveDealInCache(constructorDeal);
            }

            if (basket.PromoCode?.Code != null
                && basket.PromoCode.Code.Contains(ReninsPlusConstants.ReninsPlusPromocodePrefix))
            {
                var reninsPlusService =
                    ServiceProvider.GetRequiredService<IReninsPlusPromocodeService>();
                var promoCode = basket.PromoCode.Code.Replace(
                    ReninsPlusConstants.ReninsPlusPromocodePrefix,
                    string.Empty);
                reninsPlusService.UnholdPromocode(promoCode, PolicyType.Kasko);
            }

            basket.PromoCode = null;
namespace iRIS.KaskoLink2.Code.Link2.ResponseCreation
{
    /// <summary>
    /// Часть <see cref="DiKaskoResponseDealDto"/>. Представляет данные для вывода в http-ответе на запрос расчета/импорта и т.п.
    /// </summary>
    public class UnderwriterApprovalDto
    {
        /// <summary>
        /// ID согласования андеррайтинга. 
        /// </summary>
        public string ApprovalId { get; set; }

        /// <summary>
        /// Тема андеррайтинга. 
        /// </summary>
        public string ThemeCode { get; set; }

        /// <summary>
        /// Описание запроса. 
        /// </summary>
        public string RequestDescription { get; set; }

        /// <summary>
        /// Комментарий андеррайтинга. 
        /// </summary>
        public string UnderwriterCommentary { get; set; }

        /// <summary>
        /// Статус согласования андеррайтинга. 
        /// </summary>
        public string Status { get; set; }

        /// <summary>
        /// Согласованная стоимость ТС. 
        /// </summary>
        public decimal? AutoCostApproval { get; set; }
    }
}


# Code\MapperFunctions\DiKaskoMapperFunctionsInvoker.cs
﻿using iRIS.Framework.Data;
using iRIS.Framework.UI.PresentationModel.PathManager;
using iRIS.InsuranceCore.Code.Extensions.Helpers;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.InsuranceCore.Entities.Enums;
using iRIS.KaskoLink2.Code.Extensions.DiKaskoSegmentation.Helpers;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using iRIS.InsuranceCore.Infrastructure.Constants;
using iRIS.InsuranceCore.OSS.Code.Constants;
using iRIS.KaskoLink2.Code.TypeExtensions;
using iRIS.KaskoLink2.ViewModels;
using iRIS.Framework.ExtensionMethods;
using iRIS.KaskoLink2.Code.Constants;
using iRIS.InsuranceCore.OSS.Code.Mappers;
using iRIS.KaskoCore.Code.Constants;
using iRIS.KaskoCore.Code.Extensions;
using iRIS.KaskoLink2.Code.Helpers;
using iRIS.KaskoLink2.Code.EntityExtensions;
using iRIS.KaskoCore.Code.Helpers;
using iRIS.KaskoCore.Code.Queries;

namespace iRIS.KaskoLink2.Code.MapperFunctions
{
    public class DiKaskoMapperFunctionsInvoker : IMapperFunctions
    {
        public const string TransGender = "TG";

        private const string StandartFranchiseCode = "STANDART";
        private const string CauserFranchiseCode = "CAUSER";

        private const string EmergencyComissarTwoAndMore = "AVARCOM2PAR";
        private const string EmergencyComissarforAll = "AVARCOMACCIDENT";
        private const string EmergencyComissarNotes = "AVARCOMNOTE";

        private const string DealerTechcentreOptionCode = "DEALERTECHCENTER";
        private const string TechcentreOptionCode = "TECHCENTER";
        private const string InsurantTechcentreOptionCode = "INSURANTTECHCENTER";
        private const string SecondInsEvent = "2INSEVENT";

        private const string OneGlass = "GLASS1T";
        private const string NoLimitGlass = "GLASSMANY";

        private const string BODY3P1T = "BODY3P1T";
        private const string BODY5P2T = "BODY5P2T";

        private const string DICostcenterTypeCode = "Di";

        public static decimal? GetInsurancePremium(MapperFunctionParams @params) =>
            ((Deal)@params.Target)?.GetSelectedProposal()?.GetResult()?.Value;

        public static string GetDriverLicense(MapperFunctionParams @params)
        {
            var driver = (Driver)@params.Target;
            if (driver.IsForeignDrivingLicense == true)
            {
                return string.Join(" ", new string[] { driver.DriverLicenseSeries, driver.DriverLicenseNumber });
            }

            return string.Join(" ", new string[] { driver.DriverLicenseSeries?.Insert(2, " "), driver.DriverLicenseNumber });
        }

        public static bool HasDelivery(MapperFunctionParams @params) =>
            (string)@params.Target == "ByPost";

        /// <summary>
        /// Сеттер для атрибута Разрешенная масса
        /// </summary>
        public static decimal? SetPermissibleMassInTons(MapperFunctionParams @params)
        {
            var massInKg = (decimal?)@params.Target;

            return massInKg != null
                ? massInKg / 1000
                : null;
        }

        /// <summary>
        /// Геттер для атрибута Разрешенная масса
        /// </summary>
        public static decimal? GetPermissibleMassInKg(MapperFunctionParams @params)
        {
            if (@params.Target is decimal massInTons)
            {
                return massInTons * 1000;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Получить код региона регистрации посредника для проверки по андеррайтерским исключениям.
        /// </summary>
        public static string GetIntermediaryAICheckCode(MapperFunctionParams @params)
        {
            if (@params.Target is Intermediary intermediary)
            {
                var unit = intermediary.IsSellerInsurance == true
                    ? intermediary.SalesUnit
                    : intermediary.ReninsUnit;

                return !string.IsNullOrEmpty(unit?.AICheckCode)
                    ? unit.AICheckCode
                    : null;
            }

            return null;
        }

        /// <summary>
        /// Получить имя партнера.
        /// </summary>
        /// <param name="params">MapperFunctionParams.</param>
        /// <returns>Имя партнера.</returns>
        public static string GetPartnerName(MapperFunctionParams @params)
        {
            if (!(@params.Target is Deal deal))
            {
                throw new ArgumentException($"params.Target is not {nameof(Deal)}");
            }

            string code = deal.DealIntermediaries.FirstOrDefault()?.Intermediary.Code;

            // Для данных партнеров применять спецтарифы
            if (string.Equals(code, IntermediaryCodes.SBERSPECIAL, StringComparison.OrdinalIgnoreCase)
               || string.Equals(code, IntermediaryCodes.POSTFINANCE, StringComparison.OrdinalIgnoreCase)
               || string.Equals(code, IntermediaryCodes.SRAVNIRUSITEKV10, StringComparison.OrdinalIgnoreCase))
            {
                return code;
            }

            return "0";
        }

        public static ObservableList<Driver> GetDrivers(MapperFunctionParams @params)
        {
            var basket = (Basket)@params.Target;
            return basket.Deals.FirstOrDefault(d => d.IsInBasket == true && d.AutoDeal?.IsMultidrive == false)?.AutoDeal.Drivers ?? new ObservableList<Driver>();
        }

        public static string GetDeductibleType(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            var dealHelper = new DealHelper(deal);
            var dealFranchise = GetActiveDeductible(dealHelper.DealFranchises);
            string code = dealFranchise?.ProductFranchise.Code;
            switch (code)
            {
                case StandartFranchiseCode:
                    return "стандартная";
                case CauserFranchiseCode:
                    return "виновника";
                case SecondInsEvent:
                    return "со 2-го СС";
                default:
                    return "0";
            }
        }

        public static string GetEmergencyCommissarOption(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            var dealHelper = new DealHelper(deal);

            if (dealHelper.DealOptions.Count == 0)
            {
                return "0";
            }

            var dealOption = GetActiveEmrgencyComissarOption(dealHelper.DealOptions);
            return dealOption?.ProductOption.OptionCode ?? "0";
        }

        public static string GetEmergencyCommissarNotesOption(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            var dealHelper = new DealHelper(deal);

            if (dealHelper.DealOptions.Count == 0)
            {
                return "0";
            }

            var notesOption = dealHelper.DealOptions.FirstOrDefault(d => d.ProductOption.OptionCode == EmergencyComissarNotes);

            return notesOption?.ProductOption.OptionCode ?? "0";
        }

        public static bool HaveOsago(MapperFunctionParams @params)
        {
            var basket = (Basket)@params.Target;
            var result = basket.Deals.Any(d => d.IsInBasket == true &&
                (d.Product?.ProductDictCode == ProductDictCodes.EOsago
                || d.Product?.ProductDictCode == ProductDictCodes.Osago));
            return result;
        }

        public static bool GetIsLegal(MapperFunctionParams @params)
        {
            var basket = (Basket)@params.Target;
            return basket.IsLegal ?? false;
        }

        public static string GetInn(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            return deal.Insurant.Subject.LegalEntity?.Inn;
        }

        /// <summary>
        /// Получение типа канала продаж с указанием дефолтных для Agent и IsLead.
        /// </summary>
        /// <param name="params">Параметры (корзина и массив аргументов).</param>
        /// <returns>Тип канала продаж</returns>
        /// <exception cref="ArgumentException">Выбрасывается когда на вход передан не Basket.</exception>
        public static string GetSalesChannelTypeWithDefaults(MapperFunctionParams @params)
        {
            string resultType = null;
            var defaultSalesChannelForAgent = @params.Args.ElementAtOrDefault(0);
            var defaultSalesChannelForLead = @params.Args.ElementAtOrDefault(1);

            if (!(@params.Target is Basket basket))
            {
                throw new ArgumentException($"params.Target is not {nameof(Basket)}");
            }

            var deal = basket.GetKaskoDeal();

            if (IsLeadSalesChannel(basket, deal))
            {
                resultType = defaultSalesChannelForLead;
            }
            else if (deal.Costcenter != null && deal.Costcenter.CostcenterTypeCode.EqualsIgnoreCase(CostCenterTypeCodes.Agent))
            {
                resultType = defaultSalesChannelForAgent;
            }
            else
            {
                var otherTypeCodes = new string[]
                {
                    CostCenterTypeCodes.Bank, CostCenterTypeCodes.Broker, CostCenterTypeCodes.Corpsales, CostCenterTypeCodes.Leasing
                };

                var costcenterTypeCode = deal.Costcenter?.CostcenterTypeCode;

                resultType = otherTypeCodes.Contains(costcenterTypeCode, StringComparer.OrdinalIgnoreCase)
                    ? CostCenterTypeCodes.Other
                    : costcenterTypeCode;
            }

            return resultType;
        }

        /// <summary>
        /// Получение типа канала продаж.
        /// </summary>
        /// <param name="params">Параметры (корзина).</param>
        /// <returns>Тип канала продаж.</returns>
        public static string GetSalesChannelType(MapperFunctionParams @params)
        {
            var basket = (Basket)@params.Target;
            var deal = basket.GetKaskoDeal();

            var resultType = IsLeadSalesChannel(basket, deal)
                ? DICostcenterTypeCode
                : deal.Costcenter != null && deal.Costcenter.CostcenterTypeCode != null
                    ? deal.Costcenter.CostcenterTypeCode
                    : CostCenterTypeCodes.Other;

            return resultType;
        }

        private static bool IsLeadSalesChannel(Basket basket, Deal deal)
        {
            return basket.IsLead == true || deal.DealSource == "DI" || deal.AutoDeal.CanUseSalesChannelTypeDi == true;
        }

        /// <summary>
        /// Проверяет наличие опредленного Покрытия в сделке
        /// </summary>
        /// <param name="params">Код покрытия</param>
        /// <returns></returns>
        public static bool ContainsCoverage(MapperFunctionParams @params)
        {
            var coverageCode = @params.Args.ElementAtOrDefault(0);
            var deal = (Deal)@params.Target;
            var coverage = GetCoverage(deal, coverageCode);
            return coverage != null;
        }

        /// <summary>
        /// Проверяет факт убыточности 
        /// </summary>
        /// <param name="params">Код покрытия</param>
        /// <returns></returns>
        public static bool IsBreakeven(MapperFunctionParams @params)
        {
            return false;
        }

        public static decimal? GetKbmValue(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;

            return OsagoKbmHelper.GetKbmValue(deal);
        }

        public static decimal? GetKbmValueDefault(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;

            return OsagoKbmHelper.GetKbmValueDefault(deal);
        }

        public static string GetTechcenterOption(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            var dealHelper = new DealHelper(deal);
            var codes = new[] { DealerTechcentreOptionCode, InsurantTechcentreOptionCode, TechcentreOptionCode };

            var dealOption = dealHelper.DealOptions
                    .FirstOrDefault(option => codes
                        .Any(c => c.Equals(option.ProductOption.OptionCode, StringComparison.OrdinalIgnoreCase)));

            var dealCompensationOption =
                dealHelper.DealCompensationOptions
                    .FirstOrDefault(option => codes
                        .Any(c => c.Equals(option.ProductCompensationOption.CompensationOptionCode, StringComparison.OrdinalIgnoreCase)));

            var resultCode = dealOption != null
                ? dealOption.ProductOption.OptionCode
                : dealCompensationOption != null
                    ? dealCompensationOption.ProductCompensationOption.CompensationOptionCode
                    : "0";

            return resultCode switch
            {
                DealerTechcentreOptionCode => "Ремонт на дилере",
                TechcentreOptionCode => "По выбору страховщика",
                InsurantTechcentreOptionCode => "По выбору страхователя",
                _ => "0",
            };
        }

        private static DealCoverage GetCoverage(Deal deal, string coverageCode)
        {
            if (string.IsNullOrEmpty(coverageCode))
            {
                throw new ArgumentNullException(nameof(coverageCode), "Не задан код покрытия");
            }

            var dealHelper = new DealHelper(deal);

            var coverage = dealHelper.DealCoverages.SingleOrDefault(dc => dc.ProductCoverage.CoverageCode.Equals(coverageCode, StringComparison.OrdinalIgnoreCase));
            return coverage;
        }

        /// <summary>
        /// Проверяет наличие опредленного Риска у определенного Покрытия в сделке
        /// </summary>
        /// <param name="params">Код покрытия и Код риска</param>
        /// <returns></returns>
        public static bool ContainsRisk(MapperFunctionParams @params)
        {
            var deal = (Deal)@params.Target;
            var coverageCode = @params.Args.ElementAtOrDefault(0);
            var riskCode = @params.Args.ElementAtOrDefault(1);

            if (string.IsNullOrEmpty(riskCode))
            {
                throw new ArgumentNullException(nameof(coverageCode), "Не задан код риска");
            }

            var coverage = GetCoverage(deal, coverageCode);

            if (coverage == null)
            {
                return false;
            }

            return coverage.DealRisks.Any(dr => dr.ProductRisk.RiskCode.Equals(riskCode, StringComparison.OrdinalIgnoreCase));
        }

        public static bool ContainsFranchise(MapperFunctionParams @params)
        {
            var franchiseCode = @params.Args[0];

            var deal = (Deal)@params.Target;
            var dealHelper = new DealHelper(deal);

            return dealHelper.DealFranchises.Any(dr => dr.ProductFranchise.Code.Equals(franchiseCode, StringComparison.OrdinalIgnoreCase));
        }
# Code\Constructor\CalculationPartner\CalculationPartnerRequest\ICalculationPartnerRequestClient.cs
﻿namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.CalculationPartnerRequest
{
    internal interface ICalculationPartnerRequestClient
    {
        /// <summary>
        /// Запросить токен авторизации
        /// </summary>
        /// <returns>Токен авторизации (живет около 3 минут)</returns>
        string GetAuthToken();

        /// <summary>
        /// Запрос партнеру для получения Id расчета других СК.
        /// </summary>
        /// <param name="queryString">GET параметры для расчета</param>
        /// <returns>Id запроса</returns>
        string GetRequestId(string queryString);

        /// <summary>
        /// Запрос партнеру для получения расчетов других СК.
        /// </summary>
        /// <param name="queryString">GET параметры для расчета</param>
        void GetKaskoCalc(string queryString);
    }
}

# Code\Constructor\CalculationPartner\CalculationPartnerRequest\QueryStringBuilder.cs
﻿using System.Collections.Generic;
using System.Linq;
using Castle.Core.Internal;
using iRIS.Framework.Common;
using iRIS.InsuranceCore.Code.Extensions.Helpers;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.CalculationPartnerRequest
{
    internal class QueryStringBuilder
    {
        private readonly CalculationMapHelper _calculationMapHelper;
        
        public QueryStringBuilder(CalculationMapHelper calculationMapHelper)
        {
            _calculationMapHelper = calculationMapHelper;
        }

        public void AppendToken(ref string queryString, string token)
        {
            queryString = $"token={token}&{queryString}";
        }

        public void AppendRequestId(ref string queryString, string requestId)
        {
            queryString = $"requestid={requestId}&{queryString}";
        }

        public string ToQueryString(Deal deal)
        {
            var queryParams = new Dictionary<string, string>();
            var auto = deal.GetAuto();

            AddAutoParams(auto, queryParams);
            AddConstructorParams(deal, queryParams);
            AddStaticParams(queryParams);
            AddDriversParam(deal.AutoDeal, queryParams);
            AddRegionParam(deal, queryParams);

            if (auto.IsCreditAuto == true)
            {
                queryParams.Add("bik", deal.SuggestedBanks.Last().BIK);
            }

            if (auto.HasAntiTheftSystem == true)
            {
                var antiTheftSystem = auto.AntiTheftSystems.First();
                queryParams.Add("antiTheftSystemBrandCode", antiTheftSystem.AntiTheftSystemBrandCode);
                queryParams.Add("antiTheftName", antiTheftSystem.AntiTheftSystemModel.Name.Replace(" + ", "%2b"));
            }
            else
            {
                queryParams.Add("ops", "нет");
            }

            return string.Join("&", queryParams.Select(param => $"{param.Key}={param.Value}"));
        }

        private void AddDriversParam(AutoDeal autoDeal, Dictionary<string, string> queryParams)
        {
            if (autoDeal.IsMultidrive != true)
            {
                for (var index = 0; index < autoDeal.Drivers.Count; index++)
                {
                    var driver = autoDeal.Drivers[index];

                    queryParams.Add($"drivers[{index}][sex]", "M");
                    queryParams.Add($"drivers[{index}][age]", $"{driver.Subject.IndividualEntity.Person.Age}");
                    queryParams.Add($"drivers[{index}][exp]", $"{driver.DrivingExperiences.First().FullDrivingExperience}");
                    queryParams.Add($"drivers[{index}][childs]", "0");
                    if (driver.Subject.IndividualEntity.Person.IsMaried == true)
                    {
                        queryParams.Add($"drivers[{index}][married]", "Да");
                    }
                }
            }
            else
            {
                queryParams.Add("accepted_drivers", "Неограниченное количество");
                queryParams.Add("min_age", "18");
                queryParams.Add("min_exp", "0");
            }
        }

        private void AddConstructorParams(Deal deal, Dictionary<string, string> queryParams)
        {
            var dealHelper = new DealHelper(deal);
            var compensation = _calculationMapHelper.Compensation(dealHelper);
            if (!compensation.IsNullOrEmpty())
            {
                queryParams.Add("compensation", compensation);
            }

            var franchise = _calculationMapHelper.Franchise(dealHelper);
            if (franchise != null)
            {
                queryParams.Add("fransh", $"{DecimalToString(franchise)}");
            }
        }

        private void AddAutoParams(Auto auto, Dictionary<string, string> queryParams)
        {
            queryParams.Add("begindate", $"01.01.{auto.AutoYearOfIssueCode}");
            queryParams.Add("creationyear", $"{auto.AutoYearOfIssueCode}");
            queryParams.Add("power", $"{DecimalToString(auto.AutoEnginePowerValue)}");
            queryParams.Add("carprice", $"{DecimalToString(auto.AutoCost)}");
            queryParams.Add("mark", $"{auto.AutoBrandName}");
            queryParams.Add("model", $"{auto.AutoModelName}");
            queryParams.Add("transmission", $"{auto.AutoTransmissionTypeCode}");
            queryParams.Add("fuel", $"{auto.AutoEngineTypeCode}");
            queryParams.Add("carbody", $"{auto.AutoBodyTypeCode}");

            if (!string.IsNullOrEmpty(auto.AutoModification?.AutoEngineValueCode))
            {
                queryParams.Add("engine_capacity", $"{auto.AutoModification.AutoEngineValueCode}");
            }

            if (auto.HasMileage == true)
            {
                queryParams.Add("miliage", auto.Mileage.HasValue ? auto.Mileage.ToString() : "0");
            }
            else
            {
                queryParams.Add("new", "Да");
                queryParams.Add("miliage", "0");
            }

            // авто старше 2 лет
            if (auto.AutoYearOfIssueValue < DT.Today.Year - 1)
            {
                queryParams.Add("just_transition", "да");
                queryParams.Add("transition", "да");
            }

            // авто не старше 3 лет
            if (auto.AutoYearOfIssueValue > DT.Today.Year - 3)
            {
                queryParams.Add("waranty", "Действует");
            }
        }

        private void AddStaticParams(Dictionary<string, string> queryParams)
        {
            queryParams.Add("owner", "Физическое лицо");
            queryParams.Add("park", "1");
            queryParams.Add("storing", "Свободное хранение");
            queryParams.Add("payment_type", "Единовременно");
            queryParams.Add("period", "12");
            queryParams.Add("insuranse_sum", "Неагрегатная");
        }

        private void AddRegionParam(Deal deal, Dictionary<string, string> queryParams)
        {
            queryParams.Add("city_owner", _calculationMapHelper.CityOfRegistration(deal));
            queryParams.Add("region_owner", _calculationMapHelper.RegionOfRegistration(deal));
            queryParams.Add("city", _calculationMapHelper.CityOfUsing(deal));
            queryParams.Add("region", _calculationMapHelper.RegionOfUsing(deal));
        }

        private string DecimalToString(decimal? value)
        {
            return value.HasValue ? value.Value.ToString("0.##") : string.Empty;
        }
    }
}


# Code\Constructor\CalculationPartner\SendCalculationToPartner\ISendCalculationClient.cs
﻿using iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner
{
    internal interface ISendCalculationClient
    {
        SendCalculationResponse SendCalculationToPartner(SendCalculationRequest request);
    }
}

# Code\Constructor\CalculationPartner\SendCalculationToPartner\SendCalculationClient.cs
﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using iRIS.Framework.Common.HttpClient;
using iRIS.InsuranceApp.Infrastructure.Helpers;
using iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos;
using Microsoft.Extensions.Options;
using Serilog;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner
{
    internal class SendCalculationClient : ISendCalculationClient
    {
        private readonly IHttpClient _client;
        private readonly ILogger _logger;
        private readonly KaskoLink2ModuleConfiguration _configuration;

        public SendCalculationClient(IHttpClient client, ILogger logger, IOptions<KaskoLink2ModuleConfiguration> configuration)
        {
            _client = client;
            _logger = logger;
            _configuration = configuration.Value;
        }

        public SendCalculationResponse SendCalculationToPartner(SendCalculationRequest sendCalculationRequest)
        {
            try
            {
                var requestUrl = $"{_configuration.CalculationPartner.SendCalculationToPartnerServiceUrl}";

                var svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(
                    $"{_configuration.CalculationPartner.SendCalculationToPartnerAuthUser}:{_configuration.CalculationPartner.SendCalculationToPartnerPassword}"));

                var headers = new Dictionary<string, string>
                {
                    {
                        HttpRequestHeader.Authorization.ToString(),
                        "Basic " + svcCredentials
                    }
                };

                var xmlRequest = XmlHelper.ToXml(sendCalculationRequest);

                var response = _client.PerformPut(requestUrl, "application/xml", xmlRequest, headers: headers);

                var xmlResponse = response.Data;
                var sendCalculationResponse = XmlHelper.FromXml<SendCalculationResponse>(xmlResponse);

                _logger.ForContext<SendCalculationClient>()
                    .ForContext("Request", xmlRequest)
                    .ForContext("Response", xmlResponse)
                    .Information("Отправка расчетов в сервис 1С");

                return sendCalculationResponse;
            }
            catch (Exception ex)
            {
                _logger.ForContext<SendCalculationClient>()
                    .ForContext("Request", XmlHelper.ToXml(sendCalculationRequest))
                    .Error(ex, "Ошибка при отправке расчетов в сервис 1С.");

                throw;
            }
        }
    }
}

# Code\Constructor\CalculationPartner\SendCalculationToPartner\SendCalculationRequestCreator.cs
﻿using System.Linq;
using iRIS.Framework.Common;
using iRIS.InsuranceCore.Code.Extensions.Helpers;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos;
using Siebel.Code.Responses;
using Driver = iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos.Driver;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner
{
    internal class SendCalculationRequestCreator
    {
        private CalculationMapHelper _calculationMapHelper;

        public SendCalculationRequestCreator(CalculationMapHelper calculationMapHelper)
        {
            _calculationMapHelper = calculationMapHelper;
        }

        internal SendCalculationRequest Create(string basketNumber, string requestId, Deal deal, GetQuoteStatusResponse getQuoteStatusResponse)
        {
            var order = new Order
            {
                Id = basketNumber,
                RequestId = requestId,
                Date = DT.Now.ToString("yyyyMMdd"),
                Owner = "Физическое лицо",
                PaymentType = "Единовременно",
                Period = "12",
                InsuranseSum = "Неагрегатная",
                Reason = getQuoteStatusResponse?.Reason,
                Comment = getQuoteStatusResponse?.Comment
            };

            FillPerson(deal, order);
            FillAuto(deal, order);
            FillBank(deal, order);
            FillRegions(deal, order);
            FillDrivers(deal.AutoDeal, order);
            FillConstructor(deal, order);

            return new SendCalculationRequest
            {
                Order = order
            };
        }

        private void FillPerson(Deal deal, Order order)
        {
            var person = deal.Insurant.Subject.IndividualEntity.Person;

            order.Name = person.GetFullName().Trim();
            order.Phone = person.Phone1;
            order.Email = person.Email1;
        }

        private void FillAuto(Deal deal, Order order)
        {
            var auto = deal.GetAuto();
            order.Year = auto.AutoYearOfIssueCode;
            order.Price = DecimalToString(auto.AutoCost);
            order.Mark = auto.AutoBrandName;
            order.Model = auto.AutoModelName;
            order.Power = DecimalToString(auto.AutoEnginePowerValue);
            order.Carbody = auto.AutoBodyType.Name;
            order.Transmission = auto.AutoTransmissionType.Name;
            order.Fuel = auto.AutoEngineType.Name;
            order.EngineCapacity = auto.AutoModification?.AutoEngineValueCode;
            order.Miliage = auto.HasMileage == true && auto.Mileage.HasValue ? auto.Mileage.ToString() : "0";
        }

        private void FillBank(Deal deal, Order order)
        {
            if (deal.GetAuto().IsCreditAuto == true)
            {
                order.Bank = deal.SuggestedBanks.Last().Name;
            }
            else
            {
                order.Bank = string.Empty;
            }
        }

        private void FillRegions(Deal deal, Order order)
        {
            order.City = _calculationMapHelper.CityOfUsing(deal);
            order.Region = _calculationMapHelper.RegionOfUsing(deal);
            order.CityOwner = _calculationMapHelper.CityOfRegistration(deal);
            order.RegionOwner = _calculationMapHelper.RegionOfRegistration(deal);
        }

        private void FillDrivers(AutoDeal autoDeal, Order order)
        {
            if (autoDeal.IsMultidrive != true)
            {
                order.Drivers.AddRange(autoDeal.Drivers.Select(x => new Driver
                {
                    Age = x.Subject.IndividualEntity.Person.Age.ToString(),
                    Experience = x.DrivingExperiences.First().FullDrivingExperience.ToString()
                }));
            }
            else
            {
                order.AcceptedDrivers = "Неограниченное количество";
                order.MinAge = "18";
                order.MinExp = "0";
            }
        }

        private void FillConstructor(Deal deal, Order order)
        {
            var dealHelper = new DealHelper(deal);
            order.Compensation = _calculationMapHelper.Compensation(dealHelper);
            order.Franshrur = DecimalToString(_calculationMapHelper.Franchise(dealHelper));
        }

        private string DecimalToString(decimal? value)
        {
            return value.HasValue ? value.Value.ToString("0.##") : string.Empty;
        }
    }
}


# Code\Constructor\CalculationPartner\SendCalculationToPartner\Dtos\Driver.cs
﻿using System.Xml.Serialization;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos
{
    public class Driver
    {
        [XmlElement("age")]
        public string Age { get; set; }

        [XmlElement("experience")]
        public string Experience { get; set; }
    }
}


# Code\Constructor\CalculationPartner\SendCalculationToPartner\Dtos\Order.cs
﻿using System.Collections.Generic;
using System.Xml.Serialization;

namespace iRIS.KaskoLink2.Code.Constructor.CalculationPartner.SendCalculationToPartner.Dtos
{
    public class Order
    {
        [XmlElement("id")]
        public string Id { get; set; }

        [XmlElement("date")] 
        public string Date { get; set; }

        [XmlElement("name")] 
        public string Name { get; set; }

        [XmlElement("email")] 
        public string Email { get; set; }
Что такое проверка URM и где она назначается в коде?