Finalized payments and CSVs and inactivity

This commit is contained in:
Will Bradley 2013-08-28 08:19:01 -07:00
parent e8e024c042
commit 25c0d1e1cb
11 changed files with 120 additions and 13 deletions

View File

@ -5,6 +5,8 @@ def index
@recent_certs = UserCertification.where("created_at > ?", DateTime.now - 7.days).count @recent_certs = UserCertification.where("created_at > ?", DateTime.now - 7.days).count
@num_users = User.count @num_users = User.count
@recent_users = User.where("created_at > ?", DateTime.now - 7.days).count @recent_users = User.where("created_at > ?", DateTime.now - 7.days).count
@num_paid_users = User.all.select{|u| u.member_status >= 250 }.count
@num_delinquent_users = User.all.select{|u| !u.payment_status }.count
if can? :read, User then if can? :read, User then
@recent_user_names = User.where("member_level > 10").accessible_by(current_ability).order('created_at desc').limit(5) @recent_user_names = User.where("member_level > 10").accessible_by(current_ability).order('created_at desc').limit(5)
end end

View File

@ -33,6 +33,10 @@ class UsersController < ApplicationController
end end
end end
def inactive
@users = @users.all.select{|u| u if u.payment_status == false }.sort_by{ |u| -u.delinquency }
end
# GET /users/1 # GET /users/1
# GET /users/1.json # GET /users/1.json
def show def show

View File

@ -35,9 +35,11 @@ class Ability
can :read, UserCertification can :read, UserCertification
end end
# Accountants can manage all # Accountants can manage payments
if user.accountant? if user.accountant?
can :manage, Payment can :manage, Payment
can :manage, Ipn
can :manage, PaypalCsv
end end
# Admins can manage all # Admins can manage all

View File

@ -45,6 +45,7 @@ class Ipn < ActiveRecord::Base
end end
unless response == "VERIFIED" unless response == "VERIFIED"
Rails.logger.error "Invalid IPN: #{response}" Rails.logger.error "Invalid IPN: #{response}"
Rails.logger.error "Data: #{self.data}"
return false return false
end end
@ -58,8 +59,8 @@ class Ipn < ActiveRecord::Base
private private
def create_payment def create_payment
# find user by email, then by payee # find user by email, then by payee
user = User.find_by_email(self.payer_email) user = User.where("lower(email) = ?", self._from_email_address.downcase).first
user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present? user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present?
# Only create payments if the IPN matches a member # Only create payments if the IPN matches a member
if user.present? if user.present?

View File

@ -7,7 +7,6 @@ class Payment < ActiveRecord::Base
validates_presence_of :user_id, :date, :amount # not created_by validates_presence_of :user_id, :date, :amount # not created_by
validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.' validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.'
def human_date def human_date
if date.year < DateTime.now.year if date.year < DateTime.now.year
date.strftime("%b %e, %y") date.strftime("%b %e, %y")

View File

@ -38,8 +38,8 @@ class PaypalCsv < ActiveRecord::Base
private private
def create_payment def create_payment
# find user by email, then by payee # find user by email, then by payee
user = User.find_by_email(self._from_email_address) user = User.where("lower(email) = ?", self._from_email_address.downcase).first
user = User.find_by_payee(self._from_email_address) if user.nil? && self._from_email_address.present? user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present?
# Only create payments if the CSV matches a member # Only create payments if the CSV matches a member
if user.present? if user.present?

View File

@ -89,6 +89,11 @@ class User < ActiveRecord::Base
{25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"} {25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"}
end end
def payment_status
results = payment_status_calculation
return results[:paid]
end
def member_status def member_status
results = member_status_calculation results = member_status_calculation
return results[:rank] return results[:rank]
@ -99,6 +104,15 @@ class User < ActiveRecord::Base
return "<img src='/#{results[:icon]}#{results[:flair]}-coin.png' title='#{results[:message]}' />" return "<img src='/#{results[:icon]}#{results[:flair]}-coin.png' title='#{results[:message]}' />"
end end
def delinquency
if self.payments.count > 0
paydate = self.payments.maximum(:date)
(Date.today - paydate).to_i
else
(Date.today - self.created_at.to_date).to_i
end
end
private private
def member_status_calculation def member_status_calculation
@ -112,7 +126,7 @@ class User < ActiveRecord::Base
case self.member_level.to_i case self.member_level.to_i
when 0..9 when 0..9
if self.payments.count > 0 then if self.payments.count > 0 then
message = "Former Member (#{(DateTime.now - self.payments.last.date).to_i} days ago)" message = "Former Member (#{(DateTime.now - self.payments.maximum(:date)).to_i/30} months ago)"
icon = :timeout icon = :timeout
rank = 1 rank = 1
else else
@ -138,27 +152,41 @@ class User < ActiveRecord::Base
rank = 1000 rank = 1000
end end
payment_results = payment_status_calculation
flair = payment_results[:flair]
rank = rank/10 unless payment_results[:paid]
message = payment_results[:message] unless payment_results[:message].blank?
return {:message => message, :icon => icon, :flair => flair, :rank => rank}
end
def payment_status_calculation
flair = ""
message = ""
paid = true
# Second status item is payment status # Second status item is payment status
case self.member_level.to_i case self.member_level.to_i
when 25..999 when 25..999
# There are payments # There are payments
if self.payments.count > 0 then if self.payments.count > 0 then
# They're on time # They're on time
if self.payments.last.date > (DateTime.now - 60.days) if self.payments.maximum(:date) > (DateTime.now - 60.days)
flair = "-paid" flair = "-paid"
paid = true
else else
message = "Last Payment #{(DateTime.now - self.payments.last.date).to_i/30} months ago" message = "Last Payment #{(DateTime.now - self.payments.maximum(:date)).to_i/30} months ago"
rank = rank/10 paid = false
end end
else else
message = "No Payments Recorded" message = "No Payments Recorded"
rank = rank/10 paid = false
end end
end end
return {:message => message, :paid => paid, :flair => flair}
return {:message => message, :icon => icon, :flair => flair, :rank => rank}
end end
def send_new_user_email def send_new_user_email
Rails.logger.info UserMailer.new_user_email(self).deliver Rails.logger.info UserMailer.new_user_email(self).deliver
end end

