From 63b0f0c061a4df83caf1cd2a577c2301a2c52bdb Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 24 Nov 2016 17:57:48 +0100 Subject: [PATCH] [to test] compute prices/invoices using cash coupons --- app/models/invoice.rb | 4 +++- app/models/reservation.rb | 23 ++++++++++++++------- app/models/subscription.rb | 31 ++++++++++++++++++---------- app/pdfs/pdf/invoice.rb | 10 ++++++++- app/services/coupon_apply_service.rb | 24 ++++++++++++++++----- app/services/statistic_service.rb | 6 +++--- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 2bf66a0cc..bc0e9683f 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -153,7 +153,9 @@ class Invoice < ActiveRecord::Base if avoir.coupon.type == 'percent_off' discount = avoir.total * avoir.coupon.percent_off / 100.0 elsif avoir.coupon.type == 'amount_off' - discount = avoit.coupon.amount_off + discount = avoir.coupon.amount_off + else + raise InvalidCouponError end avoir.total -= discount end diff --git a/app/models/reservation.rb b/app/models/reservation.rb index 005d04a31..c108b0105 100644 --- a/app/models/reservation.rb +++ b/app/models/reservation.rb @@ -134,16 +134,25 @@ class Reservation < ActiveRecord::Base # === Coupon === unless coupon_code.nil? - cp = Coupon.find_by(code: coupon_code) - if not cp.nil? and cp.status(user.id) == 'active' - @coupon = cp + @coupon = Coupon.find_by(code: coupon_code) + if not @coupon.nil? and @coupon.status(user.id) == 'active' total = invoice.invoice_items.map(&:amount).map(&:to_i).reduce(:+) + + discount = 0 + if @coupon.type == 'percent_off' + discount = (total * @coupon.percent_off / 100).to_i + elsif @coupon.type == 'amount_off' + discount = @coupon.amount_off + else + raise InvalidCouponError + end + unless on_site invoice_items << Stripe::InvoiceItem.create( customer: user.stp_customer_id, - amount: -(total * cp.percent_off / 100).to_i, + amount: -discount, currency: Rails.application.secrets.stripe_currency, - description: "coupon #{cp.code} - reservation" + description: "coupon #{@coupon.code} - reservation" ) end else @@ -395,7 +404,7 @@ class Reservation < ActiveRecord::Base total += plan.amount end if @coupon - total = (total - (total * @coupon.percent_off / 100.0)).to_i + total = CouponApplyService.new.(total, @coupon, user.id) end wallet_amount = (user.wallet.amount * 100).to_i @@ -423,7 +432,7 @@ class Reservation < ActiveRecord::Base unless coupon_code.nil? cp = Coupon.find_by(code: coupon_code) if not cp.nil? and cp.status(user.id) == 'active' - total = total - (total * cp.percent_off / 100.0) + total = CouponApplyService.new.(total, cp, user.id) self.invoice.coupon_id = cp.id else raise InvalidCouponError diff --git a/app/models/subscription.rb b/app/models/subscription.rb index dd940c15f..5882036ad 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -25,15 +25,24 @@ class Subscription < ActiveRecord::Base invoice_items = [] unless coupon_code.nil? - cp = Coupon.find_by(code: coupon_code) - if not cp.nil? and cp.status(user.id) == 'active' - @coupon = cp + @coupon = Coupon.find_by(code: coupon_code) + if not @coupon.nil? and @coupon.status(user.id) == 'active' total = plan.amount + + discount = 0 + if @coupon.type == 'percent_off' + discount = (total * @coupon.percent_off / 100).to_i + elsif @coupon.type == 'amount_off' + discount = @coupon.amount_off + else + raise InvalidCouponError + end + invoice_items << Stripe::InvoiceItem.create( customer: user.stp_customer_id, - amount: -(total * cp.percent_off / 100.0).to_i, + amount: -discount, currency: Rails.application.secrets.stripe_currency, - description: "coupon #{cp.code} - subscription" + description: "coupon #{@coupon.code} - subscription" ) else raise InvalidCouponError @@ -159,11 +168,11 @@ class Subscription < ActiveRecord::Base total = plan.amount unless coupon_code.nil? - cp = Coupon.find_by(code: coupon_code) - if not cp.nil? and cp.status(user.id) == 'active' - @coupon = cp - coupon_id = cp.id - total = plan.amount - (plan.amount * cp.percent_off / 100.0) + @coupon = Coupon.find_by(code: coupon_code) + + unless @coupon.nil? + total = CouponApplyService.new.(plan.amount, @coupon, user.id) + coupon_id = @coupon.id end end @@ -293,7 +302,7 @@ class Subscription < ActiveRecord::Base def get_wallet_amount_debit total = plan.amount if @coupon - total = (total - (total * @coupon.percent_off / 100.0)).to_i + total = CouponApplyService.new.(total, @coupon, user.id) end wallet_amount = (user.wallet.amount * 100).to_i return wallet_amount >= total ? total : wallet_amount diff --git a/app/pdfs/pdf/invoice.rb b/app/pdfs/pdf/invoice.rb index db9b951a6..dfc1c699d 100644 --- a/app/pdfs/pdf/invoice.rb +++ b/app/pdfs/pdf/invoice.rb @@ -143,7 +143,15 @@ module PDF # subtract the coupon, if any unless invoice.coupon_id.nil? cp = invoice.coupon - discount = total_calc * cp.percent_off / 100.0 + discount = 0 + if cp.type == 'percent_off' + discount = total_calc * cp.percent_off / 100.0 + elsif cp.type == 'amount_off' + discount = cp.amount_off + else + raise InvalidCouponError + end + total_calc = total_calc - discount # add a row for the coupon diff --git a/app/services/coupon_apply_service.rb b/app/services/coupon_apply_service.rb index f1f573abb..73e0361f1 100644 --- a/app/services/coupon_apply_service.rb +++ b/app/services/coupon_apply_service.rb @@ -1,11 +1,25 @@ class CouponApplyService - def call(total, coupon_code, user_id = nil) + ## + # Apply the provided coupon, if active, to the given price. Usability tests will be run depending on the + # provided parameters. + # If no coupon/coupon code or if the code does not match, return origin price without change + # + # @param total {Number} invoice total, before any coupon is applied + # @param coupon {String|Coupon} Coupon's code OR Coupon object + # @param user_id {Number} user's id against the coupon will be tested for usability + # @return {Number} + ## + def call(total, coupon, user_id = nil) price = total - # if no coupon code or if code does not match, return origin price without change - unless coupon_code.nil? - _coupon = Coupon.find_by(code: coupon_code) - if not _coupon.nil? and _coupon.status(user_id) == 'active' + if coupon.instance_of? Coupon + _coupon = coupon + elsif coupon.instance_of? String + _coupon = Coupon.find_by(code: coupon) + end + + unless coupon.nil? + if _coupon.status(user_id, total) == 'active' if _coupon.type == 'percent_off' price = price - (price * _coupon.percent_off / 100.0) elsif _coupon.type == 'amount_off' diff --git a/app/services/statistic_service.rb b/app/services/statistic_service.rb index 913ccabc9..aeabba259 100644 --- a/app/services/statistic_service.rb +++ b/app/services/statistic_service.rb @@ -127,7 +127,7 @@ class StatisticService if sub ca = i.amount.to_i / 100.0 unless i.invoice.coupon_id.nil? - ca = ca - ( ca * i.invoice.coupon.percent_off / 100.0 ) + ca = CouponApplyService.new(ca, i.invoice.coupon) end u = sub.user p = sub.plan @@ -353,7 +353,7 @@ class StatisticService end # subtract coupon discount from invoices and refunds unless invoice.coupon_id.nil? - ca = ca - ( ca * invoice.coupon.percent_off / 100.0 ) + ca = CouponApplyService.new(ca, invoice.coupon) end # divide the result by 100 to convert from centimes to monetary unit ca == 0 ? ca : ca / 100.0 @@ -366,7 +366,7 @@ class StatisticService end # subtract coupon discount from the refund unless invoice.coupon_id.nil? - ca = ca - ( ca * invoice.coupon.percent_off / 100.0 ) + ca = CouponApplyService.new(ca, invoice.coupon) end ca == 0 ? ca : ca / 100.0 end