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

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

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

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

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

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

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

        // реализация по заполнения обязательными и дефолтными условиями
        private void FillSingleDealConditions(
            Deal deal,
            KaskoConditionsFilter conditionsFilter,
            List<StructIdAndSum> dealConditionsStructIdsAndSums,
            List<int> structIdsToIgnore,
            ToggledCondition toggledCondition,
            bool? loadDefaultConditions = null)
        {
            List<int> dealConditionsStructIds = dealConditionsStructIdsAndSums.Select(x => x.StructId).ToList();
            bool loadDefaultConditionsFlag = loadDefaultConditions ?? toggledCondition == null;

            MakeEmptyConditionBlockIfNull(deal);
            AddOCFConditionsToBlock(deal.StructId.Value, deal.ConditionBlock, conditionsFilter, dealConditionsStructIdsAndSums, structIdsToIgnore, loadDefaultConditionsFlag);

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

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

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

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

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

                AddConditionGroupToDeal(deal, conditionGroup);
            }

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

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

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

                    AddInsuranceObjectConditionToDeal(deal, dealConditionGroup, ioTypeCondition);
                }
            }

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

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

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

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

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

                    AddRiskToDeal(dealCoverage, risk);
                }
            }

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

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

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

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

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

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

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

            return false;
        }

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

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

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

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

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

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

                    // проставить все родительские условия
                    FillConditionUp(deal, parentConfigurations, dealConditionsStructIdsAndSums);
                }

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

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

            AddConditionGroupToDeal(deal, new ProductConfigurationAndSum(conditionGroupConfig));
            var dealConditionGroup = deal.DealConditionGroups.SingleOrDefault(x => x.StructId == conditionGroupConfig.StructId);
            CorrectDealConditionGroupSum(dealConditionGroup, dealConditionsStructIdsAndSums);

            var insuranceObjectType = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.TypeIOInProduct.ToString());
            if (insuranceObjectType == null)
            {
                return;
            }

            AddInsuranceObjectConditionToDeal(deal, dealConditionGroup, insuranceObjectType);
            var dealInsuranceObjectConditions = deal.DealConditionGroups.SelectMany(x => x.InsuranceObjectConditions).Where(x => x.StructId == insuranceObjectType.StructId);

            foreach (var dealInsuranceObjectCondition in dealInsuranceObjectConditions)
            {
                var coverage = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Coverage.ToString());
                if (coverage == null)
                {
                    return;
                }

                AddCoverageToDeal(dealInsuranceObjectCondition, new ProductConfigurationAndSum(coverage), deal: deal);
                var dealCoverage = dealInsuranceObjectCondition.DealCoverages.SingleOrDefault(x => x.StructId == coverage.StructId);

                var risk = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Risk.ToString());
                if (risk != null)
                {
                    AddRiskToDeal(
                        dealCoverage, 
                        new ProductConfigurationAndSum(
                            risk, 
                            dealConditionsStructIdsAndSums.FirstOrDefault(s => s.StructId == risk.StructId)?.Sum));
                }
            }

            return;
        }

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

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

        private bool UncheckConditionUp(Deal deal, KaskoConditionsFilter conditionsFilter, int toggledStructId, List<int> dealConditionsStructIds)
        {
            // найти все родительские условия для toggledCondition, чтобы проставить или снять их
            List<ProductConfiguration> parentConfigurations = conditionsFilter.GetParentProductConfigurationsFor(toggledStructId);
            bool isRequired = false;

            var currentNode = conditionsFilter.GetProductConfigurationByStructId(toggledStructId);

            // Берем из списка всех родительсикх условий (настроек продукта) Покрытие
            var coverage = parentConfigurations.SingleOrDefault(x => x.ProductConfigurationChildType.Name == ProductConfigurationType.Coverage.ToString());
/// <summary>
        /// Получение названия продукта: ОСАГО, каско, каско+ОСАГО.
        /// </summary>
        internal static string ProductName(Basket basket)
        {
            if (basket.HasOnlyOneProduct(ProductDictCodes.Kasko))
            {
                return "каско";
            }
            else if (basket.IsClearOsago())
            {
                return "ОСАГО";
            }
            else
            {
                return "каско+ОСАГО";
            }
        }

        /// <summary>
        /// Получение страховой премий для сделок Каско и Осаго.
        /// </summary>
        internal static decimal KaskoOsagoPrice(Basket basket)
        {
            decimal totalSum = 0m;

            totalSum += basket.Deals
                .FirstOrDefault(d => d.IsInBasket == true && (d.Product.ProductDictCode == ProductDictCodes.EOsago || d.Product.ProductDictCode == ProductDictCodes.Osago))
                ?.GetSelectedProposal()?.TotalSum ?? 0m;

            totalSum += basket.Deals
                .FirstOrDefault(d => d.IsInBasket == true && d.Product.ProductDictCode == ProductDictCodes.Kasko)
                ?.GetSelectedProposal()?.GetResult()?.Value ?? 0m;

            return totalSum;
        }

        internal static DateTime? GetDealEndDate(DateTime? dateTime, DateTime? currentEndDate, bool isSubscription = false, bool isShortKasko = false, IEntitySettingsManager settingsManager = null, Intermediary intermediary = null, int? hoursCount = null, bool isUpsale = false)
        {
            if (!dateTime.HasValue)
            {
                return null;
            }

            var endDate = DT.Now;
            bool nonStandartPeriodSet = false;

            if (settingsManager is not null && currentEndDate.HasValue && isUpsale)
            {
                var isInsuranceLessThanYearForUpsale = settingsManager.GetSettingForDefaultOrPartnerConfiguration(
                        iRIS.KaskoCore.Code.Constants.EntitySettingCodes.InsuranceLessThanYearForUpsale,
                        iRIS.KaskoCore.Code.Constants.EntitySettingCodes.InsuranceLessThanYearForUpsaleDefault,
                        iRIS.KaskoCore.Code.Constants.EntitySettingCodes.InsuranceLessThanYearForUpsalePartner,
                        intermediary,
                        false,
                        null);

                if (isInsuranceLessThanYearForUpsale)
                {
                    endDate = currentEndDate.Value;
                    nonStandartPeriodSet = true;
                }
            }

            if (settingsManager is not null)
            {
                settingsManager.TryGetSettingValue<List<string>>(
                    KaskoEndDateEntitySettingCodes.AllowedInsurancePeriod,
                    out var allowedInsuranceTypePeriods,
                    x => x.Where(c => c.Code == KaskoEndDateEntitySettingCodes.AllowedInsurancePeriodDefault));

                settingsManager.TryGetSettingValue<bool>(
                    KaskoEndDateEntitySettingCodes.KaskoIsAllowedNonStandartInsurancePeriod,
                    intermediary,
                    out var isAllowedNonStandartInsurancePeriod,
                    x => x.Where(c => c.Code == KaskoEndDateEntitySettingCodes.KaskoIsAllowedNonStandartInsurancePeriodByIntermediary));

                if (allowedInsuranceTypePeriods is not null)
                {
                    if (isSubscription && allowedInsuranceTypePeriods.Contains(KaskoInsuransePeriods.Month))
                    {
                        endDate = dateTime.Value.AddMonths(1);
                        endDate = endDate.Day == dateTime.Value.Day
                            ? endDate.AddDays(-1)
                            : endDate;

                        nonStandartPeriodSet = true;
                    }
                    else if (isAllowedNonStandartInsurancePeriod)
                    {
                        if (isShortKasko && allowedInsuranceTypePeriods.Contains(KaskoInsuransePeriods.Day) && !hoursCount.HasValue)
                        {
                            endDate = dateTime.Value;
                            nonStandartPeriodSet = true;
                        }
                        else if (isShortKasko && allowedInsuranceTypePeriods.Contains(KaskoInsuransePeriods.Hour) && hoursCount.HasValue)
                        {
                            endDate = dateTime.Value.AddHours(hoursCount.Value);
                            return endDate;
                        }
                    }
                }
            }

            if (!nonStandartPeriodSet)
            {
                endDate = dateTime.Value.AddYears(1);

                endDate = endDate.Day == dateTime.Value.Day
                    ? endDate.AddDays(-1)
                    : endDate;
            }

            return new DateTime(endDate.Year, endDate.Month, endDate.Day, 23, 59, 59);
        }

        internal static bool IsYoungerThen2Years(int? year)
        {
            return IsYoungerThenNYears(year, 2);
        }

        internal static bool IsYoungerThenNYears(int? year, int years)
        {
            if (year != null && year > (DT.Now.Year - years))
            {
                return true;
            }

            return false;
        }

        internal static bool IsProlongationTestMode(IEntitySettingsManager entitySettingsManager)
        {
            return entitySettingsManager.GetSettingValue<bool>(_kaskoProlongationTestMode);
        }

        internal static bool IsProlongationErrorMode(IEntitySettingsManager entitySettingsManager, InsuranceCoreModuleConfiguration configuration)
        {
            return !IsProdEnvironment(configuration) && entitySettingsManager.GetSettingValue<bool>(_kaskoProlongationErrorMode);
        }

        /// <summary>
        /// Текущая среда - Production.
        /// </summary>
        /// <param name="configuration">конфигурация СЯ.</param>
        /// <returns>true - production, иначе false.</returns>
        internal static bool IsProdEnvironment(InsuranceCoreModuleConfiguration configuration)
            => string.IsNullOrEmpty(configuration.EnvCode);

        internal static bool ShouldDisableDelivery(Basket basket)
        {
            var osagoDeal = basket.GetOsagoDeal();
            if (!basket.IsClearOsago())
            {
                return false;
            }

            var autoCheckResult = osagoDeal?.AutoDeal?.AutoCheckResults?.Where(x => x.Name == AutoCheckResultNames.NonSegment)
                .OrderBy(x => x.DateCreate)
                .LastOrDefault();

            if (osagoDeal.IsInBasket == true
                && autoCheckResult != null
                && autoCheckResult.Details == "Полность выполнена"
                && autoCheckResult.Description == "Проверка не пройдена")
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Нужно ли блокировать поля на анкете после оплаты электронных полисов
        /// </summary>
        /// <param name="basket">Корзина</param>
        /// <returns>true - блокировать, иначе false</returns>
        internal static bool ShouldDisableQuestFields(Basket basket)
        {
            // Для старых процессов не меняем логику.
            if (basket.GetEOsagoDeal() != null)
            {
                return false;
            }

            return basket.Deals.Any(d =>
                    d.PaymentStatusCode == PaymentStatusCodes.Paid
                    && d.IsEPolicy == true
                    && d.IsInBasket == true);
        }

        internal static string KaskoBasketLink(this Basket basket, IServiceProvider serviceProvider)
        {
            var configuration = serviceProvider.GetRequiredService<IOptions<BusinessAppConfiguration>>().Value;
            var sb = new StringBuilder();
            sb.Append(configuration.BaseUrl);
            sb.Append(PipelineUrlBuilder.Build(
                          configuration.BaseUrl,
                          configuration.WebApplicationBasePath,
                          $"DI/process/dikaskoinsurance/{basket.Number}"));

            return sb.ToString();
        }

        /// <summary>
        /// Максимальная дата начала действия полиса (наиболее свежая).
        /// </summary>
        internal static DateTime GetMaxDealDateStart(Basket basket)
        {
            var dates = new List<DateTime>();

            var kaskoDeal = basket.GetKaskoDeal();
            var osagoDeal = basket.GetOsagoDeal();

            if (kaskoDeal?.IsInBasket == true)
            {
                dates.Add(kaskoDeal.DateStart.GetValueOrDefault());
            }

            if (osagoDeal?.IsInBasket == true)
            {
                dates.Add(osagoDeal.DateStart.GetValueOrDefault());
            }

            return dates.Max();
        }

        public static bool TryGetDictionaryViewModelPropertyValue<T>(this BaseViewModel viewModel, string fieldName, out DictionaryViewModelProperty<T> value)
            where T : Framework.Data.BaseDictionary
        {
            if (viewModel[fieldName] is DictionaryViewModelProperty<T> resValue
                && resValue.Value != null)
            {
                value = resValue;
                return true;
            }

            value = null;
            return false;
        }

        //1. (ПробегДА ИЛИ ТС старше 2 лет) И Выходим за вилку стоимости
        //2. (ПробегДА ИЛИ ТС старше 2 лет) И Выходим за 7 (для НБ) ИЛИ 10 млн(для Пролонгации)
        //3. (ПробегДА ИЛИ ТС старше 2 лет) И У ТС отсутствует вилка стоимости
        internal static async Task<bool> AutoMileageVisibilityAsync(IAutoCostCalculator autoCostCalculator, Basket basket)
        {
            if (basket.IsClearOsago())
            {
                return false;
            }

            var showMileage = false;
            var deal = basket.GetKaskoDeal();
            var auto = deal.GetAuto();

            if (auto.HasMileage == true || !IsYoungerThen2Years(auto.AutoYearOfIssueValue))
            {
                var autoPrices = await autoCostCalculator.GetAutoPricesAsync(auto, new List<string> { auto.AutoTypeCode }, deal.DateFirstCalculation);

                var autoPiceFiltered = autoPrices
                    .Where(t => (auto.AutoEngineTypeCode == null || t.AutoModification.AutoEngineTypeCode.Equals(auto.AutoEngineTypeCode, StringComparison.OrdinalIgnoreCase)) &&
                                (auto.AutoTransmissionTypeCode == null || t.AutoModification.AutoTransmissionTypeCode.Equals(auto.AutoTransmissionTypeCode, StringComparison.OrdinalIgnoreCase)))
                    .ToList();

                autoCostCalculator.GetMinAndMaxPrices(deal, autoPiceFiltered, out _, out var recommendedMaxPrice);

                if (auto.AutoCost > recommendedMaxPrice)
                {
                    return true;
                }

                if (deal.IsProlongation == true)
                {
                    showMileage = auto.AutoCost > AutoCostValues.AutoCost10000000;
                }
                else
                {
                    showMileage = autoPiceFiltered.Count == 0 || auto.AutoCost > AutoCostValues.AutoCost7000000;
                }
            }

            return showMileage;
        }

        /// <summary>
        /// Выбрана опция "Ограничение пробега".
        /// </summary>
        /// <param name="basket">Корзина.</param>
        internal static bool HasMileageLimitOption(Basket basket)
        {
            var deal = basket.GetKaskoDeal();

            if (deal != null && deal.IsInBasket == true)
            {
                var dealHelper = new DealHelper(deal);
                
                return dealHelper.DealOptions.Any(x => x.ProductOption?.OptionCode == OptionCodes.MileLimit);
            }

            return false;
        }

        /// <summary>
        /// Получить позицию блока: "Контактная информация". 
        /// </summary>
        /// <param name="abTestHelper">KaskoOsagoAbTestHelper.</param>
        /// <returns>Позиция блока: "Контактная информация".</returns>
        internal static ContactInfoPosition GetContactInfoPosition(KaskoOsagoAbTestHelper abTestHelper) =>
            abTestHelper.GetContactInfoPosition();

        internal static bool IsIrisLk(Deal deal)
        {
            return deal?.GetMainIntermediary()?.IntermediaryInternalName?.ToLower() == IntermediaryNames.IRIS_LK;
        }
    }
}


