diff --git a/app/assets/javascripts/payments.js.coffee b/app/assets/javascripts/payments.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/payments.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/payments.css.scss b/app/assets/stylesheets/payments.css.scss new file mode 100644 index 0000000..09456e2 --- /dev/null +++ b/app/assets/stylesheets/payments.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Payments controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb new file mode 100644 index 0000000..a5ce955 --- /dev/null +++ b/app/controllers/payments_controller.rb @@ -0,0 +1,88 @@ +class PaymentsController < ApplicationController + load_and_authorize_resource :payment + load_and_authorize_resource :user, :through => :payment + before_filter :authenticate_user! + + # Load users and certs based on current ability + before_filter do + @users = User.accessible_by(current_ability).sort_by(&:name_with_payee_and_member_level) + end + + before_filter :only => [:create, :update] do + @payment.created_by = current_user.id + end + + # GET /payments + # GET /payments.json + def index + @payments = @payments.order("date DESC") + + respond_to do |format| + format.html # index.html.erb + format.json { render :json => @payments } + end + end + + # GET /payments/1 + # GET /payments/1.json + def show + respond_to do |format| + format.html # show.html.erb + format.json { render :json => @payment } + end + end + + # GET /payments/new + # GET /payments/new.json + def new + respond_to do |format| + format.html # new.html.erb + format.json { render :json => @payment } + end + end + + # GET /payments/1/edit + def edit + end + + # POST /payments + # POST /payments.json + def create + Rails.logger.warn "payment:" + Rails.logger.warn @payment.inspect + respond_to do |format| + if @payment.save + format.html { redirect_to payments_url, :notice => 'Payment was successfully created.' } + format.json { render :json => @payment, :status => :created, :location => @payment } + else + format.html { render :action => "new" } + format.json { render :json => @payment.errors, :status => :unprocessable_entity } + end + end + end + + # PUT /payments/1 + # PUT /payments/1.json + def update + respond_to do |format| + if @payment.update_attributes(params[:payment]) + format.html { redirect_to payments_url, :notice => 'Payment was successfully updated.' } + format.json { head :no_content } + else + format.html { render :action => "edit" } + format.json { render :json => @payment.errors, :status => :unprocessable_entity } + end + end + end + + # DELETE /payments/1 + # DELETE /payments/1.json + def destroy + @payment.destroy + + respond_to do |format| + format.html { redirect_to payments_url } + format.json { head :no_content } + end + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 27c2206..6e2e609 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -15,7 +15,7 @@ class UsersController < ApplicationController when "waiver" @users = @users.sort_by{ |u| [-u.waiver.to_i,u.name] } when "member" - @users = @users.sort_by{ |u| [-u.member.to_i,-u.member_level.to_i,u.name] } + @users = @users.sort_by{ |u| [-u.member_status.to_i,u.name] } when "card" @users = @users.sort_by{ |u| [-u.cards.count,u.name] } when "instructor" diff --git a/app/helpers/payments_helper.rb b/app/helpers/payments_helper.rb new file mode 100644 index 0000000..c1b884f --- /dev/null +++ b/app/helpers/payments_helper.rb @@ -0,0 +1,2 @@ +module PaymentsHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb index cf66197..5ec9915 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -28,6 +28,11 @@ class Ability can :read, UserCertification end + # Accountants can manage all + if user.accountant? + can :manage, Payment + end + # Admins can manage all if user.admin? can :manage, :all @@ -41,6 +46,7 @@ class Ability cannot :destroy, MacLog cannot :destroy, UserCertification cannot :destroy, DoorLog + # no exception for destroying payments end # Define abilities for the passed in user here. For example: # diff --git a/app/models/payment.rb b/app/models/payment.rb new file mode 100644 index 0000000..ef9d681 --- /dev/null +++ b/app/models/payment.rb @@ -0,0 +1,15 @@ +class Payment < ActiveRecord::Base + belongs_to :user + attr_accessible :date, :user_id, :created_by + + validates_presence_of :user_id, :date, :created_by + validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.' + + def human_date + if date.year < DateTime.now.year + date.strftime("%b %e, %y") + else + date.strftime("%b %e") + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c3182ed..33e63f3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,46 +9,103 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable # Setup accessible (or protected) attributes for your model - attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :admin, :instructor, :member, :emergency_name, :emergency_phone, :current_skills, :desired_skills, :waiver, :emergency_email, :phone, :payment_method, :orientation, :member_level, :certifications, :hidden, :marketing_source #TODO: make admin/instructor/member/etc not accessible + attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :admin, :instructor, :member, :emergency_name, :emergency_phone, :current_skills, :desired_skills, :waiver, :emergency_email, :phone, :payment_method, :orientation, :member_level, :certifications, :hidden, :marketing_source, :payee, :accountant #TODO: make admin/instructor/member/etc not accessible has_many :cards has_many :user_certifications has_many :certifications, :through => :user_certifications + has_many :payments after_create :send_new_user_email - - def member_status - output = "" - - if self.member_level.to_i >= 1 then - output = "" + def name_with_payee_and_member_level + if payee.blank? then + "#{name} - #{member_level_string}" + else + "#{payee} for #{name} - #{member_level_string}" end - - unless self.member.nil? then - # 1 = inactive, show an X - if self.member >= 10 then - output = "" - # 25 or higher is paying, show a check - end - if self.member >= 25 then - output = "" - end - if self.member >= 50 then - output = "" - end - if self.member >= 100 then - output = "" - end - - if self.member < self.member_level.to_i then - output = "" - end - end - - return output end + def member_level_string + case self.member_level.to_i + when 0 + "None" + when 1 + "Unable" + when 10..24 + "Volunteer" + when 25..49 + "Associate ($25)" + when 50..99 + "Basic ($50)" + when 100..999 + "Plus ($100)" + end + end + + def member_status + case self.member_level.to_i + when 0 + if self.payments.count > 0 then + 2 + else + -1 + end + when 1 + 1 + when 10..24 + 10 + when 25..999 + if self.payments.count > 0 then + if self.payments.last.date < (DateTime.now - 1.month) + 3 + else + case self.member_level.to_i + when 25..49 + 25 + when 50..99 + 50 + when 100..999 + 100 + end + end + else + return 0 + end + end + end + + def member_status_symbol + case self.member_level.to_i + when 0 + if self.payments.count > 0 then + ":(" + else + "" + end + when 1 + "Unable" + when 10..24 + "" + when 25..999 + if self.payments.count > 0 then + if self.payments.last.date < (DateTime.now - 1.month) + "" + else + case self.member_level.to_i + when 25..49 + "" + when 50..99 + "" + when 100..999 + "" + end + end + else + "?" + end + end + end private diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 83bb022..89d2509 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -17,6 +17,7 @@ <% else %> <%= link_to 'Certifications', certifications_path if can? :read, Certification %> <% end %> + <%= link_to 'Payments', payments_path if can? :read, Payment %> <%= link_to 'Door Logs', door_logs_path if can? :read, DoorLog %> <%= link_to 'Computers', macs_path if user_signed_in? && (can? :read, Mac) %> <% if user_signed_in? then %><%= link_to 'Profile', edit_user_registration_path %><% end %> diff --git a/app/views/payments/_form.html.erb b/app/views/payments/_form.html.erb new file mode 100644 index 0000000..161ce8a --- /dev/null +++ b/app/views/payments/_form.html.erb @@ -0,0 +1,25 @@ +<%= form_for(@payment) do |f| %> + <% if @payment.errors.any? %> +
+

