1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

uses users_credits/manager service in models reservation and subscription, and adds integration tests

This commit is contained in:
Nicolas Florentin 2016-04-07 16:02:09 +02:00
parent 02b56ed6a7
commit 7748d601f8
4 changed files with 246 additions and 103 deletions

View File

@ -45,68 +45,36 @@ class Reservation < ActiveRecord::Base
# === Machine reservation ===
when Machine
base_amount = reservable.prices.find_by(group_id: user.group_id, plan_id: plan.try(:id)).amount
if plan
machine_credit = plan.machine_credits.select {|credit| credit.creditable_id == reservable_id}.first
if machine_credit
hours_available = machine_credit.hours
if !new_plan_being_bought
user_credit = user.users_credits.find_by_credit_id(machine_credit.id)
if user_credit
hours_available = machine_credit.hours - user_credit.hours_used
end
end
slots.each_with_index do |slot, index|
description = reservable.name + " #{I18n.l slot.start_at, format: :long} - #{I18n.l slot.end_at, format: :hour_minute}"
ii_amount = (index < hours_available ? 0 : base_amount)
ii_amount = 0 if (slot.offered and on_site)
unless on_site
ii = Stripe::InvoiceItem.create(
customer: user.stp_customer_id,
amount: ii_amount,
currency: Rails.application.secrets.stripe_currency,
description: description
)
invoice_items << ii
end
self.invoice.invoice_items.push InvoiceItem.new(amount: ii_amount, stp_invoice_item_id: (ii.id if ii), description: description)
end
else
slots.each do |slot|
description = reservable.name + " #{I18n.l slot.start_at, format: :long} - #{I18n.l slot.end_at, format: :hour_minute}"
ii_amount = base_amount
ii_amount = 0 if (slot.offered and on_site)
unless on_site
ii = Stripe::InvoiceItem.create(
customer: user.stp_customer_id,
amount: ii_amount,
currency: Rails.application.secrets.stripe_currency,
description: description
)
invoice_items << ii
end
self.invoice.invoice_items.push InvoiceItem.new(amount: ii_amount, stp_invoice_item_id: (ii.id if ii), description: description)
end
users_credits_manager = UsersCredits::Manager.new(reservation: self)
slots.each_with_index do |slot, index|
description = reservable.name + " #{I18n.l slot.start_at, format: :long} - #{I18n.l slot.end_at, format: :hour_minute}"
ii_amount = base_amount # ii_amount default to base_amount
if users_credits_manager.will_use_credits?
ii_amount = (index < users_credits_manager.free_hours_count) ? 0 : base_amount
end
else
slots.each do |slot|
description = reservable.name + " #{I18n.l slot.start_at, format: :long} - #{I18n.l slot.end_at, format: :hour_minute}"
ii_amount = base_amount
ii_amount = 0 if (slot.offered and on_site)
unless on_site
ii = Stripe::InvoiceItem.create(
customer: user.stp_customer_id,
amount: ii_amount,
currency: Rails.application.secrets.stripe_currency,
description: description
)
invoice_items << ii
end
self.invoice.invoice_items.push InvoiceItem.new(amount: ii_amount, stp_invoice_item_id: (ii.id if ii), description: description)
ii_amount = 0 if slot.offered and on_site # if it's a local payment and slot is offered free
unless on_site # if it's local payment then do not create Stripe::InvoiceItem
ii = Stripe::InvoiceItem.create(
customer: user.stp_customer_id,
amount: ii_amount,
currency: Rails.application.secrets.stripe_currency,
description: description
)
invoice_items << ii
end
self.invoice.invoice_items.push InvoiceItem.new(amount: ii_amount, stp_invoice_item_id: (ii.id if ii), description: description)
end
# === Training reservation ===
when Training
# TO BE REFACTORED WHEN PLAN PURCHASE AND RESERVATION PURCHASE WILL BE DECOUPLED
base_amount = reservable.amount_by_group(user.group_id).amount
if plan
# Return True if the subscription link a training credit for training reserved by the user
@ -176,32 +144,6 @@ class Reservation < ActiveRecord::Base
invoice_items
end
def update_users_credits
if user.subscribed_plan
if reservable_type == 'Machine'
machine_credit = user.subscribed_plan.machine_credits.select {|credit| credit.creditable_id == reservable_id}.first
if machine_credit
hours_available = machine_credit.hours
user_credit = user.users_credits.find_or_initialize_by(credit_id: machine_credit.id)
user_credit.hours_used ||= 0
hours_available = machine_credit.hours - user_credit.hours_used
if hours_available >= slots.size
user_credit.hours_used = user_credit.hours_used + slots.size
else
user_credit.hours_used = machine_credit.hours
end
user_credit.save
end
elsif reservable_type == 'Training'
training_credit = user.subscribed_plan.training_credits.select {|credit| credit.creditable_id == reservable_id}.first
if user.training_credits.size < user.subscribed_plan.training_credit_nb and training_credit
user.credits << training_credit
end
end
end
return self
end
def save_with_payment
build_invoice(user: user)
invoice_items = generate_invoice_items
@ -286,7 +228,8 @@ class Reservation < ActiveRecord::Base
end
end
update_users_credits
UsersCredits::Manager.new(reservation: self).update_credits
return true
end
end
@ -318,7 +261,7 @@ class Reservation < ActiveRecord::Base
if user.invoicing_disabled?
if valid?
save!
update_users_credits
UsersCredits::Manager.new(reservation: self).update_credits
return true
end
else
@ -345,7 +288,8 @@ class Reservation < ActiveRecord::Base
save!
end
update_users_credits
UsersCredits::Manager.new(reservation: self).update_credits
return true
end
end

