public virtual RefugeeOutputDto GetRefugee(Guid id)
        {
            if (id == default(Guid))
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.InvalidIdentifier, new ArgumentException(Constants.Messages.InvalidIdentifier, nameof(id)));
            }

            RefugeeModel refugee;

            HotSpot hotSpot;

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                refugee = unitOfWork.RefugeeRepository.GetById(id);

                if (refugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                hotSpot = unitOfWork.HotSpotRepository.GetByRefugee(refugee);
            }

            RefugeeOutputDto refugeeOutputDto = Mapper.Map <RefugeeModel, RefugeeOutputDto>(refugee);

            refugeeOutputDto.HotSpot = Mapper.Map <HotSpot, HotSpotOutputDto>(hotSpot);

            return(refugeeOutputDto);
        }
        public virtual RefugeeOutputDto CreateRefugee(CreateRefugeeInputDto createRefugeeInputDto)
        {
            if (createRefugeeInputDto == null)
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.MissingInputDto, new ArgumentNullException(nameof(createRefugeeInputDto)));
            }

            try
            {
                CreateRefugeeInputDtoValidator.ValidateAndThrow(createRefugeeInputDto);
            }
            catch (ValidationException exception)
            {
                throw new RestException(HttpStatusCode.BadRequest, exception.Message, exception);
            }

            RefugeeModel refugee;

            HotSpot hotSpot;

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                unitOfWork.BeginTransaction();

                hotSpot = unitOfWork.HotSpotRepository.GetById(createRefugeeInputDto.HotSpotId);

                if (hotSpot == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                refugee = Mapper.Map <CreateRefugeeInputDto, RefugeeModel>(createRefugeeInputDto);

                unitOfWork.RefugeeRepository.Save(refugee);

                unitOfWork.HotSpotRelationshipManager.Relate(refugee, hotSpot);

                unitOfWork.CommitTransaction();
            }

            RefugeeOutputDto refugeeOutputDto = Mapper.Map <RefugeeModel, RefugeeOutputDto>(refugee);

            refugeeOutputDto.HotSpot = Mapper.Map <HotSpot, HotSpotOutputDto>(hotSpot);

            return(refugeeOutputDto);
        }
        public virtual IList <RefugeeOutputDto> GetRefugees()
        {
            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                IList <RefugeeWithHotSpot> refugeeWithHotSpots = unitOfWork.RefugeeRepository.GetRefugeesWithHotSpots();

                IList <RefugeeOutputDto> refugeeOutputDtos = new List <RefugeeOutputDto>();

                foreach (RefugeeWithHotSpot refugeeWithHotSpotPair in refugeeWithHotSpots)
                {
                    RefugeeOutputDto refugeeOutputDto = Mapper.Map <RefugeeModel, RefugeeOutputDto>(refugeeWithHotSpotPair.Refugee);

                    refugeeOutputDto.HotSpot = Mapper.Map <HotSpot, HotSpotOutputDto>(refugeeWithHotSpotPair.HotSpot);

                    refugeeOutputDtos.Add(refugeeOutputDto);
                }

                return(refugeeOutputDtos);
            }
        }
        public virtual IList <RefugeeOutputDto> GetAdultRefugeesWithNoFamily()
        {
            int currentYear = DateTime.UtcNow.Year;

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                IList <RefugeeWithHotSpot> refugeeWithHotSpots = unitOfWork.RefugeeRepository.GetRefugeesWithNoFamilyAndWithHotSpots();

                refugeeWithHotSpots = refugeeWithHotSpots.Where(o => (currentYear - o.Refugee.BirthYear) >= Properties.Settings.Default.UnderageAgeThreshold).ToList();

                IList <RefugeeOutputDto> refugeeOutputDtos = new List <RefugeeOutputDto>();

                foreach (RefugeeWithHotSpot refugeeWithHotSpotPair in refugeeWithHotSpots)
                {
                    RefugeeOutputDto refugeeOutputDto = Mapper.Map <RefugeeModel, RefugeeOutputDto>(refugeeWithHotSpotPair.Refugee);

                    refugeeOutputDto.HotSpot = Mapper.Map <HotSpot, HotSpotOutputDto>(refugeeWithHotSpotPair.HotSpot);

                    refugeeOutputDtos.Add(refugeeOutputDto);
                }

                return(refugeeOutputDtos);
            }
        }
        public virtual RefugeeOutputDto UpdateRefugee(Guid id, [FromBody] UpdateRefugeeInputDto updateRefugeeInputDto)
        {
            if (id == default(Guid))
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.InvalidIdentifier, new ArgumentException(Constants.Messages.InvalidIdentifier, nameof(id)));
            }

            if (updateRefugeeInputDto == null)
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.MissingInputDto, new ArgumentNullException(nameof(updateRefugeeInputDto)));
            }

            if (updateRefugeeInputDto.GenderType.HasValue && !Enum.IsDefined(typeof(GenderType), updateRefugeeInputDto.GenderType))
            {
                throw new RestException(HttpStatusCode.BadRequest, "The provided gender type is not supported.", new ArgumentException("The value of the gender type is not defined in the enumeration."));
            }

            try
            {
                UpdateRefugeeInputDtoValidator.ValidateAndThrow(updateRefugeeInputDto);
            }
            catch (ValidationException exception)
            {
                throw new RestException(HttpStatusCode.BadRequest, exception.Message, exception);
            }

            RefugeeModel refugee;

            HotSpot hotSpot;

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                unitOfWork.BeginTransaction();

                refugee = unitOfWork.RefugeeRepository.GetById(id);

                if (refugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                hotSpot = unitOfWork.HotSpotRepository.GetByRefugee(refugee);

                if (updateRefugeeInputDto.HotSpotId.HasValue && hotSpot.Id != updateRefugeeInputDto.HotSpotId.Value)
                {
                    hotSpot = unitOfWork.HotSpotRepository.GetById(updateRefugeeInputDto.HotSpotId.Value);

                    if (hotSpot == null)
                    {
                        throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                    }

                    unitOfWork.HotSpotRelationshipManager.UnRelate(refugee);

                    unitOfWork.HotSpotRelationshipManager.Relate(refugee, hotSpot);
                }

                if (updateRefugeeInputDto.Name != null)
                {
                    refugee.Name = updateRefugeeInputDto.Name;
                }

                if (updateRefugeeInputDto.Nationality != null)
                {
                    refugee.Nationality = updateRefugeeInputDto.Nationality;
                }

                if (updateRefugeeInputDto.Passport != null)
                {
                    refugee.Passport = updateRefugeeInputDto.Passport;
                }

                if (updateRefugeeInputDto.BirthYear.HasValue)
                {
                    refugee.BirthYear = updateRefugeeInputDto.BirthYear.Value;
                }

                if (updateRefugeeInputDto.GenderType.HasValue)
                {
                    refugee.GenderType = (GenderType)updateRefugeeInputDto.GenderType.Value;
                }

                unitOfWork.RefugeeRepository.Update(refugee);

                unitOfWork.CommitTransaction();
            }

            RefugeeOutputDto refugeeOutputDto = Mapper.Map <RefugeeModel, RefugeeOutputDto>(refugee);

            refugeeOutputDto.HotSpot = Mapper.Map <HotSpot, HotSpotOutputDto>(hotSpot);

            return(refugeeOutputDto);
        }