diff --git a/.rvmrc b/.rvmrc new file mode 100644 index 0000000..d462736 --- /dev/null +++ b/.rvmrc @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# This is an RVM Project .rvmrc file, used to automatically load the ruby +# development environment upon cd'ing into the directory + +# First we specify our desired [@], the @gemset name is optional, +# Only full ruby name is supported here, for short names use: +# echo "rvm use 1.8.7" > .rvmrc +environment_id="ruby-1.9.3-p385@members-hsl" + +# Uncomment the following lines if you want to verify rvm version per project +# rvmrc_rvm_version="1.18.8 (stable)" # 1.10.1 seams as a safe start +# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { +# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." +# return 1 +# } + +# First we attempt to load the desired environment directly from the environment +# file. This is very fast and efficient compared to running through the entire +# CLI and selector. If you want feedback on which environment was used then +# insert the word 'use' after --create as this triggers verbose mode. +if [[ -d "${rvm_path:-$HOME/.rvm}/environments" + && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] +then + \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" + [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && + \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true +else + # If the environment file has not yet been created, use the RVM CLI to select. + rvm --create "$environment_id" || { + echo "Failed to create RVM environment '${environment_id}'." + return 1 + } +fi + diff --git a/Gemfile b/Gemfile index 8ecbde8..ca2b42f 100644 --- a/Gemfile +++ b/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,9 @@ gem 'bcrypt-ruby', '~> 3.0.0' # gem 'capistrano' # To use debugger -# gem 'ruby-debug' +#gem 'debugger' #gem "paperclip", "~> 3.0" gem 'gravtastic' + +gem 'passenger' diff --git a/Gemfile.lock b/Gemfile.lock index 94abf55..0f56725 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,6 +39,7 @@ GEM coffee-script-source execjs coffee-script-source (1.3.3) + daemon_controller (1.1.5) devise (2.1.1) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) @@ -63,6 +64,10 @@ GEM mime-types (1.19) multi_json (1.3.6) orm_adapter (0.1.0) + passenger (4.0.14) + daemon_controller (>= 1.1.0) + rack + rake (>= 0.8.1) polyglot (0.3.3) rack (1.4.1) rack-cache (1.2) @@ -124,6 +129,7 @@ DEPENDENCIES gravtastic jquery-rails json + passenger rails (= 3.2.3) sass-rails (~> 3.2.3) sqlite3 diff --git a/app/assets/javascripts/ipn.js.coffee b/app/assets/javascripts/ipn.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/ipn.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 38f2c00..f8ee609 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -12,3 +12,37 @@ *= 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); +} diff --git a/app/assets/stylesheets/ipn.css.scss b/app/assets/stylesheets/ipn.css.scss new file mode 100644 index 0000000..ee38bc7 --- /dev/null +++ b/app/assets/stylesheets/ipn.css.scss @@ -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/ diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index da2d5ef..838f7de 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -5,6 +5,8 @@ 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 + @num_paid_users = User.all.select{|u| u.member_status >= 250 }.count + @num_delinquent_users = User.all.select{|u| !u.payment_status }.count if can? :read, User then @recent_user_names = User.where("member_level > 10").accessible_by(current_ability).order('created_at desc').limit(5) end diff --git a/app/controllers/ipns_controller.rb b/app/controllers/ipns_controller.rb new file mode 100644 index 0000000..6451415 --- /dev/null +++ b/app/controllers/ipns_controller.rb @@ -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 diff --git a/app/controllers/macs_controller.rb b/app/controllers/macs_controller.rb index 245dfd7..8f8401a 100644 --- a/app/controllers/macs_controller.rb +++ b/app/controllers/macs_controller.rb @@ -1,5 +1,15 @@ class MacsController < ApplicationController -load_and_authorize_resource :mac, :except => [:index, :scan, :import] +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" diff --git a/app/controllers/paypal_csvs_controller.rb b/app/controllers/paypal_csvs_controller.rb new file mode 100644 index 0000000..2f48d23 --- /dev/null +++ b/app/controllers/paypal_csvs_controller.rb @@ -0,0 +1,28 @@ +class PaypalCsvsController < ApplicationController + load_and_authorize_resource :paypal_csv + before_filter :authenticate_user! + + def index + end + + def show + end + + def new + end + + def create + PaypalCsv.batch_import_from_csv(params[:file].path) + redirect_to paypal_csvs_path, :notice => 'Paypal CSV batch was successfully loaded.' + end + + def link + result = @paypal_csv.link_payment + if result.first + redirect_to paypal_csvs_url, :notice => 'Payment was successfully linked.' + else + redirect_to paypal_csvs_url, :notice => result.last + end + end + +end diff --git a/app/controllers/user_certifications_controller.rb b/app/controllers/user_certifications_controller.rb index 6d222ee..aff149a 100644 --- a/app/controllers/user_certifications_controller.rb +++ b/app/controllers/user_certifications_controller.rb @@ -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.where(:hidden => false).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 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 02cfc23..4b6877c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -33,6 +33,10 @@ class UsersController < ApplicationController end end + def inactive + @users = @users.all.select{|u| u if u.payment_status == false }.sort_by{ |u| -u.delinquency } + end + # GET /users/1 # GET /users/1.json def show @@ -69,7 +73,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" } @@ -83,7 +87,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" } diff --git a/app/helpers/ipn_helper.rb b/app/helpers/ipn_helper.rb new file mode 100644 index 0000000..a56c555 --- /dev/null +++ b/app/helpers/ipn_helper.rb @@ -0,0 +1,2 @@ +module IpnHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 70c3ee7..4f5ea1b 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -3,14 +3,20 @@ class Ability def initialize(user) # Anonymous can read mac - 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 + 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? @@ -29,9 +35,11 @@ class Ability can :read, UserCertification end - # Accountants can manage all + # Accountants can manage payments if user.accountant? can :manage, Payment + can :manage, Ipn + can :manage, PaypalCsv end # Admins can manage all diff --git a/app/models/card.rb b/app/models/card.rb index 1416ac3..700cb3b 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -2,7 +2,8 @@ class Card < ActiveRecord::Base require 'open-uri' attr_accessible :id, :user_id, :name, :card_number, :card_permissions - validates_uniqueness_of :id,:card_number + validates_presence_of :user_id, :card_number, :card_permissions + validates_uniqueness_of :id, :card_number belongs_to :user def upload_to_door diff --git a/app/models/ipn.rb b/app/models/ipn.rb new file mode 100644 index 0000000..417884a --- /dev/null +++ b/app/models/ipn.rb @@ -0,0 +1,95 @@ +require 'net/http' +class Ipn < ActiveRecord::Base + attr_accessible :data + belongs_to :payment + + after_create :create_payment + + def date_parsed + begin + Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z") + rescue + Date.new + end + end + + 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}" + Rails.logger.error "Data: #{self.data}" + 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.where("lower(email) = ?", self._from_email_address.downcase).first + user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present? + + # Only create payments if the IPN matches a member + 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 diff --git a/app/models/payment.rb b/app/models/payment.rb index ef9d681..8c4ab5b 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -1,8 +1,10 @@ class Payment < ActiveRecord::Base belongs_to :user - attr_accessible :date, :user_id, :created_by + has_one :ipn + has_one :paypal_csv + attr_accessible :date, :user_id, :created_by, :amount - validates_presence_of :user_id, :date, :created_by + validates_presence_of :user_id, :date, :amount # not created_by validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.' def human_date diff --git a/app/models/paypal_csv.rb b/app/models/paypal_csv.rb new file mode 100644 index 0000000..d150e8e --- /dev/null +++ b/app/models/paypal_csv.rb @@ -0,0 +1,73 @@ +require 'csv' +class PaypalCsv < ActiveRecord::Base + attr_accessible :data, :_address_status, :_counterparty_status, :_currency, :_fee, :_from_email_address, :_gross, :_item_id, :_item_title, :_name, :_net, :_status, :_time, :_time_zone, :_to_email_address, :_transaction_id, :_type, :date, :string + belongs_to :payment + + after_create :create_payment + + def date_parsed + begin + Date.strptime(self._date, "%m/%d/%Y") + rescue + Date.new + end + end + + def self.batch_import_from_csv(filename) + csv = CSV.table(filename) + csv.each do |row| + paypal_csv = PaypalCsv.new() + + paypal_csv.attributes.each do |c| + unless row[c.first.to_sym].nil? + paypal_csv[c.first.to_sym] = row[c.first.to_sym] + end + end + + paypal_csv.data = row.to_json + paypal_csv.save + end + + return true + end + + def link_payment + create_payment + end + + private + def create_payment + # find user by email, then by payee + user = User.where("lower(email) = ?", self._from_email_address.downcase).first + user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present? + + # Only create payments if the CSV matches a member + if user.present? + # And is a payment (not a cancellation, etc) + payment_types = ["Recurring Payment Received","Payment Received"] + if payment_types.include?(self._type) + # And a member level + if User.member_levels[self._gross.to_i].present? + payment = Payment.new + payment.date = Date.strptime(self._date, "%m/%d/%Y") #7/6/2013 for Jul 06 + payment.user_id = user.id + payment.amount = self._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._gross.to_i}'."] + end + else + return [false, "Unable to link payment. Transaction is a '#{self._type}' instead of '#{payment_types.inspect}'."] + end + else + return [false, "Unable to link payment. Couldn't find user/payee '#{self._from_email_address}'."] + end + + return [true] + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 512a0aa..899ee2f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -85,72 +85,108 @@ class User < ActiveRecord::Base end end + def self.member_levels + {25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"} + end + + def payment_status + results = payment_status_calculation + return results[:paid] + end + def member_status - case self.member_level.to_i - when 0 - if self.payments.count > 0 then - 2 - else - -1 - end - when 1 - 1 - when 10..24 - 10 - when 25..999 - if self.payments.count > 0 then - if self.payments.last.date < (DateTime.now - 45.days) - 3 - else - case self.member_level.to_i - when 25..49 - 25 - when 50..99 - 50 - when 100..999 - 100 - end - end - else - return 0 - end - end + results = member_status_calculation + return results[:rank] end def member_status_symbol - case self.member_level.to_i - when 0 - if self.payments.count > 0 then - ":(" - else - "" - end - when 1 - "Unable" - when 10..24 - "" - when 25..999 - if self.payments.count > 0 then - if self.payments.last.date < (DateTime.now - 45.days) - "" - else - case self.member_level.to_i - when 25..49 - "" - when 50..99 - "" - when 100..999 - "" - end - end - else - "?" - end + results = member_status_calculation + return "" + end + + def delinquency + if self.payments.count > 0 + paydate = self.payments.maximum(:date) + (Date.today - paydate).to_i + else + (Date.today - self.created_at.to_date).to_i end end private + 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.maximum(:date)).to_i/30} months 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 + + payment_results = payment_status_calculation + flair = payment_results[:flair] + rank = rank/10 unless payment_results[:paid] + message = payment_results[:message] unless payment_results[:message].blank? + + return {:message => message, :icon => icon, :flair => flair, :rank => rank} + end + + def payment_status_calculation + flair = "" + message = "" + paid = true + + # Second status item is payment status + 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.maximum(:date) > (DateTime.now - 60.days) + flair = "-paid" + paid = true + else + message = "Last Payment #{(DateTime.now - self.payments.maximum(:date)).to_i/30} months ago" + paid = false + end + else + message = "No Payments Recorded" + paid = false + end + end + return {:message => message, :paid => paid, :flair => flair} + end + + def send_new_user_email Rails.logger.info UserMailer.new_user_email(self).deliver end diff --git a/app/models/user_certification.rb b/app/models/user_certification.rb index e1694c4..271c038 100644 --- a/app/models/user_certification.rb +++ b/app/models/user_certification.rb @@ -1,6 +1,7 @@ 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 diff --git a/app/views/cards/_form.html.erb b/app/views/cards/_form.html.erb index 3a63ed0..6a14351 100644 --- a/app/views/cards/_form.html.erb +++ b/app/views/cards/_form.html.erb @@ -11,9 +11,10 @@ <% end %> + <% @card.user_id = params[:user] if params[:user].present? %>
<%= f.label :user %>
- <%= 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) %>
<%= f.label :name, "Card Note" %>
diff --git a/app/views/certifications/show.html.erb b/app/views/certifications/show.html.erb index 272deae..c9fce2b 100644 --- a/app/views/certifications/show.html.erb +++ b/app/views/certifications/show.html.erb @@ -8,13 +8,10 @@ <%= simple_format @certification.description %>

