Example #1
0
        public async ValueTask <ResultGrpcResponse> UpdateAsync(UpdatePersonalDataGrpcContract request)
        {
            var pd = await ServiceLocator.PersonalDataRepository.GetByIdAsync(request.Id, ServiceLocator.EncodingKey);

            await ServiceLocator.PersonalDataRepository.UpdateAsync(new PersonalDataPostgresUpdateEntity
            {
                Id                   = request.Id,
                FirstName            = request.FirstName,
                LastName             = request.LastName,
                City                 = request.City,
                Phone                = request.Phone,
                PostalCode           = request.PostalCode,
                CountryOfCitizenship = request.CountryOfCitizenship,
                CountryOfResidence   = request.CountryOfResidence,
                Address              = request.Address,
                Sex                  = request.Sex,
                BirthDay             = request.DateOfBirth
            }, ServiceLocator.EncodingKey);

            var updatedPd =
                await ServiceLocator.PersonalDataRepository.GetByIdAsync(request.Id, ServiceLocator.EncodingKey);

            /*
             * var log = new AuditLogGrpcModel
             * {
             *  TraderId = request.Id,
             *  ProcessId = request.AuditLog.ProcessId,
             *  Ip = request.AuditLog.Ip,
             *  ServiceName = request.AuditLog.ServiceName,
             *  Context = request.AuditLog.Context,
             *  Before = ToJson(pd),
             *  UpdatedData = ToJson(request),
             *  After = ToJson(updatedPd)
             * };
             *
             * await ServiceLocator.AuditLogServiceGrpc.RegisterEventAsync(log);
             */

            return(new ResultGrpcResponse {
                Ok = true
            });
        }