<%= pluralize(@payment.errors.count, "error") %> prohibited this payment from being saved:

+ + +
+ <% end %> + +
+ <%= f.label :user_id, "User" %>
+ <%= collection_select(:payment, :user_id, @users, :id, :name_with_payee_and_member_level) %> +
+
+ <%= f.label :date, "Paid for month beginning" %>
+ <%= f.date_select :date %> +
+
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/payments/edit.html.erb b/app/views/payments/edit.html.erb new file mode 100644 index 0000000..07df43e --- /dev/null +++ b/app/views/payments/edit.html.erb @@ -0,0 +1,6 @@ +

Editing payment

+ +<%= render 'form' %> + +<%= link_to 'Show', @payment %> | +<%= link_to 'Back', payments_path %> diff --git a/app/views/payments/index.html.erb b/app/views/payments/index.html.erb new file mode 100644 index 0000000..9be4eff --- /dev/null +++ b/app/views/payments/index.html.erb @@ -0,0 +1,24 @@ +

Listing payments

+ +<%= link_to 'New Payment', new_payment_path %> +
+ + + + + + + + + +<% @payments.each do |payment| %> + + + + + + +<% end %> +
UserPaid for month
beginning
<%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %><%= payment.human_date %><%= link_to 'Details', payment %><%= link_to 'Edit', edit_payment_path(payment) %>
+ + diff --git a/app/views/payments/new.html.erb b/app/views/payments/new.html.erb new file mode 100644 index 0000000..d96c87c --- /dev/null +++ b/app/views/payments/new.html.erb @@ -0,0 +1,5 @@ +