# Code\Helpers\MessageTemplateHelper.cs
﻿using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.Entities.EntityExtensions;
using iRIS.KaskoLink2.Code.Constants;
using iRIS.KaskoCore.Printing.Code;
using iRIS.KaskoLink2.Code.TypeExtensions;
using System.Collections.Generic;
using System.Linq;
using iRIS.KaskoCore.Code.Constants;
using iRIS.KaskoCore.Code.Extensions;

namespace iRIS.KaskoLink2.Code.Helpers
{
    internal static class MessageTemplateHelper
    {
        /// <summary>
        /// Получить шаблон письма для оплаты Каско и Осаго.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <returns>Код шаблона письма.</returns>
        public static string GetPaymentTemplateCode(Basket basket)
        {
            if (basket.HasKasko())
            {
                if (basket.HasOsago())
                {
                    return KaskoOsagoMessageTemplateCodes.KaskoOsagoLinkToPayment;
                }

                return KaskoOsagoMessageTemplateCodes.KaskoLinkToPayment;
            }

            return KaskoOsagoMessageTemplateCodes.OsagoLinkToPayment;
        }
        
        /// <summary>
        /// Получить шаблон письма для макета Каско и Осаго.
        /// </summary>
        /// <param name="basket">Корзина.</param>
        /// <returns>Код шаблона письма.</returns>
        public static string GetPolicyLayoutTemplateCode(Basket basket)
        {
            var hasClearOsagoProlongation = basket.HasProlongationOsagoDeal() && basket.IsClearOsago();

            if (hasClearOsagoProlongation)
            {
                return KaskoOsagoMessageTemplateCodes.OsagoProlongationPolicyLayout;
            }
            else if (basket.IsClearOsago())
            {
                return KaskoOsagoMessageTemplateCodes.OsagoPolicyLayout;
            }
            else
            {
                return KaskoOsagoMessageTemplateCodes.KaskoPolicyLayout;
            }
        }

