From 7736ac5c342dd9de6ddc9647f1243a8ac1a5f027 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sat, 29 Jun 2013 15:19:38 -0400 Subject: [PATCH] Added credit tracking and stats Added credit_conversions table so conversions can change over time Added default credit conversion fixture Added User#transaction_logs Added User#total_credits (earned minus spent) Added User#total_credits_spent (through transaction_logs) Added User#total_earned_credits (complicated query which finds the conversion rate for a log depending on its created_at date) --- app/components/user_stats.rb | 5 ++- app/models/credit_conversion.rb | 3 ++ app/models/user.rb | 40 ++++++++++++++++++- ...0130629152047_create_credit_conversions.rb | 8 ++++ db/schema.rb | 14 +++++-- db/seed/fixtures/credit_conversions.yml | 3 ++ 6 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 app/models/credit_conversion.rb create mode 100644 db/migrate/20130629152047_create_credit_conversions.rb create mode 100644 db/seed/fixtures/credit_conversions.yml diff --git a/app/components/user_stats.rb b/app/components/user_stats.rb index 896120f..854a9cb 100644 --- a/app/components/user_stats.rb +++ b/app/components/user_stats.rb @@ -3,11 +3,14 @@ class UserStats < Netzke::Base def body_content(user) bike = user.bike completed = user.completed_build_bikes - #I think it's time to switch to a template + #TODO I think it's time to switch to a template body = "" body += %Q(
) body += %Q(

Username: #{user.username}

+

Total Credits Earned: #{user.total_earned_credits}

+

Credits Available: #{user.total_credits}

+

Credits Spent: #{user.total_credits_spent}

Total Hours Worked: #{user.total_hours}

Hours worked in #{Time.now.strftime('%B')}: #{user.current_month_hours}

Current bike Shop ID: #{bike.shop_id if bike}

diff --git a/app/models/credit_conversion.rb b/app/models/credit_conversion.rb new file mode 100644 index 0000000..f7dc1d9 --- /dev/null +++ b/app/models/credit_conversion.rb @@ -0,0 +1,3 @@ +class CreditConversion < ActiveRecord::Base + attr_accessible :conversion +end diff --git a/app/models/user.rb b/app/models/user.rb index 54c7904..47f100a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,7 +10,8 @@ class User < ActiveRecord::Base :first_name, :last_name, :bike_id, :user_profiles_attributes, :username - has_many :transactions + has_many :transactions, as: :customer + has_many :transaction_logs, through: :transactions, source: :logs has_many :user_profiles accepts_nested_attributes_for :user_profiles, allow_destroy: false @@ -56,6 +57,43 @@ class User < ActiveRecord::Base WHERE bike_status_id = #{status_id}") end + def total_credits + total_earned_credits - total_credits_spent + end + + def total_credits_spent + log_action = ::ActsAsLoggable::TransactionAction.find_by_action("TIME") + transaction_logs. + where( "log_action_id = ? AND log_action_type = ?", + log_action.id, log_action.class.to_s). + sum{ |r| r.description.to_i }.round(2) + end + + def total_earned_credits + log_action = ::ActsAsLoggable::UserAction.find_by_action("CHECKIN") + + # Find the first credit conversion which has a created_at date before the + # log's created_at date and join it to the log's row so we can calculate + # the credits earned from that log entry (each log could have a different + # conversion rate) + # + # The DISTINCT ON, and ORDER BY are important to getting the + # single conversion rate that applies to the respective log. + ::ActsAsLoggable::Log.find_by_sql(" + SELECT DISTINCT ON (logs.created_at) start_date, end_date, + conversion.conversion, conversion.created_at + FROM logs + INNER JOIN( + SELECT conversion, created_at + FROM credit_conversions + ) AS conversion ON logs.created_at > conversion.created_at + WHERE logs.loggable_id = #{self.id} + AND logs.loggable_type = 'User' + AND (log_action_id != #{log_action.id} AND log_action_type = '#{log_action.class.to_s}') + ORDER BY logs.created_at, conversion.created_at DESC"). + sum{ |l| ((l.end_date - l.start_date)/3600) * l.conversion.to_i}.round(2) + end + def total_hours log_action = ::ActsAsLoggable::UserAction.find_by_action("CHECKIN") logs.where("log_action_id != ? AND log_action_type = ?", log_action.id, log_action.class.to_s).sum { |l| (l.end_date - l.start_date)/3600 }.round(2) diff --git a/db/migrate/20130629152047_create_credit_conversions.rb b/db/migrate/20130629152047_create_credit_conversions.rb new file mode 100644 index 0000000..9771a90 --- /dev/null +++ b/db/migrate/20130629152047_create_credit_conversions.rb @@ -0,0 +1,8 @@ +class CreateCreditConversions < ActiveRecord::Migration + def change + create_table(:credit_conversions) do |t| + t.integer :conversion, :default => 1 + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 263122e..2bed2b4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130614003934) do +ActiveRecord::Schema.define(:version => 20130629152047) do create_table "bike_actions", :force => true do |t| t.string "action", :limit => 128, :null => false @@ -65,6 +65,12 @@ ActiveRecord::Schema.define(:version => 20130614003934) do add_index "bikes", ["shop_id"], :name => "index_bikes_on_shop_id", :unique => true + create_table "credit_conversions", :force => true do |t| + t.integer "conversion", :default => 1 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "customers", :force => true do |t| t.string "first_name", :null => false t.string "last_name", :null => false @@ -155,9 +161,9 @@ ActiveRecord::Schema.define(:version => 20130614003934) do end create_table "user_role_joins", :force => true do |t| - t.integer "role_id", :limit => 255 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "role_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.datetime "ends" t.integer "user_id" end diff --git a/db/seed/fixtures/credit_conversions.yml b/db/seed/fixtures/credit_conversions.yml new file mode 100644 index 0000000..cbeb476 --- /dev/null +++ b/db/seed/fixtures/credit_conversions.yml @@ -0,0 +1,3 @@ +conversion: + id: 1 + conversion: 10