-Certified Users: -
    - <% @certification_users.each do |user| %> -
  • <%= link_to user.name, user %>
  • - <% end %> - <% if @certification_users.blank? then %>
  • n/a
  • <% end %> -
+

+ Certified Users: + <%= link_to "Click Here", user_certifications_path %> +

<% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %> <%= link_to 'Back', certifications_path %> diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index 9d47d6d..6be51a1 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -27,6 +27,8 @@
<%= @num_users %> (<%= @recent_users %> new in the last 7 days)
# of People Certified:
<%= @num_certs %> (<%= @recent_certs %> new in the last 7 days)
+
# of Current Paying Members:
+
<%= @num_paid_users %> (<%= @num_delinquent_users %> not-current)
# of Door Accesses Granted:
<%= @num_door_opens %> (<%= @today_door_opens %> today, <%= @recent_door_opens %> in the last 7 days)
# of Door Accesses Denied:
diff --git a/app/views/ipns/index.html.erb b/app/views/ipns/index.html.erb new file mode 100644 index 0000000..1951302 --- /dev/null +++ b/app/views/ipns/index.html.erb @@ -0,0 +1,35 @@ +

PayPal IPN Records

+

+ Automatically loaded from PayPal's servers +

+ + + + + + + + <% @ipns.sort_by(&:date_parsed).reverse!.each do |ipn| %> + + + + + + + + + + <% end %> +
DateNameItemAmount
<%= ipn.payment_date %><%= ipn.first_name %> <%= ipn.last_name %><%= ipn.item_name %> + <% if ipn.payment_gross.blank? %> + <%= ipn.txn_type %> + <% else %> + <%= ipn.payment_gross %> + <% end %> + + <% 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 %> + <%= link_to "Details", ipn %><%= link_to "Validate", validate_ipn_path(ipn) %>
diff --git a/app/views/ipns/new.html.erb b/app/views/ipns/new.html.erb new file mode 100644 index 0000000..8839fb6 --- /dev/null +++ b/app/views/ipns/new.html.erb @@ -0,0 +1,123 @@ + <%= form_tag('/ipns') do |f| %> + + + +
+ <%= submit_tag %> +
+
+ <%= label_tag :first_name %> + <%= text_field_tag :first_name, "John" %> +
+
+ <%= label_tag :last_name %> + <%= text_field_tag :last_name, "Smith" %> +
+
+ <%= label_tag :payer_email %> + <%= text_field_tag :payer_email, "jsmith@example.com" %> +
+
+ <%= label_tag :item_name %> + <%= text_field_tag :item_name, "Associate Membership" %> +
+
+ <%= label_tag :payment_gross %> + <%= text_field_tag :payment_gross, "25.00" %> +
+
+ <%= label_tag :transaction_subject %> + <%= text_field_tag :transaction_subject, "" %> +
+
+ <%= label_tag :payment_date %> + <%= text_field_tag :payment_date, "20:46:54 Jun 20, 2013 PDT" %> +
+
+ <%= label_tag :txn_type %> + <%= text_field_tag :txn_type, "subscr_payment" %> +
+
+ <%= label_tag :subscr_id %> + <%= text_field_tag :subscr_id, "I-1234567890" %> +
+
+ <%= label_tag :residence_country %> + <%= text_field_tag :residence_country, "US" %> +
+
+ <%= label_tag :mc_currency %> + <%= text_field_tag :mc_currency, "USD" %> +
+
+ <%= label_tag :business %> + <%= text_field_tag :business, "hslfinances@gmail.com" %> +
+
+ <%= label_tag :payment_type %> + <%= text_field_tag :payment_type, "instant" %> +
+
+ <%= label_tag :protection_eligibility %> + <%= text_field_tag :protection_eligibility, "Ineligible" %> +
+
+ <%= label_tag :verify_sign %> + <%= text_field_tag :verify_sign, "12ru9021j9f21j90fj1290fj2910fj0219fj0" %> +
+
+ <%= label_tag :payer_status %> + <%= text_field_tag :payer_status, "verified" %> +
+
+ <%= label_tag :txn_id %> + <%= text_field_tag :txn_id, "1234567890" %> +
+
+ <%= label_tag :receiver_email %> + <%= text_field_tag :receiver_email, "hslfinances@gmail.com" %> +
+
+ <%= label_tag :payer_id %> + <%= text_field_tag :payer_id, "V812314914" %> +
+
+ <%= label_tag :receiver_id %> + <%= text_field_tag :receiver_id, "V90R1280182" %> +
+
+ <%= label_tag :payment_status %> + <%= text_field_tag :payment_status, "Completed" %> +
+
+ <%= label_tag :payment_fee %> + <%= text_field_tag :payment_fee, "0.85" %> +
+
+ <%= label_tag :mc_fee %> + <%= text_field_tag :mc_fee, "0.85" %> +
+
+ <%= label_tag :mc_gross %> + <%= text_field_tag :mc_gross, "25.00" %> +
+
+ <%= label_tag :charset %> + <%= text_field_tag :charset, "windows-1252" %> +
+
+ <%= label_tag :notify_version %> + <%= text_field_tag :notify_version, "3.7" %> +
+
+ <%= label_tag :ipn_track_id %> + <%= text_field_tag :ipn_track_id, "9d3d032d9070" %> +
+
+ <%= submit_tag %> +
+ <% end %> \ No newline at end of file diff --git a/app/views/ipns/show.html.erb b/app/views/ipns/show.html.erb new file mode 100644 index 0000000..146481c --- /dev/null +++ b/app/views/ipns/show.html.erb @@ -0,0 +1,18 @@ +