View File

@ -28,7 +28,7 @@ class Subscription < ActiveRecord::Base
self.expired_at = Time.at(new_subscription.current_period_end)
save!
reset_users_credits if expired_date_changed
UsersCredits::Manager.new(user: self.user).reset_credits if expired_date_changed
# generate invoice
stp_invoice = Stripe::Invoice.all(customer: user.stp_customer_id, limit: 1).data.first
@ -77,7 +77,7 @@ class Subscription < ActiveRecord::Base
self.canceled_at = nil
set_expired_at
save!
reset_users_credits if expired_date_changed
UsersCredits::Manager.new(user: self.user).reset_credits if expired_date_changed
generate_invoice.save if invoice
return true
else
@ -140,7 +140,7 @@ class Subscription < ActiveRecord::Base
self.expired_at = expired_at
if save
reset_users_credits if !free_days
UsersCredits::Manager.new(user: self.user).reset_credits if !free_days
notify_subscription_extended(free_days)
return true
end
@ -215,10 +215,6 @@ class Subscription < ActiveRecord::Base
p_value.to_date != expired_at.to_date and expired_at > p_value
end
def reset_users_credits
user.users_credits.destroy_all
end
# def is_being_extended?
# !expired_at_was.nil? and expired_at_changed?
# end

View File

