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);
        }
Exemple #2
0
        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());
        }
Exemple #3
0
        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());
        }
Exemple #4
0
        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));
        }
Exemple #5
0
        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
                }));
            }
        }
Exemple #6
0
        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,
            }));
        }