IPN Details

+ +<% @ipn.attributes.except("data","payment_id").each do |attr| %> +

+ <%= attr.first.to_s %>: + <%= @ipn.attributes[attr.first] %> +

+<% end %> +

+ <% if @ipn.payment.present? %> + <%= link_to "Linked Payment", @ipn.payment %> + <% else %> + 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) %>. + <% end %> + +

+ +<%= link_to "Back", ipns_path %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 5d907ec..6b2658a 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,7 +11,7 @@ <%= 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 %> diff --git a/app/views/macs/scan.html.erb b/app/views/macs/scan.html.erb index 5068661..74934ca 100644 --- a/app/views/macs/scan.html.erb +++ b/app/views/macs/scan.html.erb @@ -1,5 +1,7 @@ Scanning... -<% @log.each do |log| %> +<% if can? :read_details, Mac + @log.each do |log| %> <%= log.mac %> = <%= log.ip %>
-<% end %> +<% end +end %> diff --git a/app/views/payments/_form.html.erb b/app/views/payments/_form.html.erb index dd04aad..72043e4 100644 --- a/app/views/payments/_form.html.erb +++ b/app/views/payments/_form.html.erb @@ -19,6 +19,10 @@ <%= f.label :date, "Paid for month beginning" %>
<%= f.date_select :date, :default => (DateTime.now - 1.month) %>
+
+ <%= f.label :amount %>
+ <%= f.number_field :amount %> +
<%= f.submit %>
diff --git a/app/views/payments/index.html.erb b/app/views/payments/index.html.erb index 9be4eff..a12862a 100644 --- a/app/views/payments/index.html.erb +++ b/app/views/payments/index.html.erb @@ -1,11 +1,17 @@

