条款优惠券代码一次性使用

时间:2017-05-26 21:14:05

标签: ruby-on-rails ruby-on-rails-4 mongoid stripe-payments

我按照条纹说明将优惠券添加到我的应用中。优惠券运作良好,但我想制作一张有效的优惠券,但每位用户只能使用一次。

我的优惠券模型

Coupon.rb

class Coupon
  include Mongoid::Document

  has_many :charges
  has_one :manager

  validates_presence_of :code, :discount_percent, :coupon_count, :description
  validates_uniqueness_of :code

  field :code, type: String
  field :discount_percent, type: Integer
  field :expires_at, type: Date
  field :coupon_count, type: Integer
  field :description, type: String


  def self.get(code)
    where(
      :code => (normalize_code(code)),
      :$and => [
        {
          :$or => [
            { :coupon_count.gte => 1  },
            { :coupon_count    => nil }
          ]
        }, {
          :$or => [
            { :expires_at.gte => Date.today },
            { :expires_at    => nil }
          ]
        }
      ]
    ).first
  end

  def apply_discount(amount)
    discount = amount * (self.discount_percent * 0.01)
    (amount - discount.to_i)
  end

  def discount_percent_human
    if discount_percent.present?
      discount_percent.to_s + '%'
    end
  end

  def generate_subscription_code(manager)
    # Random, unguessable number as a base20 string
    #  .reverse ensures we don't use first character (which may not take all values)
    raw_string = SecureRandom.random_number( 2**80 ).to_s( 20 ).reverse

    # Convert Ruby base 20 to better characters for user experience
    long_code = raw_string.tr( '0123456789abcdefghij', '234679QWERTYUPADFGHX' )

    # Format the code for printing
    short_code = long_code[0..3] + '-' + long_code[4..7] + '-' + long_code[8..11]
      self.code = short_code
      self.discount_percent = 100
      self.expires_at = DateTime.now + 1.year
      self.coupon_count = 120
      self.description = "#{manager.email} Annual Subscription"
    save
  end

  private

  def self.normalize_code(code)
    code.gsub(/ +/, '').upcase
  end

end

这是我的收费控制器

charges_controller.rb

class Managers::ChargesController < ApplicationController
  before_filter :authenticate_manager!

  def new
    @reportapproval = Reportapproval.find(params[:id])
    @manager = current_manager
    @amount = @reportapproval.manager_request_report_type
  end

  def create
    # Amount in cents
    @reportapproval = Reportapproval.find params[:reportapproval_id]
    @manager = current_manager
    @amount = @reportapproval.manager_request_report_type
    @final_amount = @amount

    @code = params[:couponCode]

    if !@code.blank?
      @coupon = Coupon.get(@code)

      if @coupon.nil?
        flash[:error] = 'Coupon code is not valid or expired.'
        redirect_to new_managers_charge_path(id: @reportapproval.id)
        return
      elsif @coupon.discount_percent == 100
        @reportapproval.report_paid = true
        @reportapproval.free_coupon_used = true
        @reportapproval.save!
        @coupon.coupon_count = @coupon.coupon_count - 1
        @coupon.save!
        redirect_to managers_dashboard_path, :notice => "You have successfully requested a pre-paid report from #{@reportapproval.tenant_last_name} with a 'No-Pay' coupon."
        return
      else
        @final_amount = @coupon.apply_discount(@amount.to_i)
        @discount_amount = (@amount.to_i - @final_amount.to_i)
      end

      if @coupon.present?
        charge_metadata = {
          :coupon_code => @coupon.code,
          :coupon_discount => @coupon.discount_percent_human
        }
      end
    end

    charge_metadata ||= {}

    customer = Stripe::Customer.create(
      :email => @manager.email,
      :card  => params[:stripeToken]
    )

    stripe_charge = Stripe::Charge.create(
      :customer    => customer.id,
      :amount      => @final_amount,
      :description => 'Manager Paid Report',
      :currency    => 'usd',
      :metadata    => charge_metadata
    )
    @charge = Charge.create!(amount: @final_amount, coupon: @coupon, stripe_id: stripe_charge.id)
    @reportapproval.report_paid = true
    @reportapproval.save!
    if @coupon.present?
      @coupon.coupon_count = @coupon.coupon_count - 1
      @coupon.save!
    else
      redirect_to managers_dashboard_path, :notice => "You have successfully requested a pre-paid report from #{@reportapproval.tenant_last_name}."
      return
    end

    rescue Stripe::CardError => e
      flash[:error] = e.message
      redirect_to managers_charges_path
    end

end

如何添加检查管理员之前是否使用优惠券并且只允许他们使用一次的功能?

0 个答案:

没有答案