public async Task DoRescue_AuthorizationAndCreation_NoBalance() { _mockUnitOfWork.Setup(x => x.CommitAsync()).ReturnsAsync(true); _mockUserRepository.Setup(x => x.CustomFind(It.IsAny <Expression <Func <User, bool> > >())).ReturnsAsync(new List <User> { new User { Id = 10 } }); _mockOrderRepository.Setup(x => x.GetLast(It.IsAny <Expression <Func <Order, bool> > >(), It.IsAny <Expression <Func <Order, int> > >())).ReturnsAsync(new Order { Id = 10, CreatedAt = DateTime.Now.AddDays(-1) }); _mockUserPunctuationRepository.Setup(x => x.CustomFind(It.IsAny <Expression <Func <UserPunctuation, bool> > >())).ReturnsAsync(new List <UserPunctuation> { new UserPunctuation { Id = 10, Punctuation = 45 } }); var rescueRequest = new RescueRequestDto { Total = 50, RescueRequestItems = new List <RescueRequestItemsDto> { new RescueRequestItemsDto { TotalValue = 50 } } }; var service = new OrderService(_mockOrderReversalItemRepository.Object, _mockUserPunctuationRepository.Object, _mockUserPunctuationSourceRepository.Object, _mockUserRepository.Object, _mockLogger.Object, _mockOrderRepository.Object, _mockOrderItemRepository.Object, _mockOrderStatusRepository.Object, _mockUnitOfWork.Object, _mockShopUserRepository.Object, _mapper); var result = await service.DoRescue(rescueRequest); Assert.False(result.Success); Assert.Equal("Saldo insuficiente", result.Message); }
public async Task DoRescue_AuthorizationAndCreation_FailByTimeValidation() { _mockUnitOfWork.Setup(x => x.CommitAsync()).ReturnsAsync(true); _mockUserRepository.Setup(x => x.CustomFind(It.IsAny <Expression <Func <User, bool> > >())).ReturnsAsync(new List <User> { new User { Id = 10 } }); _mockOrderRepository.Setup(x => x.GetLast(It.IsAny <Expression <Func <Order, bool> > >(), It.IsAny <Expression <Func <Order, int> > >())).ReturnsAsync(new Order { Id = 10, CreatedAt = DateTime.Now.AddMinutes(-1) }); _mockUserPunctuationRepository.Setup(x => x.CustomFind(It.IsAny <Expression <Func <UserPunctuation, bool> > >())).ReturnsAsync(new List <UserPunctuation> { new UserPunctuation { Id = 10, Punctuation = 100 } }); var rescueRequest = new RescueRequestDto { Total = 50, RescueRequestItems = new List <RescueRequestItemsDto> { new RescueRequestItemsDto { TotalValue = 50 } } }; var service = new OrderService(_mockOrderReversalItemRepository.Object, _mockUserPunctuationRepository.Object, _mockUserPunctuationSourceRepository.Object, _mockUserRepository.Object, _mockLogger.Object, _mockOrderRepository.Object, _mockOrderItemRepository.Object, _mockOrderStatusRepository.Object, _mockUnitOfWork.Object, _mockShopUserRepository.Object, _mapper); var result = await service.DoRescue(rescueRequest); Assert.False(result.Success); Assert.Equal("suspeita de fraude por tentativa de gerar pedidos em um pequeno intervalo de tempo", result.Message); }
public async Task <IActionResult> Order([FromBody] RescueRequestDto rescueRequestDto) { try { var result = await _orderService.DoRescue(rescueRequestDto); if (!result.Success) { return(BadRequest(result)); } return(Ok(result)); } catch (Exception ex) { #if (!DEBUG) _logger.Fatal($"Tentativa de gerar pedido do cpf :{rescueRequestDto.Cpf} - {ex.ToLogString(Environment.StackTrace)}"); #endif return(BadRequest($"Tentativa de gerar pedido do cpf :{rescueRequestDto.Cpf} - {ex.ToLogString(Environment.StackTrace)}")); } }
public async Task <RescueResponseDto <Order> > DoRescue(RescueRequestDto rescueRequestDto) { var user = await _userRepository.CustomFind(x => x.Cpf.Equals(rescueRequestDto.Cpf) && (x.UserStatus.Id == (int)UserStatusEnum.Active || x.UserStatus.Id == (int)UserStatusEnum.OnlyCatalog)); _logger.Info($"resgate para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - iniciada"); if (!user.Any()) { _logger.Info($"resgate para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - usuario invalido"); return(new RescueResponseDto <Order> { Success = false, Message = "usuario invalido" }); } var lastRescue = await _orderRepository.GetLast(x => x.User.Cpf.Equals(rescueRequestDto.Cpf), x => x.Id); if (lastRescue != null && (DateTime.Now - lastRescue.CreatedAt).TotalMinutes < 2) { _logger.Fatal($"resgate para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - suspeita de fraude por tentativa de gerar pedidos em um pequeno intervalo de tempo"); return(new RescueResponseDto <Order> { Success = false, Message = "suspeita de fraude por tentativa de gerar pedidos em um pequeno intervalo de tempo" }); } if (!rescueRequestDto.RescueRequestItems.Any()) { _logger.Info($"resgate para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - pedido não possue itens"); return(new RescueResponseDto <Order> { Success = false, Message = "pedido não possue itens" }); } var balance = (await _userPunctuationRepository.CustomFind(x => x.User.Id == user.First().Id)).Sum(x => x.Punctuation); var order = new Order(); if (balance < rescueRequestDto.Total) { _logger.Info($"autorizacao de pedido para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - autorizacao recusada saldo insuficiente"); return(new RescueResponseDto <Order> { Success = false, Message = "Saldo insuficiente" }); } order = new Order { Activated = true, ConversionRate = rescueRequestDto.ConversionRate, CreatedAt = DateTime.Now, ExternalOrderId = rescueRequestDto.ExternalOrderId, Freight = rescueRequestDto.Freight, Login = rescueRequestDto.Cpf, ForecastDate = rescueRequestDto.ForecastDate, OrderStatus = await _orderStatusRepository.GetById((int)OrderStatusEnum.Confirmed), OrderValue = rescueRequestDto.OrderValue, Total = rescueRequestDto.Total, User = user.First() }; _orderRepository.Save(order); await _unitOfWork.CommitAsync(); _userPunctuationRepository.Save(new UserPunctuation { CreatedAt = DateTime.Now, CurrentMonth = DateTime.Now.Month, CurrentYear = DateTime.Now.Year, Description = "Pedido Confirmado", OperationType = 'D', Punctuation = -1 * rescueRequestDto.Total, ReferenceEntityId = order.Id, UserPunctuationSource = await _userPunctuationSourceRepository.GetById((int)SourceUserPunctuationEnum.OrderConfirmed), User = user.First() }); foreach (var item in rescueRequestDto.RescueRequestItems) { _orderItemRepository.Save(new OrderItem { Activated = true, Ammout = item.Ammout, Category = item.Category, CodeItem = item.CodeItem, CreatedAt = DateTime.Now, Department = item.Department, ExternalOrderId = rescueRequestDto.ExternalOrderId, Order = order, Partner = item.Partner, ProductName = item.ProductName, TotalValue = item.TotalValue, UnitValue = item.UnitValue }); } var confirmSaved = await _unitOfWork.CommitAsync(); if (confirmSaved) { order.User = null; _logger.Info($"autorizacao de pedido para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - Pedido gerado com sucesso!"); return(new RescueResponseDto <Order> { Success = true, Message = "Pedido gerado com sucesso!", Data = new List <Order> { order } }); } else { _logger.Info($"autorizacao de pedido para login {rescueRequestDto.Cpf} com codigo externo {rescueRequestDto.ExternalOrderId} - autorizacao recusada ocorreu erro ao tentar gerar o pedido"); return(new RescueResponseDto <Order> { Success = false, Message = "ocorreu erro ao tentar gerar o pedido" }); } }