diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index f4dc350d..98ca6b08 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -2,6 +2,7 @@ class CustomersController < ApplicationController SORT_FIELDS = %w(name registered_at postal_code) before_action :parse_query_args + before_action :find_customer, only: [:show, :currently_checked_out, :checkout_history] def index if @sort @@ -18,6 +19,78 @@ def index ) end + def show + customer = Customer.find_by(id: params[:id]) + + if customer.nil? + return render json: {ok: false, message: "Customer not found", errors: ['Not Found']}, status: :not_found + end + + render json: customer.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone, :account_credit],methods: [:videos_checked_out_count]), status: :ok + end + + def currently_checked_out + message = "#{@customer.name} does not currently have any checked out videos" + videos = Video.parameterized_list(params[:sort], params[:n], params[:p]).filter { |video| video.rentals.any? {|rental| rental.customer == @customer && !rental.returned} } + if videos.empty? + render json: { + ok: true, + message: message, + errors: [message] + }, status: :ok + else + video_list = videos.map { |video| + found_rental = video.rentals.find {|rental| rental.customer == @customer && !rental.returned} + video_hash = { + title: video.title, + image_url: video.image_url, + overview: video.overview, + external_id: video.external_id, + release_date: video.release_date, + inventory: video.inventory, + checkout_date: found_rental.checkout_date, + checkin_date: found_rental.returned ? found_rental.checkin_date : nil, + due_date: found_rental.due_date, + available_inventory: video.available_inventory + } + video_hash + } + render json: video_list.as_json, status: :ok + end + return + end + + def checkout_history + message = "#{@customer.name} has not previously checked out any videos" + videos = Video.parameterized_list(params[:sort], params[:n], params[:p]).filter { |video| video.rentals.any? {|rental| rental.customer == @customer && rental.returned} } + if videos.empty? + render json: { + ok: true, + message: message, + errors: [message] + }, status: :ok + else + video_list = videos.map { |video| + found_rental = video.rentals.find {|rental| rental.customer == @customer && rental.returned } + video_hash = { + title: video.title, + image_url: video.image_url, + overview: video.overview, + external_id: video.external_id, + release_date: video.release_date, + inventory: video.inventory, + checkout_date: found_rental.checkout_date, + checkin_date: found_rental.returned ? found_rental.checkin_date : nil, + due_date: found_rental.due_date, + available_inventory: video.available_inventory + } + video_hash + } + render json: video_list.as_json, status: :ok + end + return + end + private def parse_query_args errors = {} @@ -30,4 +103,16 @@ def parse_query_args render status: :bad_request, json: { errors: errors } end end + + def customer_params + params.permit(:name, :registered_at, :address, :city, :state, :postal_code, :phone, :videos_checked_out_count) + end + + def find_customer + @customer = Customer.find_by(id: params[:id]) + + if @customer.nil? + return render json: {ok: false, message: "Customer not found", errors: ['Not Found']}, status: :not_found + end + end end diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index c36d8cd0..014eb916 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,8 +4,8 @@ class RentalsController < ApplicationController # TODO: make sure that wave 2 works all the way def check_out - rental = Rental.new(video: @video, customer: @customer, due_date: params[:due_date]) - + rental = Rental.new(video: @video, customer: @customer) + rental[:due_date] = Date.today + 7.days if rental.save render status: :ok, json: {} else @@ -22,6 +22,7 @@ def check_in } } end + rental.checkin_date = Date.today rental.returned = true if rental.save render status: :ok, json: {} diff --git a/app/controllers/videos_controller.rb b/app/controllers/videos_controller.rb index c9a2bb08..c190d408 100644 --- a/app/controllers/videos_controller.rb +++ b/app/controllers/videos_controller.rb @@ -1,7 +1,25 @@ class VideosController < ApplicationController - before_action :require_video, only: [:show] + before_action :require_video, only: [:show, :currently_checked_out_to, :checkout_history] + + def create + video = Video.new( + title: params[:title], + overview: params[:overview], + release_date: params[:release_date], + image_url: params[:image_url], + external_id: params[:external_id], + inventory: 1) + + if video.save + render status: :ok, json: {} + else + render status: :bad_request, json: { errors: video.errors.messages } + end + + end def index + if params[:query] data = VideoWrapper.search(params[:query]) else @@ -15,13 +33,86 @@ def show render( status: :ok, json: @video.as_json( - only: [:title, :overview, :release_date, :inventory], + only: [:title, :overview, :release_date, :inventory, :image_url], methods: [:available_inventory] ) ) end + def currently_checked_out_to + message = "#{@video.title} is not currently checked out to any customer" + # customers = @video.currently_checked_out_to + customers = Customer.parameterized_list(params[:sort], params[:n], params[:p]).filter { |customer| customer.rentals.any? {|rental| rental.video == @video && !rental.returned} } + if customers.empty? + render json: { + ok: true, + message: message, + errors: [message] + }, status: :ok + else + customer_list = customers.map { |customer| + found_rental = customer.rentals.find {|rental| rental.video == @video && !rental.returned } + customer_hash = { + id: customer.id, + name: customer.name, + registered_at: customer.registered_at, + address: customer.address, + city: customer.city, + state: customer.state, + postal_code: customer.postal_code, + phone: customer.postal_code, + account_credit: customer.account_credit, + videos_checked_out_count: customer.videos_checked_out_count, + checkout_date: found_rental.checkout_date, + checkin_date: found_rental.returned ? found_rental.checkin_date : nil, + due_date: found_rental.due_date, + } + customer_hash + } + render json: customer_list.as_json, status: :ok + end + return + end + + def checkout_history + message = "#{@video.title} has not been previously checked out to any customer" + # customers = @video.previously_checked_out_to + customers = Customer.parameterized_list(params[:sort], params[:n], params[:p]).filter { |customer| customer.rentals.any? {|rental| rental.video == @video && rental.returned} } + if customers.empty? + render json: { + ok: true, + message: message, + errors: [message] + }, status: :ok + else + customer_list = customers.map { |customer| + found_rental = customer.rentals.find {|rental| rental.video == @video && rental.returned } + customer_hash = { + id: customer.id, + name: customer.name, + registered_at: customer.registered_at, + address: customer.address, + city: customer.city, + state: customer.state, + postal_code: customer.postal_code, + phone: customer.postal_code, + account_credit: customer.account_credit, + videos_checked_out_count: customer.videos_checked_out_count, + checkout_date: found_rental.checkout_date, + checkin_date: found_rental.returned ? found_rental.checkin_date : nil, + due_date: found_rental.due_date, + } + customer_hash + } + render json: customer_list.as_json, status: :ok + end + return + end + private + def video_params + params.permit(:title, :overview, :release_date, :total_inventory, :available_inventory) + end def require_video @video = Video.find_by(title: params[:title]) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 10a4cba8..313dc900 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,3 +1,7 @@ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true + + def self.parameterized_list(sort = "id", n = 10, p = 1) + return self.all.order(sort).paginate(page: p, per_page: n) + end end diff --git a/config/environments/production.rb b/config/environments/production.rb index b4b82e6d..19cd9037 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -40,7 +40,7 @@ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true + config.force_ssl = true # Use the lowest log level to ensure availability of diagnostic information # when problems arise. diff --git a/config/routes.rb b/config/routes.rb index 16fc2214..7a661af1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,9 +1,13 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - resources :customers, only: [:index] + get 'customers/:id/current', to: "customers#currently_checked_out", as: "customer_current_videos" + get 'customers/:id/history', to: "customers#checkout_history", as: "customer_checkout_history" + resources :customers, only: [:index, :show] - resources :videos, only: [:index, :show], param: :title + get 'videos/:title/current', to: "videos#currently_checked_out_to", as: "video_current_customers" + get 'videos/:title/history', to: "videos#checkout_history", as: "video_checkout_history" + resources :videos, only: [:index, :show, :create], param: :title post "/rentals/:title/check-out", to: "rentals#check_out", as: "check_out" post "/rentals/:title/return", to: "rentals#check_in", as: "check_in" diff --git a/db/migrate/20210122023357_add_rental_check_in_date.rb b/db/migrate/20210122023357_add_rental_check_in_date.rb new file mode 100644 index 00000000..25d511aa --- /dev/null +++ b/db/migrate/20210122023357_add_rental_check_in_date.rb @@ -0,0 +1,5 @@ +class AddRentalCheckInDate < ActiveRecord::Migration[6.1] + def change + add_column(:rentals, :checkin_date, :date) + end +end diff --git a/db/schema.rb b/db/schema.rb index 38821b06..ef4a7766 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_07_06_194441) do +ActiveRecord::Schema.define(version: 2021_01_22_023357) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -36,6 +36,7 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "returned" + t.date "checkin_date" t.index ["customer_id"], name: "index_rentals_on_customer_id" t.index ["video_id"], name: "index_rentals_on_video_id" end