Listing payments

-<%= link_to 'New Payment', new_payment_path %> -
+

+Create Payments: +<%= link_to 'Manually', new_payment_path %> | +<%= link_to 'Batched CSV', paypal_csvs_path %> | +<%= link_to 'IPN', ipns_path %> +

+ + @@ -15,6 +21,7 @@ + diff --git a/app/views/payments/show.html.erb b/app/views/payments/show.html.erb index 59906ce..95cc9db 100644 --- a/app/views/payments/show.html.erb +++ b/app/views/payments/show.html.erb @@ -1,6 +1,6 @@

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

@@ -8,9 +8,19 @@ <%= @payment.date %>

+

+ Amount: + <%= @payment.amount %> +

+

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

@@ -23,6 +33,18 @@ <%= @payment.updated_at %>

+<% if @payment.ipn.present? %> +

+ <%= link_to "Paid via PayPal (IPN)", @payment.ipn %> +

+<% end %> +<% if @payment.paypal_csv.present? %> +

+ <%= link_to "Paid via PayPal (CSV)", @payment.paypal_csv %> +

+<% 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 %> | diff --git a/app/views/paypal_csvs/index.html.erb b/app/views/paypal_csvs/index.html.erb new file mode 100644 index 0000000..2343574 --- /dev/null +++ b/app/views/paypal_csvs/index.html.erb @@ -0,0 +1,35 @@ +

