<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>db/migrate/20091022150926_add_type_to_donations.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff></diff>
      <filename>app/controllers/myspot/donation_amounts_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,7 +38,11 @@ class Myspot::DonationsController &lt; ApplicationController
   end
 
   def new_resource
-    current_user.donations.new(params[:donation])
+     current_user.donations.new(params[:donation])
+     # TODO: figure out why donation_type does not get properly assigned with params / should not need to assign after new
+     # d = Donation.new(params[:donation])
+     # d.donation_type = params[:donation][:donation_type]
+     # d
   end
 
   def find_resources</diff>
      <filename>app/controllers/myspot/donations_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -46,6 +46,7 @@ class Donation &lt; ActiveRecord::Base
   belongs_to :user
   belongs_to :pitch
   belongs_to :purchase
+  belongs_to :credit
   belongs_to :group
   validates_presence_of :pitch_id
   validates_presence_of :user_id
@@ -53,13 +54,15 @@ class Donation &lt; ActiveRecord::Base
   validates_numericality_of :amount, :greater_than =&gt; 0
   validate_on_update :disable_updating_paid_donations, :check_donation, :if =&gt; lambda { |me| me.pitch }
   validate_on_create :check_donation, :if =&gt; lambda { |me| me.pitch }
-
+  
+  #default_scope :conditions =&gt; {:donation_type =&gt; &quot;payment&quot;}
   named_scope :unpaid, :conditions =&gt; &quot;status = 'unpaid'&quot;
   named_scope :paid, :conditions =&gt; &quot;status = 'paid'&quot;
   named_scope :from_organizations, :include =&gt; :user, :conditions =&gt; &quot;users.type = 'organization'&quot;
   named_scope :for_pitch, lambda {|pitch| { :conditions =&gt; {:pitch_id =&gt; pitch.id} } }
   named_scope :by_user, lambda {|user| { :conditions =&gt; {:user_id =&gt; user.id} } }
