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/models/ipn.rb b/app/models/ipn.rb index 2b37017..002a834 100644 --- a/app/models/ipn.rb +++ b/app/models/ipn.rb @@ -5,6 +5,14 @@ class Ipn < ActiveRecord::Base 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() diff --git a/app/models/paypal_csv.rb b/app/models/paypal_csv.rb new file mode 100644 index 0000000..1791aa6 --- /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.find_by_email(self._from_email_address) + user = User.find_by_payee(self._from_email_address) 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/views/ipns/index.html.erb b/app/views/ipns/index.html.erb index 724c670..70c7709 100644 --- a/app/views/ipns/index.html.erb +++ b/app/views/ipns/index.html.erb @@ -6,7 +6,7 @@ Item Amount - <% @ipns.reverse!.each do |ipn| %> + <% @ipns.sort_by(&:date_parsed).reverse!.each do |ipn| %> <%= ipn.payment_date %> <%= ipn.first_name %> <%= ipn.last_name %> diff --git a/app/views/paypal_csvs/index.html.erb b/app/views/paypal_csvs/index.html.erb new file mode 100644 index 0000000..305bf70 --- /dev/null +++ b/app/views/paypal_csvs/index.html.erb @@ -0,0 +1,31 @@ +<%= link_to "Upload CSV", new_paypal_csv_path %> + + + + + + + +<% @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/config/routes.rb b/config/routes.rb index 4cfeb05..ba34d4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,9 @@ Dooraccess::Application.routes.draw do 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 resources :user_certifications 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 ac3f771..25dbad2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,3 +1,4 @@ +# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -10,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130824072157) do +ActiveRecord::Schema.define(:version => 20130828104240) do create_table "cards", :force => true do |t| t.string "card_number" @@ -90,6 +91,31 @@ ActiveRecord::Schema.define(:version => 20130824072157) do 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/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/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