public async Task <int> Create(ReservationRequest request, bool booking, int userId)
        {
            var device = await _dbContext.Devices
                         .FirstOrDefaultAsync(x => x.Id == request.DeviceId);

            if (device == null)
            {
                throw new InvalidDeviceException();
            }

            DateTime roundFrom = booking ? request.From : RoundTime(request.From);
            DateTime roundTo   = RoundTime(request.To);

            await CheckIfDateAvailable(request.From, request.To, device);

            var newItem = new Reservation
            {
                UserId   = userId,
                Status   = request.Status,
                DeviceId = device.Id,
                From     = roundFrom,
                To       = roundTo,
            };

            _dbContext.Reservations.Add(newItem);
            Action eventAction = Action.Reserved;

            if (booking)
            {
                eventAction      = Action.Booked;
                device.Available = false;
                device.UserId    = userId;
            }

            await _dbContext.Events.AddAsync(new Event
            {
                Action    = eventAction,
                OfficeId  = device.OfficeId,
                UserId    = userId,
                CreatedOn = DateTime.UtcNow,
                DeviceId  = request.DeviceId,
            });

            await _dbContext.SaveChangesAsync();

            return(newItem.Id);
        }
        public async Task Update(int id, ReservationUpdateRequest request, int userId)
        {
            var item = await _dbContext.Reservations
                       .FirstOrDefaultAsync(x => x.Id == id);

            if (item == null)
            {
                throw new InvalidReservationException();
            }

            var device = await _dbContext.Devices
                         .FirstOrDefaultAsync(x => x.Id == request.DeviceId);

            if (device == null)
            {
                throw new InvalidDeviceException();
            }

            Action eventAction = Action.ReservationCanceled;
            int    officeId    = device.OfficeId;

            if (request.Status == Status.CheckedIn)
            {
                device.UserId    = userId;
                device.Available = false;
                eventAction      = Action.CheckedIn;
            }

            if (request.Status == Status.Completed)
            {
                var office = await _dbContext.Offices
                             .AsNoTracking()
                             .FirstOrDefaultAsync(x => x.Id == request.OfficeId);

                if (office == null)
                {
                    throw new InvalidOfficeException();
                }

                eventAction = item.Status == Status.OverDue ? Action.ReturnedLate : Action.Returned;
                officeId    = office.Id;

                device.UserId    = null;
                device.Available = true;
                device.OfficeId  = request.OfficeId.Value;
            }

            await _dbContext.Events.AddAsync(new Event
            {
                Action    = eventAction,
                OfficeId  = officeId,
                UserId    = userId,
                CreatedOn = DateTime.UtcNow,
                DeviceId  = request.DeviceId,
            });

            item.Status   = request.Status;
            item.DeviceId = device.Id;
            item.UserId   = userId;
            item.From     = request.From;
            item.To       = request.To;

            await _dbContext.SaveChangesAsync();
        }