stay_commerce 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/stay/stripe_concern.rb +99 -64
  3. data/app/controllers/stay/admin/properties_controller.rb +1 -9
  4. data/app/controllers/stay/api/v1/credit_cards_controller.rb +33 -12
  5. data/app/controllers/stay/api/v1/messages_controller.rb +15 -10
  6. data/app/controllers/stay/api/v1/payments_controller.rb +73 -28
  7. data/app/controllers/stay/payments_controller.rb +13 -13
  8. data/app/models/stay/amenity.rb +2 -4
  9. data/app/models/stay/feature.rb +2 -3
  10. data/app/models/stay/property.rb +1 -1
  11. data/app/serializers/credit_card_serializer.rb +1 -2
  12. data/app/serializers/room_serializer.rb +1 -1
  13. data/app/views/stay/admin/amenities/index.html.erb +2 -2
  14. data/app/views/stay/admin/features/index.html.erb +2 -2
  15. data/app/views/stay/admin/properties/_description.html.erb +12 -53
  16. data/app/views/stay/admin/properties/_details.html.erb +2 -26
  17. data/app/views/stay/admin/properties/_form.html.erb +2 -34
  18. data/app/views/stay/admin/properties/_location.html.erb +6 -6
  19. data/app/views/stay/admin/properties/_sidebar.html.erb +7 -7
  20. data/app/views/stay/admin/properties/index.html.erb +0 -4
  21. data/app/views/stay/admin/properties/show.html.erb +0 -78
  22. data/app/views/stay/admin/rooms/_form.html.erb +42 -34
  23. data/app/views/stay/admin/rooms/index.html.erb +14 -14
  24. data/app/views/stay/admin/rooms/show.html.erb +15 -5
  25. data/config/initializers/stripe.rb +6 -6
  26. data/config/routes.rb +5 -1
  27. data/db/migrate/20250123053039_add_stripe_customer_id_to_stay_users.rb +5 -0
  28. data/db/migrate/20250123112636_add_payment_method_id_to_credit_cards.rb +6 -0
  29. data/lib/stay/version.rb +1 -1
  30. metadata +22 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8ab666ef6621d55e7d2aac249f86d0ea9e2c0ccb902bda7de026a5013181372
4
- data.tar.gz: 432b2ded3073a63f4757e7721dec5c9e21203f3a51377382f23eb5a503650d52
3
+ metadata.gz: 9d0d6e7e7fd52f6bc5e4fc1cc93e67e3c25f0189e68819f5ccfd6960000f19c3
4
+ data.tar.gz: 30020c4ff02d737546258c180fd61ae13993381cca5889864573761c9713c3ad
5
5
  SHA512:
6
- metadata.gz: d046d3c8f75dc3e92614d66d991770d3d03a606458aec4c81fc3a3a9108fc1d2c5f8e45aea562cc8d62b50d55b8f9325949a16451daf41683ef59e33f20a0014
7
- data.tar.gz: aa34ce806d5e6f5300f7386f359dcc57d25e1920a869b2181e327710480cd88007846930e378dc2e77256e2b528dd784ddbf1c5b46a545c368c92c8b3853e66c
6
+ metadata.gz: 00070b66f223b1df2595071ce2afe1852f36c090794240a91a898bbd6edb5349149715398da5e2f80762ac032f2e9699ea1e4c89ee85a86f514402e10aa80ff0
7
+ data.tar.gz: c6b7951b2199d3e61d31ae9dde5482c48b915b9cfa1e8d2362ae4a48b934c77c82e7413f7f8aaf00249fa9c5dadb6f2caf7a869da5d04dba3d428b3c2ec9b2b8
@@ -1,72 +1,107 @@
1
+ require "openssl"
2
+ require "base64"
3
+ require "dotenv/load"
1
4
  module Stay
2
5
  module StripeConcern
3
- extend ActiveSupport::Concern
4
- def user
5
- current_devise_api_user || current_user
6
- end
6
+ extend ActiveSupport::Concern
7
7
 
8
- def create_payment_method
9
- Stripe::PaymentMethod.create({
10
- type: params[:payment_method_type],
11
- card: {
12
- number: params[:number],
13
- exp_month: params[:exp_month],
14
- exp_year: params[:exp_year],
15
- cvc: params[:cvc],
16
- },
17
- })
18
- end
19
- def create_customer
20
- Stripe::Customer.create({
21
- email: user.email,
22
- name: "#{user.first_name} #{user.last_name}",
23
- address: {
24
- city: user.addresses.last&.city,
25
- state: user.addresses.last&.state.name,
26
- country: user.addresses.last&.country.name,
27
- line1: user.addresses.last&.address1,
28
- line2: user.addresses.last&.address2,
29
- postal_code: user.addresses.last&.zipcode
30
- },
31
- metadata: { order_id: user.id }
32
- })
33
- end
8
+ included do
9
+ Stripe.api_key = Rails.configuration.stripe[:secret_key]
10
+ end
34
11
 
35
- def create_or_retrieve_customer
36
- customers = Stripe::Customer.list(email: user.email).data
37
- if customers.empty?
38
- create_customer
39
- else
40
- customers.first
41
- end
42
- end
12
+ def user
13
+ current_devise_api_user || current_user
14
+ end
15
+
16
+ def create_payment_method
17
+ Stripe::PaymentMethod.create({
18
+ type: params[:payment_method_type],
19
+ card: {
20
+ number: params[:number],
21
+ exp_month: params[:exp_month],
22
+ exp_year: params[:exp_year],
23
+ cvc: params[:cvc]
24
+ }
25
+ })
26
+ end
27
+
28
+ def create_customer
29
+ customer = Stripe::Customer.create({
30
+ email: user.email,
31
+ name: "#{user.first_name} #{user.last_name}",
32
+ address: {
33
+ city: user.addresses.last&.city,
34
+ state: user.addresses.last&.state&.name,
35
+ country: user.addresses.last&.country&.name,
36
+ line1: user.addresses.last&.address1,
37
+ line2: user.addresses.last&.address2,
38
+ postal_code: user.addresses.last&.zipcode
39
+ },
40
+ metadata: { order_id: user.id }
41
+ })
42
+ user.update(stripe_customer_id: customer.id)
43
+ end
43
44
 
44
- def create_payment_intent
45
- Stripe::PaymentIntent.create(
46
- amount: @booking.total.to_i* 100,
47
- description: @booking.user.email,
48
- currency: params[:currency] || 'INR',
49
- payment_method: params[:payment_method_id],
50
- automatic_payment_methods: { enabled: true },
51
- receipt_email: user.email,
52
- customer: @customer,
53
- confirm: params[:confirm],
54
- return_url: params[:redirect_url]
55
- )
45
+ def create_or_retrieve_customer
46
+ if user.stripe_customer_id.present?
47
+ @customer = Stripe::Customer.retrieve(user.stripe_customer_id)
48
+ else
49
+ @customer = create_customer
56
50
  end
51
+ end
52
+
53
+ def create_payment_intent
54
+ payment_method_id = params[:payment_method_id]
55
+ payment_intent = Stripe::PaymentIntent.create(
56
+ amount: (@booking.total_amount * 100).to_i,
57
+ description: @booking.user.email,
58
+ currency: params[:currency] || "usd",
59
+ payment_method: payment_method_id,
60
+ receipt_email: user.email,
61
+ customer: @customer,
62
+ confirm: false
63
+ )
64
+ if payment_intent.status == "requires_confirmation"
65
+ payment_intent = confirm_payment_intent(payment_intent.id, payment_method_id)
66
+ end
67
+ end
68
+
69
+ def get_payment_intent
70
+ Stripe::PaymentIntent.retrieve(@booking.payment_intent_id)
71
+ end
72
+
73
+ def attach_payment_method_to_customer(payment_method_token, customer_id)
74
+ Stripe::PaymentMethod.attach(
75
+ payment_method_token,{ customer: customer_id }
76
+ )
77
+ end
78
+
79
+ def create_payment_method_from_token(token)
80
+ payment_method = Stripe::PaymentMethod.create({
81
+ type: "card",
82
+ card: { token: token }
83
+ })
57
84
 