PayPal CSV Records

+

+ <%= link_to "Upload CSV", new_paypal_csv_path %> +

+ +
User Paid for month
beginning
Amount
<%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %> <%= payment.human_date %><%= payment.amount %> <%= link_to 'Details', payment %> <%= link_to 'Edit', edit_payment_path(payment) %>
+ + + + + + +<% @paypal_csvs.sort_by(&:date_parsed).reverse!.each do |paypal_csv| %> + + + + + + + + +<% end %> +
DateNameItemAmount
<%= paypal_csv.date %><%= paypal_csv._name %><%= paypal_csv._item_title %> + <% if paypal_csv._gross.blank? %> + <%= paypal_csv._type %> + <% else %> + <%= paypal_csv._gross %> + <% end %> + + <% if paypal_csv.payment.present? %> + <%= link_to "Linked Payment", paypal_csv.payment %> + <% else %> + <%= link_to "Try to link email '#{paypal_csv._from_email_address}' at membership level '#{paypal_csv._gross.to_i}'", link_paypal_csv_path(paypal_csv) %> + <% end %> + <%= link_to "Details", paypal_csv %>
diff --git a/app/views/paypal_csvs/new.html.erb b/app/views/paypal_csvs/new.html.erb new file mode 100644 index 0000000..275f41e --- /dev/null +++ b/app/views/paypal_csvs/new.html.erb @@ -0,0 +1,15 @@ + + +<%= form_tag('/paypal_csvs', :multipart => true) do |f| %> +
+ <%= label_tag :file %> + <%= file_field_tag :file %> +
+
+ <%= submit_tag %> +
+<% end %> \ No newline at end of file diff --git a/app/views/paypal_csvs/show.html.erb b/app/views/paypal_csvs/show.html.erb new file mode 100644 index 0000000..5aa7bb2 --- /dev/null +++ b/app/views/paypal_csvs/show.html.erb @@ -0,0 +1,17 @@ +

