diff options
Diffstat (limited to 'billing/app')
28 files changed, 607 insertions, 0 deletions
diff --git a/billing/app/controllers/billing_base_controller.rb b/billing/app/controllers/billing_base_controller.rb new file mode 100644 index 0000000..dc15194 --- /dev/null +++ b/billing/app/controllers/billing_base_controller.rb @@ -0,0 +1,11 @@ +class BillingBaseController < ApplicationController + before_filter :assign_user + + helper 'billing' + + # required for navigation to work. + def assign_user + @user = current_user + end + +end diff --git a/billing/app/controllers/credit_card_info_controller.rb b/billing/app/controllers/credit_card_info_controller.rb new file mode 100644 index 0000000..75865fe --- /dev/null +++ b/billing/app/controllers/credit_card_info_controller.rb @@ -0,0 +1,34 @@ +class CreditCardInfoController < ApplicationController + before_filter :authorize, :set_user + + def edit + @credit_card = Braintree::CreditCard.find(params[:id]) + customer = Customer.find_by_user_id(current_user.id) + if customer and customer.braintree_customer_id == @credit_card.customer_id + @tr_data = Braintree::TransparentRedirect. + update_credit_card_data(:redirect_url => confirm_credit_card_info_url, + :payment_method_token => @credit_card.token) + else + access_denied + end + + end + + def confirm + @result = Braintree::TransparentRedirect.confirm(request.query_string) + if @result.success? + render :action => "confirm" + else + @credit_card = Braintree::CreditCard.find(@result.params[:payment_method_token]) + render :action => "edit" + end + end + + + private + + def set_user + @user = current_user + end + +end diff --git a/billing/app/controllers/customer_controller.rb b/billing/app/controllers/customer_controller.rb new file mode 100644 index 0000000..14ea8a7 --- /dev/null +++ b/billing/app/controllers/customer_controller.rb @@ -0,0 +1,61 @@ +class CustomerController < BillingBaseController + before_filter :authorize + def show + customer.with_braintree_data! + @default_cc = customer.default_credit_card #TODO not actually right way + @active_subscription = customer.subscriptions + @transactions = customer.braintree_customer.transactions + end + + def new + if customer.has_payment_info? + redirect_to edit_customer_path(customer), :notice => 'Here is your saved customer data' + else + fetch_new_transparent_redirect_data + end + end + + def edit + fetch_edit_transparent_redirect_data + end + + def confirm + @result = Braintree::TransparentRedirect.confirm(request.query_string) + + if @result.success? + customer.braintree_customer = @result.customer + customer.save + render :action => "confirm" + elsif customer.has_payment_info? + fetch_edit_transparent_redirect_data + render :action => "edit" + else + fetch_new_transparent_redirect_data + render :action => "new" + end + end + + protected + + def fetch_new_transparent_redirect_data + @tr_data = Braintree::TransparentRedirect. + create_customer_data(:redirect_url => confirm_customer_url) + end + + def fetch_edit_transparent_redirect_data + customer.with_braintree_data! + @default_cc = customer.default_credit_card + @tr_data = Braintree::TransparentRedirect. + update_customer_data(:redirect_url => confirm_customer_url, + :customer_id => customer.braintree_customer_id) ##?? + end + + def customer + @customer ||= Customer.find(params[:id]) if params[:id] # edit, show + @customer ||= Customer.find_by_user_id(current_user.id) # confirm + @customer ||= Customer.new(user: current_user) + # TODO will want case for admins, presumably + access_denied unless @customer.user == current_user + return @customer + end +end diff --git a/billing/app/controllers/payments_controller.rb b/billing/app/controllers/payments_controller.rb new file mode 100644 index 0000000..224b78e --- /dev/null +++ b/billing/app/controllers/payments_controller.rb @@ -0,0 +1,46 @@ +class PaymentsController < BillingBaseController + before_filter :authorize, :only => [:index] + + def new + fetch_transparent_redirect + end + + def confirm + @result = Braintree::TransparentRedirect.confirm(request.query_string) + if @result.success? + render :action => "confirm" + else + fetch_transparent_redirect + render :action => "new" + end + end + + def index + customer = Customer.find_by_user_id(current_user.id) + braintree_data = Braintree::Customer.find(customer.braintree_customer_id) + # these will be ordered by created_at descending, per http://stackoverflow.com/questions/16425475/ + @transactions = braintree_data.transactions + end + + protected + + + def fetch_transparent_redirect + if @user = current_user #set user for navigation + if @customer = Customer.find_by_user_id(current_user.id) + @customer.with_braintree_data! + braintree_customer_id = @customer.braintree_customer_id + @default_cc = @customer.default_credit_card + else + # TODO: this requires user to add self to vault before making payment. Is that desired functionality? + redirect_to new_customer_path, :notice => 'Before making payment, please add your customer data' + end + end + + # TODO: What is this supposed to do if braintree_customer_id was not set yet? + # Response: it can be used to make a payment that is not attributed to any customer (ie, a donation) + @tr_data = Braintree::TransparentRedirect.transaction_data redirect_url: confirm_payment_url, + transaction: { type: "sale", customer_id: braintree_customer_id, options: {submit_for_settlement: true } } + end + +end diff --git a/billing/app/controllers/subscriptions_controller.rb b/billing/app/controllers/subscriptions_controller.rb new file mode 100644 index 0000000..38dbff1 --- /dev/null +++ b/billing/app/controllers/subscriptions_controller.rb @@ -0,0 +1,45 @@ +class SubscriptionsController < BillingBaseController + before_filter :authorize + before_filter :fetch_subscription, :only => [:show, :destroy] + before_filter :confirm_no_active_subscription, :only => [:new, :create] + + def new + # don't show link to subscribe if they are already subscribed? + credit_card = @customer.default_credit_card #safe to assume default? + @payment_method_token = credit_card.token + @plans = Braintree::Plan.all + end + + # show has no content, so not needed at this point. + + def create + @result = Braintree::Subscription.create( :payment_method_token => params[:payment_method_token], :plan_id => params[:plan_id] ) + end + + def destroy + @result = Braintree::Subscription.cancel params[:id] + end + + def index + customer = Customer.find_by_user_id(current_user.id) + @subscriptions = customer.subscriptions(nil, false) + end + + private + + def fetch_subscription + @subscription = Braintree::Subscription.find params[:id] + @subscription_customer_id = @subscription.transactions.first.customer_details.id #all of subscriptions transactions should have same customer + @customer = Customer.find_by_user_id(current_user.id) + access_denied unless @customer and @customer.braintree_customer_id == @subscription_customer_id + # TODO: will presumably want to allow admins to view/cancel subscriptions for all users + end + + def confirm_no_active_subscription + @customer = Customer.find_by_user_id(current_user.id) + if subscription = @customer.subscriptions # will return active subscription, if it exists + redirect_to subscription_path(subscription.id), :notice => 'You already have an active subscription' + end + end + +end diff --git a/billing/app/helpers/billing_helper.rb b/billing/app/helpers/billing_helper.rb new file mode 100644 index 0000000..7ec9285 --- /dev/null +++ b/billing/app/helpers/billing_helper.rb @@ -0,0 +1,20 @@ +module BillingHelper + + def braintree_form_for(object, options = {}, &block) + options.reverse_merge! params: @result && @result.params[object], + errors: @result && @result.errors.for(object), + builder: BraintreeFormHelper::BraintreeFormBuilder, + url: Braintree::TransparentRedirect.url + + form_for object, options, &block + end + + def show_or_new_customer_link(user) + if (customer = Customer.find_by_user_id(user.id)) and customer.has_payment_info? + show_customer_path(user) + else + new_customer_path + end + end + +end diff --git a/billing/app/helpers/braintree_form_helper.rb b/billing/app/helpers/braintree_form_helper.rb new file mode 100644 index 0000000..cb322fa --- /dev/null +++ b/billing/app/helpers/braintree_form_helper.rb @@ -0,0 +1,64 @@ +module BraintreeFormHelper + class BraintreeFormBuilder < ActionView::Helpers::FormBuilder + include ActionView::Helpers::AssetTagHelper + include ActionView::Helpers::TagHelper + + def initialize(object_name, object, template, options, proc) + super + @braintree_params = @options[:params] + @braintree_errors = @options[:errors] + @braintree_existing = @options[:existing] + end + + def fields_for(record_name, *args, &block) + options = args.extract_options! + options[:builder] = BraintreeFormBuilder + options[:params] = @braintree_params && @braintree_params[record_name] + options[:errors] = @braintree_errors && @braintree_errors.for(record_name) + new_args = args + [options] + super record_name, *new_args, &block + end + + def text_field(method, options = {}) + has_errors = @braintree_errors && @braintree_errors.on(method).any? + field = super(method, options.merge(:value => determine_value(method))) + result = content_tag("div", field, :class => has_errors ? "fieldWithErrors" : "") + result.safe_concat validation_errors(method) + result + end + + protected + + def determine_value(method) + if @braintree_params + @braintree_params[method] + elsif @braintree_existing + + if @braintree_existing.kind_of?(Braintree::CreditCard) + + case method + when :number + method = :masked_number + when :cvv + return nil + end + end + + @braintree_existing.send(method) + else + nil + end + end + + def validation_errors(method) + if @braintree_errors && @braintree_errors.on(method).any? + @braintree_errors.on(method).map do |error| + content_tag("div", ERB::Util.h(error.message), {:style => "color: red;"}) + end.join + else + "" + end + end + end +end + diff --git a/billing/app/helpers/braintree_helper.rb b/billing/app/helpers/braintree_helper.rb new file mode 100644 index 0000000..2d18b6c --- /dev/null +++ b/billing/app/helpers/braintree_helper.rb @@ -0,0 +1,5 @@ +module BraintreeHelper + + +end + diff --git a/billing/app/models/customer.rb b/billing/app/models/customer.rb new file mode 100644 index 0000000..f01c300 --- /dev/null +++ b/billing/app/models/customer.rb @@ -0,0 +1,58 @@ +class Customer < CouchRest::Model::Base + + FIELDS = [:first_name, :last_name, :phone, :website, :company, :fax, :addresses, :credit_cards, :custom_fields] + attr_accessor *FIELDS + + use_database "customers" + belongs_to :user + belongs_to :braintree_customer + + # Braintree::Customer - stored on braintrees servers - we only have the id. + def braintree_customer + @braintree_customer ||= Braintree::Customer.find(braintree_customer_id) + end + + validates :user, presence: true + + design do + view :by_user_id + view :by_braintree_customer_id + end + + def has_payment_info? + !!braintree_customer_id + end + + # from braintree_ruby_examples/rails3_tr_devise and should be tweaked + def with_braintree_data! + return self unless has_payment_info? + + FIELDS.each do |field| + send(:"#{field}=", braintree_customer.send(field)) + end + self + end + + def default_credit_card + return unless has_payment_info? + + credit_cards.find { |cc| cc.default? } + end + + # based on 2nd parameter, either returns the single active subscription (or nil if there isn't one), or an array of all subsciptions + def subscriptions(braintree_data=nil, only_active=true) + self.with_braintree_data! + return unless has_payment_info? + + subscriptions = [] + self.default_credit_card.subscriptions.each do |sub| + if only_active and sub.status == 'Active' + return sub + else + subscriptions << sub + end + end + only_active ? nil : subscriptions + end + +end diff --git a/billing/app/views/credit_card_info/confirm.html.haml b/billing/app/views/credit_card_info/confirm.html.haml new file mode 100644 index 0000000..9dd8176 --- /dev/null +++ b/billing/app/views/credit_card_info/confirm.html.haml @@ -0,0 +1,5 @@ +%h1 Payment Info Confirmation +%p Your payment information was successfully saved. +%dl + %dt Credit Card + %dd= @result.credit_card.masked_number diff --git a/billing/app/views/credit_card_info/edit.html.haml b/billing/app/views/credit_card_info/edit.html.haml new file mode 100644 index 0000000..39269ca --- /dev/null +++ b/billing/app/views/credit_card_info/edit.html.haml @@ -0,0 +1,17 @@ +%h1 Change Credit Card +- if @result + #total-errors{:style => "color:red;"} + = h(@result.errors.size) + error(s) += braintree_form_for :credit_card, :existing => @credit_card do |f| + = field_set_tag "Credit Card" do + %dl + %dt= f.label :number, 'Number' + %dd= f.text_field :number + %dt= f.label :expiration_date, 'Expiration Date (MM/YY)' + %dd= f.text_field :expiration_date + %dt= f.label :cvv, 'CVV' + %dd= f.text_field :cvv + = hidden_field_tag :tr_data, @tr_data + = f.submit 'Save Payment Info', :class => :btn + = link_to t(:cancel), edit_customer_path(@credit_card.customer_id), :class => :btn diff --git a/billing/app/views/customer/_transaction.html.haml b/billing/app/views/customer/_transaction.html.haml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/billing/app/views/customer/_transaction.html.haml diff --git a/billing/app/views/customer/confirm.html.haml b/billing/app/views/customer/confirm.html.haml new file mode 100644 index 0000000..5551622 --- /dev/null +++ b/billing/app/views/customer/confirm.html.haml @@ -0,0 +1,14 @@ +%h1 Payment Info Confirmation +%p Your payment information was successfully saved. +%dl + %dt First Name + %dd= @result.customer.first_name + %dt Last Name + %dd= @result.customer.last_name + %dt Phone + %dd= @result.customer.phone + %dt Credit Card + - @result.customer.credit_cards.each do |cc| + %dd= cc.masked_number +- customer = Customer.find_by_user_id(current_user.id) += link_to 'View Customer Info', show_customer_path(customer.braintree_customer_id), :class=> :btn
\ No newline at end of file diff --git a/billing/app/views/customer/edit.html.haml b/billing/app/views/customer/edit.html.haml new file mode 100644 index 0000000..8a232c5 --- /dev/null +++ b/billing/app/views/customer/edit.html.haml @@ -0,0 +1,23 @@ +- if @result + #total-errors{:style => "color:red;"} + = h(@result.errors.size) + error(s) += braintree_form_for :customer, existing: @customer do |f| + = field_set_tag "Customer" do + %dl + %dt= f.label :first_name, 'First Name' + %dd= f.text_field :first_name + %dt= f.label :last_name, 'Last Name' + %dd= f.text_field :last_name + %dt= f.label :phone, 'Phone' + %dd= f.text_field :phone + - if @default_cc + = # todo, as they will need a credit card, so not sure about conditional? + %dt= t(:stored_credit_card) + %dd + = @default_cc.masked_number + = link_to t(:change_credit_card), edit_credit_card_info_path(:id => @default_cc.token), :class => :btn + = hidden_field_tag :tr_data, @tr_data + .form-actions + = f.submit t(:save_customer_info), :class => 'btn btn-primary' + = link_to t(:cancel), show_customer_path(@customer), :class=> :btn diff --git a/billing/app/views/customer/new.html.haml b/billing/app/views/customer/new.html.haml new file mode 100644 index 0000000..e1f5ba9 --- /dev/null +++ b/billing/app/views/customer/new.html.haml @@ -0,0 +1,24 @@ +- if @result + #total-errors{:style => "color:red;"} + = h(@result.errors.size) + error(s) += braintree_form_for :customer do |f| + = field_set_tag "Customer" do + %dl + %dt= f.label :first_name, 'First Name' + %dd= f.text_field :first_name + %dt= f.label :last_name, 'Last Name' + %dd= f.text_field :last_name + %dt= f.label :phone, 'Phone' + %dd= f.text_field :phone + = field_set_tag "Credit Card" do + - f.fields_for :credit_card do |cc| + %dl + %dt= cc.label :number, 'Number' + %dd= cc.text_field :number + %dt= cc.label :expiration_date, 'Expiration Date (MM/YY)' + %dd= cc.text_field :expiration_date + %dt= cc.label :cvv, 'CVV' + %dd= cc.text_field :cvv + = hidden_field_tag :tr_data, @tr_data + = f.submit 'Save Payment Info' diff --git a/billing/app/views/customer/show.html.haml b/billing/app/views/customer/show.html.haml new file mode 100644 index 0000000..639d180 --- /dev/null +++ b/billing/app/views/customer/show.html.haml @@ -0,0 +1,22 @@ +.form-actions + = link_to t(:make_payment), new_payment_path, :class => 'btn btn-primary' += render :partial => 'payments/customer_data' +%legend= t(:last_three_transactions) +- counter = 0 += # these will be ordered with most recently created first, per http://stackoverflow.com/questions/16425475/ +- @transactions.each do |t| + - break if counter > 2 # not ruby-like, but object is a Braintree::ResourceCollection so limited methods available + = render :partial => "payments/transaction_details", :locals => {:transaction => t} + - counter += 1 += link_to t(:transaction_history), payments_path +%legend= t(:subscriptions) +- if @active_subscription + = render :partial => "subscriptions/subscription_details", :locals => {:subscription => @active_subscription} +- else + %p + = t(:no_active_subscription) + %p + .form-actions + = link_to t(:subscribe_to_plan), new_subscription_path, :class => :btn +%p + = link_to t(:all_subscriptions), subscriptions_path diff --git a/billing/app/views/payments/_customer_data.html.haml b/billing/app/views/payments/_customer_data.html.haml new file mode 100644 index 0000000..87b8209 --- /dev/null +++ b/billing/app/views/payments/_customer_data.html.haml @@ -0,0 +1,15 @@ +%legend= t(:customer_information) +%dl + %dt First Name + %dd= @customer.first_name + %dt Last Name + %dd= @customer.last_name + %dt Phone + %dd= @customer.phone +%legend= t(:credit_card_information) +%dl + %dt Number + %dd= @default_cc.masked_number + %dt Expiration Date + %dd= @default_cc.expiration_date + = link_to t(:edit_saved_data), edit_customer_path(@customer), :class => :btn diff --git a/billing/app/views/payments/_non_customer_fields.html.haml b/billing/app/views/payments/_non_customer_fields.html.haml new file mode 100644 index 0000000..99b420d --- /dev/null +++ b/billing/app/views/payments/_non_customer_fields.html.haml @@ -0,0 +1,16 @@ += field_set_tag "Customer" do + = f.fields_for :customer do |c| + %div= c.label :first_name, "First Name" + %div= c.text_field :first_name + %div= c.label :last_name, "Last Name" + %div= c.text_field :last_name + %div= c.label :email, "Email" + %div= c.text_field :email += field_set_tag "Credit Card" do + = f.fields_for :credit_card do |c| + %div= c.label :number, "Number" + %div= c.text_field :number + %div= c.label :expiration_date, "Expiration Date (MM/YY)" + %div= c.text_field :expiration_date + %div= c.label :cvv, "CVV" + %div= c.text_field :cvv
\ No newline at end of file diff --git a/billing/app/views/payments/_transaction_details.html.haml b/billing/app/views/payments/_transaction_details.html.haml new file mode 100644 index 0000000..030639e --- /dev/null +++ b/billing/app/views/payments/_transaction_details.html.haml @@ -0,0 +1,15 @@ +%p + = transaction.id + Type: + = transaction.type + Amount: + = number_to_currency(transaction.amount) + Status: + = transaction.status + Date + = transaction.created_at.strftime("%Y-%m-%d") + - if sub_start = transaction.subscription_details.billing_period_start_date + From subscription which started + = sub_start + - else + Not paid as part of subscription
\ No newline at end of file diff --git a/billing/app/views/payments/confirm.html.haml b/billing/app/views/payments/confirm.html.haml new file mode 100644 index 0000000..9479eb9 --- /dev/null +++ b/billing/app/views/payments/confirm.html.haml @@ -0,0 +1,29 @@ +%h1 Payment Result +%div Thank you for your payment. +%h2 Transaction Details +%table + %tr + %td Amount + %td + $#{@result.transaction.amount} + %tr + %td Transaction ID: + %td= @result.transaction.id + %tr + %td First Name: + %td= h @result.transaction.customer_details.first_name + %tr + %td Last Name: + %td= h @result.transaction.customer_details.last_name + %tr + %td Email: + %td= h @result.transaction.customer_details.email + %tr + %td Credit Card: + %td= h @result.transaction.credit_card_details.masked_number + %tr + %td Card Type: + %td= h @result.transaction.credit_card_details.card_type +- if current_user + - customer = Customer.find_by_user_id(current_user.id) + = link_to 'View Customer Info', show_customer_path(customer.braintree_customer_id), :class=> :btn
\ No newline at end of file diff --git a/billing/app/views/payments/index.html.haml b/billing/app/views/payments/index.html.haml new file mode 100644 index 0000000..a3ad067 --- /dev/null +++ b/billing/app/views/payments/index.html.haml @@ -0,0 +1,2 @@ +- @transactions.each do |t| + = render :partial => "transaction_details", :locals => {:transaction => t}
\ No newline at end of file diff --git a/billing/app/views/payments/new.html.haml b/billing/app/views/payments/new.html.haml new file mode 100644 index 0000000..4523e13 --- /dev/null +++ b/billing/app/views/payments/new.html.haml @@ -0,0 +1,18 @@ +%h1 + = t(:payment) +- if @result and @result.errors.size > 0 + %div{:style => "color: red;"} + = h @result.errors.size + error(s) +- if @result and @result.transaction and @result.transaction.status == 'processor_declined' + %div{:style => "color: red;"} + = t(:processor_declined) += braintree_form_for :transaction, :html => {:autocomplete => "off"} do |f| + = f.label :amount, t(:amount) + = f.text_field :amount + - if !@customer + = render :partial => 'non_customer_fields', :locals => {:f => f} + - else + = render :partial => 'customer_data' + = hidden_field_tag :tr_data, @tr_data + = f.submit "Submit Payment", :class => 'btn btn-primary' diff --git a/billing/app/views/subscriptions/_subscription_details.html.haml b/billing/app/views/subscriptions/_subscription_details.html.haml new file mode 100644 index 0000000..fb18210 --- /dev/null +++ b/billing/app/views/subscriptions/_subscription_details.html.haml @@ -0,0 +1,19 @@ +%p + = link_to subscription.id, subscription_path(subscription.id) + Balance: + = number_to_currency(subscription.balance) + Bill on: + = subscription.billing_day_of_month + Start date: + = subscription.first_billing_date + Paid through: + = subscription.paid_through_date + Plan: + = subscription.plan_id + Price: + = subscription.price + - color = (subscription.status == 'Active') ? "green" : "red" + Status: + %font{:color => color} + = subscription.status + - # would be good to get plan name but not sure if that is possible?
\ No newline at end of file diff --git a/billing/app/views/subscriptions/create.html.haml b/billing/app/views/subscriptions/create.html.haml new file mode 100644 index 0000000..2b6c5e9 --- /dev/null +++ b/billing/app/views/subscriptions/create.html.haml @@ -0,0 +1,9 @@ +- if @result.success? + %h1 + Subscription Status + = @result.subscription.status + = render :partial => "subscription_details", :locals => {:subscription => @result.subscription} +- else + %h1 + Error: + = @result.message
\ No newline at end of file diff --git a/billing/app/views/subscriptions/destroy.html.haml b/billing/app/views/subscriptions/destroy.html.haml new file mode 100644 index 0000000..e7ed6e8 --- /dev/null +++ b/billing/app/views/subscriptions/destroy.html.haml @@ -0,0 +1,7 @@ +- if @result.success? + Subscription destroyed +- else + Error: + = @result.message +%p + = link_to 'Customer Information', show_customer_path(@customer.braintree_customer_id), :class=> :btn
\ No newline at end of file diff --git a/billing/app/views/subscriptions/index.html.haml b/billing/app/views/subscriptions/index.html.haml new file mode 100644 index 0000000..0e84619 --- /dev/null +++ b/billing/app/views/subscriptions/index.html.haml @@ -0,0 +1,7 @@ +- active = false +- @subscriptions.each do |s| + - if s.status == 'Active' + - active = true + = render :partial => "subscription_details", :locals => {:subscription => s} +- if !active + = link_to 'subscribe to plan', new_subscription_path, :class => :btn
\ No newline at end of file diff --git a/billing/app/views/subscriptions/new.html.haml b/billing/app/views/subscriptions/new.html.haml new file mode 100644 index 0000000..4183458 --- /dev/null +++ b/billing/app/views/subscriptions/new.html.haml @@ -0,0 +1,15 @@ +- if @payment_method_token + %h1 + Subscribe to plan + = #currently just one plan + = @plans[0].name + = number_to_currency(@plans[0].price) + = simple_form_for :subscription, :url => :subscriptions do |f| + = hidden_field_tag :payment_method_token, @payment_method_token + = hidden_field_tag :plan_id, @plans[0].id + .form-actions + = f.submit t(:subscribe), :class => 'btn btn-primary' +- else + = t(:must_create_customer) + %p + = link_to t(:create_new_customer), new_customer_path diff --git a/billing/app/views/subscriptions/show.html.haml b/billing/app/views/subscriptions/show.html.haml new file mode 100644 index 0000000..10eb667 --- /dev/null +++ b/billing/app/views/subscriptions/show.html.haml @@ -0,0 +1,6 @@ +%h1 + - if @subscription.status == 'Active' + Current + Subscription += render :partial => "subscription_details", :locals => {:subscription => @subscription} += link_to t(:cancel_subscription), subscription_path, :confirm => t(:are_you_sure), :method => :delete, :class => 'btn btn-danger' if @subscription.status == 'Active' # permission check or should that just be on show? |