From 8e605457536fed90e0d94fccf687b0746de8eb90 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 10 Dec 2018 13:24:00 +0100 Subject: [PATCH] extend subscription and offer free days will keep track of previous subscription --- Gemfile | 2 + Gemfile.lock | 17 +++++++ app/controllers/api/members_controller.rb | 2 +- .../api/subscriptions_controller.rb | 9 ++-- app/models/subscription.rb | 45 +++++++++---------- app/models/user.rb | 10 ++--- app/services/subscriptions/subscribe.rb | 22 +++++++-- ...at_to_expiration_date_from_subscription.rb | 9 ++++ db/schema.rb | 4 +- 9 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 db/migrate/20181210105917_rename_expired_at_to_expiration_date_from_subscription.rb diff --git a/Gemfile b/Gemfile index 07dce838d..74586879a 100644 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,8 @@ group :development, :test do gem 'spring' gem 'railroady' + + gem 'rubocop', '~> 0.61.1', require: false end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 5539afb1a..64c3b81a9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,6 +59,7 @@ GEM apipie-rails (0.3.6) json arel (6.0.4) + ast (2.4.0) autoprefixer-rails (5.1.8) execjs json @@ -211,6 +212,7 @@ GEM i18n (0.9.1) concurrent-ruby (~> 1.0) ice_nine (0.11.2) + jaro_winkler (1.5.1) jbuilder (2.5.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) @@ -289,6 +291,9 @@ GEM openlab_ruby (0.0.4) httparty (~> 0.13) orm_adapter (0.5.0) + parallel (1.12.1) + parser (2.5.3.0) + ast (~> 2.4.0) pdf-core (0.5.1) pdf-reader (1.4.0) Ascii85 (~> 1.0.0) @@ -297,6 +302,7 @@ GEM ruby-rc4 ttfunk pg (0.18.1) + powerpack (0.1.2) prawn (2.0.1) pdf-core (~> 0.5.1) ttfunk (~> 1.4.0) @@ -344,6 +350,7 @@ GEM activesupport (= 4.2.10) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) + rainbow (3.0.0) raindrops (0.13.0) rake (12.2.1) rb-fsevent (0.9.4) @@ -364,6 +371,14 @@ GEM mime-types (>= 1.16, < 3.0) netrc (~> 0.7) rolify (4.0.0) + rubocop (0.61.1) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.5, != 2.5.1.1) + powerpack (~> 0.1) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.4.0) ruby-progressbar (1.7.5) ruby-rc4 (0.1.5) rubyzip (1.2.2) @@ -465,6 +480,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.6) + unicode-display_width (1.4.0) unicorn (4.8.3) kgio (~> 2.6) rack @@ -549,6 +565,7 @@ DEPENDENCIES recurrence responders (~> 2.0) rolify + rubocop (~> 0.61.1) rubyzip (>= 1.2.2) rvm-capistrano sass-rails (= 5.0.1) diff --git a/app/controllers/api/members_controller.rb b/app/controllers/api/members_controller.rb index 7f927a66c..89c1c47bf 100644 --- a/app/controllers/api/members_controller.rb +++ b/app/controllers/api/members_controller.rb @@ -48,7 +48,7 @@ class API::MembersController < API::ApiController end if @member.save - @member.generate_admin_invoice + @member.generate_subscription_invoice @member.send_confirmation_instructions if !user_params[:password] and !user_params[:password_confirmation] UsersMailer.delay.notify_user_account_created(@member, generated_password) diff --git a/app/controllers/api/subscriptions_controller.rb b/app/controllers/api/subscriptions_controller.rb index fd097fd02..2028a7fb2 100644 --- a/app/controllers/api/subscriptions_controller.rb +++ b/app/controllers/api/subscriptions_controller.rb @@ -16,7 +16,7 @@ class API::SubscriptionsController < API::ApiController user_id = current_user.is_admin? ? subscription_params[:user_id] : current_user.id @subscription = Subscription.new(subscription_params) - is_subscribe = Subscribe.new(method, user_id).pay_and_save(@subscription, coupon_params[:coupon_code], true) + is_subscribe = Subscribe.new(user_id).pay_and_save(@subscription, method, coupon_params[:coupon_code], true) if is_subscribe render :show, status: :created, location: @subscription @@ -29,11 +29,10 @@ class API::SubscriptionsController < API::ApiController def update authorize @subscription - free_days = params[:subscription][:free] == true + free_days = params[:subscription][:free] || false - if @subscription.extend_expired_date(subscription_update_params[:expired_at], free_days) - ex_expired_at = @subscription.previous_changes[:expired_at].first - @subscription.user.generate_admin_invoice(free_days, ex_expired_at) + if Subscribe.new(@subscription.user_id) + .extend_subscription(@subscription, subscription_update_params[:expired_at], free_days) render status: :ok else render status: :unprocessable_entity diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 9bcc044e7..7d7e0a83c 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -35,7 +35,7 @@ class Subscription < ActiveRecord::Base discount = 0 if @coupon.type == 'percent_off' - discount = (total * @coupon.percent_off / 100).to_i + discount = (total * @coupon.percent_off / 100).to_i elsif @coupon.type == 'amount_off' discount = @coupon.amount_off else @@ -65,28 +65,24 @@ class Subscription < ActiveRecord::Base end new_subscription = customer.subscriptions.create(plan: plan.stp_plan_id, source: card_token) - # very important to set expired_at to nil that can allow method is_new? to return true - # for send the notification - # TODO: Refactoring - update_column(:expired_at, nil) unless new_record? self.stp_subscription_id = new_subscription.id self.canceled_at = nil self.expired_at = Time.at(new_subscription.current_period_end) save! - UsersCredits::Manager.new(user: self.user).reset_credits if expired_date_changed + UsersCredits::Manager.new(user: user).reset_credits if expired_date_changed # generate invoice stp_invoice = Stripe::Invoice.all(customer: user.stp_customer_id, limit: 1).data.first if invoice - invoc = generate_invoice(stp_invoice.id, coupon_code) + db_invoice = generate_invoice(stp_invoice.id, coupon_code) # debit wallet wallet_transaction = debit_user_wallet if wallet_transaction - invoc.wallet_amount = @wallet_amount_debit - invoc.wallet_transaction_id = wallet_transaction.id + db_invoice.wallet_amount = @wallet_amount_debit + db_invoice.wallet_transaction_id = wallet_transaction.id end - invoc.save + db_invoice.save end # cancel subscription after create cancel @@ -122,7 +118,7 @@ class Subscription < ActiveRecord::Base logger.error e errors[:payment] << e.message return false - rescue => e + rescue StandardError => e clear_wallet_and_goupon_invoice_items(invoice_items) # Something else happened, completely unrelated to Stripe logger.error e @@ -179,13 +175,6 @@ class Subscription < ActiveRecord::Base generate_invoice(stp_invoice_id).save end - def generate_and_save_offer_day_invoice(offer_day_start_at) - od = offer_days.create(start_at: offer_day_start_at, end_at: expired_at) - invoice = Invoice.new(invoiced_id: od.id, invoiced_type: 'OfferDay', user: user, total: 0) - invoice.invoice_items.push InvoiceItem.new(amount: 0, description: plan.name, subscription_id: self.id) - invoice.save - end - def cancel return unless stp_subscription_id.present? @@ -213,13 +202,23 @@ class Subscription < ActiveRecord::Base expired_at <= Time.now end - def extend_expired_date(expired_at, free_days = false) - return false if expired_at <= self.expired_at + def expired_at + last_offered = offer_days.order(:end_at).last + return last_offered.end_at if last_offered + + expiration_date + end + + def free_extend(expiration) + return false if expiration <= expired_at + + od = offer_days.create(start_at: expired_at, end_at: expiration) + invoice = Invoice.new(invoiced_id: od.id, invoiced_type: 'OfferDay', user: user, total: 0) + invoice.invoice_items.push InvoiceItem.new(amount: 0, description: plan.name, subscription_id: id) + invoice.save - self.expired_at = expired_at if save - UsersCredits::Manager.new(user: user).reset_credits unless free_days - notify_subscription_extended(free_days) + notify_subscription_extended(true) return true end false diff --git a/app/models/user.rb b/app/models/user.rb index 8d7ccc787..6134b50ce 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -104,7 +104,7 @@ class User < ActiveRecord::Base end def subscription - subscriptions.last + subscriptions.order(:created_at).last end def is_admin? @@ -119,14 +119,10 @@ class User < ActiveRecord::Base my_projects.to_a.concat projects end - def generate_admin_invoice(offer_day = false, offer_day_start_at = nil) + def generate_subscription_invoice return unless subscription - if offer_day - subscription.generate_and_save_offer_day_invoice(offer_day_start_at) unless invoicing_disabled? - else - subscription.generate_and_save_invoice unless invoicing_disabled? - end + subscription.generate_and_save_invoice unless invoicing_disabled? end def stripe_customer diff --git a/app/services/subscriptions/subscribe.rb b/app/services/subscriptions/subscribe.rb index 43924f192..a3cf1c72e 100644 --- a/app/services/subscriptions/subscribe.rb +++ b/app/services/subscriptions/subscribe.rb @@ -1,12 +1,11 @@ class Subscribe - attr_accessor :payment_method, :user_id + attr_accessor :user_id - def initialize(payment_method, user_id) - @payment_method = payment_method + def initialize(user_id) @user_id = user_id end - def pay_and_save(subscription, coupon, invoice) + def pay_and_save(subscription, payment_method, coupon, invoice) subscription.user_id = user_id if payment_method == :local subscription.save_with_local_payment(invoice, coupon) @@ -14,4 +13,19 @@ class Subscribe subscription.save_with_payment(invoice, coupon) end end + + def extend_subscription(subscription, new_expiration_date, free_days) + return subscription.free_extend(new_expiration_date) if free_days + + new_sub = Subscription.create( + plan_id: subscription.plan_id, + user_id: subscription.user_id, + expiration_date: new_expiration_date + ) + if new_sub.save + new_sub.user.generate_subscription_invoice + return true + end + false + end end diff --git a/db/migrate/20181210105917_rename_expired_at_to_expiration_date_from_subscription.rb b/db/migrate/20181210105917_rename_expired_at_to_expiration_date_from_subscription.rb new file mode 100644 index 000000000..147d77f72 --- /dev/null +++ b/db/migrate/20181210105917_rename_expired_at_to_expiration_date_from_subscription.rb @@ -0,0 +1,9 @@ +class RenameExpiredAtToExpirationDateFromSubscription < ActiveRecord::Migration + def up + rename_column :subscriptions, :expired_at, :expiration_date + end + + def down + rename_column :subscriptions, :expiration_date, :expired_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 9a65b287e..02b111e30 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171011125217) do +ActiveRecord::Schema.define(version: 20181210105917) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -667,7 +667,7 @@ ActiveRecord::Schema.define(version: 20171011125217) do t.string "stp_subscription_id" t.datetime "created_at" t.datetime "updated_at" - t.datetime "expired_at" + t.datetime "expiration_date" t.datetime "canceled_at" end