PayPal CSV Item Details

+<% @paypal_csv.attributes.except("data","payment_id").each do |attr| %> +

+ <%= attr.first.to_s %>: + <%= @paypal_csv.attributes[attr.first] %> +

+<% end %> + +

+ <% if @paypal_csv.payment.present? %> + <%= link_to "Linked Payment", @paypal_csv.payment %> + <% else %> + Couldn't link automatically. Please create payment manually or adjust the user account and try again to <%= link_to "link email '#{@paypal_csv._from_email_address}' at membership level '#{@paypal_csv._gross.to_i}'", link_paypal_csv_path(@paypal_csv) %>. + <% end %> + +

+<%= link_to "Back", paypal_csvs_path %> \ No newline at end of file diff --git a/app/views/user_certifications/_form.html.erb b/app/views/user_certifications/_form.html.erb index 919e8e5..cf571f6 100644 --- a/app/views/user_certifications/_form.html.erb +++ b/app/views/user_certifications/_form.html.erb @@ -11,13 +11,14 @@ <% end %> + <% @user_certification.user_id = params[:user] if params[:user].present? %>
<%= f.label :user_id, "User" %>
- <%= collection_select(:user_certification, :user_id, @users, :id, :name) %> + <%= collection_select(:user_certification, :user_id, @users, :id, :name, :include_blank => true) %>
<%= f.label :certification_id, "Certification" %>
- <%= collection_select(:user_certification, :certification_id, @certifications, :id, :name) %> + <%= collection_select(:user_certification, :certification_id, @certifications, :id, :name, :include_blank => true) %>
<%= f.submit %> diff --git a/app/views/user_certifications/index.html.erb b/app/views/user_certifications/index.html.erb index 0ef5b64..9996ffe 100644 --- a/app/views/user_certifications/index.html.erb +++ b/app/views/user_certifications/index.html.erb @@ -7,7 +7,7 @@
<%= cert.name %>
<% user_certifications.sort{|a,b| a.user_name <=> b.user_name}.each do |user_certification| %>
- <%= link_to user_certification.user_name, user_certification %> + <%= link_to user_certification.user_name, user_certification %>
<% end %> diff --git a/app/views/user_certifications/show.html.erb b/app/views/user_certifications/show.html.erb index 3ff98f4..1799b54 100644 --- a/app/views/user_certifications/show.html.erb +++ b/app/views/user_certifications/show.html.erb @@ -1,6 +1,6 @@

User: - <%= @user_certification.user_name %> + <%= link_to @user_certification.user.name, @user_certification.user %>

diff --git a/app/views/users/inactive.html.erb b/app/views/users/inactive.html.erb new file mode 100644 index 0000000..35c7911 --- /dev/null +++ b/app/views/users/inactive.html.erb @@ -0,0 +1,65 @@ +

Inactive Users