        public static IEnumerable<string> GetPaymentTemplateAttachmentCodes(Basket basket)
        {
            if (basket.IsClearOsago()) 
            {
                var deal = basket.GetOsagoDealInBasket();

                return new[]
                {
                    deal.GetNsUpsale()?.IsSelected == true ? KaskoOsagoPrintingFormCodes.PRINTING_FORM_CODE_KASKO_KID_NS : string.Empty,
                    deal.GetHelpOnRoadUpsale()?.IsSelected == true ? KaskoOsagoPrintingFormCodes.PRINTING_FORM_CODE_KASKO_KID_ROAD_HELP : string.Empty,
                    deal.GetDagoUpsale()?.IsSelected == true ? KaskoOsagoPrintingFormCodes.PRINTING_FORM_CODE_KASKO_KID_DAGO : string.Empty,
                    deal.GetKaskoNoPolicyUpsale()?.IsSelected == true ? KaskoOsagoPrintingFormCodes.PRINTING_FORM_CODE_KASKO_KID_NO_POLICY : string.Empty,
                }.Where(s => !string.IsNullOrEmpty(s))
                .ToArray();
            }

            return new string[0];
        }

        public static string GetKaskoPolicySuccessfulBuyMessageTemplateCode(Basket basket)
        {
            if (KaskoOsagoHelper.HasMsiOption(basket))
            {
                return KaskoOsagoMessageTemplateCodes.KaskoWithMsiPolicySuccessfulBuy;
            }

            if (basket.IsClearKasko() && basket.GetKaskoDeal().GetSelectedProposal()?.Offer_Id == DiKaskoOfferIds.Dago)
            {
                return KaskoOsagoMessageTemplateCodes.DagoPolicySuccessfulBuy;
            }

            if (basket.IsClearKasko() && basket.GetKaskoDeal().GetSelectedProposal()?.Offer_Id == DiKaskoOfferIds.KaskoNoPolicy)
            {
                return KaskoOsagoMessageTemplateCodes.KaskoNoPolicySuccessfulBuy;
            }

            return KaskoOsagoMessageTemplateCodes.KaskoPolicySuccessfulBuy;
        }
    }
}
InitializediKaskoExecutionCompletedFormAction(_diKaskoExecutionCompletedFormAction);
            InitializediKaskoSuccessfulBuyEPolicyFormAction(_diKaskoSuccessfulBuyEPolicyFormAction);
            InitializecheckPaymentFormProcessAction(_checkPaymentFormProcessAction);
            InitializeDiKaskoSuccessfulBuyEPolicy(_diKaskoSuccessfulBuyEPolicy);
            InitializesupportToolsKaskoFormAction(_supportToolsKaskoFormAction);
            InitializeAutoSupportToolsExit(_autoSupportToolsExit);
            InitializeCheckPaymentFormProcessStep(_checkPaymentFormProcessStep);
            InitializediKaskoConstructorFormAction(_diKaskoConstructorFormAction);
            InitializeDiKaskoConstructor(_diKaskoConstructor);
            InitializediKaskoPolicyLayoutFormAction(_diKaskoPolicyLayoutFormAction);
            InitializeDiKaskoPolicyLayout(_diKaskoPolicyLayout);
            InitializediKaskoQuestionnaireFormAction(_diKaskoQuestionnaireFormAction);
            InitializeDialogForm(_dialogForm);
            InitializediKaskoSegmentationFormAction(_diKaskoSegmentationFormAction);
            InitializeDiKaskoSegmentation(_diKaskoSegmentation);
            InitializediKaskoSuccessfulBuyFormAction(_diKaskoSuccessfulBuyFormAction);
            InitializeDiKaskoSuccessfulBuy(_diKaskoSuccessfulBuy);
            InitializediKaskoNoSuitablePackageFormAction(_diKaskoNoSuitablePackageFormAction);
            InitializeDiKaskoNoSuitablePackage(_diKaskoNoSuitablePackage);
            Initializeclose(_close);
            Initializeexit(_exit);
            InitializeDiKaskoQuestionnaire(_diKaskoQuestionnaire);
            InitializeDiKaskoExecutionCompleted(_diKaskoExecutionCompleted);
        }

        private void InitializeDiKaskoResumeFormSelectingProcess(FlowProcessModel model)
        {
            model.Identifier = "DiKaskoResumeFormSelectingProcess";
            model.Name = "КАСКО. Отрисовка формы для выбора точки перехода";
            model.Description = @"КАСКО. Отрисовка формы для выбора точки перехода";
            model.Version = "Draft";
            model.IsPrivate = true;
            model.ProcessResumeAccessRules = new List<FlowProcessSecurity>();
            model.ProcessStartAccessRules = new List<FlowProcessSecurity>();
            model.VariableModelInfoList = new List<ProcessVariableDefinition>();
            model.VariableModelInfoList.Add(new ProcessVariableDefinition
            {
                Name = "Basket",
                TypeName = typeof(iRIS.InsuranceCore.Entities.Basket).AssemblyQualifiedName,
                Direction = Direction.In,
                IsMainRootVariable = false,
                InitializeFromExtension = false,
                IsLocalVariable = false,
                IsOptional = false
            });
            model.Start = _dialogForm;
            model.NavigationStartPoints = new List<NavigationStartModel>();
        }

        private void InitializediKaskoExecutionCompletedFormAction(InputModel model)
        {
            model.Identifier = "diKaskoExecutionCompletedFormAction";
            model.Name = "Переход на форму Оформление завершено";
            model.Description = @"Переход на форму Оформление завершено";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = null;
            model.NextStep = _diKaskoExecutionCompleted;
        }

        private void InitializediKaskoSuccessfulBuyEPolicyFormAction(InputModel model)
        {
            model.Identifier = "diKaskoSuccessfulBuyEPolicyFormAction";
            model.Name = "Переход на форму успешной покупки e-полиса";
            model.Description = @"Переход на форму успешной покупки еКаско";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _checkPaymentFormProcessAction;
            model.NextStep = _diKaskoSuccessfulBuyEPolicy;
        }

        private void InitializecheckPaymentFormProcessAction(InputModel model)
        {
            model.Identifier = "checkPaymentFormProcessAction";
            model.Name = "Переход на форму успешной покупки e-полиса";
            model.Description = @"Переход на форму успешной покупки еКаско";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _supportToolsKaskoFormAction;
            model.NextStep = _checkPaymentFormProcessStep;
        }

        private void InitializeDiKaskoSuccessfulBuyEPolicy(ExitPointModel model)
        {
            model.Identifier = "DiKaskoSuccessfulBuyEPolicy";
            model.Name = "DiKaskoSuccessfulBuyEPolicyStep";
            model.Description = @"Выход на форму успешной покупки e-полиса";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializesupportToolsKaskoFormAction(InputModel model)
        {
            model.Identifier = "supportToolsKaskoFormAction";
            model.Name = "Переход на форму Администрирование процессов";
            model.Description = @"Переход на форму Администрирование процессов";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.ValidationGroups.Add("insurant_nont");
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoExecutionCompletedFormAction;
            model.NextStep = _autoSupportToolsExit;
        }

        private void InitializeAutoSupportToolsExit(ExitPointModel model)
        {
            model.Identifier = "AutoSupportToolsExit";
            model.Name = "AutoSupportToolsExit";
            model.Description = @"Выход на форму Администрирование процессов";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializeCheckPaymentFormProcessStep(ExitPointModel model)
        {
            model.Identifier = "CheckPaymentFormProcessStep";
            model.Name = "CheckPaymentFormProcessStep";
            model.Description = string.Empty;
            model.Title = "CheckPaymentFormProcessStep";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializediKaskoConstructorFormAction(InputModel model)
        {
            model.Identifier = "diKaskoConstructorFormAction";
            model.Name = "Переход на форму Конструктор";
            model.Description = @"Переход на форму Конструктор";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoSuccessfulBuyFormAction;
            model.NextStep = _diKaskoConstructor;
        }

        private void InitializeDiKaskoConstructor(ExitPointModel model)
        {
            model.Identifier = "DiKaskoConstructor";
            model.Name = "DiKaskoConstructorStep";
            model.Description = @"Выход на форму Конструктор";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializediKaskoPolicyLayoutFormAction(InputModel model)
        {
            model.Identifier = "diKaskoPolicyLayoutFormAction";
            model.Name = "Переход на форму Макета";
            model.Description = @"Переход на форму Макета";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoSuccessfulBuyEPolicyFormAction;
            model.NextStep = _diKaskoPolicyLayout;
        }

        private void InitializeDiKaskoPolicyLayout(ExitPointModel model)
        {
            model.Identifier = "DiKaskoPolicyLayout";
            model.Name = "DiKaskoPolicyLayoutStep";
            model.Description = @"Выход на форму макета";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializediKaskoQuestionnaireFormAction(InputModel model)
        {
            model.Identifier = "diKaskoQuestionnaireFormAction";
            model.Name = "Переход на форму Анкеты";
            model.Description = @"Переход на форму Анкеты";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoPolicyLayoutFormAction;
            model.NextStep = _diKaskoQuestionnaire;
        }

        private void InitializeDialogForm(FormDataModel model)
        {
            model.Identifier = "DialogForm";
            model.Name = "КАСКО. Отрисовка формы для выбора точки перехода";
            model.Description = @"КАСКО. Отрисовка формы для выбора точки перехода";
            model.FormDataType = FormDataType.Dialog;
            model.DialogCaption = @"'Переход на формы'";
            model.DialogMessage = @"'Переход на формы'";
            model.NextStep = _diKaskoSegmentationFormAction;
        }

        private void InitializediKaskoSegmentationFormAction(InputModel model)
        {
            model.Identifier = "diKaskoSegmentationFormAction";
            model.Name = "Переход на форму Сегментация";
            model.Description = @"Переход на форму Сегментация";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoConstructorFormAction;
            model.NextStep = _diKaskoSegmentation;
        }

        private void InitializeDiKaskoSegmentation(ExitPointModel model)
        {
            model.Identifier = "DiKaskoSegmentation";
            model.Name = "DiKaskoSegmentationStep";
            model.Description = @"Выход на форму DiKaskoSegmentation";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializediKaskoSuccessfulBuyFormAction(InputModel model)
        {
            model.Identifier = "diKaskoSuccessfulBuyFormAction";
            model.Name = "Переход на форму Спасибо";
            model.Description = @"Переход на форму Спасибо";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoNoSuitablePackageFormAction;
            model.NextStep = _diKaskoSuccessfulBuy;
        }

        private void InitializeDiKaskoSuccessfulBuy(ExitPointModel model)
        {
            model.Identifier = "DiKaskoSuccessfulBuy";
            model.Name = "DiKaskoSuccessfulBuyStep";
            model.Description = @"Выход на форму Спасибо";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializediKaskoNoSuitablePackageFormAction(InputModel model)
        {
            model.Identifier = "diKaskoNoSuitablePackageFormAction";
            model.Name = "Переход на форму  DI не может вернуть пакет";
            model.Description = @"Переход на форму DI не может вернуть пакет";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _close;
            model.NextStep = _diKaskoNoSuitablePackage;
        }

        private void InitializeDiKaskoNoSuitablePackage(ExitPointModel model)
        {
            model.Identifier = "DiKaskoNoSuitablePackage";
            model.Name = "DiKaskoNoSuitablePackageStep";
            model.Description = @"Выход на форму DI не может вернуть пакет";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void Initializeclose(InputModel model)
        {
            model.Identifier = "close";
            model.Name = "CloseModalDialogInput";
            model.Description = @"CloseModalDialogInput";
            model.ActionDefinition = new ActionDefinition();
            model.ActionDefinition.ModelSyncMode = iRIS.Framework.Entity.Metadata.Data.Enum.ModelSyncMode.NoModel;
            model.ValidationGroups = new List<string>();
            model.ValidationGroups.Add("insurant_nont");
            model.CriticalLevels = new List<iRIS.Framework.Entity.Metadata.ValidationCriticalLevel>();
            model.Bookmark = string.Empty;
            model.SuppressProcessResuming = false;
            model.ParallelInput = _diKaskoQuestionnaireFormAction;
            model.NextStep = _exit;
        }

        private void Initializeexit(ExitPointModel model)
        {
            model.Identifier = "exit";
            model.Name = "DefaultExit";
            model.Description = @"пустой выход";
            model.ReturnParameters = new List<ParameterModel>();
        }

        private void InitializeDiKaskoQuestionnaire(ExitPointModel model)
        {
            model.Identifier = "DiKaskoQuestionnaire";
            model.Name = "DiKaskoQuestionnaireStep";
            model.Description = @"Выход на форму анкеты";
            model.ReturnParameters = new List<ParameterModel>();
        }
Сколько полей у обьекта Deal