Example #2
0
        private async ValueTask HandleEvents(KycVerificationResultMessage message)
        {
            try
            {
                _logger.LogInformation(
                    "Verification {verificationId} is finished. Result {result}. ApplicantId {applicantId}",
                    message.VerificationId, message.Verified, message.ApplicantId);
                var profile = await _repository.GetProfileByApplicantId(message.ApplicantId);

                if (profile == null)
                {
                    _logger.LogWarning(
                        "Received verification for applicant without profile. Applicant id {applicantId}; Client {clientId}",
                        message.ApplicantId, message.ExternalApplicantId);
                    return;
                }

                var applicantResponse = await _kycAidHttpService.GetApplicant(message.ApplicantId);

                if (applicantResponse == null)
                {
                    _logger.LogWarning(
                        "Unable to get applicant data from KycAid. Applicant id {applicantId}; Client {clientId}",
                        message.ApplicantId, message.ExternalApplicantId);
                    return;
                }

                var existingUsers = new List <PersonalDataGrpcModel>();

                if (DateTime.TryParse(applicantResponse.DateOfBirth, out var dateBirth) &&
                    !string.IsNullOrEmpty(applicantResponse.FirstName) &&
                    !string.IsNullOrEmpty(applicantResponse.LastName))
                {
                    var existingUsersResp = await _personalData.SearchAsync(new SearchRequest()
                    {
                        SearchText = applicantResponse.LastName
                    });

                    existingUsers =
                        (existingUsersResp.PersonalDatas ?? new List <PersonalDataGrpcModel>())
                        .Where(e => e.DateOfBirth == dateBirth &&
                               e.FirstName == applicantResponse.FirstName &&
                               e.LastName == applicantResponse.LastName &&
                               e.Id != applicantResponse.ExternalApplicantId)
                        .ToList();
                }



                var oldProfile = (KycProfile)profile.Clone();

                var updatedDocs = new List <KycDocument>();
                foreach (var documentCheck in applicantResponse.Documents)
                {
                    var document = profile.Documents.FirstOrDefault(t => t.DocumentId == documentCheck.DocumentId);
                    if (document != null)
                    {
                        document.Verified      = documentCheck.Status == "valid";
                        document.DeclineReason = String.Join(", ", documentCheck.DeclineReasons);
                        updatedDocs.Add(document);
                    }
                }

                await using var context = new DatabaseContext(_dbContextOptionsBuilder.Options);
                await context.UpsertAsync(new List <Verification>(){ new Verification
                                                                     {
                                                                         VerificationId  = message.VerificationId,
                                                                         ClientId        = profile.ClientId,
                                                                         Status          = applicantResponse.Status,
                                                                         Verified        = applicantResponse.Verified,
                                                                         DocumentResults = applicantResponse.Documents.ToDictionary(t => t.DocumentId, t => new VerificationResult
                        {
                            Verified       = t.Status == "valid",
                            Comment        = t.Comment,
                            DeclineReasons = String.Join(", ", t.DeclineReasons),
                            DocumentType   = t.Type
                        })
                                                                     } });

                if (updatedDocs.Any())
                {
                    await context.UpsertAsync(updatedDocs);

                    context.AuditLogs.AddRange(updatedDocs.Select(doc =>
                                                                  KycAuditLog.Create(doc, $"Verification {message.VerificationId}", "automatic", null)));
                    await context.SaveChangesAsync();
                }

                profile.ActiveVerificationId = String.Empty;
                if (Boolean.TryParse(applicantResponse.Pep, out var pep))
                {
                    profile.Pep = pep;
                }

                profile.Country = applicantResponse.ResidenceCountry;

                await _statusSetter.UpdateProfileState(profile);

                if (existingUsers.Any())
                {
                    profile.DepositStatus    = KycOperationStatus.Blocked;
                    profile.TradeStatus      = KycOperationStatus.Blocked;
                    profile.WithdrawalStatus = KycOperationStatus.Blocked;
                    profile.BlockingReason   = "Client has same First name, Last name and DataBirth with another clients";

                    var report = new AddClientCommentRequest()
                    {
                        ClientId  = profile.ClientId,
                        ManagerId = "KYC service",
                        Text      =
                            "Client KYC Blocked Deposit, Trade, Withdrawal because user has same First name, Last name and DataBirth with another clients: "
                    };
                    foreach (var user in existingUsers)
                    {
                        report.Text += $"{user.Id}, ";
                    }

                    await _clientCommentsService.AddAsync(report);
                }

                await _repository.UpdateProfile(profile, "Verification result received", "automatic", null);

                await _publisher.PublishAsync(new KycProfileUpdatedMessage()
                {
                    ClientId   = profile.ClientId,
                    OldProfile = oldProfile,
                    NewProfile = profile
                });

                var request = new UpdatePersonalDataGrpcContract
                {
                    Id                 = profile.ClientId,
                    FirstName          = applicantResponse.FirstName,
                    LastName           = applicantResponse.LastName,
                    CountryOfResidence = applicantResponse.ResidenceCountry,
                    City               = applicantResponse.Addresses?.FirstOrDefault()?.City,
                    PostalCode         = applicantResponse.Addresses?.FirstOrDefault()?.PostalCode,
                    AuditLog           = new AuditLogGrpcContract
                    {
                        TraderId    = profile.ClientId,
                        ServiceName = "Service.KYC",
                        ProcessId   = Guid.NewGuid().ToString("N"),
                        Context     = $"KYC Verification {message.VerificationId}"
                    },
                    Address =
                        $"{applicantResponse.Addresses?.FirstOrDefault()?.StreetName}, {applicantResponse.Addresses?.FirstOrDefault()?.BuildingNumber}, unit: {applicantResponse.Addresses?.FirstOrDefault()?.UnitNumber}",
                };

                if (DateTime.TryParse(applicantResponse.DateOfBirth, out var dob))
                {
                    request.DateOfBirth = dob;
                }

                var response = await _personalData.UpdateAsync(request);

                _logger.LogInformation("Updating personal data. Update result: {result}", response.Ok);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "When handling message about verification {verificationId}", message.VerificationId);
                throw;
            }
        }