diff --git a/Gemfile b/Gemfile index 90a0beb..a043301 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem "rails", "3.0.5" gem "sqlite3" gem 'haml' - +gem 'will_paginate' # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+) gem RUBY_VERSION.include?('1.9') ? 'ruby-debug19' : 'ruby-debug' diff --git a/app/controllers/saasaparilla/admin/plans_controller.rb b/app/controllers/saasaparilla/admin/plans_controller.rb index 7e64a96..809ba27 100644 --- a/app/controllers/saasaparilla/admin/plans_controller.rb +++ b/app/controllers/saasaparilla/admin/plans_controller.rb @@ -1,5 +1,7 @@ class Saasaparilla::Admin::PlansController < ApplicationController unloadable + + include Authorization::InstanceMethods # GET /plans # GET /plans.xml diff --git a/app/controllers/saasaparilla/admin/subscriptions_controller.rb b/app/controllers/saasaparilla/admin/subscriptions_controller.rb new file mode 100644 index 0000000..1dcbac6 --- /dev/null +++ b/app/controllers/saasaparilla/admin/subscriptions_controller.rb @@ -0,0 +1,21 @@ +class Saasaparilla::Admin::SubscriptionsController < ActionController::Base + + unloadable + + include Authorization::InstanceMethods + + # GET /admin/subscriptions + def index + @subscriptions = Subscription.all.paginate(:page => params[:page], :per_page => 20, :order => "created_at DESC") + end + + def show + @subscription = Subscription.find(params[:id]) + end + + + + + + +end \ No newline at end of file diff --git a/app/controllers/saasaparilla/subscription_controller.rb b/app/controllers/saasaparilla/subscription_controller.rb index 2eb1679..e6c2c10 100644 --- a/app/controllers/saasaparilla/subscription_controller.rb +++ b/app/controllers/saasaparilla/subscription_controller.rb @@ -2,6 +2,7 @@ class Saasaparilla::SubscriptionController < ApplicationController unloadable before_filter :get_subscription, :only => [:show, :destroy] + before_filter :require_no_subscription, :only => [:new] #overide with authorization def new @subscription = current_billable.build_subscription @@ -44,6 +45,12 @@ def destroy end private + def require_no_subscription + unless current_billable.subscription.nil? + flash[:error] = "You already have a subscription" + redirect_to subscription_path + end + end def get_subscription @subscription = current_billable.subscription if @subscription.nil? diff --git a/app/models/credit_card.rb b/app/models/credit_card.rb index 0d6945c..aceeaa5 100644 --- a/app/models/credit_card.rb +++ b/app/models/credit_card.rb @@ -34,9 +34,9 @@ def validate_card when "Last name cannot be empty" errors[:card_name] = "cannot be empty" when "Month is not a valid month" - errors[:expiration_date] = "- Month is not a valid month" + errors[:expiry_month] = "Month is not a valid month" when "Year expired" - errors[:expiration_date] = "- Year expired" + errors[:expiry_year] = "Year expired" when "Number is not a valid credit card number" errors[:card_number] = "is not a valid credit card number" when "Verification value is required" @@ -83,6 +83,7 @@ def mask_card_number end def update_payment_profile + unless new_record? @profile = {:customer_profile_id => subscription.customer_cim_id, :payment_profile => {:customer_payment_profile_id => subscription.customer_payment_profile_id, @@ -90,7 +91,6 @@ def update_payment_profile :payment => {:credit_card => active_merchant_card} } } - response = GATEWAYCIM.update_customer_payment_profile(@profile) if response.success? return true diff --git a/app/models/subscription.rb b/app/models/subscription.rb index c69fd28..079fe35 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -45,6 +45,15 @@ class Subscription < ActiveRecord::Base plan.billing_period.downcase == period.downcase end end + + ContactInfo.column_names.each do |col| + unless col.include? "id" + define_method "#{col}" do + contact_info.send(col) + end + end + end + class << self def find_and_bill_recurring_subscriptions #find_all_subscriptions need billing @@ -68,6 +77,27 @@ def find_and_invoice_subscriptions end + def last_transaction_date + @transaction = transactions.recent.first + if @transaction.nil? + "-" + else + @transaction.created_at.to_s(:month_day_year) + end + end + + def last_transaction_amount + @transaction = transactions.recent.first + if @transaction.nil? + "-" + else + @transaction.amount + end + end + + def plan_name + plan.name + end def initial_bill if Saasaparilla::CONFIG["trial_period"] > 0 set_next_billing_date(Saasaparilla::CONFIG["trial_period"]) @@ -174,8 +204,10 @@ def create_cim_profile #Login to the gateway using your credentials in environment.rb #setup the user object to save @profile = {:profile => profile} + #send the create message to the gateway API response = ::GATEWAYCIM.create_customer_profile(@profile) + if response.success? and response.authorization self.customer_cim_id = response.authorization return true diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 898e25d..d98830a 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -21,7 +21,7 @@ def response=(response) scope :successful, lambda { where("success = ?", true) } - + scope :recent, order("created_at DESC") private def generate_billing_activity diff --git a/app/views/saasaparilla/admin/subscriptions/_subscription.html.haml b/app/views/saasaparilla/admin/subscriptions/_subscription.html.haml new file mode 100644 index 0000000..32b8eb9 --- /dev/null +++ b/app/views/saasaparilla/admin/subscriptions/_subscription.html.haml @@ -0,0 +1,7 @@ +%tr + %td= subscription.email + %td= subscription.created_at.to_s(:month_day_year) + %td= subscription.last_transaction_date + %td= subscription.status + %td= subscription.plan_name + %td= link_to "Show Detail", admin_subscription_path(subscription) \ No newline at end of file diff --git a/app/views/saasaparilla/admin/subscriptions/index.html.haml b/app/views/saasaparilla/admin/subscriptions/index.html.haml new file mode 100644 index 0000000..8ffff70 --- /dev/null +++ b/app/views/saasaparilla/admin/subscriptions/index.html.haml @@ -0,0 +1,13 @@ +%h1 Listing Subscriptions + +%table + %tr + %th Email + %th Sign up + %th Last Transaction Date + %th Status + %th Plan + + = render :partial => "subscription", :collection => @subscriptions + + = will_paginate @subscriptions \ No newline at end of file diff --git a/app/views/saasaparilla/admin/subscriptions/show.html.haml b/app/views/saasaparilla/admin/subscriptions/show.html.haml new file mode 100644 index 0000000..ff87245 --- /dev/null +++ b/app/views/saasaparilla/admin/subscriptions/show.html.haml @@ -0,0 +1,28 @@ +%h1 Subscription Detail + +%h2 Subscriber Contact Info +%p + = "#{@subscription.first_name} #{@subscription.last_name}" + %br + = @subscription.address + %br + = "#{@subscription.city}, #{@subscription.state} #{@subscription.zip}" + %br + = "#{@subscription.phone_number}" + +%h2 Subscription Details +%p + ="Status: " + = @subscription.status + %br + = "Balance: " + = number_to_currency(@subscription.balance) + %br + = "Last Invoiced: " + = @subscription.invoiced_on.to_s(:month_day_year) unless @subscription.invoiced_on.nil? + %br + = "Last Transaction Date: " + = @subscription.last_transaction_date + %br + = "Last Transaction Amount: " + = number_to_currency(@subscription.last_transaction_amount) \ No newline at end of file diff --git a/app/views/saasaparilla/subscription/_credit_card_form.html.haml b/app/views/saasaparilla/subscription/_credit_card_form.html.haml index 4c63d5b..f89dcfa 100644 --- a/app/views/saasaparilla/subscription/_credit_card_form.html.haml +++ b/app/views/saasaparilla/subscription/_credit_card_form.html.haml @@ -1,14 +1,13 @@ %h2 Billing info -/ = f.input :first_name -/ = f.input :last_name + = f.input :card_type, :collection => CreditCard::CARD_TYPES, :include_blank => false - if f.object.new_record? = f.input :card_number - else = f.input :card_number, :input_html => {:value => ""} = f.input :expiry_month, :collection => CreditCard::MONTHS -= f.input :expiry_year, :collection => CreditCard::YEARS += f.input :expiry_year, :collection => CreditCard::YEARS, :error_html => { :id => "subscription_credit_card_attributes_expiry_date_error"} = f.input :card_verification diff --git a/config/routes.rb b/config/routes.rb index 4c78f7f..f226ecf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ scope '/admin', :name_prefix => 'admin' do resources :plans, :controller => "saasaparilla/admin/plans" + resources :subscriptions, :controller => "saasaparilla/admin/subscriptions" end resource :subscription, :controller => "saasaparilla/subscription" diff --git a/lib/extensions/action_controller/authorization.rb b/lib/extensions/action_controller/authorization.rb new file mode 100644 index 0000000..a025574 --- /dev/null +++ b/lib/extensions/action_controller/authorization.rb @@ -0,0 +1,23 @@ +module Authorization + module ClassMethods + + end + module InstanceMethods + def self.included(base) + if Saasaparilla::CONFIG["authorization"] == "cancan" + base.rescue_from CanCan::AccessDenied do |exception| + redirect_to '/' + flash[:error] = exception.to_s + end + base.load_and_authorize_resource + end + # Override this module an initializer with Authorization::InstanceMethods.module_eval and add your own authorization + # base.before_filter :custom_method + end + + + # def custom_method + + # end + end +end \ No newline at end of file diff --git a/lib/generators/saasaparilla/install/templates/create_saasaparilla_tables.rb b/lib/generators/saasaparilla/install/templates/create_saasaparilla_tables.rb index 465eefe..3fadba5 100644 --- a/lib/generators/saasaparilla/install/templates/create_saasaparilla_tables.rb +++ b/lib/generators/saasaparilla/install/templates/create_saasaparilla_tables.rb @@ -76,7 +76,7 @@ def self.up create_table :transactions do |t| t.string :action - t.integer :amount + t.float :amount t.boolean :success t.string :authorization t.string :message diff --git a/lib/generators/saasaparilla/install/templates/saasaparilla.yml b/lib/generators/saasaparilla/install/templates/saasaparilla.yml index 591b8fe..1febb97 100644 --- a/lib/generators/saasaparilla/install/templates/saasaparilla.yml +++ b/lib/generators/saasaparilla/install/templates/saasaparilla.yml @@ -5,6 +5,7 @@ development: auth_dot_net_login: login auth_dot_net_password: pass include_free_account: false + authorization: cancan test: grace_period: 10 @@ -13,11 +14,13 @@ test: auth_dot_net_login: login auth_dot_net_password: pass include_free_account: false - + authorization: none + production: grace_period: 10 from_email: test@dev.com trial_period: 0 auth_dot_net_login: login auth_dot_net_password: pass - include_free_account: false \ No newline at end of file + include_free_account: false + authorization: cancan diff --git a/lib/saasaparilla.rb b/lib/saasaparilla.rb index 2513629..ed68b3b 100644 --- a/lib/saasaparilla.rb +++ b/lib/saasaparilla.rb @@ -1,8 +1,14 @@ -module Saasaparilla - require 'saasaparilla/engine' if defined?(Rails) -end +require 'saasaparilla/engine' if defined?(Rails) require 'extensions/billable' + require 'country_select/lib/country_select' require 'extensions/active_record/statuses' -require 'extensions/active_record/nested_attributes' \ No newline at end of file +require 'extensions/active_record/nested_attributes' + +module Saasaparilla + + + + +end diff --git a/lib/saasaparilla/engine.rb b/lib/saasaparilla/engine.rb index 56fcce9..c375cfa 100644 --- a/lib/saasaparilla/engine.rb +++ b/lib/saasaparilla/engine.rb @@ -5,7 +5,7 @@ require 'yaml' require "dynamic_attributes" - +require 'extensions/action_controller/authorization' module Saasaparilla class Engine < Rails::Engine @@ -17,8 +17,12 @@ class Engine < Rails::Engine Saasaparilla::CONFIG = YAML.load(raw_config)[RAILS_ENV] end require 'initializers/auth_dot_net' + end + + + end end \ No newline at end of file diff --git a/saasaparilla.gemspec b/saasaparilla.gemspec index 67a2f7c..84f9604 100644 --- a/saasaparilla.gemspec +++ b/saasaparilla.gemspec @@ -21,6 +21,7 @@ Gem::Specification.new do |s| #s.add_runtime_dependency(%q, [">= 0"]) #s.add_runtime_dependency(%q, ["= 3.0.5"]) #s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">=0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) diff --git a/spec/dummy/config/saasaparilla.yml b/spec/dummy/config/saasaparilla.yml index 70beeca..b250f47 100644 --- a/spec/dummy/config/saasaparilla.yml +++ b/spec/dummy/config/saasaparilla.yml @@ -5,17 +5,22 @@ development: auth_dot_net_login: 4fQ6B3Uyz auth_dot_net_password: 4QH8JM8929epy2gt include_free_account: true - + authorization: none + test: grace_period: 10 from_email: test@dev.com trial_period: 0 include_free_account: false - + auth_dot_net_login: user + auth_dot_net_password: pass + authorization: none + production: grace_period: 10 from_email: test@dev.com trial_period: 0 auth_dot_net_login: user auth_dot_net_password: pass - include_free_account: false \ No newline at end of file + include_free_account: false + authorization: cancan diff --git a/spec/models/subscription_spec.rb b/spec/models/subscription_spec.rb index 8557330..6ebce9c 100644 --- a/spec/models/subscription_spec.rb +++ b/spec/models/subscription_spec.rb @@ -151,11 +151,19 @@ @subscription.status.should == "canceled" end - + it 'should return last transaction date' do + @subscription.save + @subscription.last_transaction_date.should == Date.today.to_s(:month_day_year) + end + it 'should return - if no transactions on last transaction date' do + @subscription.last_transaction_date.should == '-' + end - - end + it 'should return plan name' do + @subscription.plan_name.should == "Gold" + end + end describe 'billing' do before(:each) do @@ -353,6 +361,7 @@ @subscription1.billing_activities.last.invoice.invoice_line_items.first.to.should == @subscription1.billing_date end + end end diff --git a/spec/requests/admin_subscriptions_spec.rb b/spec/requests/admin_subscriptions_spec.rb new file mode 100644 index 0000000..9ec44cf --- /dev/null +++ b/spec/requests/admin_subscriptions_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe "admin/subscriptions" do + before(:each) do + @plan = Factory.build(:plan, :name => "Gold", :price => 20) + @contact_info = Factory.build(:contact_info) + + @credit_card = Factory.build(:credit_card) + @subscription = Factory.build(:subscription, :contact_info => @contact_info, :plan => @plan, :credit_card => @credit_card) + @user = Factory.create(:user, :subscription => @subscription) + @contact_info2 = Factory.build(:contact_info) + + @credit_card2 = Factory.build(:credit_card) + @subscription2 = Factory.build(:subscription, :contact_info => @contact_info2, :plan => @plan, :credit_card => @credit_card2) + @user2 = Factory.create(:user, :subscription => @subscription2) + end + + it 'should load index page' do + visit admin_subscriptions_path + page.should have_content("Listing Subscriptions") + page.should have_content("bobjones@123.com") + end + + it 'should load subscription show path' do + visit admin_subscriptions_path + click_on("Show Detail") + page.should have_content("Subscription Details") + + end + +end \ No newline at end of file diff --git a/spec/requests/credit_cards.rb b/spec/requests/credit_cards_spec.rb similarity index 100% rename from spec/requests/credit_cards.rb rename to spec/requests/credit_cards_spec.rb