billingly 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -1
- data/app/controllers/billingly/redemptions_controller.rb +7 -0
- data/app/controllers/billingly/redemptions_controller_base.rb +47 -0
- data/app/controllers/billingly/subscriptions_controller.rb +1 -1
- data/app/models/billingly/base_customer.rb +3 -4
- data/app/models/billingly/base_plan.rb +1 -1
- data/app/models/billingly/special_plan_code.rb +8 -0
- data/app/views/billingly/redemptions/new.html.haml +6 -0
- data/config/locales/en.yml +4 -0
- data/lib/billingly/engine.rb +15 -0
- data/lib/billingly/rails/routes.rb +2 -0
- data/lib/billingly/version.rb +1 -1
- data/lib/generators/templates/create_billingly_tables.rb +1 -1
- metadata +32 -18
    
        data/README.md
    CHANGED
    
    | @@ -34,5 +34,5 @@ Billingly does not receive payments directly (from Paypal, or Worldpay for examp | |
| 34 34 | 
             
              * Explore the [Docs](http://rubydoc.info/github/nubis/billingly/master/frames/file/README.md).
         | 
| 35 35 |  | 
| 36 36 | 
             
            # License
         | 
| 37 | 
            -
              MIT License. Copyright 2012 Nubis ( | 
| 37 | 
            +
              MIT License. Copyright 2012 Nubis (yo@nubis.im)
         | 
| 38 38 |  | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # People who have a {Billingly::SpecialPlanCode SpecialPlanCode} can redeem it through
         | 
| 2 | 
            +
            # the {Billingly::RedemptionsController}
         | 
| 3 | 
            +
            class Billingly::RedemptionsControllerBase < ::ApplicationController
         | 
| 4 | 
            +
              def new
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              def create
         | 
| 8 | 
            +
                code = Billingly::SpecialPlanCode.find_redeemable(params[:promo_code])
         | 
| 9 | 
            +
                if code.nil?
         | 
| 10 | 
            +
                  flash[:invalid_promo_code] = t('billingly.promo_codes.invalid')
         | 
| 11 | 
            +
                  redirect_to new_redemption_path
         | 
| 12 | 
            +
                  return
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                unless current_customer
         | 
| 16 | 
            +
                  session[:current_promo_code] = params[:promo_code] 
         | 
| 17 | 
            +
                  on_redemption_by_non_customer
         | 
| 18 | 
            +
                  return
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                unless current_customer.can_subscribe_to?(code.plan)
         | 
| 22 | 
            +
                  flash[:invalid_promo_code_plan] = t('billingly.promo_codes.cannot_subscribe_to_plan')
         | 
| 23 | 
            +
                  redirect_to new_redemption_path
         | 
| 24 | 
            +
                  return
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                current_customer.redeem_special_plan_code(code)
         | 
| 28 | 
            +
                on_redemption
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              # When a code is redeemed successfully by the current customer this callback is called.
         | 
| 32 | 
            +
              # The default behavior is redirecting to the subscriptions index page.
         | 
| 33 | 
            +
              def on_redemption
         | 
| 34 | 
            +
                redirect_to subscriptions_path, notice: t('billingly.promo_codes.redeemed_successfully')
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              # The redemptions page is public, therefore there may be people redeeming valid codes
         | 
| 38 | 
            +
              # without being a customer.
         | 
| 39 | 
            +
              #
         | 
| 40 | 
            +
              # In such cases, the validated code is stored in the session and this callback is called.
         | 
| 41 | 
            +
              # You should redirect to your signup page here, and subscribe the customer using the saved
         | 
| 42 | 
            +
              # code after they sign up.
         | 
| 43 | 
            +
              # The code and plan associated to this code can be retrieved using {#current_promo_code}
         | 
| 44 | 
            +
              # and {#current_promo_code_plan}
         | 
| 45 | 
            +
              def on_redemption_by_non_customer
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -8,7 +8,7 @@ class Billingly::SubscriptionsController < ::ApplicationController | |
| 8 8 | 
             
              # It's likely the only reachable page for deactivated customers.
         | 
| 9 9 | 
             
              def index
         | 
| 10 10 | 
             
                @subscription = current_customer.active_subscription
         | 
| 11 | 
            -
                @plans = Billingly::Plan. | 
| 11 | 
            +
                @plans = Billingly::Plan.where('hidden = false')
         | 
| 12 12 | 
             
                @invoices = current_customer.invoices.order('created_at DESC')
         | 
| 13 13 | 
             
              end
         | 
| 14 14 |  | 
| @@ -133,10 +133,9 @@ module Billingly | |
| 133 133 |  | 
| 134 134 | 
             
                # Customers can subscribe to a plan using a special subscription code which would
         | 
| 135 135 | 
             
                # allow them to access an otherwise hidden plan.
         | 
| 136 | 
            -
                #  | 
| 137 | 
            -
                 | 
| 138 | 
            -
             | 
| 139 | 
            -
                  return if code.nil?
         | 
| 136 | 
            +
                # The {SpecialPlanCode} can also contain an amount to be redeemed.
         | 
| 137 | 
            +
                # @param code [SpecialPlanCode] The code being redeemed.
         | 
| 138 | 
            +
                def redeem_special_plan_code(code)
         | 
| 140 139 | 
             
                  return if code.redeemed?
         | 
| 141 140 | 
             
                  credit_payment(code.bonus_amount) if code.bonus_amount
         | 
| 142 141 | 
             
                  subscribe_to_plan(code.plan)
         | 
| @@ -5,7 +5,7 @@ module Billingly | |
| 5 5 | 
             
                self.table_name = 'billingly_plans'
         | 
| 6 6 |  | 
| 7 7 | 
             
                attr_accessible :name, :plan_code, :description, :periodicity,
         | 
| 8 | 
            -
                  :amount, :payable_upfront, :grace_period
         | 
| 8 | 
            +
                  :amount, :payable_upfront, :grace_period, :hidden
         | 
| 9 9 |  | 
| 10 10 | 
             
                has_duration :grace_period
         | 
| 11 11 | 
             
                validates :grace_period, presence: true
         | 
| @@ -57,4 +57,12 @@ class Billingly::SpecialPlanCode < ActiveRecord::Base | |
| 57 57 | 
             
              def self.cleanup_exported_files
         | 
| 58 58 | 
             
                `rm #{File.expand_path('~/ean_13_codes_for_*.csv')}`
         | 
| 59 59 | 
             
              end
         | 
| 60 | 
            +
              
         | 
| 61 | 
            +
              # Shorthand finder for a redeemable code.
         | 
| 62 | 
            +
              # This means that the code exists and has not been redeemed yet.
         | 
| 63 | 
            +
              # @param code [String] The code to lookup.
         | 
| 64 | 
            +
              # @return [SpecialPlanCode, nil] the SpecialPlanCode instance, or nothing.
         | 
| 65 | 
            +
              def self.find_redeemable(code)
         | 
| 66 | 
            +
                self.find_by_code_and_redeemed_on(code, nil)
         | 
| 67 | 
            +
              end
         | 
| 60 68 | 
             
            end
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            .span4.offset4
         | 
| 2 | 
            +
              .well
         | 
| 3 | 
            +
                %h3 Enter your Promo Code
         | 
| 4 | 
            +
                = form_tag redemptions_path, :class => 'form-inline' do
         | 
| 5 | 
            +
                  = text_field_tag :promo_code, params[:promo_code], :class => 'input-large', :placeholder => 'Promo Code'
         | 
| 6 | 
            +
                  = submit_tag 'Redeem!', :class => 'btn btn-success btn-large'
         | 
    
        data/config/locales/en.yml
    CHANGED
    
    | @@ -1,5 +1,9 @@ | |
| 1 1 | 
             
            en:
         | 
| 2 2 | 
             
              billingly:
         | 
| 3 | 
            +
                promo_codes:
         | 
| 4 | 
            +
                  redeemed_successfully: Your promo code has been redeemed!
         | 
| 5 | 
            +
                  invalid: The promo code you entered was invalid
         | 
| 6 | 
            +
                  cannot_subscribe_to_plan: You can't subscribe to the plan provided by your promo code
         | 
| 3 7 | 
             
                your_account_was_suspended: Your account was suspended
         | 
| 4 8 | 
             
                your_invoice_is_available: Your invoice is available
         | 
| 5 9 | 
             
                payment_receipt: Payment Receipt
         | 
    
        data/lib/billingly/engine.rb
    CHANGED
    
    | @@ -33,6 +33,21 @@ module Billingly | |
| 33 33 | 
             
                          redirect_to(subscriptions_path)
         | 
| 34 34 | 
             
                        end
         | 
| 35 35 | 
             
                      end
         | 
| 36 | 
            +
                      
         | 
| 37 | 
            +
                      # When an anonymous user redeems a {SpecialPlanCode} the code is stored
         | 
| 38 | 
            +
                      # in the session. You should first sign them up and then subscribe them
         | 
| 39 | 
            +
                      # using the code they previously redeemed.
         | 
| 40 | 
            +
                      # @return [SpecialPlanCode] The instance for the code they redeemed.
         | 
| 41 | 
            +
                      def current_promo_code
         | 
| 42 | 
            +
                        @current_promo_code ||=
         | 
| 43 | 
            +
                          Billingly::SpecialPlanCode.find_redeemable(session[:current_promo_code])
         | 
| 44 | 
            +
                      end
         | 
| 45 | 
            +
                      
         | 
| 46 | 
            +
                      # Shortcut for getting the plan for the current promo code, if any.
         | 
| 47 | 
            +
                      # @return [Billingly::Plan] The plan referred to by the current code.
         | 
| 48 | 
            +
                      def current_promo_code_plan
         | 
| 49 | 
            +
                        @current_promo_code.plan if @current_promo_code
         | 
| 50 | 
            +
                      end
         | 
| 36 51 | 
             
                    end
         | 
| 37 52 |  | 
| 38 53 | 
             
                    helper_method :current_customer
         | 
| @@ -8,6 +8,8 @@ class ActionDispatch::Routing::Mapper | |
| 8 8 | 
             
                      post :deactivate
         | 
| 9 9 | 
             
                    end
         | 
| 10 10 | 
             
                  end
         | 
| 11 | 
            +
                  resources :redemptions, controller: 'billingly/redemptions', only: [:new, :create]
         | 
| 12 | 
            +
                  get 'redeem' => "billingly/redemptions#new"
         | 
| 11 13 | 
             
                end
         | 
| 12 14 | 
             
                if skope then scope(skope, as: skope, &route) else route.call end
         | 
| 13 15 | 
             
              end
         | 
    
        data/lib/billingly/version.rb
    CHANGED
    
    
| @@ -63,7 +63,7 @@ class CreateBillinglyTables < ActiveRecord::Migration | |
| 63 63 | 
             
                  t.boolean 'payable_upfront', null: false
         | 
| 64 64 | 
             
                  t.string 'grace_period', null: false
         | 
| 65 65 | 
             
                  t.integer 'signup_price'
         | 
| 66 | 
            -
                  t.boolean ' | 
| 66 | 
            +
                  t.boolean 'hidden', default: false, null: false
         | 
| 67 67 | 
             
                  t.timestamps
         | 
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: billingly
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.11
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012-11- | 
| 12 | 
            +
            date: 2012-11-07 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rails
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &70200335482980 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ~>
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: 3.2.0
         | 
| 22 22 | 
             
              type: :runtime
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *70200335482980
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: validates_email_format_of
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &70200335482480 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ! '>='
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: '0'
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *70200335482480
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: has_duration
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &70200335481840 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -43,10 +43,10 @@ dependencies: | |
| 43 43 | 
             
                    version: '0'
         | 
| 44 44 | 
             
              type: :runtime
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *70200335481840
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: ean13
         | 
| 49 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &70200335481100 !ruby/object:Gem::Requirement
         | 
| 50 50 | 
             
                none: false
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - ! '>='
         | 
| @@ -54,10 +54,10 @@ dependencies: | |
| 54 54 | 
             
                    version: '0'
         | 
| 55 55 | 
             
              type: :runtime
         | 
| 56 56 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 57 | 
            +
              version_requirements: *70200335481100
         | 
| 58 58 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 59 59 | 
             
              name: timecop
         | 
| 60 | 
            -
              requirement: & | 
| 60 | 
            +
              requirement: &70200335496720 !ruby/object:Gem::Requirement
         | 
| 61 61 | 
             
                none: false
         | 
| 62 62 | 
             
                requirements:
         | 
| 63 63 | 
             
                - - ! '>='
         | 
| @@ -65,10 +65,10 @@ dependencies: | |
| 65 65 | 
             
                    version: '0'
         | 
| 66 66 | 
             
              type: :development
         | 
| 67 67 | 
             
              prerelease: false
         | 
| 68 | 
            -
              version_requirements: * | 
| 68 | 
            +
              version_requirements: *70200335496720
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 70 | 
             
              name: sqlite3
         | 
| 71 | 
            -
              requirement: & | 
| 71 | 
            +
              requirement: &70200335496140 !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                none: false
         | 
| 73 73 | 
             
                requirements:
         | 
| 74 74 | 
             
                - - ! '>='
         | 
| @@ -76,10 +76,10 @@ dependencies: | |
| 76 76 | 
             
                    version: '0'
         | 
| 77 77 | 
             
              type: :development
         | 
| 78 78 | 
             
              prerelease: false
         | 
| 79 | 
            -
              version_requirements: * | 
| 79 | 
            +
              version_requirements: *70200335496140
         | 
| 80 80 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 81 81 | 
             
              name: rspec-rails
         | 
| 82 | 
            -
              requirement: & | 
| 82 | 
            +
              requirement: &70200335495700 !ruby/object:Gem::Requirement
         | 
| 83 83 | 
             
                none: false
         | 
| 84 84 | 
             
                requirements:
         | 
| 85 85 | 
             
                - - ! '>='
         | 
| @@ -87,10 +87,10 @@ dependencies: | |
| 87 87 | 
             
                    version: '0'
         | 
| 88 88 | 
             
              type: :development
         | 
| 89 89 | 
             
              prerelease: false
         | 
| 90 | 
            -
              version_requirements: * | 
| 90 | 
            +
              version_requirements: *70200335495700
         | 
| 91 91 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 92 92 | 
             
              name: factory_girl_rails
         | 
| 93 | 
            -
              requirement: & | 
| 93 | 
            +
              requirement: &70200335495240 !ruby/object:Gem::Requirement
         | 
| 94 94 | 
             
                none: false
         | 
| 95 95 | 
             
                requirements:
         | 
| 96 96 | 
             
                - - ! '>='
         | 
| @@ -98,7 +98,18 @@ dependencies: | |
| 98 98 | 
             
                    version: '0'
         | 
| 99 99 | 
             
              type: :development
         | 
| 100 100 | 
             
              prerelease: false
         | 
| 101 | 
            -
              version_requirements: * | 
| 101 | 
            +
              version_requirements: *70200335495240
         | 
| 102 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 103 | 
            +
              name: capybara
         | 
| 104 | 
            +
              requirement: &70200335494780 !ruby/object:Gem::Requirement
         | 
| 105 | 
            +
                none: false
         | 
| 106 | 
            +
                requirements:
         | 
| 107 | 
            +
                - - ! '>='
         | 
| 108 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 109 | 
            +
                    version: '0'
         | 
| 110 | 
            +
              type: :development
         | 
| 111 | 
            +
              prerelease: false
         | 
| 112 | 
            +
              version_requirements: *70200335494780
         | 
| 102 113 | 
             
            description: Rails Engine for SaaS subscription management. Manage subscriptions,
         | 
| 103 114 | 
             
              plan changes, free trials and more!!!
         | 
| 104 115 | 
             
            email:
         | 
| @@ -107,6 +118,8 @@ executables: [] | |
| 107 118 | 
             
            extensions: []
         | 
| 108 119 | 
             
            extra_rdoc_files: []
         | 
| 109 120 | 
             
            files:
         | 
| 121 | 
            +
            - app/controllers/billingly/redemptions_controller.rb
         | 
| 122 | 
            +
            - app/controllers/billingly/redemptions_controller_base.rb
         | 
| 110 123 | 
             
            - app/controllers/billingly/subscriptions_controller.rb
         | 
| 111 124 | 
             
            - app/mailers/billingly/base_mailer.rb
         | 
| 112 125 | 
             
            - app/mailers/billingly/mailer.rb
         | 
| @@ -126,6 +139,7 @@ files: | |
| 126 139 | 
             
            - app/views/billingly/mailer/pending_notification.html.erb
         | 
| 127 140 | 
             
            - app/views/billingly/mailer/task_results.html.erb
         | 
| 128 141 | 
             
            - app/views/billingly/mailer/trial_expired_notification.html.erb
         | 
| 142 | 
            +
            - app/views/billingly/redemptions/new.html.haml
         | 
| 129 143 | 
             
            - app/views/billingly/subscriptions/_current_subscription.html.haml
         | 
| 130 144 | 
             
            - app/views/billingly/subscriptions/_deactivation_notice.html.haml
         | 
| 131 145 | 
             
            - app/views/billingly/subscriptions/_invoice_details.html.haml
         |