diff --git a/app/controllers/api/v1/doctors_controller.rb b/app/controllers/api/v1/doctors_controller.rb new file mode 100644 index 0000000..0a01acc --- /dev/null +++ b/app/controllers/api/v1/doctors_controller.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true +module Api + module V1 + class DoctorsController < ApplicationController + def all_data + + doctor_profiles = DoctorProfile.includes(services: { establishment: :address }, establishments: :address) + services = Service.includes(:doctor_profile, establishment: :address) + establishments = Establishment.includes(:address) + + + render json: { + doctors: doctor_profiles.map { |doctor| + { + id: doctor.id, + name: doctor.name, + specialization_id: doctor.specialization_id, + degree_id: doctor.degree_id, + institute_id: doctor.institute_id, + gender: doctor.gender, + date_of_birth: doctor.date_of_birth, + year_of_experience: doctor.year_of_experience, + establishments: doctor.establishments.map { |establishment| + { + id: establishment.id, + name: establishment.name, + city: establishment.address&.city, + address: "#{establishment.address&.address_line_1}, #{establishment.address&.address_line_2}" + } + }, + services: doctor.services.map { |service| + { + id: service.id, + name: service.name, + day_of_week: service.day_of_week, + amount_cents: service.amount_cents, + amount_currency: service.amount_currency, + start_time: service.start_time, + end_time: service.end_time, + establishment_id: service.establishment_id, + city: service.establishment&.address&.city, + doctor_name: doctor.name + } + } + } + }, + services: services.map { |service| + { + id: service.id, + name: service.name, + day_of_week: service.day_of_week, + amount_cents: service.amount_cents, + amount_currency: service.amount_currency, + start_time: service.start_time, + end_time: service.end_time, + establishment_id: service.establishment_id, + city: service.establishment&.address&.city, + doctor_name: service.doctor_profile.name + } + }, + establishments: establishments.map { |establishment| + { + id: establishment.id, + name: establishment.name, + city: establishment.address&.city, + address: "#{establishment.address&.address_line_1}, #{establishment.address&.address_line_2}" + } + } + }, status: :ok + end + def create + doctor_profile_params = params.require(:doctor_profile).permit( + :name, :specialization_id, :degree_id, :institute_id, :gender, :date_of_birth, + establishment_ids: [], + services_attributes: [:name, :day_of_week, :amount_cents, :establishment_id, :start_time, :end_time] + ) + + doctor_profile = DoctorProfile.new(doctor_profile_params) + + if doctor_profile.save + render json: { message: 'Doctor profile created successfully', doctor: doctor_profile }, status: :created + else + render json: { errors: doctor_profile.errors.full_messages }, status: :unprocessable_entity + end + end + def index + + doctor_profiles = DoctorProfile.includes(services: { establishment: :address }, establishments: :address) + + render json: doctor_profiles.map { |doctor| + { + id: doctor.id, + name: doctor.name, + specialization_id: doctor.specialization_id, + degree_id: doctor.degree_id, + institute_id: doctor.institute_id, + gender: doctor.gender, + date_of_birth: doctor.date_of_birth, + year_of_experience: doctor.year_of_experience, + establishments: doctor.establishments.map { |establishment| + { + id: establishment.id, + name: establishment.name, + city: establishment.address&.city, + address: "#{establishment.address&.address_line_1}, #{establishment.address&.address_line_2}" + } + }, + services: doctor.services.map { |service| + establishment = service.establishment + { + id: service.id, + name: service.name, + day_of_week: service.day_of_week, + amount_cents: service.amount_cents, + amount_currency: service.amount_currency, + start_time: service.start_time, + end_time: service.end_time, + establishment_id: service.establishment_id, + city: service.establishment&.address&.city + } + } + } + }, status: :ok + end + def by_city + city = params[:city] + + + establishments = Establishment.joins(:address) + .where(addresses: { city: city }) + + + doctor_profiles = DoctorProfile.joins(:doctor_establishments) + .where(doctor_establishments: { establishment_id: establishments.pluck(:id) }) + + + services = Service.joins(:doctor_profile, :establishment) + .where(doctor_profiles: { id: doctor_profiles.pluck(:id) }) + .where(establishments: { id: establishments.pluck(:id) }) + + + formatted_services = services.map do |service| + { + id: service.id, + name: service.name, + day_of_week: service.day_of_week, + amount_cents: service.amount_cents, + amount_currency: service.amount_currency, + start_time: service.start_time, + end_time: service.end_time, + establishment_id: service.establishment_id, + city: service.establishment.address.city, + doctor_name: service.doctor_profile.name + } + end + render json: { + doctors: doctor_profiles, + establishments: establishments.map { |establishment| + { + id: establishment.id, + name: establishment.name, + city: establishment.address.city, + address: "#{establishment.address.address_line_1}, #{establishment.address.address_line_2}" + } + }, + services: formatted_services + } + end + end + end + end diff --git a/app/controllers/api/v1/establishments_controller.rb b/app/controllers/api/v1/establishments_controller.rb new file mode 100644 index 0000000..f185f6b --- /dev/null +++ b/app/controllers/api/v1/establishments_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Api + module V1 + class EstablishmentsController < ApplicationController + def index + establishments = Establishment.includes(:address).all + render json: establishments.as_json(include: :address), status: :ok + end + + def by_city + city = params[:city] + establishments = Establishment.joins(:address).where(addresses: { city: city }) + render json: establishments.as_json(include: :address), status: :ok + end + end + end + end diff --git a/app/controllers/api/v1/services_controller.rb b/app/controllers/api/v1/services_controller.rb new file mode 100644 index 0000000..00e2fb6 --- /dev/null +++ b/app/controllers/api/v1/services_controller.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +module Api + module V1 + class ServicesController < ApplicationController + def index + services = Service.includes(establishment: :address).all + + render json: services.as_json( + only: [:id, :doctor_profile_id, :name, :day_of_week, :start_time, :end_time, :slot_length_in_minutes, :amount_cents, :amount_currency], + methods: :city_name + ), status: :ok + end + def by_city + city = params[:city] + services = Service.by_city(city) + + render json: services.as_json( + include: { + establishment: { + include: { address: { only: :city } }, + only: [:id, :name] + } + }, + only: [:id, :name, :doctor_profile_id, :day_of_week, :start_time, :end_time, :amount_cents, :amount_currency] + ), status: :ok + end + + end + end + end diff --git a/app/models/address.rb b/app/models/address.rb index a19addc..6ac5ed5 100644 --- a/app/models/address.rb +++ b/app/models/address.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true class Address < ApplicationRecord + has_many :establishments end diff --git a/app/models/doctor_establishment.rb b/app/models/doctor_establishment.rb index 8d1106e..94565df 100644 --- a/app/models/doctor_establishment.rb +++ b/app/models/doctor_establishment.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true class DoctorEstablishment < ApplicationRecord belongs_to :doctor_profile belongs_to :establishment diff --git a/app/models/doctor_profile.rb b/app/models/doctor_profile.rb index f5f3393..c6f2e68 100644 --- a/app/models/doctor_profile.rb +++ b/app/models/doctor_profile.rb @@ -1,6 +1,15 @@ +# frozen_string_literal: true class DoctorProfile < ApplicationRecord belongs_to :specialization, optional: true belongs_to :degree, optional: true belongs_to :institute, optional: true has_one :user -end \ No newline at end of file + + # Association for the join table + has_many :doctor_establishments + has_many :establishments, through: :doctor_establishments + + # Define the association with Service + has_many :services + accepts_nested_attributes_for :services +end diff --git a/app/models/establishment.rb b/app/models/establishment.rb index a8fc9a0..5f2407f 100644 --- a/app/models/establishment.rb +++ b/app/models/establishment.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true class Establishment < ApplicationRecord + belongs_to :address end diff --git a/app/models/institute.rb b/app/models/institute.rb index e13f9a3..ccf7d97 100644 --- a/app/models/institute.rb +++ b/app/models/institute.rb @@ -1,2 +1,3 @@ +# frozen_string_literal: true class Institute < ApplicationRecord end diff --git a/app/models/patient_profile.rb b/app/models/patient_profile.rb index a98b3f7..1df020a 100644 --- a/app/models/patient_profile.rb +++ b/app/models/patient_profile.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true class PatientProfile < ApplicationRecord belongs_to :address, optional: true has_one :user diff --git a/app/models/payment.rb b/app/models/payment.rb index d7493ce..a7b119b 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -11,4 +11,3 @@ class Payment < ApplicationRecord validates :stripe_id, presence: true, uniqueness: true validates :appointment_id, presence: true, uniqueness: true end - diff --git a/app/models/registration_council.rb b/app/models/registration_council.rb index ee3f00a..ee9da36 100644 --- a/app/models/registration_council.rb +++ b/app/models/registration_council.rb @@ -1,2 +1,3 @@ +# frozen_string_literal: true class RegistrationCouncil < ApplicationRecord end diff --git a/app/models/service.rb b/app/models/service.rb index 8fe9cb8..e6fa9f8 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -1,7 +1,23 @@ +# frozen_string_literal: true class Service < ApplicationRecord belongs_to :doctor_profile belongs_to :establishment enum day_of_week: { Monday: 0, Tuesday: 1, Wednesday: 2, Thursday: 3, Friday: 4, Saturday: 5, Sunday: 6 } monetize :amount_cents -end + + scope :by_city, ->(city) { + joins(establishment: :address).where(addresses: { city: city }) + } + + def city_name + establishment&.address&.city + end + + validates :name, presence: true + validates :day_of_week, presence: true + validates :amount_cents, presence: true + validates :establishment_id, presence: true + validates :start_time, presence: true + validates :end_time, presence: true +end diff --git a/config/routes.rb b/config/routes.rb index 7703399..dc578f1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions', @@ -15,4 +16,23 @@ # Defines the root path route ("/") # root "posts#index" + + namespace :api do + namespace :v1 do + resources :doctors, only: [:index] do + collection do + get 'all_data' + end + end + get 'doctors/by_city', to: 'doctors#by_city' + post 'doctors', to: 'doctors#create' + resources :services, only: [:index] + resources :establishments, only: [:index] + + + get 'establishments/by_city', to: 'establishments#by_city' + + get 'services/by_city', to: 'services#by_city' + end + end end diff --git a/db/schema.rb b/db/schema.rb index b812df4..e7ebb7e 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[7.1].define(version: 2024_11_06_140928) do +ActiveRecord::Schema[7.1].define(version: 2024_11_07_200448) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -76,8 +76,6 @@ t.string "maps_location" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "city" - t.string "address" t.index ["address_id"], name: "index_establishments_on_address_id" end