FEATURE: Show/hide campaign banner with goal status (#85)

FEATURE: Show/hide campaign banner with goal status (#85)

diff --git a/app/services/discourse_subscriptions/campaign.rb b/app/services/discourse_subscriptions/campaign.rb
index 955b15a..d85dd6a 100644
--- a/app/services/discourse_subscriptions/campaign.rb
+++ b/app/services/discourse_subscriptions/campaign.rb
@@ -17,7 +17,7 @@ module DiscourseSubscriptions
         product_ids = product_ids.include?(campaign_product) ? [campaign_product] : []
       end
 
-      amount = 0
+      amount = 0.00
       subscriptions = get_subscription_data
       subscriptions = filter_to_subscriptions_products(subscriptions, product_ids)
 
@@ -27,10 +27,12 @@ module DiscourseSubscriptions
       # calculate amount raised
       subscriptions&.each do |sub|
         sub_amount = calculate_monthly_amount(sub)
-        amount += sub_amount
+        amount += sub_amount / 100.00
       end
 
-      SiteSetting.discourse_subscriptions_campaign_amount_raised = amount
+      SiteSetting.discourse_subscriptions_campaign_amount_raised = amount.round(2)
+
+      check_goal_status
     end
 
     def create_campaign
@@ -48,6 +50,31 @@ module DiscourseSubscriptions
 
     protected
 
+    def goal_met_date_key
+      'subscriptions_goal_met_date'
+    end
+
+    def check_goal_status
+      goal = SiteSetting.discourse_subscriptions_campaign_goal
+      goal_type = SiteSetting.discourse_subscriptions_campaign_type
+
+      case goal_type
+      when "Amount"
+        current_volume = SiteSetting.discourse_subscriptions_campaign_amount_raised
+      when "Subscribers"
+        current_volume = SiteSetting.discourse_subscriptions_campaign_subscribers
+      end
+
+      goal_met_date = Discourse.redis.get(goal_met_date_key)
+
+      if goal_met_date
+        # delete the key if we're at or below 90% of the goal
+        Discourse.redis.del(goal_met_date_key) if current_volume / goal <= 0.90
+      else
+        Discourse.redis.set(goal_met_date_key, Time.now) if current_volume > goal
+      end
+    end
+
     def create_campaign_group
       campaign_group = SiteSetting.discourse_subscriptions_campaign_group
       group = ::Group.find_by_id(campaign_group) if campaign_group.present?
@@ -161,10 +188,10 @@ module DiscourseSubscriptions
       when "week"
         unit_amount = unit_amount * 4
       when "year"
-        unit_amount = unit_amount / 12
+        unit_amount = unit_amount / 12.00
       end
 
-      unit_amount
+      unit_amount.to_f
     end
   end
 end
diff --git a/assets/javascripts/discourse/components/campaign-banner.js.es6 b/assets/javascripts/discourse/components/campaign-banner.js.es6
index 7436027..a5dcbd6 100644
--- a/assets/javascripts/discourse/components/campaign-banner.js.es6
+++ b/assets/javascripts/discourse/components/campaign-banner.js.es6
@@ -27,6 +27,7 @@ export default Component.extend({
     "Subscribers"
   ),
   currency: setting("discourse_subscriptions_currency"),
+  amountRaised: setting("discourse_subscriptions_campaign_amount_raised"),
   goalTarget: setting("discourse_subscriptions_campaign_goal"),
   product: setting("discourse_subscriptions_campaign_product"),
   showContributors: setting(
@@ -120,6 +121,10 @@ export default Component.extend({
       !currentRoute.split(".")[0].includes("admin") &&
       currentRoute.split(".")[0] !== "s";
 
+    if (!this.site.show_campaign_banner) {
+      return false;
+    }
+
     // make sure not to render above main container when inside a topic
     if (
       this.connectorName === "above-main-container" &&
@@ -155,13 +160,6 @@ export default Component.extend({
   },
 
   @discourseComputed
-  amountRaised() {
-    return (
-      this.siteSettings.discourse_subscriptions_campaign_amount_raised / 100
-    );
-  },
-
-  @discourseComputed
   isGoalMet() {
     const currentVolume = this.subscriberGoal
       ? this.subscribers
diff --git a/config/settings.yml b/config/settings.yml
index 5e6fda3..8a08b09 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -64,7 +64,7 @@ plugins:
     default: ""
   discourse_subscriptions_campaign_amount_raised:
     client: true
-    default: 0
+    default: 0.00
     hidden: true
   discourse_subscriptions_campaign_subscribers:
     client: true
diff --git a/plugin.rb b/plugin.rb
index b9c2e76..a2d74cf 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -57,4 +57,16 @@ after_initialize do
   Discourse::Application.routes.append do
     mount ::DiscourseSubscriptions::Engine, at: 's'
   end
+
+  add_to_serializer(:site, :show_campaign_banner) do
+    begin
+      enabled = SiteSetting.discourse_subscriptions_enabled
+      campaign_enabled = SiteSetting.discourse_subscriptions_campaign_enabled
+      goal_met = Discourse.redis.get("subscriptions_goal_met_date")
+
+      enabled && campaign_enabled && (!goal_met || 7.days.ago <= Date.parse(goal_met))
+    rescue
+      false
+    end
+  end
 end
diff --git a/spec/serializers/site_serializer_spec.rb b/spec/serializers/site_serializer_spec.rb
new file mode 100644
index 0000000..96b53d2
--- /dev/null
+++ b/spec/serializers/site_serializer_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe SiteSerializer do
+  fab!(:user)  { Fabricate(:user) }
+  let(:guardian) { Guardian.new(user) }
+
+  before do
+    Discourse.redis.del("subscriptions_goal_met_date")
+    SiteSetting.discourse_subscriptions_enabled = true
+    SiteSetting.discourse_subscriptions_campaign_enabled = true
+  end
+  it 'is false if the goal_met date is < 7 days old' do
+    Discourse.redis.set('subscriptions_goal_met_date', 10.days.ago)
+    data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
+
+    expect(data[:show_campaign_banner]).to be false
+  end
+
+  it 'is true if the goal_met date is > 7 days old' do
+    Discourse.redis.set('subscriptions_goal_met_date', 1.days.ago)
+    data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
+
+    expect(data[:show_campaign_banner]).to be true
+  end
+
+  it 'fails gracefully if the goal_met date is invalid' do
+    Discourse.redis.set('subscriptions_goal_met_date', 'bananas')
+    data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
+    expect(data[:show_campaign_banner]).to be false
+  end
+end
diff --git a/spec/services/campaign_spec.rb b/spec/services/campaign_spec.rb
index d966057..9b1968a 100644
--- a/spec/services/campaign_spec.rb
+++ b/spec/services/campaign_spec.rb
@@ -39,7 +39,24 @@ describe DiscourseSubscriptions::Campaign do
           DiscourseSubscriptions::Campaign.new.refresh_data
 
           expect(SiteSetting.discourse_subscriptions_campaign_subscribers).to eq 1
-          expect(SiteSetting.discourse_subscriptions_campaign_amount_raised).to eq 1000
+          expect(SiteSetting.discourse_subscriptions_campaign_amount_raised).to eq 10.00
+        end
+
+        it "checks if the goal is completed or not" do
+          SiteSetting.discourse_subscriptions_campaign_goal = 5
+          ::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
+
+          DiscourseSubscriptions::Campaign.new.refresh_data
+          expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_present
+        end
+
+        it "checks if goal is < 90% met after being met" do
+          SiteSetting.discourse_subscriptions_campaign_goal = 15
+          Discourse.redis.set('subscriptions_goal_met_date', 10.days.ago)
+          ::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
+
+          DiscourseSubscriptions::Campaign.new.refresh_data
+          expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_blank
         end
       end
 
@@ -76,7 +93,7 @@ describe DiscourseSubscriptions::Campaign do
           DiscourseSubscriptions::Campaign.new.refresh_data
 
           expect(SiteSetting.discourse_subscriptions_campaign_subscribers).to eq 1
-          expect(SiteSetting.discourse_subscriptions_campaign_amount_raised).to eq 833

[... diff too long, it was truncated ...]

GitHub sha: 6414a1f6e5ea7b1f7e6a4fa883bf7e1609f400b8

This commit appears in #85 which was approved by pmusaraj. It was merged by justindirose.