Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.23 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text.RegularExpressions;
  5. using System.Threading.Tasks;
  6. using JetBrains.Annotations;
  7. using log4net;
  8. using SKBKontur.Billy.Core.BusinessObjects.External;
  9. using SKBKontur.Billy.Core.Buzz.OrganizationsSearcher.Converters;
  10. using SKBKontur.Billy.Core.Buzz.OrganizationsSearcher.Extensions;
  11. using SKBKontur.Billy.Core.Buzz.OrganizationsSearcher.Models;
  12. using SKBKontur.Billy.Core.Buzz.OrganizationsService;
  13. using SKBKontur.Billy.Core.Common;
  14. using SKBKontur.Billy.Core.Common.Extensions;
  15. using SKBKontur.Billy.Core.Common.Threading;
  16.  
  17. namespace SKBKontur.Billy.Core.Buzz.OrganizationsSearcher
  18. {
  19.     public class OrganizationsSearcher : IOrganizationsSearcher
  20.     {
  21.         private const int batchSize = 1000;
  22.         private readonly IOrganizationServiceClient organizationServiceClient;
  23.         private readonly IOrganizationPropsConverter organizationPropsConverter;
  24.         private readonly ILog log = LogManager.GetLogger(typeof(OrganizationsSearcher));
  25.  
  26.         public OrganizationsSearcher(
  27.             IOrganizationServiceClient organizationServiceClient,
  28.             IOrganizationPropsConverter organizationPropsConverter
  29.             )
  30.         {
  31.             this.organizationServiceClient = organizationServiceClient;
  32.             this.organizationPropsConverter = organizationPropsConverter;
  33.         }
  34.  
  35.         public PayerOrganizationSearchDto[] Select(Requisites[] innKppPairs)
  36.         {
  37.             return SelectAsync(innKppPairs).AwaitResult();
  38.         }
  39.  
  40.         public PayerOrganizationSearchDto[] Select(string[] inns)
  41.         {
  42.             return SelectAsync(inns).AwaitResult();
  43.         }
  44.  
  45.         public async Task<PayerOrganizationSearchDto[]> SelectAsync(Requisites[] innKppPairs)
  46.         {
  47.             using (Timewatcher.CreateMs(t => log.Info($"Select payers time = {t} ms. Payers {innKppPairs.JoinToString()}")))
  48.             {
  49.                 return await InnerSelectAsync(innKppPairs).ConfigureAwait(false);
  50.             }
  51.         }
  52.  
  53.         public async Task<PayerOrganizationSearchDto[]> SelectAsync(string[] inns)
  54.         {
  55.             if (inns.IsNullOrEmpty())
  56.             {
  57.                 return new PayerOrganizationSearchDto[0];
  58.             }
  59.  
  60.             var payers = await SelectBatchedAsync(organizationServiceClient.SelectByInnsAsync, inns).ConfigureAwait(false);
  61.             return payers
  62.                 .Where(p => !p.IsDeleted())
  63.                 .Select(organizationPropsConverter.Convert)
  64.                 .ToArray();
  65.         }
  66.  
  67.         public async Task<PayerOrganizationSearchDto[]> SelectAsync(Guid[] payerIds)
  68.         {
  69.             var payers = await SelectBatchedAsync(organizationServiceClient.SelectAsync, payerIds).ConfigureAwait(false);
  70.             return payers
  71.                 .Where(p => !p.IsDeleted())
  72.                 .Select(organizationPropsConverter.Convert)
  73.                 .ToArray();
  74.         }
  75.  
  76.         public (Requisites InnKpp, PayerOrganizationSearchDto ExistedOrHeadPayer)[] SelectExistedOrHead(Requisites[] innKpps)
  77.         {
  78.             return SelectExistedOrHeadAsync(innKpps).AwaitResult();
  79.         }
  80.  
  81.         public async Task<(Requisites InnKpp, PayerOrganizationSearchDto ExistedOrHeadPayer)[]> SelectExistedOrHeadAsync(Requisites[] innKpps)
  82.         {
  83.             var completedInnKpps = innKpps
  84.                 .Where(i => i.IsComplete())
  85.                 .Distinct()
  86.                 .ToArray();
  87.  
  88.             var inns = completedInnKpps.Select(i => i.Inn).ToArray();
  89.             var allPayers = await SelectAsync(inns).ConfigureAwait(false);
  90.  
  91.             var payersHelper = new PayerHelper(allPayers);
  92.  
  93.             return completedInnKpps
  94.                 .Select(innKpp => (InnKpp: innKpp, ExistedOrHeadPayer: payersHelper.FindExistedOrHead(innKpp)))
  95.                 .Where(t => t.ExistedOrHeadPayer != null)
  96.                 .ToArray();
  97.         }
  98.  
  99.         [NotNull, ItemNotNull]
  100.         private async Task<PayerOrganizationSearchDto[]> InnerSelectAsync([NotNull] Requisites[] innKppPairs)
  101.         {
  102.             if (innKppPairs.Length == 0)
  103.             {
  104.                 return new PayerOrganizationSearchDto[0];
  105.             }
  106.  
  107.             var nonEmptyInnKpps = innKppPairs
  108.                 .Where(ik => ik.IsComplete())
  109.                 .ToHashSet();
  110.  
  111.             var searchedInns = nonEmptyInnKpps
  112.                 .Select(ik => ik.Inn)
  113.                 .Distinct()
  114.                 .ToArray();
  115.  
  116.             var payers = await SelectAsync(searchedInns).ConfigureAwait(false);
  117.             return payers
  118.                 .ToLookup(p => p.ToInnKpp())
  119.                 .Where(g => nonEmptyInnKpps.Contains(g.Key))
  120.                 .Select(g => g.First())
  121.                 .ToArray();
  122.         }
  123.  
  124.         [NotNull, ItemNotNull]
  125.         private async Task<TResult[]> SelectBatchedAsync<TResult, TKey>(Func<TKey[], Task<TResult[]>> method, TKey[] keys)
  126.         {
  127.             var result = new List<TResult>();
  128.             foreach (var keysBatch in keys.Split(batchSize))
  129.             {
  130.                 var batchContent = await method(keysBatch.ToArray()).ConfigureAwait(false);
  131.                 result.AddRange(batchContent);
  132.             }
  133.  
  134.             return result.ToArray();
  135.         }
  136.  
  137.         private class PayerHelper
  138.         {
  139.             private readonly ILookup<string, PayerOrganizationSearchDto> payersByInns;
  140.             private static readonly Regex is01HeadKpp = new Regex(@"\d{4}01\d{3}", RegexOptions.Compiled);
  141.             private static readonly Regex is50HeadKpp = new Regex(@"\d{4}50\d{3}", RegexOptions.Compiled);
  142.  
  143.             public PayerHelper([NotNull] PayerOrganizationSearchDto[] abonents)
  144.             {
  145.                 payersByInns = abonents.ToLookup(a => a.Inn);
  146.             }
  147.  
  148.             [CanBeNull]
  149.             public PayerOrganizationSearchDto FindExistedOrHead(Requisites innKpp)
  150.             {
  151.                 var existed = FindExisted(innKpp);
  152.                 if (existed != null || !CanFindHead(innKpp))
  153.                 {
  154.                     return existed;
  155.                 }
  156.  
  157.                 return FindHead(innKpp);
  158.             }
  159.  
  160.             [CanBeNull]
  161.             private PayerOrganizationSearchDto FindExisted(Requisites innKpp)
  162.             {
  163.                 return payersByInns[innKpp.Inn].FirstOrDefault(payer => innKpp.Equals(payer.ToInnKpp()));
  164.             }
  165.  
  166.  
  167.             [CanBeNull]
  168.             private PayerOrganizationSearchDto FindHead(Requisites innKpp)
  169.             {
  170.                 var found01Payer = payersByInns[innKpp.Inn].FirstOrDefault(p => is01HeadKpp.IsMatch(p.Kpp));
  171.                 var found50Payer = payersByInns[innKpp.Inn].FirstOrDefault(p => is50HeadKpp.IsMatch(p.Kpp));
  172.  
  173.                 if (is01HeadKpp.IsMatch(innKpp.Kpp))
  174.                 {
  175.                     return found01Payer ?? found50Payer;
  176.                 }
  177.  
  178.                 if (is50HeadKpp.IsMatch(innKpp.Kpp))
  179.                 {
  180.                     return found50Payer ?? found01Payer;
  181.                 }
  182.  
  183.                 return null;
  184.             }
  185.  
  186.             private bool CanFindHead(Requisites innKpp)
  187.             {
  188.                 return innKpp.ClientType == ClientType.LegalEntity
  189.                        && innKpp.IsValid();
  190.             }
  191.         }
  192.  
  193.     }
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement