1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00

allow reservations & subscriptions at price of zero

This commit is contained in:
Sylvain 2019-09-11 11:51:04 +02:00
parent 14e726cfd1
commit f60d19fa27
10 changed files with 94 additions and 39 deletions

View File

@ -111,7 +111,7 @@ class API::PaymentsController < API::ApiController
def card_amount
if params[:cart_items][:reservation]
reservable = cart_items_params[:reservable_type].constantize.find(cart_items_params[:reservable_id])
subscription = cart_items_params[:plan_id]
plan_id = cart_items_params[:plan_id]
slots = cart_items_params[:slots_attributes] || []
nb_places = cart_items_params[:nb_reserve_places]
tickets = cart_items_params[:tickets_attributes]
@ -119,7 +119,7 @@ class API::PaymentsController < API::ApiController
raise NotImplementedError unless params[:cart_items][:subscription]
reservable = nil
subscription = subscription_params[:plan_id]
plan_id = subscription_params[:plan_id]
slots = []
nb_places = nil
tickets = nil
@ -129,7 +129,7 @@ class API::PaymentsController < API::ApiController
current_user,
reservable,
slots,
subscription,
plan_id,
nb_places,
tickets,
coupon_params[:coupon_code])

View File

@ -28,7 +28,7 @@ class API::PlansController < API::ApiController
res = PlansService.create(type, partner, plan_params)
if res[:errors]
render res[:errors], status: :unprocessable_entity
render json: res[:errors], status: :unprocessable_entity
else
render json: res, status: :created
end

View File

@ -24,9 +24,10 @@ class API::ReservationsController < API::ApiController
# Admins can create any reservations. Members can directly create reservations if total = 0,
# otherwise, they must use payments_controller#confirm_payment
def create
authorize Reservation
user_id = current_user.admin? ? params[:reservation][:user_id] : current_user.id
amount = transaction_amount(current_user.admin?, user_id)
user_id = params[:reservation][:user_id]
authorize ReservationContext.new(Reservation, amount)
@reservation = Reservation.new(reservation_params)
is_reserve = Reservations::Reserve.new(user_id, current_user.invoicing_profile.id)
@ -54,6 +55,28 @@ class API::ReservationsController < API::ApiController
private
def transaction_amount(is_admin, user_id)
user = User.find(user_id)
price_details = Price.compute(is_admin,
user,
reservation_params[:reservable_type].constantize.find(reservation_params[:reservable_id]),
reservation_params[:slots_attributes] || [],
reservation_params[:plan_id],
reservation_params[:nb_reserve_places],
reservation_params[:tickets_attributes],
coupon_params[:coupon_code])
# Subtract wallet amount from total
total = price_details[:total]
wallet_debit = get_wallet_debit(user, total)
total - wallet_debit
end
def get_wallet_debit(user, total_amount)
wallet_amount = (user.wallet.amount * 100).to_i
wallet_amount >= total_amount ? total_amount : wallet_amount
end
def set_reservation
@reservation = Reservation.find(params[:id])
end

View File

@ -9,10 +9,13 @@ class API::SubscriptionsController < API::ApiController
authorize @subscription
end
# Admins can create any subscriptions. Members can directly create subscriptions if total = 0,
# otherwise, they must use payments_controller#confirm_payment
def create
authorize Subscription
user_id = current_user.admin? ? params[:subscription][:user_id] : current_user.id
amount = transaction_amount(current_user.admin?, user_id)
user_id = params[:subscription][:user_id]
authorize SubscriptionContext.new(Subscription, amount)
@subscription = Subscription.new(subscription_params)
is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, user_id)
@ -44,6 +47,28 @@ class API::SubscriptionsController < API::ApiController
private
def transaction_amount(is_admin, user_id)
user = User.find(user_id)
price_details = Price.compute(is_admin,
user,
nil,
[],
subscription_params[:plan_id],
nil,
nil,
coupon_params[:coupon_code])
# Subtract wallet amount from total
total = price_details[:total]
wallet_debit = get_wallet_debit(user, total)
total - wallet_debit
end
def get_wallet_debit(user, total_amount)
wallet_amount = (user.wallet.amount * 100).to_i
wallet_amount >= total_amount ? total_amount : wallet_amount
end
# Use callbacks to share common setup or constraints between actions.
def set_subscription
@subscription = Subscription.find(params[:id])

View File

@ -16,14 +16,10 @@ class Plan < ActiveRecord::Base
accepts_nested_attributes_for :prices
accepts_nested_attributes_for :plan_file, allow_destroy: true, reject_if: :all_blank
after_update :update_stripe_plan, if: :amount_changed?
after_create :create_stripe_plan, unless: :skip_create_stripe_plan
after_create :create_machines_prices
after_create :create_spaces_prices
after_create :create_statistic_type
after_destroy :delete_stripe_plan
attr_accessor :skip_create_stripe_plan
validates :amount, :group, :base_name, presence: true
validates :interval_count, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
@ -101,19 +97,6 @@ class Plan < ActiveRecord::Base
private
def create_stripe_plan
stripe_plan = Stripe::Plan.create(
amount: amount,
interval: interval,
interval_count: interval_count,
name: "#{base_name} - #{group.name} - #{interval}",
currency: Rails.application.secrets.stripe_currency,
id: "#{base_name.parameterize}-#{group.slug}-#{interval}-#{DateTime.now.to_s(:number)}"
)
update_columns(stp_plan_id: stripe_plan.id, name: stripe_plan.name)
stripe_plan
end
def create_statistic_subtype
StatisticSubType.create!(key: slug, label: name)
end
@ -126,14 +109,4 @@ class Plan < ActiveRecord::Base
'Possible causes: the type or the subtype were not created successfully.'
end
end
def update_stripe_plan
old_stripe_plan = Stripe::Plan.retrieve(stp_plan_id)
old_stripe_plan.delete
create_stripe_plan
end
def delete_stripe_plan
Stripe::Plan.retrieve(stp_plan_id).delete
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
# Pundit Additional context to validate the price of a reservation
class ReservationContext
attr_reader :reservation, :price
def initialize(reservation, price)
@reservation = reservation
@price = price
end
def policy_class
ReservationPolicy
end
end

View File

@ -1,9 +1,12 @@
# frozen_string_literal: true
# Check the access policies for API::ReservationsController
class ReservationPolicy < ApplicationPolicy
def create?
user.admin?
user.admin? || record.price.zero?
end
def update?
user.admin? or record.user == user
user.admin? || record.user == user
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
# Pundit Additional context to validate the price of a subscription
class SubscriptionContext
attr_reader :subscription, :price
def initialize(subscription, price)
@subscription = subscription
@price = price
end
def policy_class
SubscriptionPolicy
end
end

View File

@ -4,7 +4,7 @@
class SubscriptionPolicy < ApplicationPolicy
include FablabConfiguration
def create?
!fablab_plans_deactivated? && user.admin?
!fablab_plans_deactivated? && (user.admin? || record.price.zero?)
end
def show?

View File

@ -16,7 +16,8 @@ class PlansService
partner&.add_role :partner, plan
plan
else
{ errors: @plan.errors }
puts plan.errors
{ errors: plan.errors }
end
end
rescue Stripe::InvalidRequestError => e