<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -8,6 +8,7 @@ Wed, Nov 4, 2009
 ---------------------------------------------------------------------
 - Correctly set opportunity campaign and source when converting a lead (LH #119).
 - Show correct campaign name and source when adding a lead from campaign landing page.
+- Update lead counters when reassigning leads between campaigns (LH #117).
 
 Sat, Oct 31, 2009
 ---------------------------------------------------------------------</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -117,6 +117,7 @@ class LeadsController &lt; ApplicationController
   #----------------------------------------------------------------------------
   def update
     @lead = Lead.my(@current_user).find(params[:id])
+    @campaign = @lead.campaign.dup if @lead.campaign &amp;&amp; !called_from_index_page?
 
     respond_to do |format|
       if @lead.update_with_permissions(params[:lead], params[:users])</diff>
      <filename>app/controllers/leads_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -100,6 +100,19 @@ class Lead &lt; ActiveRecord::Base
     end
   end
 
+  # Update lead attributes taking care of campaign lead counters when necessary.
+  #----------------------------------------------------------------------------
+  def update_with_permissions(attributes, users)
+    if self.campaign_id == attributes[:campaign_id] # Same campaign (if any).
+      super(attributes, users)                      # See lib/fat_free_crm/permissions.rb
+    else                                            # Campaign has been changed -- update lead counters...
+      decrement_leads_count                         # ..for the old campaign...
+      lead = super(attributes, users)               # Assign new campaign.
+      increment_leads_count                         # ...and now for the new campaign.
+      lead
+    end
+  end
+
   # Promote the lead by creating contact and optional opportunity. Upon
   # successful promotion Lead status gets set to :converted.
   #----------------------------------------------------------------------------</diff>
      <filename>app/models/lead.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,11 +2,6 @@
 - collapsed = session[:lead_status].nil? # &amp;&amp; @lead.errors.empty?
 = subtitle :lead_status, collapsed
 
-- logger.i @lead.campaign
-- logger.i @lead.source
-- logger.i @campaign
-- logger.i called_from_landing_page?(&quot;campaigns&quot;)
-
 .section
   %small#lead_status_intro{ hidden_if(!collapsed) }
     = &quot;You can add lead status information later.&quot; unless edit</diff>
      <filename>app/views/leads/_status.html.haml</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,9 @@ if @lead.errors.empty?
     page[id].visual_effect :highlight, :duration =&gt; 1.0
     if called_from_index_page?
       page &lt;&lt; refresh_sidebar(:index, :filters)
+    elsif @campaign # Lead updated on Campaign landing page: refresh Campaign summary.
+      @campaign.reload
+      page &lt;&lt; refresh_sidebar_for(:campaigns, :show, :summary)
     else
       page[:recently].replace :partial =&gt; &quot;common/recently&quot;
     end</diff>
      <filename>app/views/leads/update.js.rjs</filename>
    </modified>
    <modified>
      <diff>@@ -358,9 +358,9 @@ describe LeadsController do
     describe &quot;with valid params&quot; do
 
       it &quot;should update the requested lead, expose it as @lead, and render [update] template&quot; do
-        @lead = Factory(:lead, :id =&gt; 42, :first_name =&gt; &quot;Billy&quot;, :user =&gt; @current_user)
+        @lead = Factory(:lead, :first_name =&gt; &quot;Billy&quot;, :user =&gt; @current_user)
 
-        xhr :put, :update, :id =&gt; 42, :lead =&gt; { :first_name =&gt; &quot;Bones&quot; }
+        xhr :put, :update, :id =&gt; @lead.id, :lead =&gt; { :first_name =&gt; &quot;Bones&quot; }
         @lead.reload.first_name.should == &quot;Bones&quot;
         assigns[:lead].should == @lead
         assigns[:lead_status_total].should == nil
@@ -368,26 +368,56 @@ describe LeadsController do
       end
 
       it &quot;should update lead status&quot; do
-        @lead = Factory(:lead, :id =&gt; 42, :status =&gt; &quot;new&quot;, :user =&gt; @current_user)
+        @lead = Factory(:lead, :status =&gt; &quot;new&quot;, :user =&gt; @current_user)
 
-        xhr :put, :update, :id =&gt; 42, :lead =&gt; { :status =&gt; &quot;rejected&quot; }
+        xhr :put, :update, :id =&gt; @lead.id, :lead =&gt; { :status =&gt; &quot;rejected&quot; }
         @lead.reload.status.should == &quot;rejected&quot;
       end
 
       it &quot;should update lead source&quot; do
-        @lead = Factory(:lead, :id =&gt; 42, :source =&gt; &quot;campaign&quot;, :user =&gt; @current_user)
+        @lead = Factory(:lead, :source =&gt; &quot;campaign&quot;, :user =&gt; @current_user)
 
-        xhr :put, :update, :id =&gt; 42, :lead =&gt; { :source =&gt; &quot;cald_call&quot; }
+        xhr :put, :update, :id =&gt; @lead.id, :lead =&gt; { :source =&gt; &quot;cald_call&quot; }
         @lead.reload.source.should == &quot;cald_call&quot;
       end
 
       it &quot;should update lead campaign&quot; do
-        old_campaign = Factory(:campaign)
-        new_campaign = Factory(:campaign)
-        @lead = Factory(:lead, :id =&gt; 42, :campaign =&gt; old_campaign, :user =&gt; @current_user)
+        @campaigns = { :old =&gt; Factory(:campaign), :new =&gt; Factory(:campaign) }
+        @lead = Factory(:lead, :campaign =&gt; @campaigns[:old])
 
-        xhr :put, :update, :id =&gt; 42, :lead =&gt; { :campaign_id =&gt; new_campaign.id }
-        @lead.reload.campaign.should == new_campaign
+        xhr :put, :update, :id =&gt; @lead.id, :lead =&gt; { :campaign_id =&gt; @campaigns[:new].id }
+        @lead.reload.campaign.should == @campaigns[:new]
+      end
+
+      it &quot;should decrement campaign leads count if campaign has been removed&quot; do
+        @campaign = Factory(:campaign)
+        @lead = Factory(:lead, :campaign =&gt; @campaign)
+        @count = @campaign.reload.leads_count
+
+        xhr :put, :update, :id =&gt; @lead, :lead =&gt; { :campaign_id =&gt; nil }
+        @lead.reload.campaign.should == nil
+        @campaign.reload.leads_count.should == @count - 1
+      end
+
+      it &quot;should increment campaign leads count if campaign has been assigned&quot; do
+        @campaign = Factory(:campaign)
+        @lead = Factory(:lead, :campaign =&gt; nil)
+        @count = @campaign.leads_count
+
+        xhr :put, :update, :id =&gt; @lead, :lead =&gt; { :campaign_id =&gt; @campaign.id }
+        @lead.reload.campaign.should == @campaign
+        @campaign.reload.leads_count.should == @count + 1
+      end
+
+      it &quot;should update both campaign leads counts if reassigned to a new campaign&quot; do
+        @campaigns = { :old =&gt; Factory(:campaign), :new =&gt; Factory(:campaign) }
+        @lead = Factory(:lead, :campaign =&gt; @campaigns[:old])
+        @counts = { :old =&gt; @campaigns[:old].reload.leads_count, :new =&gt; @campaigns[:new].leads_count }
+
+        xhr :put, :update, :id =&gt; @lead, :lead =&gt; { :campaign_id =&gt; @campaigns[:new].id }
+        @lead.reload.campaign.should == @campaigns[:new]
+        @campaigns[:old].reload.leads_count.should == @counts[:old] - 1
+        @campaigns[:new].reload.leads_count.should == @counts[:new] + 1
       end
 
       it &quot;should update shared permissions for the campaign&quot; do
@@ -400,14 +430,23 @@ describe LeadsController do
       end
 
       it &quot;should get the data for leads sidebar when called from leads index&quot; do
-        @lead = Factory(:lead, :id =&gt; 42, :user =&gt; @current_user)
+        @lead = Factory(:lead)
 
         request.env[&quot;HTTP_REFERER&quot;] = &quot;http://localhost/leads&quot;
-        xhr :put, :update, :id =&gt; 42, :lead =&gt; { :first_name =&gt; &quot;Billy&quot; }
+        xhr :put, :update, :id =&gt; @lead.id, :lead =&gt; { :first_name =&gt; &quot;Billy&quot; }
         assigns[:lead_status_total].should_not be_nil
         assigns[:lead_status_total].should be_an_instance_of(Hash)
       end
 
+      it &quot;should reload lead campaign if called from campaign landing page&quot; do
+        @campaign = Factory(:campaign)
+        @lead = Factory(:lead, :campaign =&gt; @campaign)
+      
+        request.env[&quot;HTTP_REFERER&quot;] = &quot;http://localhost/campaigns/#{@campaign.id}&quot;
+        xhr :put, :update, :id =&gt; @lead, :lead =&gt; { :first_name =&gt; &quot;Hello&quot; }
+        assigns[:campaign].should == @campaign
+      end
+
       describe &quot;lead got deleted or otherwise unavailable&quot; do
         it &quot;should reload current page with the flash message if the lead got deleted&quot; do
           @lead = Factory(:lead, :user =&gt; @current_user).destroy</diff>
      <filename>spec/controllers/leads_controller_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -68,6 +68,17 @@ describe &quot;/leads/update.js.rjs&quot; do
         response.should include_text(%Q/$(&quot;lead_#{@lead.id}&quot;).visualEffect(&quot;highlight&quot;/)
       end
 
+      it &quot;should update related asset sidebar from related asset&quot; do
+        assigns[:campaign] = campaign = Factory(:campaign)
+        request.env[&quot;HTTP_REFERER&quot;] = &quot;http://localhost/campaigns/#{campaign.id}&quot;
+        render &quot;leads/create.js.rjs&quot;
+
+        response.should have_rjs(&quot;sidebar&quot;) do |rjs|
+          with_tag(&quot;div[class=panel][id=summary]&quot;)
+          with_tag(&quot;div[class=panel][id=recently]&quot;)
+        end
+      end
+
       it &quot;should update recently viewed items&quot; do
         render &quot;leads/update.js.rjs&quot;
         response.should have_rjs(&quot;recently&quot;) do |rjs|</diff>
      <filename>spec/views/leads/update.rjs_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>57befbcb467261b84b9fbe5780516a14726ecd07</id>
    </parent>
  </parents>
  <author>
    <name>Mike Dvorkin</name>
    <email>mike@dvorkin.net</email>
  </author>
  <url>http://github.com/michaeldv/fat_free_crm/commit/90ba3e77774ed912be109384daf0cb1039fe9ceb</url>
  <id>90ba3e77774ed912be109384daf0cb1039fe9ceb</id>
  <committed-date>2009-11-04T20:04:20-08:00</committed-date>
  <authored-date>2009-11-04T20:04:20-08:00</authored-date>
  <message>Update lead counters when reassigning leads between campaigns
[#117 state:resolved]</message>
  <tree>ad9600ff29367a5ee965f95a298d66cf393ef41e</tree>
  <committer>
    <name>Mike Dvorkin</name>
    <email>mike@dvorkin.net</email>
  </committer>
</commit>