58
- def get_payment_intent
59
- Stripe::PaymentIntent.retrieve(@booking.payment_intent_id)
60
- end
85
+ attach_payment_method_to_customer( payment_method.id, current_devise_api_user.stripe_customer_id)
86
+ payment_method.id
87
+ end
61
88
 
62
- def confirm_payment_intent
63
- Stripe::PaymentIntent.confirm(
64
- params[:payment_intent_id],
65
- {
66
- payment_method: params[:payment_method_id],
67
- return_url: params[redirect_url],
68
- })
69
- end
70
-
71
- end
72
- end
89
+ def confirm_payment_intent(payment_intent_id, payment_method_id)
90
+ Stripe::PaymentIntent.confirm(
91
+ payment_intent_id,
92
+ {
93
+ payment_method: payment_method_id,
94
+ # return_url: params[redirect_url]
95
+ })
96
+ end
97
+
98
+ def destroy_payment_method(payment_method_token)
99
+ begin
100
+ Stripe::PaymentMethod.detach(payment_method_token)
101
+ rescue Stripe::InvalidRequestError => e
102
+ raise "Failed to detach payment method: #{e.message}"
103
+ end
104
+ end
105
+
106
+ end
107
+ end
@@ -93,26 +93,18 @@ module Stay
93
93
  def determine_next_step(current_step)
94
94
  case current_step
95
95
  when "description"
96
- "price"
97
- when "price"
98
96
  "images"
99
97
  when "images"
100
98
  "details"
101
99
  when "details"
102
100
  "location"
103
- when "location"
104
- "amenities"
105
- when "amenities"
106
- "features"
107
- when "features"
108
- "calendar"
109
101
  else
110
102
  "description"
111
103
  end
112
104
  end
113
105
 
114
106
  def valid_step?(step)
115
- %w[description price images details location amenities features calendar].include?(step)
107
+ %w[description images details location].include?(step)
116
108
  end
117
109
  end
118
110
  end
@@ -1,6 +1,7 @@
1
1
  class Stay::Api::V1::CreditCardsController < Stay::BaseApiController
2
2
  before_action :authenticate_devise_api_token!
3
- before_action :set_credit_card, only: %i[show edit update]
3
+ before_action :set_credit_card, only: %i[show edit update destroy]
4
+ include Stay::StripeConcern
4
5
 
5
6
  def index
6
7
  @credit_cards = current_devise_api_user.credit_cards
@@ -25,11 +26,17 @@ class Stay::Api::V1::CreditCardsController < Stay::BaseApiController
25
26
  end
26
27
 
27
28
  def create
28
- @credit_card = current_devise_api_user.credit_cards.build(credit_card_params)
29
- if @credit_card.save
30
- render json: { message: "Credit card saved successfully", data: CreditCardSerializer.new(@credit_card), success: true }, status: :ok
31
- else
32
- render json: { error: "Credit card not saved", success: false, errors: @credit_card.errors.full_messages }, status: :unprocessable_entity
29
+ begin
30
+ token = create_payment_method_from_token(credit_card_params[:card_token])
31
+ @credit_card = current_devise_api_user.credit_cards.build(credit_card_params.merge(payment_method_token: token))
32
+
33
+ if @credit_card.save
34
+ render json: { message: "Credit card saved successfully", data: CreditCardSerializer.new(@credit_card), success: true }, status: :ok
35
+ else
36
+ render json: { error: "Credit card not saved", success: false, errors: @credit_card.errors.full_messages }, status: :unprocessable_entity
37
+ end
38
+ rescue Stripe::InvalidRequestError => e
39
+ render json: { error: e.message, success: false }, status: :unprocessable_entity
33
40
  end
34
41
  end
35
42
 
@@ -38,17 +45,31 @@ class Stay::Api::V1::CreditCardsController < Stay::BaseApiController
38
45
  end
39
46
 
40
47
  def update
41
- if @credit_card.update(credit_card_params)
48
+ if @credit_card.update(credit_card_params.except(:card_token))
42
49
  render json: { message: "Credit card updated successfully", data: CreditCardSerializer.new(@credit_card), success: true }, status: :ok