New payment

+ +<%= render 'form' %> + +<%= link_to 'Back', payments_path %> diff --git a/app/views/payments/show.html.erb b/app/views/payments/show.html.erb new file mode 100644 index 0000000..59906ce --- /dev/null +++ b/app/views/payments/show.html.erb @@ -0,0 +1,29 @@ +

+ User: + <%= @payment.user.name_with_payee_and_member_level unless @payment.user.blank? %> +

+ +

+ Paid for month beginning: + <%= @payment.date %> +

+ +

+ Last Modified by: + <%= user = @users.find{|u| u.id == @payment.created_by}; link_to user.name, user unless user.blank? %> +

+ +

+ Created date: + <%= @payment.created_at %> +

+ +

+ Updated date: + <%= @payment.updated_at %> +

+ + +<%= link_to 'Edit', edit_payment_path(@payment) %> | +<%= link_to 'Destroy', @payment, :confirm => 'Are you sure you want to destroy this payment?', :method => :delete if can? :destroy, @payment %> | +<%= link_to 'Back', payments_path %> diff --git a/app/views/user_mailer/new_user_email.html.erb b/app/views/user_mailer/new_user_email.html.erb index 1dd7bf5..efeaa30 100644 --- a/app/views/user_mailer/new_user_email.html.erb +++ b/app/views/user_mailer/new_user_email.html.erb @@ -12,18 +12,22 @@

User Details: <%= link_to @url+user_path(@user), @url+user_path(@user) %>

-

- What skills, knowledge and experience do you bring to the community? - <%= simple_format @user.current_skills %> -

-

- What skills, knowledge and experiences are you looking for in HeatSync? - <%= simple_format @user.desired_skills %> -

-

- How'd you find out about HeatSync? - <%= simple_format @user.marketing_source %> -

+

+ Member Level: + <%= simple_format @user.member_level_string %> +

+

+ What skills, knowledge and experience do you bring to the community? + <%= simple_format @user.current_skills %> +

+

+ What skills, knowledge and experiences are you looking for in HeatSync? + <%= simple_format @user.desired_skills %> +

+

+ How'd you find out about HeatSync? + <%= simple_format @user.marketing_source %> +

