public async Task <TransactionToken> GenerateToken(Guid transactionId, TokenType type) { var(login, user) = await _userDataManager.AddCurrentUserIfNeeded(); var tokenString = _stringGenerator.GenerateIdentifier(100, CharsInToken.CapitalSmallNumeric_); var token = new TransactionToken { TransactionTokenId = Guid.NewGuid(), IssuedAtUtc = DateTime.UtcNow, UseAfterUtc = DateTime.UtcNow, UseBeforeUtc = DateTime.UtcNow.AddDays(6), Status = TokenStatus.Ok, Token = tokenString, Type = type, IssuerLoginId = login.LoginId }; if (type == TokenType.Receiving) { token.RegistrationId = transactionId; } else if (type == TokenType.Returning) { token.ReceivingId = transactionId; } var model = _tokensRepo.Add(token); await _tokensRepo.SaveChangesAsync(); return(model); }
public async Task <CommandResult> AddLike(AddLikeDto addLikeDto) { if (addLikeDto is null) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.ADD.NULL", Message = "Please send valid information", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var(login, user) = await _userDataManager.AddCurrentUserIfNeeded(); if (user?.UserId is null) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.ADD.UNAUTHORIZED", Message = "You are not authorized to execute this request", StatusCode = System.Net.HttpStatusCode.Unauthorized, })); } var @object = _objectsRepo.Get(addLikeDto.ObjectId); if (@object is null || @object.ObjectStatus != ObjectStatus.Available) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.ADD.UNAVAILABLE", Message = "This object is unavailable", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var previousLikes = _likesRepository.Table.Where(ol => ol.Login.UserId == user.UserId && ol.ObjectId == addLikeDto.ObjectId).ToList(); if (!previousLikes.IsNullOrEmpty()) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.ADD.ALREADY.LIKED", Message = "You already liked this object", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } _likesRepository.Add(new ObjectLike { LikedAtUtc = DateTime.UtcNow, ObjectLikeId = Guid.NewGuid(), LoginId = login.LoginId, ObjectId = addLikeDto.ObjectId }); await _likesRepository.SaveChangesAsync(); return(new CommandResult()); }
public async Task <CommandResult> Unlike(AddLikeDto removeLikeDto) { if (removeLikeDto is null) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.ADD.NULL", Message = "Please send valid information", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var(login, user) = await _userDataManager.AddCurrentUserIfNeeded(); if (user?.UserId is null) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.REMOVE.UNAUTHORIZED", Message = "You are not authorized to execute this request", StatusCode = System.Net.HttpStatusCode.Unauthorized, })); } var @object = _objectsRepo.Get(removeLikeDto.ObjectId); if (@object is null || @object.ObjectStatus != ObjectStatus.Available) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.REMOVE.UNAVAILABLE", Message = "This object is unavailable", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var previousLikes = _likesRepo.Table.Where(ol => ol.Login.UserId == user.UserId && ol.ObjectId == removeLikeDto.ObjectId).ToList(); if (previousLikes.IsNullOrEmpty()) { return(new CommandResult(new ErrorMessage { ErrorCode = "CATALOG.LIKE.REMOVE.NO.PREVIOUS.LIKE", Message = "You have not liked this object before", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } _likesRepo.Delete(previousLikes.SingleOrDefault()); await _likesRepo.SaveChangesAsync(); return(new CommandResult()); }
public async Task <CommandResult <OfferedObject> > AddObject(AddObjectDto objectDto) { if (objectDto is null) { return(new CommandResult <OfferedObject>(new ErrorMessage { ErrorCode = "OBJECT.ADD.NULL", Message = "Please fill the field with data", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (objectDto.ObjectName.IsNullOrEmpty()) { return(new CommandResult <OfferedObject>(new ErrorMessage { ErrorCode = "OBJECT.ADD.OBJECTNAME.EMPTY", Message = "Please fill the 'object name' field", StatusCode = System.Net.HttpStatusCode.BadRequest })); } // Description could be null if (objectDto.Tags is null || objectDto.Tags.Count < 2) { return(new CommandResult <OfferedObject>(new ErrorMessage { ErrorCode = "OBJECT.ADD.TAGS.TOO.FEW", Message = "Please add at least two tags", StatusCode = System.Net.HttpStatusCode.BadRequest })); } var invalidTags = from t in objectDto.Tags where t.IsNullOrEmpty() || t.Length < 4 select t; if (invalidTags.Any()) { return(new CommandResult <OfferedObject>(new ErrorMessage { ErrorCode = "OBJECT.ADD.TAGS.INVALID", Message = "Please send a valid tags", StatusCode = System.Net.HttpStatusCode.BadRequest })); } var alreadyExistedTags = (from t in _tagRepo.Table where objectDto.Tags.Any(tt => tt == t.Name) && t.TagStatus == TagStatus.Ok select t).ToList(); // No Logic for not existed tags, just discard them. var objectTags = alreadyExistedTags.Select(t => new ObjectTag { TagId = t.TagId }).ToList(); var(login, ownerUser) = await _userDataManager.AddCurrentUserIfNeeded(); var @object = new OfferedObject { Description = objectDto.Description, Name = objectDto.ObjectName, PublishedAt = DateTime.UtcNow, Tags = objectTags, OwnerLoginId = login.LoginId, CurrentTransactionType = objectDto.Type }; _objectRepo.Add(@object); _objectRepo.SaveChanges(); return(new CommandResult <OfferedObject>(@object)); }
public async Task <CommandResult <ObjectComment> > AddComment(AddCommentDto comment) { var login = await _userDataManager.AddCurrentUserIfNeeded(); if (login.Item1 is null) { return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.ADD.COMMENT.NOT.AUTHORIZED", Message = "You are not authorized to do this request", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } if (comment is null) { return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.ADD.COMMENT.NULL", Message = "Please fill out the fields", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (comment.Comment.IsNullOrEmpty()) { return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.ADD.COMMENT.COMMENT.NULL", Message = "Please fill the comment field", StatusCode = System.Net.HttpStatusCode.BadRequest })); } var @object = _objectRepo.Get(comment.ObjectId); if (@object is null) { return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.ADD.COMMENT.OBJECT.NOT.EXISTS", Message = "The object you are trying to add comment to dose not exists", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (@object is null || @object.ObjectStatus != ObjectStatus.Available) { return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.DOES.NOT.EXISTS", Message = "You are not authorized to add a photo to this object", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } var commentModel = new ObjectComment { ObjectCommentId = Guid.NewGuid(), AddedAtUtc = DateTime.UtcNow, UpdatedAtUtc = DateTime.UtcNow, Comment = comment.Comment, ObjectId = comment.ObjectId, LoginId = login.Item1.LoginId }; try { var model = _commentRepo.Add(commentModel); await _commentRepo.SaveChangesAsync(); return(new CommandResult <ObjectComment>(model)); } catch (Exception e) { _logger.LogError(e, $"There were an error while adding comment to object:{comment.ObjectId}, comment:{comment.Comment}"); return(new CommandResult <ObjectComment>(new ErrorMessage { ErrorCode = "OBJECT.ADD.INTERNAL.SERVER.ERROR", Message = "There were an error while trying to add a comment", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } }
public async Task <CommandResult <ObjectRegistrationDto> > AddNewRegistrationAsync(AddNewRegistrationDto newRegistrationDto) { var user = await _userDataManager.AddCurrentUserIfNeeded(); if (user.Login == null) { return(new ErrorMessage() { ErrorCode = "TRANSACTION.OBJECT.RESERVE.NOT.AUTHORIZED", Message = "You are not authorized to do this operation", StatusCode = System.Net.HttpStatusCode.Unauthorized }.ToCommand <ObjectRegistrationDto>()); } if (newRegistrationDto is null) { return(new ErrorMessage() { ErrorCode = "TRANSACTION.OBJECT.RESERVE.NULL", Message = "Please send a valid information", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectRegistrationDto>()); } var @object = await _objectDataManager.GetObjectAsync(newRegistrationDto.ObjectId); if (@object is null) { return(new ErrorMessage() { ErrorCode = "TRANSACTION.OBJECT.RESERVE.NOT.EXISTS", Message = "The object specified does not exists", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectRegistrationDto>()); } // Should Not Return and is not taken right now if ([email protected]) { var receivings = from receiving in _objectReceiving.Table where receiving.ObjectRegistration.ObjectId == @object.OfferedObjectId select receiving; // If The object has receiving and all of them has returnings if (receivings.Any(r => r.ObjectReturning == null)) { return(ObjectNotAvailable.ToCommand <ObjectRegistrationDto>()); } } // See Previous registrations var existingRegistrations = from registration in _registrationsRepo.Table where registration.RecipientLogin.UserId == user.User.UserId && registration.ObjectId == @object.OfferedObjectId select registration; // If The user taken and has this object OR If the user has another registeration pending receiving if (existingRegistrations.Any(reg => reg.ObjectReceiving == null || reg.ObjectReceiving.ObjectReturning == null)) { return(ObjectNotAvailable.ToCommand <ObjectRegistrationDto>()); } TimeSpan?shouldReturnItAfter; if (@object.ShouldReturn) { // If the object should return but the user has not specified the time he should return the object if (!newRegistrationDto.ShouldReturnAfter.HasValue) { return(new ErrorMessage { ErrorCode = "TRANSACTION.OBJECT.RESERVE.SHOULDRETURN.NULL", Message = "Please specify when you will return this object", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectRegistrationDto>()); } if (@object.HourlyCharge.HasValue) { shouldReturnItAfter = new TimeSpan(newRegistrationDto.ShouldReturnAfter.Value, 0, 0); } else { if (newRegistrationDto.ShouldReturnAfter > maximumHoursForFreeLending) { shouldReturnItAfter = new TimeSpan(maximumHoursForFreeLending, 0, 0); } else { shouldReturnItAfter = new TimeSpan(newRegistrationDto.ShouldReturnAfter.Value, 0, 0); } } } else { shouldReturnItAfter = null; } var registrationModel = new ObjectRegistration { ObjectRegistrationId = Guid.NewGuid(), RegisteredAtUtc = DateTime.UtcNow, ExpiresAtUtc = DateTime.UtcNow.AddHours(maximumHoursForReservationExpiration), ObjectId = @object.OfferedObjectId, Status = ObjectRegistrationStatus.OK, RecipientLoginId = user.Login.LoginId, ShouldReturnItAfter = shouldReturnItAfter, }; _registrationsRepo.Add(registrationModel); await _registrationsRepo.SaveChangesAsync(); var integrationEvent = new NewRegistrationIntegrationEvent() { Id = Guid.NewGuid(), OccuredAt = registrationModel.RegisteredAtUtc, ObjectId = @object.OriginalObjectId, RecipiantId = user.User.UserId.ToString(), ShouldReturn = @object.ShouldReturn, RegisteredAt = registrationModel.RegisteredAtUtc, RegistrationId = registrationModel.ObjectRegistrationId }; // Broadcast an event; _eventBus.Publish(integrationEvent); var token = await _tokenManager.GenerateToken(registrationModel.ObjectRegistrationId, TokenType.Receiving); var dto = new ObjectRegistrationDto { ObjectId = registrationModel.Object.OriginalObjectId, RegistrationId = registrationModel.ObjectRegistrationId, ShouldBeReturnedAfterReceving = registrationModel.ShouldReturnItAfter, RegistrationExpiresAtUtc = registrationModel.ExpiresAtUtc, RegistrationToken = new RegistrationTokenResultDto { RegistrationToken = token.Token, CreatedAtUtc = token.IssuedAtUtc, UseBeforeUtc = token.UseBeforeUtc } }; return(new CommandResult <ObjectRegistrationDto>(dto)); }
public async Task <IActionResult> ReturnObject([FromBody] AddObjectReturningDto returnDto) { if (returnDto == null || returnDto.ReturningToken.IsNullOrEmpty()) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.NULL", Message = "Please send valid data", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var(login, user) = await userDataManager.AddCurrentUserIfNeeded(); if (login is null) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.UNAUTHOROIZED", Message = "You are not authorized to make this request", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } var authResult = _transactionOwnershipAuthorizer.IsAuthorized(tt => tt.Type == TokenType.Returning && tt.Token == returnDto.ReturningToken, tt => tt.Receiving.ObjectRegistration.Object.OwnerUser); if (!authResult) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.UNAUTHOROIZED", Message = "You are not authorized to make this request", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } var theToken = (from t in _tokensRepo.Table where t.Token == returnDto.ReturningToken && t.Type == TokenType.Returning select t).FirstOrDefault(); if (theToken == null) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.NOT.EXISTS", Message = "The QR code provided is faulty", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (!(theToken.UseAfterUtc < DateTime.UtcNow && theToken.UseBeforeUtc > DateTime.UtcNow)) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.TOKEN.EXPIRED", Message = "The QR code provided is too old", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (theToken.Status != TokenStatus.Ok) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.TOKEN.USED", Message = "The QR code provided is already used", StatusCode = System.Net.HttpStatusCode.BadRequest })); } var theReceiving = (from rc in _receivingsRepo.Table where rc.Tokens.Any(returningToken => returningToken.Token == returnDto.ReturningToken) select rc).Include(rc => rc.ObjectRegistration).FirstOrDefault(); if (theReceiving is null) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.NOT.EXISTS", Message = "The QR provided is faulty", StatusCode = System.Net.HttpStatusCode.BadRequest })); } if (theReceiving.ObjectReturning is object) { return(StatusCode(new ErrorMessage { ErrorCode = "TRANSACTION.RETURNING.ADD.TOKEN.USED", Message = "The QR code provided is already used", StatusCode = System.Net.HttpStatusCode.BadRequest })); } theToken.Status = TokenStatus.Used; var returning = new ObjectReturning { ReturnedAtUtc = DateTime.UtcNow, LoanerLoginId = login.LoginId, LoaneeLoginId = theToken.IssuerLoginId, ObjectReceivingId = theReceiving.ObjectReceivingId, ObjectReturningId = Guid.NewGuid() }; _returningRepo.Add(returning); // This will save theToken.Status also await _returningRepo.SaveChangesAsync(); var returnedAfter = DateTime.UtcNow - theReceiving.ReceivedAtUtc; var evnt = new TransactionReturnedIntegrationEvent() { Id = Guid.NewGuid(), OccuredAt = DateTime.UtcNow, RegistrationId = theReceiving.ObjectRegistrationId, ReturnedAtUtc = DateTime.UtcNow, ReturnIdId = returning.ObjectReturningId, }; _eventBus.Publish(evnt); TimeSpan late = new TimeSpan(); if (theReceiving.ObjectRegistration.ShouldReturnItAfter.HasValue) { late = DateTime.UtcNow - theReceiving.ReceivedAtUtc.Add(theReceiving.ObjectRegistration.ShouldReturnItAfter.Value); // if the value is nigative (not late) if (late.TotalSeconds < 0) { late = new TimeSpan(0); } } var charge = theReceiving.HourlyCharge is null ? null : (float?)(theReceiving.HourlyCharge * returnedAfter.TotalHours); DateTime?shouldBeReturnedAtUtc = null; if (theReceiving.ObjectRegistration.ShouldReturnItAfter.HasValue) { shouldBeReturnedAtUtc = theReceiving.ReceivedAtUtc.Add(theReceiving.ObjectRegistration.ShouldReturnItAfter.Value); } return(Ok(new AddObjectReturningResultDto { RegistrationId = theReceiving.ObjectRegistrationId, ReceivingId = theReceiving.ObjectReceivingId, ReturningId = returning.ObjectReturningId, Late = late, ReturnedAfter = returnedAfter, ShouldPay = charge, RegisteredAtUtc = theReceiving.ObjectRegistration.RegisteredAtUtc, ReceivedAtUtc = theReceiving.ReceivedAtUtc, ReturnedAtUtc = returning.ReturnedAtUtc, ShouldBeReturnedAtUtc = shouldBeReturnedAtUtc })); }
public async Task <CommandResult <ObjectReceivingResultDto> > AddReceiving(AddReceivingDto addReceivingDto) { if (addReceivingDto == null || addReceivingDto.RegistrationToken.IsNullOrEmpty()) { return(new CommandResult <ObjectReceivingResultDto>(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.NULL", Message = "Please send valid data", StatusCode = System.Net.HttpStatusCode.BadRequest, })); } var(login, user) = await userDataManager.AddCurrentUserIfNeeded(); if (login is null) { return(new CommandResult <ObjectReceivingResultDto>(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.UNAUTHOROIZED", Message = "You are not authorized to make this request", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } var authResult = _ownershipAuthorization.IsAuthorized(tt => tt.Type == TokenType.Receiving && tt.Token == addReceivingDto.RegistrationToken, tt => tt.Registration.Object.OwnerUser); if (!authResult) { return(new CommandResult <ObjectReceivingResultDto>(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.UNAUTHOROIZED", Message = "You are not authorized to make this request", StatusCode = System.Net.HttpStatusCode.Unauthorized })); } var theToken = (from t in _tokensRepo.Table where t.Token == addReceivingDto.RegistrationToken && t.Type == TokenType.Receiving select t).FirstOrDefault(); if (theToken == null) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.NOT.EXISTS", Message = "The QR code provided is faulty", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } if (!(theToken.UseAfterUtc < DateTime.UtcNow && theToken.UseBeforeUtc > DateTime.UtcNow)) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.TOKEN.EXPIRED", Message = "The QR code provided is too old", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } if (theToken.Status != TokenStatus.Ok) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.TOKEN.INVALID", Message = "The QR code provided is too old", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } var theRegistration = (from rg in _registrationsRepo.Table where rg.Tokens.Any(rt => rt.Token == addReceivingDto.RegistrationToken) select rg).FirstOrDefault(); if (theRegistration is null) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.NOT.EXISTS", Message = "The QR code provided is faulty", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } if (theRegistration.ObjectReceiving is object) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.TOKEN.USED", Message = "The QR code provided is already used", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } var objectRegistrations = from rg in _registrationsRepo.Table where rg.ObjectId == theRegistration.ObjectId select rg; // if not all of them returned or not received if (!objectRegistrations.All(or => or.ObjectReceiving == null || or.ObjectReceiving.ObjectReturning != null)) { return(new ErrorMessage { ErrorCode = "TRANSACTION.RECEIVING.ADD.OBJECT.TAKEN", Message = "Do you even have the object?", StatusCode = System.Net.HttpStatusCode.BadRequest }.ToCommand <ObjectReceivingResultDto>()); } theToken.Status = TokenStatus.Used; var receiving = new ObjectReceiving { ReceivedAtUtc = DateTime.UtcNow, GiverLoginId = login.LoginId, RecipientLoginId = theToken.IssuerLoginId, HourlyCharge = 0f, ObjectRegistrationId = theRegistration.ObjectRegistrationId, ObjectReceivingId = Guid.NewGuid(), }; _receivingsRepo.Add(receiving); // this will save theToken.Status also await _receivingsRepo.SaveChangesAsync(); var evnt = new TransactionReceivedIntegrationEvent { Id = Guid.NewGuid(), OccuredAt = DateTime.UtcNow, ReceivedAtUtc = receiving.ReceivedAtUtc, ReceivingId = receiving.ObjectReceivingId, RegistrationId = receiving.ObjectRegistrationId, }; _eventBus.Publish(evnt); // Publish the event return(new CommandResult <ObjectReceivingResultDto>(new ObjectReceivingResultDto { ObjectId = _objectRepo.Get(theRegistration.ObjectId).OriginalObjectId, ReceivedAtUtc = receiving.ReceivedAtUtc, RegistrationId = theRegistration.ObjectRegistrationId, ShouldBeReturnedAfterReceving = theRegistration.ShouldReturnItAfter, })); }