43
50
  else
44
51
  render json: { error: "Credit card not updated", success: false, errors: @credit_card.errors.full_messages }, status: :unprocessable_entity
45
52
  end
46
53
  end
47
54
 
48
- # def destroy
49
- # @credit_card.destroy
50
- # render json: { message: "Credit card successfully deleted", success: true }, status: :ok
51
- # end
55
+ def destroy
56
+ begin
57
+ destroy_payment_method(@credit_card.payment_method_token)
58
+
59
+ if @credit_card.destroy
60
+ render json: { message: "Credit card successfully deleted", success: true }, status: :ok
61
+ else
62
+ render json: { error: "Failed to delete credit card", success: false, errors: @credit_card.errors.full_messages }, status: :unprocessable_entity
63
+ end
64
+ rescue Stripe::InvalidRequestError => e
65
+ render json: { error: "Stripe error: #{e.message}", success: false }, status: :unprocessable_entity
66
+ rescue ActiveRecord::RecordNotFound
67
+ render json: { error: "Credit card not found", success: false }, status: :not_found
68
+ rescue StandardError => e
69
+ render json: { error: "An unexpected error occurred: #{e.message}", success: false }, status: :internal_server_error
70
+ end
71
+ end
72
+
52
73
 
53
74
  private
54
75
 
@@ -57,6 +78,6 @@ class Stay::Api::V1::CreditCardsController < Stay::BaseApiController
57
78
  end
58
79
 
59
80
  def credit_card_params
60
- params.require(:credit_card).permit(:month, :year, :cc_number, :cc_type, :name)
81
+ params.require(:credit_card).permit(:month, :year, :cc_number, :cc_type, :name, :card_token, :payment_method_token)
61
82
  end
62
83
  end
@@ -19,22 +19,26 @@ class Stay::Api::V1::MessagesController < Stay::BaseApiController
19
19
  total_pages = (total_count.to_f / per_page).ceil
20
20
 
21
21
  messages = @chat.messages
22
- .order(created_at: :asc)
23
- .limit(cumulative_limit)
22
+ .order(created_at: :desc)
23
+ .limit(cumulative_limit)
24
24
 
25
- chat_json = ChatSerializer.new(
26
- @chat,
27
- scope: { current_user: current_devise_api_user }
28
- ).as_json
25
+ grouped_messages = messages
26
+ .select("DATE(created_at) as message_date, stay_messages.*")
27
+ .group_by { |message| message.created_at.to_date }
29
28
 
30
- messages_json = messages.map do |message|
31
- MessageSerializer.new(message, scope: current_devise_api_user).as_json
29
+ grouped_messages_json = grouped_messages.transform_keys(&:to_s).map do |date, msgs|
30
+ {
31
+ date: formatted_date(date.to_date),
32
+ messages: ActiveModelSerializers::SerializableResource.new(msgs, each_serializer: MessageSerializer)
33
+ }
32
34
  end
33
35
 