diff --git a/app/views/user_mailer/new_user_email.text.erb b/app/views/user_mailer/new_user_email.text.erb index 078379d..3e64142 100644 --- a/app/views/user_mailer/new_user_email.text.erb +++ b/app/views/user_mailer/new_user_email.text.erb @@ -4,6 +4,7 @@ Please contact them at <%= @user.email %><%= " or "+@user.phone.to_s unless @use new user orientation, waiver, welcome, payment help, etc. User Details: <%= link_to @url+user_path(@user), @url+user_path(@user) %> +Member Level: <%= simple_format @user.member_level %> What skills, knowledge and experience do you bring to the community? <%= simple_format @user.current_skills %> diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb index 436b530..73140e4 100644 --- a/app/views/users/_form.html.erb +++ b/app/views/users/_form.html.erb @@ -65,6 +65,10 @@
<%= render :partial => "/users/payment_methods", :locals => { :g => f } %>
+
+ <%= f.label :payee %>
+ <%= f.text_field :payee%> +
<%= f.label :phone %>
<%= f.text_field :phone %> @@ -81,10 +85,6 @@ <%= f.label :marketing_source, "How'd you find out about HeatSync?" %>
<%= f.text_area :marketing_source %>
-
- <%= f.label :member, "Member?" %>
- <%= f.select :member, [[nil],["No",0],["Inactive",1],["Volunteer",10],["Associate",25],["Basic",50],["Plus",100]] %> -
<%= f.label :instructor, "Instructor?" %>
<%= f.check_box :instructor %> @@ -93,6 +93,10 @@ <%= f.label :admin, "Admin?" %>
<%= f.check_box :admin %>
+
+ <%= f.label :accountant, "Accountant?" %>
+ <%= f.check_box :accountant %> +
<%= f.label :hidden, "Hidden?" %>
<%= f.check_box :hidden %> diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 86e0346..6962171 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -8,8 +8,8 @@ <% if current_user.admin? then %><% end %> - <% if current_user.admin? %><% end %> - + <% if current_user.admin? %> + <% end %> @@ -26,7 +26,7 @@ Member? Card? Instructor? - Admin? + <% if current_user.admin? then %>Admin?<% end %> @@ -44,10 +44,10 @@ <%= unless user.orientation.blank? then raw("") end %> <% end %> <%= unless user.waiver.blank? then raw("") end %> - <%= raw(user.member_status) %> + <%= raw(user.member_status_symbol) %> <%= unless user.cards.blank? then raw("") end %> <%= if user.instructor? then raw("✓") end %> - <%= if user.admin? then raw("✓") end %> + <% if current_user.admin? then %><%= if user.admin? then raw("✓") end %><% end %> <%= link_to 'Edit', edit_user_path(user) if can? :update, user %> <%= link_to 'Destroy', user, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE USER FROM THE DOOR SYSTEM! DISABLE THEM FIRST.', :method => :delete if can? :destroy, user %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 20550aa..3b26365 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -12,7 +12,7 @@

Current Member? - <%= raw(@user.member_status) %> + <%= raw(@user.member_status_symbol) %>

@@ -20,12 +20,6 @@ <%= @user.instructor? %>

-

- Admin? - <%= @user.admin? %> -

- - <% if current_user.admin? then %>

Email: @@ -56,6 +50,10 @@ Payment Method: <%= @user.payment_method %>

+

+ Payee: + <%= @user.payee %> +