View File

@ -27,6 +27,8 @@
<dd><%= @num_users %> (<%= @recent_users %> new in the last 7 days)</dd> <dd><%= @num_users %> (<%= @recent_users %> new in the last 7 days)</dd>
<dt># of People Certified:</dt> <dt># of People Certified:</dt>
<dd><%= @num_certs %> (<%= @recent_certs %> new in the last 7 days)</dd> <dd><%= @num_certs %> (<%= @recent_certs %> new in the last 7 days)</dd>
<dt># of Current Paying Members:</dt>
<dd><%= @num_paid_users %> (<%= @num_delinquent_users %> not-current)</dd>
<dt># of Door Accesses Granted:</dt> <dt># of Door Accesses Granted:</dt>
<dd><%= @num_door_opens %> (<%= @today_door_opens %> today, <%= @recent_door_opens %> in the last 7 days)</dd> <dd><%= @num_door_opens %> (<%= @today_door_opens %> today, <%= @recent_door_opens %> in the last 7 days)</dd>
<dt># of Door Accesses Denied:</dt> <dt># of Door Accesses Denied:</dt>

View File

@ -0,0 +1,65 @@
<h1>Inactive Users</h1>
<table>
<col />
<col />
<% if current_user.admin? then %><col /><% end %>
<col />
<% if current_user.admin? %><col />
<col class="col_highlight" /><% end %>
<col />
<col class="col_highlight" />
<col />
<col class="col_highlight" />
<tr>
<th></th>
<th>Name</th>
<% if current_user.admin? then %><th>Email</th><% end %>
<th>Certifications</th>
<% if current_user.admin? then %>
<th>Orientation?</th>
<% end %>
<th>Card?</th>
<th>Pmt Method</th>
<th>Desired Level</th>
<th>Last Payment</th>
<th>Joined</th>
<th></th>
<th></th>
</tr>
<% if !@users.blank? %>
<% @users.each do |user| %>
<tr<%= " class='hidden'" if user.hidden? %>>
<td><%= image_tag user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png"), :class => :avatar %></td>
<td><%= link_to user.name, user %></td>
<% if current_user.admin? then %><td><%= user.email %></td><% end %>
<td><% user.certifications.each do |c| %>
<%= link_to c.name, c %><%= "," unless c.id == user.certifications.last.id %>
<% end %></td>
<% if current_user.admin? then %><td>
<%= unless user.orientation.blank? then raw("<span class='hoverinfo' title='"+user.orientation.strftime("%B %d %Y")+"'>&#x2713;</span>") end %>
</td><% end %>
<td><%= unless user.cards.blank? then raw("<span class='iconinfo'>&#x2713;</span>") end %></td>
<td><%= user.payment_method %></td>
<td><%= user.member_level %></td>
<td><% delinquency = user.delinquency %>
<% if delinquency == 9999 %>
No Payments
<% else %>
<%= (delinquency/30).to_s+" mo. ago" %>
<% end %>
</td>
<td><%= user.created_at.to_date %></td>
<td><%= link_to 'Edit', edit_user_path(user) if can? :update, user %></td>
<td><%= 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 %></td>
</tr>
<% end %>
<% end %>
</table>
<% if current_user.orientation.blank? then %>
<p class="alert">There's a lot more to see here, but our records show you haven't completed the new member orientation yet. If that's incorrect, please contact a volunteer.</p>
<% end %>
<br />

View File

@ -6,6 +6,9 @@
<% if can? :manage, User %> <% if can? :manage, User %>
| <%= link_to 'Merge Users', users_merge_path %> | <%= link_to 'Merge Users', users_merge_path %>
<% end %> <% end %>
<% if current_user.admin? %>
| <%= link_to 'Inactive Users', users_inactive_path %>
<% end %>
<table> <table>
<col /> <col />
<col /> <col />

View File

@ -28,6 +28,7 @@ Dooraccess::Application.routes.draw do
match 'user_summary/:id' => 'users#user_summary' # User summary view match 'user_summary/:id' => 'users#user_summary' # User summary view
match 'users/merge' => 'users#merge_view', :via => :get # Merge view match 'users/merge' => 'users#merge_view', :via => :get # Merge view
match 'users/merge' => 'users#merge_action', :via => :post # Merge action match 'users/merge' => 'users#merge_action', :via => :post # Merge action
match 'users/inactive' => 'users#inactive' # Inactive users report
resources :users resources :users
match 'users/create' => 'users#create', :via => :post # Use POST users/create instead of POST users to avoid devise conflict match 'users/create' => 'users#create', :via => :post # Use POST users/create instead of POST users to avoid devise conflict