@ -1,11 +1,188 @@
# class Reservations::CreateAsAdminTest < ActionDispatch::IntegrationTest
# setup do
# admin = User.with_role(:admin).first
# login_as(admin, scope: :user)
# end
#
# test "admin reserves a machine for a user" do
# availability = Availability.find(5)
#
# end
# end
module Reservations
class CreateAsAdminTest < ActionDispatch::IntegrationTest
setup do
@user_without_subscription = User.with_role(:member).without_subscription.first
@user_with_subscription = User.with_role(:member).with_subscription.second
@admin = User.with_role(:admin).first
login_as(@admin, scope: :user)
end
test "user without subscription reserves a machine with success" do
machine = Machine.find(6)
availability = machine.availabilities.first
reservations_count = Reservation.count
invoice_count = Invoice.count
invoice_items_count = InvoiceItem.count
users_credit_count = UsersCredit.count
post reservations_path, { reservation: {
user_id: @user_without_subscription.id,
reservable_id: machine.id,
reservable_type: machine.class.name,
slots_attributes: [
{ start_at: availability.start_at.to_s(:iso8601),
end_at: (availability.start_at + 1.hour).to_s(:iso8601),
availability_id: availability.id
}
]
}}.to_json, default_headers
# general assertions
assert_equal 201, response.status
assert_equal reservations_count + 1, Reservation.count
assert_equal invoice_count + 1, Invoice.count
assert_equal invoice_items_count + 1, InvoiceItem.count
assert_equal users_credit_count, UsersCredit.count
# reservation assertions
reservation = Reservation.last
assert reservation.invoice
assert reservation.stp_invoice_id.blank?
assert_equal 1, reservation.invoice.invoice_items.count
# invoice assertions
invoice = reservation.invoice
assert invoice.stp_invoice_id.blank?
refute invoice.total.blank?
# invoice_items assertions
invoice_item = InvoiceItem.last
refute invoice_item.stp_invoice_item_id
assert_equal invoice_item.amount, machine.prices.find_by(group_id: @user_without_subscription.group_id).amount
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
test "user without subscription reserves a training with success" do
training = Training.first
availability = training.availabilities.first
reservations_count = Reservation.count
invoice_count = Invoice.count
invoice_items_count = InvoiceItem.count
post reservations_path, { reservation: {
user_id: @user_without_subscription.id,
reservable_id: training.id,
reservable_type: training.class.name,
slots_attributes: [
{ start_at: availability.start_at.to_s(:iso8601),
end_at: (availability.start_at + 1.hour).to_s(:iso8601),
availability_id: availability.id
}
]
}}.to_json, default_headers
# general assertions
assert_equal 201, response.status
assert_equal reservations_count + 1, Reservation.count
assert_equal invoice_count + 1, Invoice.count
assert_equal invoice_items_count + 1, InvoiceItem.count
# reservation assertions
reservation = Reservation.last
assert reservation.invoice
assert reservation.stp_invoice_id.blank?
assert_equal 1, reservation.invoice.invoice_items.count
# invoice assertions
invoice = reservation.invoice
assert invoice.stp_invoice_id.blank?
refute invoice.total.blank?
# invoice_items
invoice_item = InvoiceItem.last
refute invoice_item.stp_invoice_item_id
assert_equal invoice_item.amount, training.amount_by_group(@user_without_subscription.group_id).amount
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
test "user with subscription reserves a machine with success" do
plan = @user_with_subscription.subscribed_plan
machine = Machine.find(6)
availability = machine.availabilities.first
reservations_count = Reservation.count
invoice_count = Invoice.count
invoice_items_count = InvoiceItem.count
users_credit_count = UsersCredit.count
post reservations_path, { reservation: {
user_id: @user_with_subscription.id,
reservable_id: machine.id,
reservable_type: machine.class.name,
slots_attributes: [
{ start_at: availability.start_at.to_s(:iso8601),
end_at: (availability.start_at + 1.hour).to_s(:iso8601),
availability_id: availability.id
},
{ start_at: (availability.start_at + 1.hour).to_s(:iso8601),
end_at: (availability.start_at + 2.hours).to_s(:iso8601),
availability_id: availability.id
}
]
}}.to_json, default_headers
# general assertions
assert_equal 201, response.status
assert_equal reservations_count + 1, Reservation.count
assert_equal invoice_count + 1, Invoice.count
assert_equal invoice_items_count + 2, InvoiceItem.count
assert_equal users_credit_count + 1, UsersCredit.count
# reservation assertions
reservation = Reservation.last
assert reservation.invoice
assert reservation.stp_invoice_id.blank?
assert_equal 2, reservation.invoice.invoice_items.count
# invoice assertions
invoice = reservation.invoice
assert invoice.stp_invoice_id.blank?
refute invoice.total.blank?
# invoice_items assertions
invoice_items = InvoiceItem.last(2)
machine_price = machine.prices.find_by(group_id: @user_with_subscription.group_id, plan_id: plan.id).amount
assert invoice_items.any? { |invoice| invoice.amount == 0 }
assert invoice_items.any? { |invoice| invoice.amount == machine_price }
assert invoice_items.all? { |invoice| invoice.stp_invoice_item_id.blank? }
# users_credits assertions
users_credit = UsersCredit.last
assert_equal @user_with_subscription, users_credit.user
assert_equal [reservation.slots.count, plan.machine_credits.find_by(creditable_id: machine.id).hours].min, users_credit.hours_used
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
end
end

View File

@ -56,6 +56,14 @@ module Reservations
assert invoice_item.stp_invoice_item_id
assert_equal invoice_item.amount, machine.prices.find_by(group_id: @user_without_subscription.group_id).amount
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
test "user without subscription reserves a machine with error" do
@ -67,6 +75,7 @@ module Reservations
reservations_count = Reservation.count
invoice_count = Invoice.count
invoice_items_count = InvoiceItem.count
notifications_count = Notification.count
VCR.use_cassette("reservations_create_for_machine_without_subscription_error") do
post reservations_path, { reservation: {
@ -88,6 +97,7 @@ module Reservations
assert_equal reservations_count, Reservation.count
assert_equal invoice_count, Invoice.count
assert_equal invoice_items_count, InvoiceItem.count
assert_equal notifications_count, Notification.count
end
test "user without subscription reserves a training with success" do
@ -138,6 +148,14 @@ module Reservations
assert invoice_item.stp_invoice_item_id
assert_equal invoice_item.amount, training.amount_by_group(@user_without_subscription.group_id).amount
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
test "user with subscription reserves a machine with success" do
@ -204,6 +222,14 @@ module Reservations
assert_equal @user_with_subscription, users_credit.user
assert_equal [reservation.slots.count, plan.machine_credits.find_by(creditable_id: machine.id).hours].min, users_credit.hours_used
# invoice assertions
invoice = Invoice.find_by(invoiced: reservation)
assert invoice
assert File.exist?(invoice.file)
# notification
assert_not_empty Notification.where(attached_object: reservation)
end
end
end