Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 69a57bc63b | |||
| c662be6dc0 | |||
| ca7808a525 | |||
| 9fb2507aa1 | |||
| 0be2834a5d | |||
| ef46bf6a98 | |||
| 45bac6cae4 | |||
| 4dba2b8c3d | |||
| 18bc427eb3 | |||
| 810ff6b034 | |||
| ae031838dc | |||
| 59b6e3c838 | |||
| 98be42e9f9 | |||
| b5d9514914 | |||
| 125ad76a1c | |||
| 4067477cd4 | |||
| 9e4b79a353 | |||
| f8f11e3d7e | |||
| 805148ee40 | |||
| f111769b20 | |||
| eb782f11d5 | |||
| ec4cf4dea9 | |||
| 75e4907a9c | |||
| 20a007cac5 | |||
| 719b9447ab | |||
| 8a7fe29f6d | |||
| e630c81298 | |||
| cefd4b3878 | |||
| ed75ea0e90 | |||
| 3fb774d057 | |||
| 0ced399651 | |||
| 02920837e2 | |||
| 63913c0be3 | |||
| ac66cb0cbe | |||
| 1f63709887 | |||
| 3f3eb1ed65 | |||
| f1b752a4c4 | |||
| 2d0735e914 | |||
| d156edd683 | |||
| 1b64a6b931 | |||
| 1239d6682b | |||
| 50171effad | |||
| 43e2cdba78 | |||
| f3498ddcac | |||
| 04764af983 | |||
| 998558cd30 | |||
| 048ce52111 | |||
| a7e999614c | |||
| 6673573e36 |
4
Gemfile
@@ -1,5 +1,7 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
#ruby '1.9.3'
|
||||
|
||||
gem 'rails', '3.2.3'
|
||||
|
||||
# Bundle edge Rails instead:
|
||||
@@ -40,7 +42,7 @@ gem 'bcrypt-ruby', '~> 3.0.0'
|
||||
# gem 'capistrano'
|
||||
|
||||
# To use debugger
|
||||
# gem 'ruby-debug'
|
||||
#gem 'debugger'
|
||||
|
||||
#gem "paperclip", "~> 3.0"
|
||||
gem 'gravtastic'
|
||||
|
||||
3
app/assets/javascripts/ipn.js.coffee
Normal file
@@ -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/
|
||||
3
app/assets/javascripts/mac_logs.js.coffee
Normal file
@@ -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/
|
||||
3
app/assets/javascripts/pamela.js.coffee
Normal file
@@ -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/
|
||||
3
app/assets/javascripts/payments.js.coffee
Normal file
@@ -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/
|
||||
@@ -11,3 +11,38 @@
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
*/
|
||||
.caption { display: inline-block; background-color: #eee; border: 1px solid #333; border-radius: 5px; margin-bottom: 1em; }
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 4px 10px 4px;
|
||||
margin-bottom: 0;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px rgba(255,255,255,.75);
|
||||
vertical-align: middle;
|
||||
background-color: #f5f5f5;
|
||||
background-image: -moz-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -ms-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -webkit-gradient(linear,0 0,0 100%,from( #fff),to( #e6e6e6));
|
||||
background-image: -webkit-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -o-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: linear-gradient(top, #fff, #e6e6e6);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
|
||||
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
|
||||
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
border: 1px solid #ccc;
|
||||
border-bottom-color: #bbb;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
cursor: pointer;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Place all the styles related to the home controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
table, td { vertical-align: top }
|
||||
|
||||
3
app/assets/stylesheets/ipn.css.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the Ipn controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
3
app/assets/stylesheets/mac_logs.css.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the MacLogs controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
4
app/assets/stylesheets/macs.css.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
// Place all the styles related to the pamela controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
.hidden { color: #ccc; }
|
||||
3
app/assets/stylesheets/payments.css.scss
Normal file
@@ -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/
|
||||
@@ -9,6 +9,23 @@ class CardsController < ApplicationController
|
||||
#authorize! :read, @cards
|
||||
@cards = @cards.sort_by{|e| e[:id]}
|
||||
|
||||
if can? :read, DoorLog then
|
||||
Rails.logger.info "CARD STATS:"
|
||||
most_active_count = 0
|
||||
@most_active_card = nil
|
||||
@cards.each do |card|
|
||||
card_num_R = card.card_number.to_i(16)%32767
|
||||
Rails.logger.info card_num_R
|
||||
card[:accesses_this_week] = DoorLog.where('key = "G" AND data =? AND created_at > ?', card_num_R, DateTime.now - 7.days).order("created_at DESC").count
|
||||
Rails.logger.info card[:accesses_this_week]
|
||||
if(card[:accesses_this_week] > most_active_count) then
|
||||
Rails.logger.info "ACTIVE"
|
||||
most_active_count = card[:accesses_this_week]
|
||||
@most_active_card = card
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render :json => @cards }
|
||||
@@ -18,8 +35,10 @@ class CardsController < ApplicationController
|
||||
# GET /cards/1
|
||||
# GET /cards/1.json
|
||||
def show
|
||||
#@card = Card.find(params[:id])
|
||||
|
||||
if can? :read, DoorLog then
|
||||
card_num_R = @card.card_number.to_i(16)%32767
|
||||
@door_logs = DoorLog.where('key = "R" AND data =?', card_num_R).order("created_at DESC")
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render :json => @card }
|
||||
|
||||
@@ -5,10 +5,16 @@ def index
|
||||
@recent_certs = UserCertification.where("created_at > ?", DateTime.now - 7.days).count
|
||||
@num_users = User.count
|
||||
@recent_users = User.where("created_at > ?", DateTime.now - 7.days).count
|
||||
if can? :read, User then
|
||||
@recent_user_names = User.where("member_level > 10").accessible_by(current_ability).order('created_at desc').limit(5)
|
||||
end
|
||||
@num_door_opens = DoorLog.where("key = 'G'").count
|
||||
@today_door_opens = DoorLog.where("key = 'G' AND created_at > ?", DateTime.now - 1.day).count
|
||||
@recent_door_opens = DoorLog.where("key = 'G' AND created_at > ?", DateTime.now - 7.days).count
|
||||
@num_door_denieds = DoorLog.where("key = 'D'").count
|
||||
@recent_door_denieds = DoorLog.where("key = 'D' AND created_at > ?", DateTime.now - 7.days).count
|
||||
@num_door_denieds = DoorLog.where("key = 'f'").count
|
||||
@recent_door_denieds = DoorLog.where("key = 'f' AND created_at > ?", DateTime.now - 7.days).count
|
||||
@num_macs = Mac.count
|
||||
@recent_macs = Mac.where("since > ?", DateTime.now - 1.day).count
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
|
||||
54
app/controllers/ipns_controller.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
class IpnsController < ApplicationController
|
||||
load_and_authorize_resource :ipn, :except => [:new, :create]
|
||||
before_filter :authenticate_user!, :except => [:new, :create]
|
||||
|
||||
protect_from_forgery :except => [:create]
|
||||
|
||||
def index
|
||||
@ipns = Ipn.all
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
@ipn = Ipn.new_from_dynamic_params(params)
|
||||
@ipn.data = params.to_json
|
||||
@ipn.save
|
||||
render :nothing => true
|
||||
#unless @ipn.validate!
|
||||
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
|
||||
#end
|
||||
end
|
||||
|
||||
def import
|
||||
@ipn = Ipn.new_from_dynamic_params(params)
|
||||
@ipn.data = params.to_json
|
||||
@ipn.save
|
||||
redirect_to ipn_path(@ipn)
|
||||
#unless @ipn.validate!
|
||||
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
|
||||
#end
|
||||
end
|
||||
|
||||
def validate
|
||||
if @ipn.validate!
|
||||
redirect_to ipns_url, :notice => 'Valid!'
|
||||
else
|
||||
redirect_to ipns_url, :notice => 'INVALID'
|
||||
end
|
||||
end
|
||||
|
||||
def link
|
||||
result = @ipn.link_payment
|
||||
if result.first
|
||||
redirect_to ipns_url, :notice => 'Payment was successfully linked.'
|
||||
else
|
||||
redirect_to ipns_url, :notice => result.last
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
9
app/controllers/mac_logs_controller.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class MacLogsController < ApplicationController
|
||||
load_and_authorize_resource :mac_log
|
||||
before_filter :authenticate_user!
|
||||
|
||||
def index
|
||||
@mac_logs = MacLog.desc.limit(1000)
|
||||
end
|
||||
|
||||
end
|
||||
261
app/controllers/macs_controller.rb
Normal file
@@ -0,0 +1,261 @@
|
||||
class MacsController < ApplicationController
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
today = Date.today
|
||||
event = Date.new(2013,9,1)
|
||||
|
||||
if today == event
|
||||
redirect_to main_app.root_url, :alert => "CryptoParty today; no MAC scanning. Sorry, NSA!"
|
||||
else
|
||||
redirect_to main_app.root_url, :alert => "Nothing to see here!"
|
||||
end
|
||||
end
|
||||
load_and_authorize_resource :mac
|
||||
load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import]
|
||||
|
||||
#require "active_record"
|
||||
require "optparse"
|
||||
#require "rubygems"
|
||||
|
||||
def index
|
||||
#@active_macs = Mac.where(:active => true, :hidden => false)
|
||||
#@active_macs += Mac.where(:active => true, :hidden => nil)
|
||||
|
||||
# De-dupe users for the public
|
||||
if can? :update, Mac then
|
||||
@active_macs = Mac.where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).includes(:user).order("users.name ASC")
|
||||
elsif user_signed_in? then
|
||||
@active_macs = Mac.where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).includes(:user).order("users.name ASC").group("users.name")
|
||||
else
|
||||
@active_macs = Mac.select("mac, note, user_id").where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).joins(:user).order("users.name ASC").group("users.name")
|
||||
end
|
||||
|
||||
@hidden_macs = Mac.where("macs.active = ? AND macs.hidden = ?", true, true).order("note ASC")
|
||||
|
||||
@all_macs = Mac.find(:all, :order => "LOWER(mac)")
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json {
|
||||
@filtered_macs = Mac.select("macs.mac, users.name, macs.note").where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).joins(:user)
|
||||
render :json => @filtered_macs
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# GET /macs/1
|
||||
# GET /macs/1.json
|
||||
def show
|
||||
@mac = Mac.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render :json => @macs }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /macs/new
|
||||
# GET /macs/new.json
|
||||
def new
|
||||
@mac = Mac.new
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render :json => @mac }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /macs/1/edit
|
||||
def edit
|
||||
@mac = Mac.find(params[:id])
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
end
|
||||
|
||||
# POST /macs
|
||||
# POST /user
|
||||
def create
|
||||
@mac = Mac.new(params[:mac])
|
||||
authorize! :update, @mac
|
||||
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
if @mac.save
|
||||
format.html { redirect_to macs_path, :notice => 'Mac was successfully created.' }
|
||||
format.json { render :json => @mac, :status => :created, :location => @mac }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /macs/1
|
||||
# PUT /macs/1.json
|
||||
def update
|
||||
#Log who updated this
|
||||
@mac = Mac.find(params[:id])
|
||||
@mac.assign_attributes(params[:mac])
|
||||
#@mac.user_id = params[:mac][:user_id]
|
||||
authorize! :update, @mac
|
||||
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
if @mac.save
|
||||
format.html { redirect_to macs_path, :notice => 'Mac was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def scan
|
||||
Rails.logger.info "starting scan..."
|
||||
# Command line arguments
|
||||
options = {};
|
||||
OptionParser.new { |opts|
|
||||
opts.banner = "Usage: pamela-scanner.rb --interface=en0"
|
||||
|
||||
options[:verbose] = true
|
||||
opts.on("v", "--verbose", "Run verbosely") { |verbose|
|
||||
options[:verbose] = verbose
|
||||
}
|
||||
|
||||
options[:interface] = "eth0"
|
||||
opts.on("i", "--interface=interface", "Network Interface") { |interface|
|
||||
options[:interface] = interface
|
||||
}
|
||||
|
||||
options[:max_age] = 20
|
||||
opts.on("a", "--max-age=minutes", "Minutes to keep expired macs active") { |max_age|
|
||||
options[:max_age] = max_age.to_i
|
||||
}
|
||||
|
||||
options[:db_host] = "configure_me"
|
||||
opts.on("r", "--db-host=host", "Database Host") { |host|
|
||||
options[:db_host] = host
|
||||
}
|
||||
|
||||
options[:db_name] = "configure_me"
|
||||
opts.on("n", "--db-name=name", "Database Name") { |name|
|
||||
options[:db_name] = name
|
||||
}
|
||||
|
||||
options[:db_user] = "configure_me"
|
||||
opts.on("u", "--db-user=user", "Database User") { |user|
|
||||
options[:db_user] = user
|
||||
}
|
||||
|
||||
options[:db_password] = "configure_me"
|
||||
opts.on("p", "--db-password=password", "Database Password") { |password|
|
||||
options[:db_password] = password
|
||||
}
|
||||
|
||||
}.parse!
|
||||
|
||||
# Open the database
|
||||
#ActiveRecord::Base::establish_connection(
|
||||
# :adapter => "mysql2",
|
||||
# :host => options[:db_host],
|
||||
# :database => options[:db_name],
|
||||
# :username => options[:db_user],
|
||||
# :password => options[:db_password])
|
||||
|
||||
#class Mac < ActiveRecord::Base
|
||||
#end
|
||||
|
||||
#class MacLog < ActiveRecord::Base
|
||||
#end
|
||||
|
||||
# Scan the network for mac addresses
|
||||
macs = {};
|
||||
command = sprintf("arp-scan -R --interface=%s --localnet", options[:interface])
|
||||
if options[:verbose]
|
||||
Rails.logger.info "Running [#{command}]"
|
||||
end
|
||||
IO.popen(command) { |stdin|
|
||||
Rails.logger.info "Reading stdin: "+stdin.inspect
|
||||
stdin.each { |line|
|
||||
next if line !~ /^([\d\.]+)\s+([[:xdigit:]:]+)\s/;
|
||||
macs[$2] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
# Scan the existing macs and update each record as necessary
|
||||
Mac.find(:all).each { |entry|
|
||||
mac = entry.mac.downcase
|
||||
ip = entry.ip
|
||||
if macs.has_key?(mac)
|
||||
if ! entry.active || ! entry.since
|
||||
Rails.logger.info "Activating #{mac} at #{ip}" if options[:verbose]
|
||||
entry.since = Time.now
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
end
|
||||
entry.active = 1
|
||||
entry.ip = ip
|
||||
entry.refreshed = Time.now
|
||||
entry.save
|
||||
macs.delete(mac)
|
||||
next
|
||||
end
|
||||
|
||||
# Entry is no longer current
|
||||
if entry.active
|
||||
ageMinutes = ((Time.now - entry.refreshed)/60).to_i
|
||||
next if ageMinutes < options[:max_age]
|
||||
Rails.logger.info "Deactivating #{mac}, #{ageMinutes} minutes old" if options[:verbose]
|
||||
entry.active = 0
|
||||
entry.save
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "deactivate").save
|
||||
end
|
||||
}
|
||||
|
||||
# Add entries for any macs not already in the db
|
||||
macs.each { |mac, ip|
|
||||
Rails.logger.info "Activating new entry #{mac} at #{ip}" if options[:verbose]
|
||||
Mac.new(:mac => mac, :ip => ip, :active => 1, :since => Time.now, :refreshed => Time.now).save
|
||||
Rails.logger.info MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
}
|
||||
|
||||
@log = MacLog.all
|
||||
|
||||
end #def scan
|
||||
|
||||
|
||||
def import
|
||||
|
||||
require 'csv'
|
||||
|
||||
csv_text = File.read('mac_log.csv')
|
||||
csv = CSV.parse(csv_text)
|
||||
|
||||
@output = []
|
||||
|
||||
csv.each do |row|
|
||||
@output += [row[1], Mac.create({:mac => row[0], :note => row[1], :hidden => row[2]}) ]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
88
app/controllers/payments_controller.rb
Normal file
@@ -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.where(:hidden => false).where("member_level > 10").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
|
||||
@@ -6,7 +6,7 @@ class UserCertificationsController < ApplicationController
|
||||
|
||||
# Load users and certs based on current ability
|
||||
before_filter :only => [:new, :edit, :create, :update] do
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
@users = User.where(:hidden => [false,nil]).accessible_by(current_ability).sort_by(&:name)
|
||||
@certifications = Certification.accessible_by(current_ability).sort_by(&:name)
|
||||
end
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -36,12 +36,21 @@ class UsersController < ApplicationController
|
||||
# GET /users/1
|
||||
# GET /users/1.json
|
||||
def show
|
||||
@payments = Payment.where(:user_id => @user.id).order('date desc').limit(10)
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render :json => @user }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /user_summary/1
|
||||
def user_summary
|
||||
respond_to do |format|
|
||||
format.html { render :partial => "user_summary" } # show.html.erb
|
||||
format.json { render :json => @user }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /users/new
|
||||
# GET /users/new.json
|
||||
def new
|
||||
@@ -60,7 +69,7 @@ class UsersController < ApplicationController
|
||||
def create
|
||||
respond_to do |format|
|
||||
if @user.save
|
||||
format.html { redirect_to users_url, :notice => 'User was successfully created.' }
|
||||
format.html { redirect_to @user, :notice => 'User was successfully created.' }
|
||||
format.json { render :json => @user, :status => :created, :location => @user }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
@@ -74,7 +83,7 @@ class UsersController < ApplicationController
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @user.update_attributes(params[:user])
|
||||
format.html { redirect_to users_url, :notice => 'User was successfully updated.' }
|
||||
format.html { redirect_to @user, :notice => 'User was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
@@ -83,6 +92,37 @@ class UsersController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
# GET /users/merge
|
||||
def merge_view
|
||||
@users = @users.sort_by(&:name)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # merge_view.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# POST /users/merge
|
||||
def merge_action
|
||||
@user_to_keep = User.find(params[:user][:to_keep])
|
||||
Rails.logger.info "USER TO KEEP:"
|
||||
Rails.logger.info @user_to_keep.inspect
|
||||
@user_to_merge = User.find(params[:user][:to_merge])
|
||||
Rails.logger.info "USER TO MERGE:"
|
||||
Rails.logger.info @user_to_merge.inspect
|
||||
|
||||
@user_to_keep.absorb_user(@user_to_merge)
|
||||
|
||||
Rails.logger.info "RESULT:"
|
||||
Rails.logger.info @user_to_keep.inspect
|
||||
Rails.logger.info @user_to_keep.cards.inspect
|
||||
Rails.logger.info @user_to_keep.user_certifications.inspect
|
||||
Rails.logger.info @user_to_keep.payments.inspect
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @user_to_keep, :notice => 'Users successfully merged.' }
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /users/1
|
||||
# DELETE /users/1.json
|
||||
def destroy
|
||||
|
||||
2
app/helpers/ipn_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module IpnHelper
|
||||
end
|
||||
2
app/helpers/mac_logs_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module MacLogsHelper
|
||||
end
|
||||
2
app/helpers/pamela_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module PamelaHelper
|
||||
end
|
||||
2
app/helpers/payments_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module PaymentsHelper
|
||||
end
|
||||
13
app/mailers/user_mailer.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class UserMailer < ActionMailer::Base
|
||||
default :from => "wiki@heatsynclabs.org"
|
||||
|
||||
def new_user_email(user)
|
||||
@user = user
|
||||
@url = "http://members.heatsynclabs.org"
|
||||
|
||||
#@admins = User.where(:name => "Will Bradley")
|
||||
#@admins.each do |admin|
|
||||
mail(:to => 'info@heatsynclabs.org', :subject => "New HSL Member: "+user.name)
|
||||
#end
|
||||
end
|
||||
end
|
||||
@@ -2,23 +2,32 @@ class Ability
|
||||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
# Anonymous can read mac
|
||||
today = Date.today
|
||||
event = Date.new(2013,9,1)
|
||||
|
||||
unless today == event
|
||||
can :read, Mac
|
||||
can :scan, Mac # Need anonymous so CRON can scan
|
||||
end
|
||||
|
||||
if !user.nil?
|
||||
|
||||
# By default, users can only see their own stuff
|
||||
can :read, Card, :user_id => user.id
|
||||
can :read, Certification
|
||||
can :read_details, Mac unless today == event
|
||||
can [:update], Mac, :user_id => nil
|
||||
can [:create,:update], Mac, :user_id => user.id
|
||||
can :read, User, :id => user.id #TODO: why can users update themselves?
|
||||
can :read, UserCertification, :user_id => user.id
|
||||
|
||||
# Admins can manage all
|
||||
if user.admin?
|
||||
can :manage, :all
|
||||
end
|
||||
# Instructors can manage certs and see users
|
||||
if user.instructor?
|
||||
can :manage, Certification
|
||||
can [:create,:read], User, :hidden => [nil,false]
|
||||
can :manage, UserCertification
|
||||
can [:create,:read], UserCertification
|
||||
can [:update,:destroy], UserCertification, :created_by => user.id
|
||||
end
|
||||
# Users can see others' stuff if they've been oriented
|
||||
unless user.orientation.blank?
|
||||
@@ -26,12 +35,25 @@ 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
|
||||
end
|
||||
|
||||
# Prevent all destruction for now
|
||||
cannot :destroy, User
|
||||
cannot :destroy, Card
|
||||
#cannot :destroy, User
|
||||
#cannot :destroy, Card
|
||||
cannot :destroy, Certification
|
||||
cannot :destroy, UserCertification
|
||||
cannot :destroy, Mac
|
||||
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:
|
||||
#
|
||||
|
||||
@@ -2,6 +2,7 @@ class Card < ActiveRecord::Base
|
||||
require 'open-uri'
|
||||
|
||||
attr_accessible :id, :user_id, :name, :card_number, :card_permissions
|
||||
validates_presence_of :user_id, :card_number, :card_permissions
|
||||
validates_uniqueness_of :id, :card_number
|
||||
belongs_to :user
|
||||
|
||||
@@ -12,7 +13,7 @@ class Card < ActiveRecord::Base
|
||||
|
||||
# connect to door access system
|
||||
source = open("#{door_access_url}?e=#{door_access_password}").read
|
||||
results = source.scan(/authok/)
|
||||
results = source.scan(/ok/)
|
||||
if(results.size > 0) then
|
||||
#only continue if we've got an OK login
|
||||
cardid = self.id.to_s.rjust(3, '0') #TODO: provide ability for
|
||||
@@ -47,7 +48,7 @@ class Card < ActiveRecord::Base
|
||||
door_access_password = APP_CONFIG['door_access_password']
|
||||
|
||||
source = open("#{door_access_url}?e=#{door_access_password}").read
|
||||
results = source.scan(/authok/)
|
||||
results = source.scan(/ok/)
|
||||
if(results.size > 0) then
|
||||
@cards.each do |u|
|
||||
#only continue if we've got an OK login
|
||||
|
||||
@@ -9,7 +9,7 @@ class DoorLog < ActiveRecord::Base
|
||||
|
||||
# connect to door access system
|
||||
source = open("#{door_access_url}?e=#{door_access_password}").read
|
||||
results = source.scan(/authok/)
|
||||
results = source.scan(/ok/)
|
||||
if(results.size > 0) then
|
||||
@end_results = Array.new
|
||||
|
||||
|
||||
86
app/models/ipn.rb
Normal file
@@ -0,0 +1,86 @@
|
||||
require 'net/http'
|
||||
class Ipn < ActiveRecord::Base
|
||||
attr_accessible :data
|
||||
belongs_to :payment
|
||||
|
||||
after_create :create_payment
|
||||
|
||||
def self.new_from_dynamic_params(params)
|
||||
ipn = Ipn.new()
|
||||
|
||||
ipn.attributes.each do |c|
|
||||
unless params[c.first.to_sym].nil?
|
||||
ipn[c.first.to_sym] = params[c.first.to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
return ipn
|
||||
end
|
||||
|
||||
# Post back to Paypal to make sure it's valid
|
||||
def validate!
|
||||
uri = URI.parse('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate')
|
||||
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.open_timeout = 60
|
||||
http.read_timeout = 60
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
http.use_ssl = true
|
||||
response = http.post(uri.request_uri, self.data,
|
||||
'Content-Length' => "#{self.data.size}",
|
||||
'User-Agent' => "Ruby on Rails"
|
||||
).body
|
||||
|
||||
unless ["VERIFIED", "INVALID"].include?(response)
|
||||
Rails.logger.error "Faulty paypal result: #{response}"
|
||||
return false
|
||||
end
|
||||
unless response == "VERIFIED"
|
||||
Rails.logger.error "Invalid IPN: #{response}"
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def link_payment
|
||||
create_payment
|
||||
end
|
||||
|
||||
private
|
||||
def create_payment
|
||||
# find user by email, then by payee
|
||||
user = User.find_by_email(self.payer_email)
|
||||
user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present?
|
||||
|
||||
# Only create payments if the IPN matches a member
|
||||
if user.present?
|
||||
# And is a payment (not a cancellation, etc)
|
||||
payment_types = ["subscr_payment","send_money"]
|
||||
if payment_types.include?(self.txn_type)
|
||||
# And a member level
|
||||
if User.member_levels[self.payment_gross.to_i].present?
|
||||
payment = Payment.new
|
||||
payment.date = Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
|
||||
payment.user_id = user.id
|
||||
payment.amount = self.payment_gross
|
||||
if payment.save
|
||||
self.payment_id = payment.id
|
||||
self.save!
|
||||
else
|
||||
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Transaction is a '#{self.txn_type}' instead of '#{payment_types.inspect}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."]
|
||||
end
|
||||
|
||||
return [true]
|
||||
end
|
||||
|
||||
end
|
||||
6
app/models/mac.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class Mac < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
attr_accessible :active, :ip, :mac, :refreshed, :since, :hidden, :note, :user_id
|
||||
|
||||
validates_uniqueness_of :mac, :case_sensitive => false
|
||||
end
|
||||
5
app/models/mac_log.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class MacLog < ActiveRecord::Base
|
||||
attr_accessible :action, :ip, :mac
|
||||
|
||||
scope :desc, order("mac_logs.created_at DESC")
|
||||
end
|
||||
17
app/models/payment.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class Payment < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
has_one :ipn
|
||||
attr_accessible :date, :user_id, :created_by, :amount
|
||||
|
||||
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.'
|
||||
|
||||
|
||||
def human_date
|
||||
if date.year < DateTime.now.year
|
||||
date.strftime("%b %e, %y")
|
||||
else
|
||||
date.strftime("%b %e")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,40 +9,158 @@ 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 #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 absorb_user(user_to_absorb)
|
||||
# copy all attributes except email, password, name, and anything that isn't blank on the destination
|
||||
user_to_absorb.attributes.each_pair {|k,v|
|
||||
unless (v.nil? || k == :id || k == :email || k == :password || k == :name || k == :password_confirmation || k == :hidden || k == 'hidden' || k == :encrypted_password || !self.attributes[k].blank? )
|
||||
Rails.logger.info "Updating "+k.to_s+" from "+self[k].to_s
|
||||
self[k] = v
|
||||
Rails.logger.info "Updated "+k.to_s+" to "+self[k].to_s
|
||||
end
|
||||
}
|
||||
|
||||
self.save!
|
||||
|
||||
user_to_absorb.cards.each {|card|
|
||||
Rails.logger.info "CARD BEFORE: "+card.inspect
|
||||
card.user_id = self.id
|
||||
card.save!
|
||||
Rails.logger.info "CARD AFTER: "+card.inspect
|
||||
}
|
||||
user_to_absorb.user_certifications.each {|user_cert|
|
||||
Rails.logger.info "CERT BEFORE: "+user_cert.inspect
|
||||
user_cert.user_id = self.id
|
||||
user_cert.save!
|
||||
Rails.logger.info "CERT AFTER: "+user_cert.inspect
|
||||
}
|
||||
user_to_absorb.payments.each {|payment|
|
||||
Rails.logger.info "PAYMENT BEFORE: "+payment.inspect
|
||||
payment.user_id = self.id
|
||||
payment.save!
|
||||
Rails.logger.info "PAYMENT AFTER: "+payment.inspect
|
||||
}
|
||||
|
||||
user_to_absorb.destroy
|
||||
end
|
||||
|
||||
def name_with_email_and_visibility
|
||||
if hidden then
|
||||
"#{name} (#{email}) HIDDEN"
|
||||
else
|
||||
"#{name} (#{email})"
|
||||
end
|
||||
end
|
||||
|
||||
def name_with_payee_and_member_level
|
||||
if payee.blank? then
|
||||
"#{name} - #{member_level_string}"
|
||||
else
|
||||
"#{payee} for #{name} - #{member_level_string}"
|
||||
end
|
||||
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 self.member_levels
|
||||
{25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"}
|
||||
end
|
||||
|
||||
def member_status
|
||||
output = ""
|
||||
|
||||
if self.member_level.to_i >= 1 then
|
||||
output = "<span class='hoverinfo' title='Inactive'>◌</span>"
|
||||
results = member_status_calculation
|
||||
return results[:rank]
|
||||
end
|
||||
|
||||
unless self.member.nil? then
|
||||
# 1 = inactive, show an X
|
||||
if self.member >= 10 then
|
||||
output = "<span class='hoverinfo' title='Volunteer'>◔</span>"
|
||||
# 25 or higher is paying, show a check
|
||||
end
|
||||
if self.member >= 25 then
|
||||
output = "<span class='hoverinfo' title='25'>◑</span>"
|
||||
end
|
||||
if self.member >= 50 then
|
||||
output = "<span class='hoverinfo' title='50'>◕</span>"
|
||||
end
|
||||
if self.member >= 100 then
|
||||
output = "<span class='hoverinfo' title='100'>●</span>"
|
||||
def member_status_symbol
|
||||
results = member_status_calculation
|
||||
return "<img src='/#{results[:icon]}#{results[:flair]}-coin.png' title='#{results[:message]}' />"
|
||||
end
|
||||
|
||||
if self.member < self.member_level.to_i then
|
||||
output = "<span class='hoverinfo' title='Lapsed'>✗</span>"
|
||||
private
|
||||
|
||||
def member_status_calculation
|
||||
# Begin output buffer
|
||||
message = ""
|
||||
icon = ""
|
||||
flair = ""
|
||||
rank = 0
|
||||
|
||||
# First status item is level
|
||||
case self.member_level.to_i
|
||||
when 0..9
|
||||
if self.payments.count > 0 then
|
||||
message = "Former Member (#{(DateTime.now - self.payments.last.date).to_i} days ago)"
|
||||
icon = :timeout
|
||||
rank = 1
|
||||
else
|
||||
message = "Not a Member"
|
||||
icon = :no
|
||||
rank = 0
|
||||
end
|
||||
when 10..24
|
||||
message = "Volunteer"
|
||||
icon = :heart
|
||||
rank = 101
|
||||
when 25..49
|
||||
message = member_level_string
|
||||
icon = :copper
|
||||
rank = 250
|
||||
when 50..99
|
||||
message = member_level_string
|
||||
icon = :silver
|
||||
rank = 500
|
||||
when 100..999
|
||||
message = member_level_string
|
||||
icon = :gold
|
||||
rank = 1000
|
||||
end
|
||||
|
||||
# Second status item is payment status
|
||||
case self.member_level.to_i
|
||||
when 25..999
|
||||
# There are payments
|
||||
if self.payments.count > 0 then
|
||||
# They're on time
|
||||
if self.payments.last.date > (DateTime.now - 60.days)
|
||||
flair = "-paid"
|
||||
else
|
||||
message = "Last Payment #{(DateTime.now - self.payments.last.date).to_i/30} months ago"
|
||||
rank = rank/10
|
||||
end
|
||||
else
|
||||
message = "No Payments Recorded"
|
||||
rank = rank/10
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
return {:message => message, :icon => icon, :flair => flair, :rank => rank}
|
||||
end
|
||||
|
||||
def send_new_user_email
|
||||
Rails.logger.info UserMailer.new_user_email(self).deliver
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
class UserCertification < ActiveRecord::Base
|
||||
attr_accessible :certification_id, :user_id
|
||||
|
||||
validates_presence_of :certification_id, :user_id
|
||||
validates_uniqueness_of :certification_id, :scope => :user_id, :message => 'already exists for this user.' # Makes sure users don't get certified twice
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :certification
|
||||
|
||||
def user_name
|
||||
if self.user.blank?
|
||||
""
|
||||
else
|
||||
self.user.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @card.user_id = params[:user] if params[:user].present? %>
|
||||
<div class="field">
|
||||
<%= f.label :user %><br />
|
||||
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name) %>
|
||||
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :name, "Card Note" %><br />
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
<%= link_to 'New Card', new_card_path if can? :create, Card %>
|
||||
<%= link_to 'Upload all cards', upload_all_path if can? :upload_all, Card %>
|
||||
<%= link_to 'Door Logs', door_logs_path if can? :read, DoorLog %>
|
||||
<p>
|
||||
<b>Most Active Card Last 7 Days:</b> <%= @most_active_card.name unless @most_active_card.blank? %> (<%= @most_active_card.accesses_this_week unless @most_active_card.blank? %> times)
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<col />
|
||||
<col />
|
||||
@@ -14,6 +19,7 @@
|
||||
<th>DB ID</th>
|
||||
<th>Card #</th>
|
||||
<th>Access?</th>
|
||||
<th>Accesses Last 7 Days</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
@@ -22,11 +28,18 @@
|
||||
<% if !@cards.blank? %>
|
||||
<% @cards.each do |card| %>
|
||||
<tr>
|
||||
<td><%= card.user.name %></td>
|
||||
<td>
|
||||
<% if card.user.nil? %>
|
||||
n/a
|
||||
<% else %>
|
||||
<%= link_to card.user.name , card %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= card.name %></td>
|
||||
<td><%= card.id %></td>
|
||||
<td><%= card.card_number %></td>
|
||||
<td><%= if card.card_permissions == 1 then "Access" end %></td>
|
||||
<td><%= card.accesses_this_week unless card.accesses_this_week < 1 %></td>
|
||||
<td><%= link_to 'Upload', upload_path(card) if can? :upload, card %></td>
|
||||
<td><%= link_to 'Edit', edit_card_path(card) if can? :update, card %></td>
|
||||
<td><%= link_to 'Destroy', card, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE CARD FROM THE DOOR SYSTEM! DISABLE AND UPLOAD IT FIRST.', :method => :delete if can? :destroy, card %></td>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<p>
|
||||
<b>User:</b>
|
||||
<%= @card.user.name unless @card.user.blank? %>
|
||||
<%= link_to @card.user.name, @card.user unless @card.user.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -20,9 +20,20 @@
|
||||
|
||||
<p>
|
||||
<b>Card Permissions:</b>
|
||||
<%= @card.card_permissions %>
|
||||
<%= if @card.card_permissions == 1 then "Enabled" else "Disabled" end %>
|
||||
</p>
|
||||
|
||||
<% if can? :read, DoorLog %>
|
||||
<p>
|
||||
<b>Access attempts:</b>
|
||||
<ul>
|
||||
<% @door_logs.each do |log| %>
|
||||
<li><%= log.created_at %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Upload to Door', upload_path(@card) if can? :upload, @card %>
|
||||
<% if can? :update, @card then %><%= link_to 'Edit', edit_card_path(@card) %> |<% end %>
|
||||
<%= link_to 'Back', cards_path %>
|
||||
|
||||
@@ -8,13 +8,10 @@
|
||||
<%= simple_format @certification.description %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Certified Users:</b>
|
||||
<ul>
|
||||
<% @certification_users.each do |user| %>
|
||||
<li><%= link_to user.name, user %></li>
|
||||
<% end %>
|
||||
<% if @certification_users.blank? then %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
<%= link_to "Click Here", user_certifications_path %>
|
||||
</p>
|
||||
|
||||
<% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %>
|
||||
<%= link_to 'Back', certifications_path %>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<% if params[:flash] == "welcome_msg" then %>
|
||||
<p class="notice"><strong>Thank for you choosing to become a HeatSync Labs member!</strong> As we foster this community of learning, science, and the arts every member is important. <br/><br/>
|
||||
You can get your payments started by following the instructions on this page. <strong>Please note electronic recurring payments are -highly- encouraged</strong>-- we do not have staff. If you must pay via cash/check, please consider prepaying for 3, 6 or 12 months up front.<br/>
|
||||
<strong>To claim member benefits</strong> such as storage, grab a volunteer during your next stop into HeatSync or schedule a time to meet up in advance. Someone should also be contacting you shortly via the email address you provided.<br/>
|
||||
Please also note that certain privileges like 24/7 card access require community approval.<br/>
|
||||
You can get your payments started by following the instructions on this page. <strong>Please note electronic recurring payments are -highly- encouraged</strong>-- we do not have staff. If you must pay via cash/check, please consider prepaying for 3, 6 or 12 months up front.<br/><br/>
|
||||
<strong>To claim member benefits</strong> such as storage, grab a volunteer during your next stop into HeatSync or schedule a time to meet up in advance. Someone should also be contacting you shortly via the email address you provided.<br/><br/>
|
||||
Please also note that certain privileges like 24/7 card access require community approval.<br/><br/>
|
||||
Thanks again, and happy hacking!</p>
|
||||
<% end %>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => html) do |f| %>
|
||||
<div class="field">
|
||||
<%= f.label :name %><br />
|
||||
<%= f.label :name, "Full Name" %><br />
|
||||
<%= f.text_field :name %>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ Thanks again, and happy hacking!</p>
|
||||
<%= f.text_field :phone %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :emergency_name, "Emergency contact" %><br />
|
||||
<%= f.label :emergency_name, "Emergency Contact Name" %><br />
|
||||
<%= f.text_field :emergency_name %>
|
||||
</div>
|
||||
<div class="field">
|
||||
@@ -41,22 +41,26 @@ Thanks again, and happy hacking!</p>
|
||||
<%= render :partial => "/users/payment_methods", :locals => { :g => f } %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :current_skills %><br />
|
||||
<%= f.label :current_skills, "What skills, knowledge and experience do you bring to the community?" %><br />
|
||||
<%= f.text_area :current_skills %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :desired_skills %><br />
|
||||
<%= f.label :desired_skills, "What skills, knowledge and experiences are you looking for in HeatSync?" %><br />
|
||||
<%= f.text_area :desired_skills %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :marketing_source, "How'd you find out about HeatSync?" %><br />
|
||||
<%= f.text_area :marketing_source %>
|
||||
</div>
|
||||
|
||||
<div><%= f.label :password %><br />
|
||||
<div><%= f.label :password %><% if params[:action]!='new' %> <em>(Only if you want to change your password)</em><% end %><br />
|
||||
<%= f.password_field :password %></div>
|
||||
|
||||
<div><%= f.label :password_confirmation %><br />
|
||||
<%= f.password_field :password_confirmation %></div>
|
||||
|
||||
<% if params[:action]!='new' %>
|
||||
<div><%= f.label :current_password %><br />
|
||||
<div><%= f.label :current_password, "Type Your Current Password" %> <em>(For your account's security)</em><br />
|
||||
<%= f.password_field :current_password %></div>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
<h2>Edit Your Profile</h2>
|
||||
<h2>Profile:</h2>
|
||||
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div class="payment_links">
|
||||
|
||||
<% if can? :read, resource.payments then %>
|
||||
<h3>Recorded Payments:</h3>
|
||||
<ul>
|
||||
<% resource.payments.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<hr/>
|
||||
<% end %>
|
||||
|
||||
<% if resource.payment_method == "Dwolla" %>
|
||||
<h3>Dwolla Payment Link</h3>
|
||||
<% if resource.member_level == "25" %>
|
||||
@@ -61,7 +72,10 @@
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to image_tag(resource.gravatar_url), "https://www.gravatar.com", :title => "Adjust your photo at Gravatar.com" %>
|
||||
<div class="caption">
|
||||
<%= link_to image_tag(resource.gravatar_url), "https://www.gravatar.com", :title => "Adjust your photo at Gravatar.com" %><br/>
|
||||
Adjust your photo <br/>at Gravatar.com
|
||||
</div>
|
||||
|
||||
<%= render :partial => "user", :locals => { :resource => resource, :html => { :method => :put }, :button_label => "Update Profile" } %>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h2>Sign up</h2>
|
||||
<h2>Membership Application</h2>
|
||||
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
|
||||
@@ -1,22 +1,66 @@
|
||||
<h1>Welcome to the HeatSync Labs Members App.</h1>
|
||||
|
||||
<% if !user_signed_in? then %>
|
||||
<p>You can sign up to become a member here!</p>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if user_signed_in? && 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 %>
|
||||
<% if user_signed_in? && current_user.member.to_i < current_user.member_level.to_i then %>
|
||||
<p class="alert">Looks like we haven't acknowledged a recent payment for you yet. This could be because we're slow, or this app just got started, but if in doubt please see your profile for payment instructions, or consider updating your membership level to something accurate.<br/>Thanks for supporting HeatSync!</p>
|
||||
<% end %>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<% if ((can? :read, @recent_user_names) && (@recent_user_names.count > 1)) then %>
|
||||
<h2>New People: <em>(say hi!)</em></h2>
|
||||
<ul>
|
||||
<% @recent_user_names.each do |user| %>
|
||||
<li><%= link_to user.name, user %> <%= raw(user.member_status_symbol) %> <em>(Signed up <%= user.created_at.strftime("%b %d") %>)</em></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<h2>Cool Stats:</h2>
|
||||
<dl>
|
||||
<dt># of People in this DB:</dt>
|
||||
<dd><%= @num_users %> (<%= @recent_users %> in the last 7 days)</dd>
|
||||
<dd><%= @num_users %> (<%= @recent_users %> new in the last 7 days)</dd>
|
||||
<dt># of People Certified:</dt>
|
||||
<dd><%= @num_certs %> (<%= @recent_certs %> in the last 7 days)</dd>
|
||||
<dt># of Accesses Granted:</dt>
|
||||
<dd><%= @num_door_opens %> (<%= @recent_door_opens %> in the last 7 days)</dd>
|
||||
<dt># of Accesses Denied:</dt>
|
||||
<dd><%= @num_door_denieds %> (<%= @recent_door_denieds %> in the last 7 days)</dd>
|
||||
<dt># of Accesses Denied:</dt>
|
||||
<dd><%= @num_certs %> (<%= @recent_certs %> new in the last 7 days)</dd>
|
||||
<dt># of Door Accesses Granted:</dt>
|
||||
<dd><%= @num_door_opens %> (<%= @today_door_opens %> today, <%= @recent_door_opens %> in the last 7 days)</dd>
|
||||
<dt># of Door Accesses Denied:</dt>
|
||||
<dd><%= @num_door_denieds %> (<%= @recent_door_denieds %> in the last 7 days)</dd>
|
||||
<dt># of Computers in this DB:</dt>
|
||||
<dd><%= @num_macs %> (<%= @recent_macs %> seen today)</dd>
|
||||
</dl>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<h2>Member Resources</h2>
|
||||
<ul>
|
||||
<li><%= link_to "Wiki", "http://wiki.heatsynclabs.org" %></li>
|
||||
<li><%= link_to "Discussion Group", "http://groups.google.com/group/heatsynclabs" %></li>
|
||||
<li><%= link_to "IRC", "irc://irc.freenode.net#heatsynclabs" %></li>
|
||||
<li><%= link_to "Live Webcams", "http://live.heatsynclabs.org/" %></li>
|
||||
<li>Lab Phone: (480) 751-1929</li>
|
||||
<li>
|
||||
<style type="text/css">
|
||||
form input {font-family: 'Lucida Console', Monaco, monospace; }
|
||||
</style>
|
||||
|
||||
<b>Send a Message!</b>
|
||||
<form method="post" action="http://tweet.zyphon.com/signage.php">
|
||||
<em>Type here and your message will show up on the LED sign in the front window!</em><br/>
|
||||
<em>(Please be nice!)</em><br/>
|
||||
<input type="text" name="msg" id="msg" value=" Hello" size="9" /> (max 9 chars per line)<br/>
|
||||
<input type="text" name="msg2" id="msg2" value=" World" size="9" /><br/>
|
||||
<input type="submit" name="submitbutton" id="submitbutton" value="Go!" />
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
33
app/views/ipns/index.html.erb
Normal file
@@ -0,0 +1,33 @@
|
||||
<html><body>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Name</th>
|
||||
<th>Item</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
<% @ipns.reverse!.each do |ipn| %>
|
||||
<tr>
|
||||
<td><%= ipn.payment_date %></td>
|
||||
<td><%= ipn.first_name %> <%= ipn.last_name %></td>
|
||||
<td><%= ipn.item_name %></td>
|
||||
<td>
|
||||
<% if ipn.payment_gross.blank? %>
|
||||
<%= ipn.txn_type %>
|
||||
<% else %>
|
||||
<%= ipn.payment_gross %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if ipn.payment.present? %>
|
||||
<%= link_to "Linked Payment", ipn.payment %>
|
||||
<% else %>
|
||||
<%= link_to "Try to link email '#{ipn.payer_email}' at membership level '#{ipn.payment_gross.to_i}'", link_ipn_path(ipn) %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= link_to "Details", ipn %></td>
|
||||
<td><%= link_to "Validate", validate_ipn_path(ipn) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
</body></html>
|
||||
123
app/views/ipns/new.html.erb
Normal file
@@ -0,0 +1,123 @@
|
||||
<%= form_tag('/ipns') do |f| %>
|
||||
|
||||
<style type="text/css">
|
||||
label {
|
||||
width: 10em;
|
||||
display: inline-block;}
|
||||
</style>
|
||||
|
||||
<div class="actions">
|
||||
<%= submit_tag %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :first_name %>
|
||||
<%= text_field_tag :first_name, "John" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :last_name %>
|
||||
<%= text_field_tag :last_name, "Smith" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_email %>
|
||||
<%= text_field_tag :payer_email, "jsmith@example.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :item_name %>
|
||||
<%= text_field_tag :item_name, "Associate Membership" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_gross %>
|
||||
<%= text_field_tag :payment_gross, "25.00" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :transaction_subject %>
|
||||
<%= text_field_tag :transaction_subject, "" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_date %>
|
||||
<%= text_field_tag :payment_date, "20:46:54 Jun 20, 2013 PDT" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :txn_type %>
|
||||
<%= text_field_tag :txn_type, "subscr_payment" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :subscr_id %>
|
||||
<%= text_field_tag :subscr_id, "I-1234567890" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :residence_country %>
|
||||
<%= text_field_tag :residence_country, "US" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_currency %>
|
||||
<%= text_field_tag :mc_currency, "USD" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :business %>
|
||||
<%= text_field_tag :business, "hslfinances@gmail.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_type %>
|
||||
<%= text_field_tag :payment_type, "instant" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :protection_eligibility %>
|
||||
<%= text_field_tag :protection_eligibility, "Ineligible" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :verify_sign %>
|
||||
<%= text_field_tag :verify_sign, "12ru9021j9f21j90fj1290fj2910fj0219fj0" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_status %>
|
||||
<%= text_field_tag :payer_status, "verified" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :txn_id %>
|
||||
<%= text_field_tag :txn_id, "1234567890" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :receiver_email %>
|
||||
<%= text_field_tag :receiver_email, "hslfinances@gmail.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_id %>
|
||||
<%= text_field_tag :payer_id, "V812314914" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :receiver_id %>
|
||||
<%= text_field_tag :receiver_id, "V90R1280182" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_status %>
|
||||
<%= text_field_tag :payment_status, "Completed" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_fee %>
|
||||
<%= text_field_tag :payment_fee, "0.85" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_fee %>
|
||||
<%= text_field_tag :mc_fee, "0.85" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_gross %>
|
||||
<%= text_field_tag :mc_gross, "25.00" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :charset %>
|
||||
<%= text_field_tag :charset, "windows-1252" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :notify_version %>
|
||||
<%= text_field_tag :notify_version, "3.7" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :ipn_track_id %>
|
||||
<%= text_field_tag :ipn_track_id, "9d3d032d9070" %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= submit_tag %>
|
||||
</div>
|
||||
<% end %>
|
||||
18
app/views/ipns/show.html.erb
Normal file
@@ -0,0 +1,18 @@
|
||||
<h2>IPN Details</h2>
|
||||
|
||||
<% @ipn.attributes.except("data","payment_id").each do |attr| %>
|
||||
<p>
|
||||
<b><%= attr.first.to_s %>:</b>
|
||||
<%= @ipn.attributes[attr.first] %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<% if @ipn.payment.present? %>
|
||||
<%= link_to "Linked Payment", @ipn.payment %>
|
||||
<% else %>
|
||||
<span class="alert">Couldn't link automatically. Please create payment manually or adjust the user account and try again to <%= link_to "link email '#{@ipn.payer_email}' at membership level '#{@ipn.payment_gross.to_i}'", link_ipn_path(@ipn) %>.</span>
|
||||
<% end %>
|
||||
|
||||
</p>
|
||||
|
||||
<%= link_to "Back", ipns_path %>
|
||||
@@ -11,17 +11,18 @@
|
||||
<a href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a>
|
||||
<%= link_to 'People', users_path if can? :read, User %>
|
||||
<%= link_to 'Access Cards', cards_path if can? :manage, Card %>
|
||||
<% if can? :manage, UserCertification %>
|
||||
<% if can? :create, UserCertification %>
|
||||
<%= link_to 'Cert Classes', certifications_path if can? :read, Certification %>
|
||||
<%= link_to 'User Certs', user_certifications_path if can? :create, UserCertification %>
|
||||
<% else %>
|
||||
<%= link_to 'Certifications', certifications_path if can? :read, Certification %>
|
||||
<% end %>
|
||||
<%= link_to 'Door Logs', door_logs_path if can? :read, DoorLog %>
|
||||
<%= link_to 'Payments', payments_path if can? :read, Payment %>
|
||||
<%= 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 %>
|
||||
<%= link_to 'Logout', destroy_user_session_path, :method => :delete if user_signed_in? %>
|
||||
<%= link_to 'Login', new_user_session_path unless user_signed_in? %>
|
||||
<%= link_to 'Become a Member', new_user_registration_path unless user_signed_in? %>
|
||||
<%= link_to 'Membership Application', new_user_registration_path unless user_signed_in? %>
|
||||
</div>
|
||||
<div id="content">
|
||||
<p class="notice"><%= raw(notice) %></p>
|
||||
|
||||
10
app/views/mac_logs/index.html.erb
Normal file
@@ -0,0 +1,10 @@
|
||||
<table>
|
||||
<% @mac_logs.each do |mac_log| %>
|
||||
<tr>
|
||||
<td><%= mac_log.mac %></td>
|
||||
<td><%= mac_log.ip %></td>
|
||||
<td><%= mac_log.action %></td>
|
||||
<td><%= mac_log.created_at %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
33
app/views/macs/_form.html.erb
Normal file
@@ -0,0 +1,33 @@
|
||||
<%= form_for(@mac) do |f| %>
|
||||
<% if @mac.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(@mac.errors.count, "error") %> prohibited this Mac from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% @mac.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :user_id, "User" %><br />
|
||||
<%= collection_select(:mac, :user_id, @users, :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :mac %><br />
|
||||
<%= f.text_field :mac %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :note %><br />
|
||||
<%= f.text_field :note %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :hidden %><br />
|
||||
<%= f.check_box :hidden %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
6
app/views/macs/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<h1>Editing Mac</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
<%= link_to 'Show', @mac %> |
|
||||
<%= link_to 'Back', macs_path %>
|
||||
1
app/views/macs/import.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= @output %>
|
||||
47
app/views/macs/index.html.erb
Normal file
@@ -0,0 +1,47 @@
|
||||
<h2>What machines are on our network?</h2>
|
||||
<%= link_to "New MAC registration", new_mac_path if can? :create, Mac %>
|
||||
|
||||
<ul class="mac_list">
|
||||
<%
|
||||
@active_macs.each do |mac|
|
||||
Rails.logger.info mac.inspect %>
|
||||
<li>
|
||||
<span title="<%= mac.mac if user_signed_in? %><%= " - "+mac.ip.to_s if can? :read_details, mac %><%= " - "+((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" if can? :manage, mac %>">
|
||||
<%= mac.user.name unless mac.user.blank? %>
|
||||
<%= mac.mac if mac.user.blank? %>
|
||||
<%= "("+mac.note+")" unless mac.note.blank? %></span>
|
||||
<%= link_to ' Edit', edit_mac_path(mac) if can? :update, mac %> <br/>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<% if can? :read_details, Mac %>
|
||||
<ul class="mac_list hidden">
|
||||
<% @hidden_macs.each do |mac| %>
|
||||
<li>
|
||||
<span title="<%= mac.mac %><%= " - "+mac.ip.to_s if can? :read_details, mac %><%= " - "+((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" if can? :manage, mac %>">
|
||||
<%= mac.user.name unless mac.user.blank? %>
|
||||
<%= "("+mac.note+")" unless mac.note.blank? %></span>
|
||||
<%= link_to ' Edit', edit_mac_path(mac) if can? :update, mac %> <br/>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% if can? :manage, Mac %>
|
||||
<h3>All Macs</h3>
|
||||
<table>
|
||||
<% @all_macs.each do |mac| %>
|
||||
<tr <%= raw('class="hidden"') if mac.hidden? %>>
|
||||
<td><%= mac.mac.downcase %> </td>
|
||||
<td><%= mac.user.name unless mac.user.blank? %></td>
|
||||
<td><%= "("+mac.note+")" unless mac.note.blank? %></td>
|
||||
<td><%= if mac.active? then raw("<strong>Here</strong>") else "Gone" end %></td>
|
||||
<td><%= ((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" unless mac.since.blank? %></td>
|
||||
<td><%= link_to 'Edit', edit_mac_path(mac) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
|
||||
5
app/views/macs/new.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<h1>New Mac</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
<%= link_to 'Back', macs_path %>
|
||||
7
app/views/macs/scan.html.erb
Normal file
@@ -0,0 +1,7 @@
|
||||
Scanning...
|
||||
<% if can? :read_details, Mac
|
||||
@log.each do |log| %>
|
||||
<%= log.mac %> =
|
||||
<%= log.ip %><br/>
|
||||
<% end
|
||||
end %>
|
||||
27
app/views/macs/show.html.erb
Normal file
@@ -0,0 +1,27 @@
|
||||
<p>
|
||||
<b>User:</b>
|
||||
<%= @mac.user.name unless @mac.user.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Mac:</b>
|
||||
<%= @mac.mac %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note:</b>
|
||||
<%= @mac.note %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Hidden:</b>
|
||||
<%= @mac.hidden %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>IP:</b>
|
||||
<%= @mac.ip %>
|
||||
</p>
|
||||
|
||||
<%= link_to 'Edit', edit_mac_path(@mac) %> |
|
||||
<%= link_to 'Back', macs_path %>
|
||||
29
app/views/payments/_form.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<%= form_for(@payment) do |f| %>
|
||||
<% if @payment.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(@payment.errors.count, "error") %> prohibited this payment from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% @payment.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :user_id, "User" %><br />
|
||||
<%= collection_select(:payment, :user_id, @users, :id, :name_with_payee_and_member_level) %> (inactive members are not shown.)
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :date, "Paid for month beginning" %><br />
|
||||
<%= f.date_select :date, :default => (DateTime.now - 1.month) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :amount %><br />
|
||||
<%= f.number_field :amount %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
6
app/views/payments/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<h1>Editing payment</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
<%= link_to 'Show', @payment %> |
|
||||
<%= link_to 'Back', payments_path %>
|
||||
26
app/views/payments/index.html.erb
Normal file
@@ -0,0 +1,26 @@
|
||||
<h1>Listing payments</h1>
|
||||
|
||||
<%= link_to 'New Payment', new_payment_path %>
|
||||
<br />
|
||||
<table>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th>Paid for month <br/>beginning</th>
|
||||
<th>Amount</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% @payments.each do |payment| %>
|
||||
<tr>
|
||||
<td><%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %></td>
|
||||
<td><%= payment.human_date %></td>
|
||||
<td><%= payment.amount %></td>
|
||||
<td><%= link_to 'Details', payment %></td>
|
||||
<td><%= link_to 'Edit', edit_payment_path(payment) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
|
||||
5
app/views/payments/new.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<h1>New payment</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
<%= link_to 'Back', payments_path %>
|
||||
46
app/views/payments/show.html.erb
Normal file
@@ -0,0 +1,46 @@
|
||||
<p>
|
||||
<b>User:</b>
|
||||
<%= link_to @payment.user.name_with_payee_and_member_level, @payment.user unless @payment.user.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Paid for month beginning:</b>
|
||||
<%= @payment.date %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Amount:</b>
|
||||
<%= @payment.amount %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Last Modified by:</b>
|
||||
<% user = @users.find{|u| u.id == @payment.created_by} %>
|
||||
<% if user.blank? %>
|
||||
n/a
|
||||
<% else %>
|
||||
<%= link_to user.name, user %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Created date:</b>
|
||||
<%= @payment.created_at %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Updated date:</b>
|
||||
<%= @payment.updated_at %>
|
||||
</p>
|
||||
|
||||
<% if @payment.ipn.present? %>
|
||||
<p>
|
||||
<%= link_to "Paid via PayPal", @payment.ipn %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
<%= 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 %>
|
||||
@@ -11,13 +11,14 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @user_certification.user_id = params[:user] if params[:user].present? %>
|
||||
<div class="field">
|
||||
<%= f.label :user_id, "User" %><br />
|
||||
<%= collection_select(:user_certification, :user_id, @users, :id, :name) %>
|
||||
<%= collection_select(:user_certification, :user_id, @users, :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :certification_id, "Certification" %><br />
|
||||
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name) %>
|
||||
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<% @grouped_user_certs.sort.each do |cert, user_certifications| %>
|
||||
<dl class="collapsible">
|
||||
<dt><%= cert.name %></dt>
|
||||
<% user_certifications.sort{|a,b| a.user.name <=> b.user.name}.each do |user_certification| %>
|
||||
<% user_certifications.sort{|a,b| a.user_name <=> b.user_name}.each do |user_certification| %>
|
||||
<dd>
|
||||
<%= link_to user_certification.user.name, user_certification %>
|
||||
<%= link_to user_certification.user_name, user_certification %>
|
||||
</dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<p>
|
||||
<b>User:</b>
|
||||
<%= @user_certification.user.name %>
|
||||
<%= link_to @user_certification.user.name, @user_certification.user %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -18,8 +18,14 @@
|
||||
at <%= @user_certification.updated_at %>
|
||||
</p>
|
||||
|
||||
<%= link_to 'Edit', edit_user_certification_path(@user_certification) %> |
|
||||
<%= link_to 'Back', user_certifications_path %>
|
||||
<p>
|
||||
<%= link_to 'Destroy', @user_certification, :confirm => "Are you sure you want to destroy this user's certification?", :method => :delete if can? :destroy, @user_certification %>
|
||||
<% if can? :update, @user_certification %>
|
||||
<%= link_to 'Edit', edit_user_certification_path(@user_certification) %> |
|
||||
<% end %>
|
||||
|
||||
<% if can? :destroy, @user_certification %>
|
||||
<%= link_to 'Delete', @user_certification, :confirm => "Are you sure you want to destroy this user's certification?", :method => :delete %> |
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', user_certifications_path %>
|
||||
</p>
|
||||
|
||||
33
app/views/user_mailer/new_user_email.html.erb
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
</head>
|
||||
<body>
|
||||
<h2><%= @user.name %> just signed up.</h2>
|
||||
<p>
|
||||
Please contact them at <%= @user.email %><%= " or "+@user.phone.to_s unless @user.phone.blank? %> to set up a
|
||||
new user orientation, waiver, welcome, payment help, etc.
|
||||
</p>
|
||||
<p>
|
||||
User Details: <%= link_to @url+user_path(@user), @url+user_path(@user) %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Member Level:</b>
|
||||
<%= simple_format @user.member_level_string %>
|
||||
</p>
|
||||
<p>
|
||||
<b>What skills, knowledge and experience do you bring to the community?</b>
|
||||
<%= simple_format @user.current_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>What skills, knowledge and experiences are you looking for in HeatSync?</b>
|
||||
<%= simple_format @user.desired_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>How'd you find out about HeatSync?</b>
|
||||
<%= simple_format @user.marketing_source %>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
17
app/views/user_mailer/new_user_email.text.erb
Normal file
@@ -0,0 +1,17 @@
|
||||
<%= @user.name %> just signed up.
|
||||
---
|
||||
Please contact them at <%= @user.email %><%= " or "+@user.phone.to_s unless @user.phone.blank? %> to set up a
|
||||
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 %>
|
||||
|
||||
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 %>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :name %><br />
|
||||
<%= f.label :name, "Full Name" %><br />
|
||||
<%= f.text_field :name %>
|
||||
</div>
|
||||
<div class="field">
|
||||
@@ -60,26 +60,30 @@
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :member_level, "Desired Member Level" %><br />
|
||||
<%= f.select :member_level, [[nil],["None",0],["Unable",1],["Volunteer",10],["Associate",25],["Basic",50],["Plus",100]] %>
|
||||
<%= f.select :member_level, [[nil],["None",0],["Unable",1],["Volunteer",10],["Associate ($25)",25],["Basic ($50)",50],["Plus ($100)",100]] %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= render :partial => "/users/payment_methods", :locals => { :g => f } %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :payee %><br />
|
||||
<%= f.text_field :payee%>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :phone %><br />
|
||||
<%= f.text_field :phone %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :current_skills %><br />
|
||||
<%= f.label :current_skills, "What skills, knowledge and experience do you bring to the community?" %><br />
|
||||
<%= f.text_area :current_skills %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :desired_skills %><br />
|
||||
<%= f.label :desired_skills, "What skills, knowledge and experiences are you looking for in HeatSync?" %><br />
|
||||
<%= f.text_area :desired_skills %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :member, "Member?" %><br />
|
||||
<%= f.select :member, [[nil],["No",0],["Inactive",1],["Volunteer",10],["Associate",25],["Basic",50],["Plus",100]] %>
|
||||
<%= f.label :marketing_source, "How'd you find out about HeatSync?" %><br />
|
||||
<%= f.text_area :marketing_source %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :instructor, "Instructor?" %><br />
|
||||
@@ -89,6 +93,10 @@
|
||||
<%= f.label :admin, "Admin?" %><br />
|
||||
<%= f.check_box :admin %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :accountant, "Accountant?" %><br />
|
||||
<%= f.check_box :accountant %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :hidden, "Hidden?" %><br />
|
||||
<%= f.check_box :hidden %>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<% @payment_methods = [[nil],["PayPal"],["Dwolla"],["Bill Pay","BillPay"],["Check"],["Cash"],["Other"]]
|
||||
@payment_instructions = {nil => nil,
|
||||
:PayPal => "Set up a monthly recurring payment to hslfinances@gmail.com",
|
||||
:Dwolla => "Set up a monthly recurring payment to hslfinances@gmail.com",
|
||||
:PayPal => "Set up a monthly recurring payment to hslfinances@gmail.com or via the button on the next page.",
|
||||
:Dwolla => "Set up a monthly recurring payment to hslfinances@gmail.com or via the button on the next page.",
|
||||
:BillPay => "Have your bank send a monthly check to HeatSync Labs Treasurer, 140 W Main St, Mesa AZ 85201",
|
||||
:Check => "Mail to HeatSync Labs Treasurer, 140 W Main St, Mesa AZ 85201 OR put in the drop safe at the Lab with a deposit slip firmly attached each month.",
|
||||
:Cash => "Put in the drop safe at the Lab with a deposit slip firmly attached each month.",
|
||||
:Other => "Hmm... talk to a Treasurer!"} %>
|
||||
|
||||
<%= g.label :payment_method %> <i>(after changing this, please make sure you update your payment service, it's not automatic.)</i><br />
|
||||
<%= g.label :payment_method %><% if params[:action] != 'new' %> <i>(after changing this, please make sure you update your payment service, it's not automatic.)</i><% end %><br />
|
||||
<%= g.select :payment_method, @payment_methods %>
|
||||
<% @payment_instructions.each_pair do |key, value| %>
|
||||
<span class="payment_instructions" id="pmt_<%= key %>"><%= value %></span>
|
||||
|
||||
95
app/views/users/_user_summary.html.erb
Normal file
@@ -0,0 +1,95 @@
|
||||
<% user ||= @user #unless @user.blank? %>
|
||||
|
||||
<p>
|
||||
<b>Name:</b>
|
||||
<%= user.name %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Email:</b>
|
||||
<%= user.email %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Orientation?</b>
|
||||
<%= user.orientation.strftime("%B %d %Y") unless user.orientation.blank? %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<b>Waiver?</b>
|
||||
<%= user.waiver.strftime("%B %d %Y") unless user.waiver.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Current Member?</b>
|
||||
<%= raw(user.member_status_symbol) %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Desired Member Level:</b>
|
||||
<%= user.member_level %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payment Method:</b>
|
||||
<%= user.payment_method %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payee:</b>
|
||||
<%= user.payee %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Phone:</b>
|
||||
<%= user.phone %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Current Skills:</b>
|
||||
<%= simple_format user.current_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Desired Skills:</b>
|
||||
<%= simple_format user.desired_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Card:</b>
|
||||
<% if current_user.admin? then %>
|
||||
<% user.cards.each do |c| %>
|
||||
<%= link_to c.card_number, c %><%= "," unless c == user.cards.last %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= unless user.cards.blank? then raw("✓") end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<b>Certifications:</b>
|
||||
<ul>
|
||||
<% user.certifications.each do |certification| %>
|
||||
<li><%= link_to certification.name, certification %></li>
|
||||
<% end %>
|
||||
<% if user.certifications.blank? %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Payments:</b>
|
||||
<ul>
|
||||
<% user.payments.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Created:</b>
|
||||
<%= user.created_at %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Last signed in:</b>
|
||||
<%= user.current_sign_in_at %>
|
||||
</p>
|
||||
<% end %>
|
||||
@@ -3,13 +3,16 @@
|
||||
<% if can? :create, User %>
|
||||
<%= link_to 'New User', new_user_path %>
|
||||
<% end %>
|
||||
<% if can? :manage, User %>
|
||||
| <%= link_to 'Merge Users', users_merge_path %>
|
||||
<% end %>
|
||||
<table>
|
||||
<col />
|
||||
<col />
|
||||
<% if current_user.admin? then %><col /><% end %>
|
||||
<col />
|
||||
<% if current_user.admin? %><col /><% end %>
|
||||
<col class="col_highlight" />
|
||||
<% if current_user.admin? %><col />
|
||||
<col class="col_highlight" /><% end %>
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<col />
|
||||
@@ -26,7 +29,7 @@
|
||||
<th><a href="?sort=member">Member?</a></th>
|
||||
<th><a href="?sort=card">Card?</a></th>
|
||||
<th><a href="?sort=instructor">Instructor?</a></th>
|
||||
<th><a href="?sort=admin">Admin?</a></th>
|
||||
<% if current_user.admin? then %><th><a href="?sort=admin">Admin?</a></th><% end %>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -44,10 +47,10 @@
|
||||
<%= unless user.orientation.blank? then raw("<span class='hoverinfo' title='"+user.orientation.strftime("%B %d %Y")+"'>✓</span>") end %>
|
||||
</td><% end %>
|
||||
<td><%= unless user.waiver.blank? then raw("<span class='hoverinfo' title='"+user.waiver.strftime("%B %d %Y")+"'>✓</span>") end %></td>
|
||||
<td><%= raw(user.member_status) %></td>
|
||||
<td><%= raw(user.member_status_symbol) %></td>
|
||||
<td><%= unless user.cards.blank? then raw("<span class='iconinfo'>✓</span>") end %></td>
|
||||
<td><%= if user.instructor? then raw("<span class='iconinfo'>✓</a>") end %></td>
|
||||
<td><%= if user.admin? then raw("<span class='iconinfo'>✓</a>") end %></td>
|
||||
<% if current_user.admin? then %><td><%= if user.admin? then raw("<span class='iconinfo'>✓</a>") end %></td><% end %>
|
||||
<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>
|
||||
|
||||
48
app/views/users/merge_view.html.erb
Normal file
@@ -0,0 +1,48 @@
|
||||
<style type="text/css">
|
||||
#user_to_merge_details, #user_to_keep_details,
|
||||
#user_to_merge_details p, #user_to_keep_details p {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Merging users</h1>
|
||||
|
||||
<%= form_tag('/users/merge', :method => :post) do %>
|
||||
<b>Everything except the email, password, name, id, hidden, and blank values will be moved to the "user to keep" UNLESS there is a value already there. The "user to merge" will be deleted.</b>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="field">
|
||||
<%= label_tag :user_to_keep, "User to Keep" %><br />
|
||||
<%= collection_select(:user, :to_keep, @users, :id, :name_with_email_and_visibility, :include_blank => true) %>
|
||||
</div>
|
||||
<div id="user_to_keep_details"></div>
|
||||
</td>
|
||||
<td style="font-size: 16px">◀◀</td>
|
||||
<td>
|
||||
<div class="field">
|
||||
<%= label_tag :user_to_merge, "User to Merge" %><br />
|
||||
<%= collection_select(:user, :to_merge, @users, :id, :name_with_email_and_visibility, :include_blank => true) %>
|
||||
</div>
|
||||
<div id="user_to_merge_details"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr/>
|
||||
<div class="actions">
|
||||
<%= submit_tag "Merge" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', users_path %>
|
||||
|
||||
<script>
|
||||
$("#user_to_keep").change(function(event,handler){
|
||||
$("#user_to_keep_details").load("/user_summary/"+event.target.value);
|
||||
});
|
||||
$("#user_to_merge").change(function(event,handler){
|
||||
$("#user_to_merge_details").load("/user_summary/"+event.target.value);
|
||||
});
|
||||
</script>
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<p>
|
||||
<b>Current Member?</b>
|
||||
<%= raw(@user.member_status) %>
|
||||
<%= raw(@user.member_status_symbol) %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -20,12 +20,6 @@
|
||||
<%= @user.instructor? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Admin?</b>
|
||||
<%= @user.admin? %>
|
||||
</p>
|
||||
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Email:</b>
|
||||
@@ -56,6 +50,10 @@
|
||||
<b>Payment Method:</b>
|
||||
<%= @user.payment_method %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payee:</b>
|
||||
<%= @user.payee %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Phone:</b>
|
||||
<%= @user.phone %>
|
||||
@@ -69,18 +67,26 @@
|
||||
<b>Desired Skills:</b>
|
||||
<%= simple_format @user.desired_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Card:</b>
|
||||
<% if current_user.admin? then %>
|
||||
<% @user.cards.each do |c| %>
|
||||
<%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %>
|
||||
<p>
|
||||
<b>Found HeatSync via:</b>
|
||||
<%= simple_format @user.marketing_source %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Card: </b><%= link_to "+ Add", (new_card_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, Card %>
|
||||
<% if current_user.admin? then %>
|
||||
<ul>
|
||||
<% @user.cards.each do |c| %>
|
||||
<li><%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<%= unless @user.cards.blank? then raw("✓") end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<b>Certifications:</b>
|
||||
<b>Certifications: </b><%= link_to "+ Add", (new_user_certification_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, UserCertification %>
|
||||
<ul>
|
||||
<% @user.certifications.each do |certification| %>
|
||||
<li><%= link_to certification.name, certification %></li>
|
||||
@@ -88,5 +94,27 @@
|
||||
<% if @user.certifications.blank? %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Payments:</b>
|
||||
<ul>
|
||||
<% @payments.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Created:</b>
|
||||
<%= @user.created_at %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Last signed in:</b>
|
||||
<%= @user.current_sign_in_at %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if can? :update, @user then %><%= link_to 'Edit', edit_user_path(@user) %> |<% end %>
|
||||
<%= link_to 'Back', users_path %>
|
||||
|
||||
@@ -23,3 +23,9 @@ production:
|
||||
database: db/production.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
# adapter: postgresql
|
||||
# encoding: unicode
|
||||
# database: members
|
||||
# pool: 5
|
||||
# username: postgres
|
||||
# password:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
Dooraccess::Application.routes.draw do
|
||||
match 'ipns/import' => 'ipns#import', :as => :import_ipn
|
||||
resources :ipns
|
||||
match 'ipns/:id/link' => 'ipns#link', :as => :link_ipn
|
||||
match 'ipns/:id/validate' => 'ipns#validate', :as => :validate_ipn
|
||||
|
||||
resources :payments
|
||||
|
||||
resources :user_certifications
|
||||
|
||||
@@ -16,6 +22,9 @@ Dooraccess::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
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_action', :via => :post # Merge action
|
||||
resources :users
|
||||
match 'users/create' => 'users#create', :via => :post # Use POST users/create instead of POST users to avoid devise conflict
|
||||
|
||||
@@ -27,6 +36,12 @@ Dooraccess::Application.routes.draw do
|
||||
match 'door_logs/download' => 'door_logs#download', :as => :download
|
||||
match 'door_logs/auto_download' => 'door_logs#auto_download', :as => :auto_download
|
||||
|
||||
match 'macs/scan' => 'macs#scan'
|
||||
match 'macs/import' => 'macs#import'
|
||||
resources :macs
|
||||
|
||||
resources :mac_logs
|
||||
|
||||
root :to => "home#index"
|
||||
|
||||
# The priority is based upon order of creation:
|
||||
|
||||
15
db/migrate/20130201021949_create_macs.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateMacs < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :macs do |t|
|
||||
t.references :user
|
||||
t.string :mac
|
||||
t.string :ip
|
||||
t.datetime :since
|
||||
t.datetime :refreshed
|
||||
t.boolean :active
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :macs, :user_id
|
||||
end
|
||||
end
|
||||
11
db/migrate/20130201022153_create_mac_logs.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateMacLogs < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :mac_logs do |t|
|
||||
t.string :mac
|
||||
t.string :ip
|
||||
t.string :action
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
6
db/migrate/20130201042646_add_properties_to_macs.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddPropertiesToMacs < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :macs, :hidden, :boolean
|
||||
add_column :macs, :note, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddMarketingSourceToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :marketing_source, :string
|
||||
end
|
||||
end
|
||||
11
db/migrate/20130212030630_create_payments.rb
Normal file
@@ -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
|
||||
5
db/migrate/20130212032046_add_created_by_to_payments.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddCreatedByToPayments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :payments, :created_by, :integer
|
||||
end
|
||||
end
|
||||
5
db/migrate/20130212054755_add_payee_to_users.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddPayeeToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :payee, :string
|
||||
end
|
||||
end
|
||||
5
db/migrate/20130212083412_add_accountant_to_users.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddAccountantToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :accountant, :boolean
|
||||
end
|
||||
end
|
||||
24
db/migrate/20130824062334_create_ipns.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
class CreateIpns < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :ipns do |t|
|
||||
t.integer :payment_id
|
||||
t.text :data
|
||||
t.string :txn_id
|
||||
t.string :txn_type
|
||||
t.string :first_name
|
||||
t.string :last_name
|
||||
t.string :payer_business_name
|
||||
t.string :payer_email
|
||||
t.string :payer_id
|
||||
t.string :auth_amount
|
||||
t.string :payment_date
|
||||
t.string :payment_fee
|
||||
t.string :payment_gross
|
||||
t.string :payment_status
|
||||
t.string :item_name
|
||||
t.string :payment_type
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
5
db/migrate/20130824072157_add_amount_to_payments.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddAmountToPayments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :payments, :amount, :decimal
|
||||
end
|
||||
end
|
||||
60
db/schema.rb
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20130125185724) do
|
||||
ActiveRecord::Schema.define(:version => 20130824072157) do
|
||||
|
||||
create_table "cards", :force => true do |t|
|
||||
t.string "card_number"
|
||||
@@ -35,6 +35,61 @@ ActiveRecord::Schema.define(:version => 20130125185724) do
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "ipns", :force => true do |t|
|
||||
t.integer "payment_id"
|
||||
t.text "data"
|
||||
t.string "txn_id"
|
||||
t.string "txn_type"
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "payer_business_name"
|
||||
t.string "payer_email"
|
||||
t.string "payer_id"
|
||||
t.string "auth_amount"
|
||||
t.string "payment_date"
|
||||
t.string "payment_fee"
|
||||
t.string "payment_gross"
|
||||
t.string "payment_status"
|
||||
t.string "item_name"
|
||||
t.string "payment_type"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "mac_logs", :force => true do |t|
|
||||
t.string "mac"
|
||||
t.string "ip"
|
||||
t.string "action"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "macs", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
t.string "mac"
|
||||
t.string "ip"
|
||||
t.datetime "since"
|
||||
t.datetime "refreshed"
|
||||
t.boolean "active"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "hidden"
|
||||
t.string "note"
|
||||
end
|
||||
|
||||
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"
|
||||
t.decimal "amount"
|
||||
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"
|
||||
@@ -72,6 +127,9 @@ ActiveRecord::Schema.define(:version => 20130125185724) do
|
||||
t.string "desired_skills"
|
||||
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
|
||||
|
||||
BIN
public/copper-coin.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/copper-paid-coin.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 661 B |
BIN
public/gold-coin.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/gold-paid-coin.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
public/heart-coin.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/no-coin.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/silver-coin.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/silver-paid-coin.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/timeout-coin.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
7
test/fixtures/ipns.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
||||
|
||||
one:
|
||||
data: MyText
|
||||
|
||||
two:
|
||||
data: MyText
|
||||
11
test/fixtures/mac_logs.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
||||
|
||||
one:
|
||||
mac: MyString
|
||||
ip: MyString
|
||||
action: MyString
|
||||
|
||||
two:
|
||||
mac: MyString
|
||||
ip: MyString
|
||||
action: MyString
|
||||
17
test/fixtures/macs.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
||||
|
||||
one:
|
||||
user:
|
||||
mac: MyString
|
||||
ip: MyString
|
||||
since: 2013-01-31 19:19:49
|
||||
refreshed: 2013-01-31 19:19:49
|
||||
active: false
|
||||
|
||||
two:
|
||||
user:
|
||||
mac: MyString
|
||||
ip: MyString
|
||||
since: 2013-01-31 19:19:49
|
||||
refreshed: 2013-01-31 19:19:49
|
||||
active: false
|
||||
9
test/fixtures/payments.yml
vendored
Normal file
@@ -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
|
||||
7
test/functional/ipn_controller_test.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class IpnControllerTest < ActionController::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/functional/mac_logs_controller_test.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class MacLogsControllerTest < ActionController::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/functional/pamela_controller_test.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class PamelaControllerTest < ActionController::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
49
test/functional/payments_controller_test.rb
Normal file
@@ -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
|
||||