Phone: <%= @user.phone %> @@ -94,5 +92,12 @@ <% if @user.certifications.blank? %>

  • n/a
  • <% end %> +<% if current_user.admin? then %> +

    + Created: + <%= @user.created_at %> +

    +<% end %> + <% if can? :update, @user then %><%= link_to 'Edit', edit_user_path(@user) %> |<% end %> <%= link_to 'Back', users_path %> diff --git a/config/routes.rb b/config/routes.rb index 5613b4b..606152a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,7 @@ Dooraccess::Application.routes.draw do + resources :payments + resources :user_certifications resources :certifications diff --git a/db/migrate/20130212030630_create_payments.rb b/db/migrate/20130212030630_create_payments.rb new file mode 100644 index 0000000..55c7a23 --- /dev/null +++ b/db/migrate/20130212030630_create_payments.rb @@ -0,0 +1,11 @@ +class CreatePayments < ActiveRecord::Migration + def change + create_table :payments do |t| + t.references :user + t.date :date + + t.timestamps + end + add_index :payments, :user_id + end +end diff --git a/db/migrate/20130212032046_add_created_by_to_payments.rb b/db/migrate/20130212032046_add_created_by_to_payments.rb new file mode 100644 index 0000000..6b23ec9 --- /dev/null +++ b/db/migrate/20130212032046_add_created_by_to_payments.rb @@ -0,0 +1,5 @@ +class AddCreatedByToPayments < ActiveRecord::Migration + def change + add_column :payments, :created_by, :integer + end +end diff --git a/db/migrate/20130212054755_add_payee_to_users.rb b/db/migrate/20130212054755_add_payee_to_users.rb new file mode 100644 index 0000000..a757d15 --- /dev/null +++ b/db/migrate/20130212054755_add_payee_to_users.rb @@ -0,0 +1,5 @@ +class AddPayeeToUsers < ActiveRecord::Migration + def change + add_column :users, :payee, :string + end +end diff --git a/db/migrate/20130212083412_add_accountant_to_users.rb b/db/migrate/20130212083412_add_accountant_to_users.rb new file mode 100644 index 0000000..a6ca5c8 --- /dev/null +++ b/db/migrate/20130212083412_add_accountant_to_users.rb @@ -0,0 +1,5 @@ +class AddAccountantToUsers < ActiveRecord::Migration + def change + add_column :users, :accountant, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index bf8e2f2..19fced1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130209103457) do +ActiveRecord::Schema.define(:version => 20130212083412) do create_table "cards", :force => true do |t| t.string "card_number" @@ -58,6 +58,16 @@ ActiveRecord::Schema.define(:version => 20130209103457) do add_index "macs", ["user_id"], :name => "index_macs_on_user_id" + create_table "payments", :force => true do |t| + t.integer "user_id" + t.date "date" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "created_by" + end + + add_index "payments", ["user_id"], :name => "index_payments_on_user_id" + create_table "user_certifications", :force => true do |t| t.integer "user_id" t.integer "certification_id" @@ -96,6 +106,8 @@ ActiveRecord::Schema.define(:version => 20130209103457) do t.boolean "instructor" t.boolean "hidden" t.string "marketing_source" + t.string "payee" + t.boolean "accountant" end add_index "users", ["email"], :name => "index_users_on_email", :unique => true diff --git a/test/fixtures/payments.yml b/test/fixtures/payments.yml new file mode 100644 index 0000000..c3d297c --- /dev/null +++ b/test/fixtures/payments.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + user: + date: 2013-02-11 + +two: + user: + date: 2013-02-11 diff --git a/test/functional/payments_controller_test.rb b/test/functional/payments_controller_test.rb new file mode 100644 index 0000000..63a037a --- /dev/null +++ b/test/functional/payments_controller_test.rb @@ -0,0 +1,49 @@ +require 'test_helper' + +class PaymentsControllerTest < ActionController::TestCase + setup do + @payment = payments(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:payments) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create payment" do + assert_difference('Payment.count') do + post :create, :payment => { :date => @payment.date } + end + + assert_redirected_to payment_path(assigns(:payment)) + end + + test "should show payment" do + get :show, :id => @payment + assert_response :success + end + + test "should get edit" do + get :edit, :id => @payment + assert_response :success + end + + test "should update payment" do + put :update, :id => @payment, :payment => { :date => @payment.date } + assert_redirected_to payment_path(assigns(:payment)) + end + + test "should destroy payment" do + assert_difference('Payment.count', -1) do + delete :destroy, :id => @payment + end + + assert_redirected_to payments_path + end +end diff --git a/test/unit/helpers/payments_helper_test.rb b/test/unit/helpers/payments_helper_test.rb new file mode 100644 index 0000000..f400942 --- /dev/null +++ b/test/unit/helpers/payments_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class PaymentsHelperTest < ActionView::TestCase +end diff --git a/test/unit/payment_test.rb b/test/unit/payment_test.rb new file mode 100644 index 0000000..13cc3cf --- /dev/null +++ b/test/unit/payment_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PaymentTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end