36
+ serialized_chat = ActiveModelSerializers::SerializableResource.new(@chat, serializer: ChatSerializer, scope: { current_user: current_devise_api_user })
37
+
34
38
  render json: {
35
39
  data: "Messages Found",
36
- chat: chat_json,
37
- message: messages_json,
40
+ chat: serialized_chat,
41
+ message: grouped_messages_json,
38
42
  success: true,
39
43
  meta: {
40
44
  total_pages: total_pages,
@@ -48,6 +52,7 @@ class Stay::Api::V1::MessagesController < Stay::BaseApiController
48
52
  render json: { error: e.message, success: false }, status: :internal_server_error
49
53
  end
50
54
  end
55
+
51
56
  def new
52
57
  @message = @chat.messages.new
53
58
  render json: { data: "Message form loaded", message: @message, success: true }, status: :ok
@@ -1,5 +1,5 @@
1
1
  class Stay::Api::V1::PaymentsController < Stay::BaseApiController
2
- include Stay::StripeConcern
2
+ include Stay::StripeConcern
3
3
 
4
4
  before_action :set_booking, except: :payment_method
5
5
  before_action :authenticate_devise_api_token!
@@ -13,33 +13,80 @@ class Stay::Api::V1::PaymentsController < Stay::BaseApiController
13
13
  render json: { error: "no method found", success: false }, status: :unprocessable_entity
14
14
  end
15
15
  end
16
-
16
+
17
+ def create_payment_method
18
+ payment_method = create_payment_method(payment_method_params)
19
+ attach_payment_method(payment_method.id)
20
+ render json: { message: "Payment method created and attached successfully.", payment_method: payment_method }
21
+ rescue Stripe::StripeError => e
22
+ render json: { error: e.message }, status: :unprocessable_entity
23
+ end
24
+
25
+ def list_payment_methods
26
+ payment_methods = list_payment_methods
27
+ render json: { payment_methods: payment_methods.data }
28
+ rescue Stripe::StripeError => e
29
+ render json: { error: e.message }, status: :unprocessable_entity
30
+ end
31
+
17
32
  def create
18
- begin
19
- customer = create_or_retrieve_customer
20
- payment_intent = @booking.payment_intent_id ? get_payment_intent : create_payment_intent.tap { |pi| @booking.update(payment_intent_id: pi.id) }
21
- if params[:confirm]
22
- if payment_intent.status == 'succeeded'
23
- render json: { message: "Payment successful", payment_intent: payment_intent }, status: :ok
24
- elsif payment_intent.status == 'requires_action'
25
- render json: { message: "Payment requires further action", client_secret: payment_intent.client_secret, payment_intent_id: payment_intent["id"] }, status: :ok
26
- else
27
- render json: { message: "Payment failed", error: payment_intent.last_payment_error }, status: :unprocessable_entity
28
- end
29
- else
30
- render json: {payment_intent: payment_intent, client_secret: payment_intent.client_secret}, status: :ok
31
- end
32
- rescue Stripe::CardError => e
33
- render json: { error: e.message }, status: :unprocessable_entity
34
- rescue => e
35
- render json: { error: "Something went wrong" }, status: :internal_server_error
33
+ begin
34
+ customer = create_or_retrieve_customer
35
+
36
+ payment_intent = if @booking.payment_intent_id && @booking.payment_state == "confirmed"
37
+ get_payment_intent
38
+ else
39
+ create_payment_intent
40
+ end
41
+
42
+ payment_status = case payment_intent.status
43
+ when "succeeded"
44
+ "confirmed"
45
+ when "requires_action"
46
+ "pending"
47
+ else
48
+ "failed"
49
+ end
50
+ create_payment(payment_intent, payment_status, @booking)
51
+ @booking.update(payment_intent_id: payment_intent.id, payment_state:payment_status)
52
+
53
+ if payment_intent.status == "requires_action"
54
+ render json: {
55
+ message: "Payment requires further action",
56
+ client_secret: payment_intent.client_secret,
57
+ payment_intent_id: payment_intent.id
58
+ }, status: :ok
59
+ elsif payment_intent.status == "succeeded"
60
+ render json: {
61
+ message: "Payment successful",
62
+ payment_intent: payment_intent
63
+ }, status: :ok
64
+ else
65
+ render json: {
66
+ message: "Payment failed",
67
+ error: payment_intent.last_payment_error
68
+ }, status: :unprocessable_entity
36
69
  end
70
+ rescue Stripe::CardError => e
71
+ render json: { error: e.message }, status: :unprocessable_entity
72
+ rescue => e
73
+ render json: { error: e.message }, status: :internal_server_error
74
+ end
75
+ end
76
+
77
+ def create_payment(payment_intent, status, booking)
78
+ Stay::Payment.create!(
79
+ booking: booking,
80
+ payment_method: Stay::PaymentMethod.last,
81
+ amount: booking.total_amount,
82
+ state: status,
83
+ )
37
84
  end
38
-
85
+
39
86
  def confirm
40
87
  payment_intent = get_payment_intent
41
- if payment_intent.status == 'succeeded'
42
- @booking.update(status: 'completed')
88
+ if payment_intent.status == "succeeded"
89
+ @booking.update(status: "completed")
43
90
  render json: { success: true, redirect_url: params[:redirect_url] }
44
91
  else
45
92
  render json: { error: payment_intent.last_payment_error.message }, status: 422
@@ -48,14 +95,12 @@ class Stay::Api::V1::PaymentsController < Stay::BaseApiController
48
95
 
49
96
  private
50
97
 
51
-
98
+
52
99
  def payment_params
53
100
  params.require(:payment).permit(:amount, :currency, :payment_method_id, :description, :customer_email)
54
101
  end
55
-
102
+
56
103
  def set_booking
57
104
  @booking = Stay::Booking.find(params[:booking_id])
58
105
  end
59
-
60
- end
61
-
106
+ end
@@ -1,11 +1,11 @@
1
1
  class Stay::PaymentsController < ApplicationController
2
2
  include Stay::StripeConcern
3
-
4
- before_action :authenticate_user!
3
+ skip_before_action :verify_authenticity_token
4
+ before_action :authenticate_devise_api_token!
5
5
  before_action :set_property_and_booking
6
-
6
+
7
7
  def new
8
- render layout: 'stay/application'
8
+ render layout: "stay/application"
9
9
  end
10
10
 
11
11
  def create
@@ -13,28 +13,28 @@ class Stay::PaymentsController < ApplicationController
13
13
  @customer = create_or_retrieve_customer
14
14
  payment_intent = @booking.payment_intent_id ? get_payment_intent : create_payment_intent.tap { |pi| @booking.update(payment_intent_id: pi.id) }
15
15
  if params[:confirm]
16
- if payment_intent.status == 'succeeded'
16
+ if payment_intent.status == "succeeded"
17
17
  render json: { success: true, redirect_url: params[:redirect_url] }, status: :ok
18
- elsif payment_intent.status == 'requires_action'
18
+ elsif payment_intent.status == "requires_action"
19
19
  render json: { message: "Payment requires further action", client_secret: payment_intent.client_secret }, status: :ok
20
20
  else
21
21
  render json: { message: "Payment failed", error: payment_intent.last_payment_error }, status: :unprocessable_entity
22
22
  end
23
- else
24
- render json: {payment_intent: payment_intent, client_secret: payment_intent.client_secret}, status: :ok
23
+ else
24
+ render json: { payment_intent: payment_intent, client_secret: payment_intent.client_secret }, status: :ok
25
25
  end
26
26
  rescue Stripe::CardError => e
27
27
  render json: { error: e.message }, status: :unprocessable_entity
28
28
  rescue => e
29
- render json: { error: e.message}, status: :internal_server_error
29
+ render json: { error: e.message }, status: :internal_server_error
30
30
  end
31
31
  end
32
32
 
33
33
  def confirm
34
34
  payment_intent = get_payment_intent
35
- if payment_intent.status == 'succeeded'
36
- @booking.update(status: 'completed')
37
- flash[:notice] = 'Payment Completed Successfully'
35
+ if payment_intent.status == "succeeded"
36
+ @booking.update(status: "completed")
37
+ flash[:notice] = "Payment Completed Successfully"
38
38
  render json: { success: true, redirect_url: params[:redirect_url] }
39
39
  else
40
40
  flash[:alert] = payment_intent.last_payment_error.message
@@ -47,4 +47,4 @@ class Stay::PaymentsController < ApplicationController
47
47
  @property = Stay::Property.find(params[:property_id])
48
48
  @booking = Stay::Booking.find(params[:booking_id])
49
49
  end
50
- end
50
+ end
@@ -1,13 +1,11 @@
1
1
  module Stay
2
2
  class Amenity < ApplicationRecord
3
3
  belongs_to :amenity_category, class_name: "Stay::AmenityCategory", optional: true
4
- has_many :property_amenities, class_name: "Stay::PropertyAmenity"
4
+ has_many :property_amenities, class_name: "Stay::PropertyAmenity", dependent: :destroy
5
5
  has_many :properties, through: :property_amenities, class_name: "Stay::Property"
6
6
  enum :amenity_type, { property: 0, room: 1 }
7
7
 
8
- has_many :room_amenities, class_name: "Stay::RoomAmenity"
8
+ has_many :room_amenities, class_name: "Stay::RoomAmenity", dependent: :destroy
9
9
  has_many :rooms, through: :room_amenities, class_name: "Stay::Room"
10
-
11
- validates :name, presence: true, uniqueness: { case_sensitive: false }
12
10
  end
13
11
  end
@@ -1,11 +1,10 @@
1
1
  module Stay
2
2
  class Feature < ApplicationRecord
3
- has_many :property_features, class_name: "Stay::PropertyFeature"
3
+ has_many :property_features, class_name: "Stay::PropertyFeature", dependent: :destroy
4
4
  has_many :properties, through: :property_features, class_name: "Stay::Property"
5
- has_many :room_features, class_name: "Stay::RoomFeature"
5
+ has_many :room_features, class_name: "Stay::RoomFeature", dependent: :destroy
6
6
  has_many :rooms, through: :room_features, class_name: "Stay::Room"
7
7
 
8
8
  enum :feature_type, { property: 0, room: 1 }
9
- validates :name, presence: true, uniqueness: { case_sensitive: false }
10
9
  end
11
10
  end
@@ -1,5 +1,6 @@
1
1
  module Stay
2
2
  class Property < ApplicationRecord
3
+ STATUSES = %w[active inactive].freeze
3
4
  ACTIVE_STATUS = "active".freeze
4
5
  APPROVED = "approved".freeze
5
6
  PROPERTY = "property".freeze
@@ -58,7 +59,6 @@ module Stay
58
59
 
59
60
  after_restore :restore_associated_rooms
60
61
  after_restore :restore_active_storage_files
61
- after_create :create_default_room
62
62
  after_update :update_prices
63
63
  after_create :create_store_property
64
64
  geocoded_by :combine_address
@@ -1,4 +1,3 @@
1
1
  class CreditCardSerializer < ActiveModel::Serializer
2
- attributes :id, :month, :year, :cc_number, :cc_type, :name, :user
3
- belongs_to :user
2
+ attributes :id, :month, :year, :cc_number, :cc_type, :name, :payment_method_token, :card_token
4
3
  end
@@ -1,5 +1,5 @@
1
1
  class RoomSerializer < ActiveModel::Serializer
2
- attributes :id, :max_guests, :price_per_month, :status, :booked_dates,
2
+ attributes :id, :name,:max_guests, :price_per_month, :status, :booked_dates,
3
3
  :booking_start, :booking_end, :description,
4
4
  :size, :bed_type, :room_type, :amenities, :features, :room_images
5
5
 
@@ -33,8 +33,8 @@
33
33
  <% @amenities.each_with_index do |amenity, index| %>
34
34
  <tr>
35
35
  <td><%= index + 1%></td>
36
- <td><%= amenity.name %></td>
37
- <th scope="col"><%= amenity.amenity_type%></th>
36
+ <td><%= amenity.name&.humanize %></td>
37
+ <th scope="col"><%= amenity.amenity_type&.humanize%></th>
38
38
  <td class="text-end d-flex justify-content-center">
39
39
  <%= link_to edit_admin_amenity_path(amenity), class: 'btn d-inline-flex btn-sm btn-neutral mx-1' do %>
40
40
  <i class="bi bi-pencil"></i>
@@ -33,8 +33,8 @@
33
33
  <% @features.each_with_index do |feature, index| %>
34
34
  <tr>
35
35
  <td><%= index + 1%></td>
36
- <td><%= feature.name %></td>
37
- <td><%= feature.feature_type %></td>
36
+ <td><%= feature.name&.humanize %></td>
37
+ <td><%= feature.feature_type&.humanize %></td>
38
38
  <td class="text-end d-flex justify-content-center">
39
39
  <%= link_to edit_admin_feature_path(feature), class: 'btn d-inline-flex btn-sm btn-neutral mx-1' do %>
40
40
  <i class="bi bi-pencil"></i>