+ + + + + <% if current_user.admin? then %><% end %> + + <% if current_user.admin? %>+ <% end %> + + + + + + + + <% if current_user.admin? then %><% end %> + + <% if current_user.admin? then %> + + <% end %> + + + + + + + + + +<% if !@users.blank? %> + <% @users.each do |user| %> + + + <% if current_user.admin? then %><% end %> + + <% if current_user.admin? then %><% end %> + + + + + + + + + <% end %> +<% end %> +
NameEmailCertificationsOrientation?Card?Pmt MethodDesired LevelLast PaymentJoined
<%= image_tag user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png"), :class => :avatar %><%= link_to user.name, user %><%= user.email %><% user.certifications.each do |c| %> + <%= link_to c.name, c %><%= "," unless c.id == user.certifications.last.id %> + <% end %> + <%= unless user.orientation.blank? then raw("") end %> + <%= unless user.cards.blank? then raw("") end %><%= user.payment_method %><%= user.member_level %><% delinquency = user.delinquency %> + <% if delinquency == 9999 %> + No Payments + <% else %> + <%= (delinquency/30).to_s+" mo. ago" %> + <% end %> + <%= user.created_at.to_date %><%= link_to 'Edit', edit_user_path(user) if can? :update, user %><%= link_to 'Destroy', user, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE USER FROM THE DOOR SYSTEM! DISABLE THEM FIRST.', :method => :delete if can? :destroy, user %>
+ +<% if current_user.orientation.blank? then %> +

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.

+<% end %> + +
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 19a48e2..bcbff58 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -6,6 +6,9 @@ <% if can? :manage, User %> | <%= link_to 'Merge Users', users_merge_path %> <% end %> +<% if current_user.admin? %> + | <%= link_to 'Inactive Users', users_inactive_path %> +<% end %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 5d2e308..fe5e953 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -74,17 +74,19 @@

<% end %>