-
+  named_scope :other_than, lambda {|donation| { :conditions =&gt; &quot;id != #{donation.id}&quot; } }
+  
   after_save :update_pitch_funding, :send_thank_you, :if =&gt; lambda {|me| me.paid?}
 
   def self.createable_by?(user)
@@ -88,7 +91,7 @@ class Donation &lt; ActiveRecord::Base
   end
 
   def update_pitch_funding
-    pitch.current_funding += amount
+    pitch.current_funding += amount.to_f
     pitch.save
   end
 
@@ -101,6 +104,42 @@ class Donation &lt; ActiveRecord::Base
   def being_marked_as_paid?
     status_changed? &amp;&amp; status_was == 'unpaid'
   end
+  
+  def keep_under_user_limit
+    #max_donation_amount(user) - 
+    #debugger
+    if self.amount &gt; self.pitch.max_donation_amount(user) - self.pitch.total_amount_allocated_by_user(user)
+      if self.id # updating 
+        self.amount = pitch.max_donation_amount(user) - pitch.donations.by_user(user).other_than(self).map(&amp;:amount).sum + 
+          pitch.credit_pitches.by_user(user).other_than(self).map(&amp;:amount).sum
+      else # creating
+        self.amount = pitch.max_donation_amount(user) - pitch.donations.by_user(user).map(&amp;:amount).sum + 
+          pitch.credit_pitches.by_user(user).map(&amp;:amount).sum
+      end
+    end
+  end
+  
+  def limit_to_existing_donation
+    #debugger
+    existing_donation = pitch.donations.unpaid.by_user(user).map(&amp;:amount).sum #Donation.unpaid.find(:all, :conditions =&gt; &quot;pitch_id = #{pitch.id} and user_id = #{user.id}&quot;).map(&amp;:amount).sum
+    if existing_donation &gt; 0
+      self.amount = existing_donation
+    end
+  end
+  
+  def check_credit
+    #debugger
+    # limit if not an org and the amount is greater than the pitch/user's remaining limit (under 20% of pitch total)
+    if !user.organization? 
+      keep_under_user_limit #self.pitch.max_donation_amount(user) - self.pitch.total_amount_allocated_by_user(user)
+    end
+    
+    limit_to_existing_donation
+    # limit if amount is greater than the remaining funding sought for pitch
+    if self.amount &gt; pitch.requested_amount - pitch.current_funding
+      self.amount = pitch.requested_amount - pitch.current_funding
+    end 
+  end
 
   def check_donation
     if pitch.fully_funded?
@@ -108,9 +147,12 @@ class Donation &lt; ActiveRecord::Base
       return
     end
 
-    #TODO: convert user_can_donate_more? to use BigDecimal and pass in amount
-    unless pitch.user_can_donate_more?(user, amount)
+    if donation_type == &quot;credit&quot;
+        check_credit
+    end
+    unless pitch.user_can_donate_more?(user, self.amount)
       errors.add_to_base(&quot;Thanks for your support but we only allow donations of 20% of requested amount from one user. Please lower your donation amount and try again.&quot;)
+      return
     end
   end
 
@@ -129,5 +171,14 @@ class Donation &lt; ActiveRecord::Base
       paypal_params.delete(spotus_keys.first)
     end
   end
+  
+  def self.has_enough_credits?(credit_pitch_amounts, user)
+      credit_total = 0
+      credit_pitch_amounts.values.each do |val|
+        credit_total += val[&quot;amount&quot;].to_f
+      end
+      return true if credit_total &lt;= user.total_credits
+      return false
+  end
 end
 </diff>
      <filename>app/models/donation.rb</filename>
    </modified>
    <modified>
      <diff>@@ -81,7 +81,7 @@ class Pitch &lt; NewsItem
   has_many :tips, :through =&gt; :affiliations
   has_many :organization_pitches, :foreign_key =&gt; :pitch_id
   has_many :supporting_organizations, :through =&gt; :organization_pitches, :source =&gt; :organization
-  has_many :donations, :dependent =&gt; :destroy do
+  has_many :donations, :conditions =&gt; {:donation_type =&gt; &quot;payment&quot;}, :dependent =&gt; :destroy do
     def for_user(user)
       find_all_by_user_id(user.id)
     end
@@ -90,11 +90,22 @@ class Pitch &lt; NewsItem
       for_user(user).map(&amp;:amount).sum
     end
   end
+  
+  has_many :credit_pitches, :class_name =&gt; &quot;Donation&quot;, :conditions =&gt; {:donation_type =&gt; &quot;credit&quot;}, :dependent =&gt; :destroy do
+    def for_user(user)
+      find_all_by_user_id(user.id)
+    end
+
+    def total_amount_for_user(user)
+      for_user(user).map(&amp;:amount).sum
+    end
+  end
+  has_many :donations_and_credits, :class_name =&gt; &quot;Donation&quot;
   has_many :organizational_donors, :through =&gt; :donations, :source =&gt; :user, :order =&gt; &quot;donations.created_at&quot;, 
             :conditions =&gt; &quot;users.type = 'organization'&quot;,
             :uniq =&gt; true
             
-  has_many :supporters, :through =&gt; :donations, :source =&gt; :user, :order =&gt; &quot;donations.created_at&quot;, :uniq =&gt; true
+  has_many :supporters, :through =&gt; :donations_and_credits, :source =&gt; :user, :order =&gt; &quot;donations.created_at&quot;, :uniq =&gt; true
   has_many :blog_subscribers, :through =&gt; :donations, :source =&gt; :user, :conditions =&gt; &quot;users.notify_blog_posts = 1&quot;, 
             :order =&gt; &quot;donations.created_at&quot;, :uniq =&gt; true
   has_many :posts, :order =&gt; &quot;created_at desc&quot;, :dependent =&gt; :destroy do
@@ -252,7 +263,11 @@ class Pitch &lt; NewsItem
   end
 
   def total_amount_donated
-    donations.paid.map(&amp;:amount).sum
+    donations.paid.map(&amp;:amount).sum + credit_pitches.paid.map(&amp;:amount).sum
+  end
+  
+  def total_amount_allocated_by_user(user)
+    donations.by_user(user).map(&amp;:amount).sum + credit_pitches.by_user(user).map(&amp;:amount).sum
   end
 
   def donated_to?
@@ -279,8 +294,10 @@ class Pitch &lt; NewsItem
     return false if attempted_donation_amount.nil?
     return true if user.organization? &amp;&amp; attempted_donation_amount &lt;= requested_amount
     return false if attempted_donation_amount &gt; funding_needed
-    user_donations = donations.paid.total_amount_for_user(user)
+    user_donations = donations.paid.total_amount_for_user(user) + credit_pitches.paid.total_amount_for_user(user)
+    #user_donations = donations.total_amount_for_user(user) + credit_pitches.total_amount_for_user(user)
     (user_donations + attempted_donation_amount) &lt;= max_donation_amount(user)
+    #user_donations &lt;= max_donation_amount(user)
   end
 
   def dispatch_fact_checker</diff>
      <filename>app/models/pitch.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ class Purchase &lt; ActiveRecord::Base
 
   cattr_accessor :gateway
 
-  after_create :associate_donations, :apply_credit_pitches, :associate_spotus_donations
+  after_create :associate_donations, :associate_spotus_donations, :associate_credits
   before_create :bill_credit_card, :unless =&gt; lambda {|p| p.paypal_transaction? }
 
   before_validation_on_create :build_credit_card, :set_credit_card_number_ending, :unless =&gt; lambda {|p| p.paypal_transaction? }
@@ -42,7 +42,8 @@ class Purchase &lt; ActiveRecord::Base
   validate :validate_credit_card, :on =&gt; :create, :unless =&gt; lambda {|p| p.credit_covers_total? || p.paypal_transaction? }
 
   belongs_to :user
-  has_many   :donations
+  has_many   :donations, :conditions =&gt; {:donation_type =&gt; &quot;payment&quot;}
+  has_many :credit_pitches, :class_name =&gt; &quot;Donation&quot;, :conditions =&gt; {:donation_type =&gt; &quot;credit&quot;}
   has_one    :spotus_donation
 
   def credit_covers_total?
@@ -60,6 +61,10 @@ class Purchase &lt; ActiveRecord::Base
   def donations=(donations)
     @new_donations = donations
   end
+  
+  def credit_pitches=(credit_pitches)
+    @new_credit_pitches = credit_pitches
+  end
 
   def total_amount
     return self[:total_amount] unless self[:total_amount].blank?
@@ -85,10 +90,6 @@ class Purchase &lt; ActiveRecord::Base
     self[:total_amount] = total_amount
   end
 
-  def apply_credit_pitches
-      self.user.apply_credit_pitches
-  end
-
   def build_credit_card
     @credit_card = ActiveMerchant::Billing::CreditCard.new(credit_card_hash)
   end
@@ -107,6 +108,20 @@ class Purchase &lt; ActiveRecord::Base
     (@new_donations || []).each do |donation|
       donation.purchase = self
       donation.pay!
+      
+    end
+  end
+  
+  def associate_credits
+    transaction do 
+      credit_pitch_ids = user.credit_pitches.unpaid.map{|credit_pitch| [credit_pitch.pitch.id]}.join(&quot;, &quot;)
+      credit = Credit.create(:user =&gt; user, :description =&gt; &quot;Applied to Pitches (#{credit_pitch_ids})&quot;,
+                      :amount =&gt; (0 - user.allocated_credits))
+      user.credit_pitches.unpaid.each do |credit_pitch|
+        credit_pitch.credit_id = credit.id
+        credit_pitch.status = &quot;deducted&quot;
+        credit_pitch.save(false)
+      end
     end
   end
 </diff>
      <filename>app/models/purchase.rb</filename>
    </modified>
    <modified>
      <diff>@@ -54,7 +54,6 @@ class Tip &lt; NewsItem
 
   named_scope :most_pledged, :order =&gt; &quot;(select sum(amount) from pledges where pledges.tip_id = #{table_name}.id) DESC&quot;
 
-
   def self.createable_by?(user)
     !user.nil?
   end</diff>
      <filename>app/models/tip.rb</filename>
    </modified>
    <modified>
      <diff>@@ -68,11 +68,19 @@ class User &lt; ActiveRecord::Base
 
   belongs_to :category
 
-  has_many :donations do
+  has_many :donations, :conditions =&gt; {:donation_type =&gt; &quot;payment&quot;} do
     def pitch_sum(pitch)
       self.paid.all(:conditions =&gt; {:pitch_id =&gt; pitch}).map(&amp;:amount).sum
     end
   end
+  
+  has_many :credit_pitches, :class_name =&gt; &quot;Donation&quot;, :conditions =&gt; {:donation_type =&gt; &quot;credit&quot;} do
+    def pitch_sum(pitch)
+      self.paid.all(:conditions =&gt; {:pitch_id =&gt; pitch}).map(&amp;:amount).sum
+    end
+  end
+
+  has_many :all_donations, :class_name =&gt; &quot;Donation&quot;
 
   has_many :spotus_donations
   has_many :tips
@@ -82,7 +90,7 @@ class User &lt; ActiveRecord::Base
   has_many :jobs
   has_many :samples
   has_many :credits
-  has_many :credit_pitches
+
   has_many :comments
   has_many :contributor_applications
   has_many :pledges do
@@ -193,16 +201,15 @@ class User &lt; ActiveRecord::Base
   
   def apply_credit_pitches
       #refactor - there must be a nicer ruby-like way to do this
+      
       transaction do 
-          credit_pitch_ids = self.credit_pitches.map{|credit_pitch| [credit_pitch.id]}.join(&quot;, &quot;)
-          credit = Credit.create(:user =&gt; self, :description =&gt; &quot;Applied to Pitches (#{credit_pitch_ids})&quot;,
-                          :amount =&gt; (0 - self.allocated_credits))
-          self.credit_pitches.each do |credit_pitch|
-              credit_pitch.status = &quot;paid&quot;
-              credit_pitch.paid_credit_id = credit.id
-              credit_pitch.update_pitch_funding
-              credit_pitch.save
-          end
+        credit_pitch_ids = self.credit_pitches.unpaid.map{|credit_pitch| [credit_pitch.pitch.id]}.join(&quot;, &quot;)
+        credit = Credit.create(:user =&gt; self, :description =&gt; &quot;Applied to Pitches (#{credit_pitch_ids})&quot;,
+                        :amount =&gt; (0 - self.allocated_credits))
+        self.credit_pitches.unpaid.each do |credit_pitch|
+          credit_pitch.credit_id = credit.id
+          credit_pitch.pay!
+        end
       end 
   end
 
@@ -255,7 +262,7 @@ class User &lt; ActiveRecord::Base
   end
 
   def amount_donated_to(pitch)
-    self.donations.pitch_sum(pitch)
+    self.donations.pitch_sum(pitch) + self.credit_pitches.pitch_sum(pitch)
   end
 
   # Encrypts the password with the user salt</diff>
      <filename>app/models/user.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,8 @@
-- form_for CreditPitch.new(:pitch =&gt; news_item, :amount =&gt; current_user.remaining_credits), :url =&gt; myspot_credit_pitches_path, :html =&gt; {:id =&gt; &quot;new_credit_pitch_#{news_item.id}&quot;, :class =&gt; &quot;auth&quot;} do |f|
+- form_for Donation.new(:pitch =&gt; news_item, :amount =&gt; current_user.remaining_credits, :donation_type =&gt; &quot;credit&quot;), :url =&gt; myspot_donations_path, :html =&gt; {:id =&gt; &quot;new_credit_pitch_#{news_item.id}&quot;, :class =&gt; &quot;auth&quot;} do |f|
   = f.hidden_field :amount, :id =&gt; &quot;credit_pitch_amount&quot;
   = f.hidden_field :pitch_id
-  = image_submit_tag &quot;apply_credits.png&quot;, :alt =&gt; &quot;Apply credits&quot;, :title =&gt; &quot;Apply credits&quot;
\ No newline at end of file
+  = f.hidden_field :user_id, :value =&gt; current_user.id
+  = f.hidden_field :donation_type, :value =&gt; &quot;credit&quot;
+  = image_submit_tag &quot;apply_credits.png&quot;, :alt =&gt; &quot;Apply credits&quot;, :title =&gt; &quot;Apply credits&quot;
+.double_content_border
+= render :partial =&gt; &quot;shared/progress_bar&quot;, :locals =&gt; {:pitch =&gt; news_item}
\ No newline at end of file</diff>
      <filename>app/views/credits/_credit_pitch.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
 - case
-  - when news_item.fully_funded?
+  - when news_item.fully_funded? 
     = render :partial =&gt; 'donations/fully_funded'
-  - when current_user &amp;&amp; current_user.remaining_credits &gt; 0
+  - when current_user &amp;&amp; (current_user.remaining_credits &gt; 0) &amp;&amp; (news_item.total_amount_allocated_by_user(current_user) &lt; current_user.max_donation_for(news_item))
     = render :partial =&gt; 'credits/credit_pitch', :locals =&gt; {:news_item =&gt; news_item}
-  - when current_user &amp;&amp; !current_user.can_donate_to?(news_item)
+  - when current_user &amp;&amp; !current_user.can_donate_to?(news_item) || (news_item.total_amount_allocated_by_user(current_user) &gt;= current_user.max_donation_for(news_item))
     = render :partial =&gt; 'donations/can_not_donate', :locals =&gt; {:news_item =&gt; news_item}
   - when news_item.funding_needed &lt; Donation::DEFAULT_AMOUNT || (current_user &amp;&amp; current_user.max_donation_for(news_item) &lt; Donation::DEFAULT_AMOUNT)
     = render :partial =&gt; 'donations/donate_variable_amount', :locals =&gt; {:news_item =&gt; news_item} </diff>
      <filename>app/views/donations/_button.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 - # dashboard navigation
 #dashboard_tab_container
   %ul.dashboard_navigation
-    %li= link_to &quot;My Donations (#{current_user.donations.paid.count})&quot;, myspot_donations_path, :id =&gt; &quot;dashboard_donations_tab&quot;
+    %li= link_to &quot;My Donations (#{current_user.all_donations.paid.count})&quot;, myspot_donations_path, :id =&gt; &quot;dashboard_donations_tab&quot;
     %li= link_to &quot;My Pledges (#{current_user.pledges.count})&quot;,   myspot_pledges_path,   :id =&gt; &quot;dashboard_pledges_tab&quot;
     %li= link_to &quot;My Pitches (#{current_user.pitches.count})&quot;, myspot_pitches_path,   :id =&gt; &quot;dashboard_pitches_tab&quot;
     %li= link_to &quot;My Blog Posts (#{current_user.posts.count})&quot;, myspot_posts_path, :id =&gt; &quot;dashboard_posts_tab&quot;</diff>
      <filename>app/views/myspot/_dashboard_nav.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -55,12 +55,12 @@
               = text_field_tag &quot;donation_amounts[#{donation.id}][amount]&quot;, number_to_currency(donation.amount, :delimiter =&gt; '', :unit =&gt; ''), :size =&gt; 4, :id =&gt; &quot;donation_amounts_#{donation.id}_amount&quot;
               .action= link_to &quot;Remove&quot;, myspot_donation_path(donation), :method =&gt; :delete, :confirm =&gt; &quot;Are you sure you'd like to remove this donation of #{number_to_currency(donation.amount)}?&quot;
             %hr
-        - if current_user.credit_pitches.unpaid.any?
+        - if unpaid_credits.any?
           %h3 
             Apply Credits
           %ul.unpaid_donations 
             %hr
-              - current_user.credit_pitches.unpaid.each do |credit_pitch|
+              - unpaid_credits.each do |credit_pitch|
                 - content_tag_for :li, credit_pitch, :class =&gt; 'unpaid' do
                   .column.span-70
                     = link_to image_tag(credit_pitch.pitch.featured_image.url(:thumb)), credit_pitch.pitch
@@ -74,7 +74,7 @@
                   .column.span-95
                     $
                     = text_field_tag &quot;credit_pitch_amounts[#{credit_pitch.id}][amount]&quot;, number_to_currency(credit_pitch.amount, :delimiter =&gt; '', :unit =&gt; ''), :size =&gt; 4, :id =&gt; &quot;credit_pitch_amounts_#{credit_pitch.id}_amount&quot;
-                    .action= link_to &quot;Remove&quot;, myspot_credit_pitch_path(credit_pitch), :method =&gt; :delete, :confirm =&gt; &quot;Are you sure you'd like to remove this credit of #{number_to_currency(credit_pitch.amount)}?&quot;
+                    .action= link_to &quot;Remove&quot;, myspot_donation_path(credit_pitch), :method =&gt; :delete, :confirm =&gt; &quot;Are you sure you'd like to remove this credit of #{number_to_currency(credit_pitch.amount)}?&quot;
                   %hr  
         %li#support_spotus
           %h3 Support Spot.Us
@@ -90,7 +90,7 @@
             = text_field_tag &quot;spotus_donation_amount&quot;, number_to_currency(spotus_donation.amount, :unit =&gt; ''), :size =&gt; 5, :id =&gt; &quot;spotus_donation&quot;
             .action= link_to &quot;Remove&quot;, '#', :id =&gt; 'remove_spotus_donation'
       .float-right
-        = image_submit_tag 'update.png', :alt =&gt; 'Update', :name =&gt;&quot;submit&quot;, :value =&gt; &quot;update&quot;
+        =# image_submit_tag 'update.png', :alt =&gt; 'Update', :name =&gt;&quot;submit&quot;, :value =&gt; &quot;update&quot;
         = image_submit_tag 'purchase.png', :alt =&gt; 'Purchase', :name =&gt;&quot;submit&quot;, :value =&gt; &quot;purchase&quot;
     .double_content_border
 </diff>
      <filename>app/views/myspot/donation_amounts/edit.html.haml</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>app/models/credit_pitch.rb</filename>
    </removed>
    <removed>
      <filename>spec/controllers/myspot/credit_pitches_controller_spec.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>6baccf536283468d08d0b168766f5379d86788bc</id>
    </parent>
    <parent>
      <id>e5bff778f772d2bdeae48c61970081f278969f37</id>
    </parent>
  </parents>
  <author>
    <name>Dan Newman</name>
    <email>dpnewman@gmail.com</email>
  </author>
  <url>http://github.com/spot-us/spot-us/commit/b5a3ea73bffee8aca654a3901ed9ed6f340d1bea</url>
  <id>b5a3ea73bffee8aca654a3901ed9ed6f340d1bea</id>
  <committed-date>2009-10-27T10:14:55-07:00</committed-date>
  <authored-date>2009-10-27T10:14:55-07:00</authored-date>
  <message>merged with master</message>
  <tree>5da0078bcd2d59da5d40b3e570c24a1106212b93</tree>
  <committer>
    <name>Dan Newman</name>
    <email>dpnewman@gmail.com</email>
  </committer>
</commit>