- Card: + Card: <%= link_to "+ Add", (new_card_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, Card %> <% if current_user.admin? then %> +

    <% @user.cards.each do |c| %> - <%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %> +
  • <%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %>
  • <% end %> +
<% else %> <%= unless @user.cards.blank? then raw("✓") end %> <% end %>

-Certifications: +Certifications: <%= link_to "+ Add", (new_user_certification_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, UserCertification %>
    <% @user.certifications.each do |certification| %>
  • <%= link_to certification.name, certification %>
  • diff --git a/config/routes.rb b/config/routes.rb index 518a30a..46ceb98 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,11 @@ 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 :paypal_csvs + match 'paypal_csvs/:id/link' => 'paypal_csvs#link', :as => :link_paypal_csv resources :payments @@ -21,6 +28,7 @@ Dooraccess::Application.routes.draw do 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 + match 'users/inactive' => 'users#inactive' # Inactive users report resources :users match 'users/create' => 'users#create', :via => :post # Use POST users/create instead of POST users to avoid devise conflict diff --git a/db/migrate/20130824062334_create_ipns.rb b/db/migrate/20130824062334_create_ipns.rb new file mode 100644 index 0000000..fad43b4 --- /dev/null +++ b/db/migrate/20130824062334_create_ipns.rb @@ -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 diff --git a/db/migrate/20130824072157_add_amount_to_payments.rb b/db/migrate/20130824072157_add_amount_to_payments.rb new file mode 100644 index 0000000..37b65e6 --- /dev/null +++ b/db/migrate/20130824072157_add_amount_to_payments.rb @@ -0,0 +1,5 @@ +class AddAmountToPayments < ActiveRecord::Migration + def change + add_column :payments, :amount, :decimal + end +end diff --git a/db/migrate/20130828104240_create_paypal_csvs.rb b/db/migrate/20130828104240_create_paypal_csvs.rb new file mode 100644 index 0000000..f0d682e --- /dev/null +++ b/db/migrate/20130828104240_create_paypal_csvs.rb @@ -0,0 +1,28 @@ +class CreatePaypalCsvs < ActiveRecord::Migration + def change + create_table :paypal_csvs do |t| + t.integer :payment_id + t.text :data + t.string :date + t.string :_time + t.string :_time_zone + t.string :_name + t.string :_type + t.string :_status + t.string :_currency + t.string :_gross + t.string :_fee + t.string :_net + t.string :_from_email_address + t.string :_to_email_address + t.string :_transaction_id + t.string :_counterparty_status + t.string :_address_status + t.string :_item_title + t.string :_item_id + t.string :string + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 19fced1..3cb31fb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130212083412) do +ActiveRecord::Schema.define(:version => 20130828104240) do create_table "cards", :force => true do |t| t.string "card_number" @@ -35,6 +35,27 @@ ActiveRecord::Schema.define(:version => 20130212083412) 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" @@ -64,10 +85,36 @@ ActiveRecord::Schema.define(:version => 20130212083412) do 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 "paypal_csvs", :force => true do |t| + t.integer "payment_id" + t.text "data" + t.string "date" + t.string "_time" + t.string "_time_zone" + t.string "_name" + t.string "_type" + t.string "_status" + t.string "_currency" + t.string "_gross" + t.string "_fee" + t.string "_net" + t.string "_from_email_address" + t.string "_to_email_address" + t.string "_transaction_id" + t.string "_counterparty_status" + t.string "_address_status" + t.string "_item_title" + t.string "_item_id" + t.string "string" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "user_certifications", :force => true do |t| t.integer "user_id" t.integer "certification_id" diff --git a/public/copper-coin.png b/public/copper-coin.png new file mode 100644 index 0000000..809bbbb Binary files /dev/null and b/public/copper-coin.png differ diff --git a/public/copper-paid-coin.png b/public/copper-paid-coin.png new file mode 100644 index 0000000..6d40b7b Binary files /dev/null and b/public/copper-paid-coin.png differ diff --git a/public/favicon.ico b/public/favicon.ico index e69de29..f3f28f6 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/gold-coin.png b/public/gold-coin.png new file mode 100644 index 0000000..e3f3836 Binary files /dev/null and b/public/gold-coin.png differ diff --git a/public/gold-paid-coin.png b/public/gold-paid-coin.png new file mode 100644 index 0000000..ffa678a Binary files /dev/null and b/public/gold-paid-coin.png differ diff --git a/public/heart-coin.png b/public/heart-coin.png new file mode 100644 index 0000000..84bfcf6 Binary files /dev/null and b/public/heart-coin.png differ diff --git a/public/no-coin.png b/public/no-coin.png new file mode 100644 index 0000000..7318232 Binary files /dev/null and b/public/no-coin.png differ diff --git a/public/silver-coin.png b/public/silver-coin.png new file mode 100644 index 0000000..0d525ea Binary files /dev/null and b/public/silver-coin.png differ diff --git a/public/silver-paid-coin.png b/public/silver-paid-coin.png new file mode 100644 index 0000000..4b30951 Binary files /dev/null and b/public/silver-paid-coin.png differ diff --git a/public/timeout-coin.png b/public/timeout-coin.png new file mode 100644 index 0000000..fbdcea4 Binary files /dev/null and b/public/timeout-coin.png differ diff --git a/test/fixtures/ipns.yml b/test/fixtures/ipns.yml new file mode 100644 index 0000000..6d2f6e4 --- /dev/null +++ b/test/fixtures/ipns.yml @@ -0,0 +1,7 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + data: MyText + +two: + data: MyText diff --git a/test/fixtures/paypal_csvs.yml b/test/fixtures/paypal_csvs.yml new file mode 100644 index 0000000..c103612 --- /dev/null +++ b/test/fixtures/paypal_csvs.yml @@ -0,0 +1,41 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + date: MyString + _time: MyString + _time_zone: MyString + _name: MyString + _type: MyString + _status: MyString + _currency: MyString + _gross: MyString + _fee: MyString + _net: MyString + _from_email_address: MyString + _to_email_address: MyString + _transaction_id: MyString + _counterparty_status: MyString + _address_status: MyString + _item_title: MyString + _item_id: MyString + string: MyString + +two: + date: MyString + _time: MyString + _time_zone: MyString + _name: MyString + _type: MyString + _status: MyString + _currency: MyString + _gross: MyString + _fee: MyString + _net: MyString + _from_email_address: MyString + _to_email_address: MyString + _transaction_id: MyString + _counterparty_status: MyString + _address_status: MyString + _item_title: MyString + _item_id: MyString + string: MyString diff --git a/test/functional/ipn_controller_test.rb b/test/functional/ipn_controller_test.rb new file mode 100644 index 0000000..0d5ac04 --- /dev/null +++ b/test/functional/ipn_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class IpnControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/helpers/ipn_helper_test.rb b/test/unit/helpers/ipn_helper_test.rb new file mode 100644 index 0000000..be0cbae --- /dev/null +++ b/test/unit/helpers/ipn_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class IpnHelperTest < ActionView::TestCase +end diff --git a/test/unit/ipn_test.rb b/test/unit/ipn_test.rb new file mode 100644 index 0000000..fbdc7fa --- /dev/null +++ b/test/unit/ipn_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class IpnTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/paypal_csv_test.rb b/test/unit/paypal_csv_test.rb new file mode 100644 index 0000000..c610e02 --- /dev/null +++ b/test/unit/paypal_csv_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class PaypalCsvTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end