diff --git a/Rakefile b/Rakefile index cc27eab..01efb3d 100644 --- a/Rakefile +++ b/Rakefile @@ -12,4 +12,4 @@ Rake::TestTask.new do |t| end desc "Run tests" -task default: :test \ No newline at end of file +task default: :test diff --git a/lib/statisfy.rb b/lib/statisfy.rb index 5670e35..a76231a 100644 --- a/lib/statisfy.rb +++ b/lib/statisfy.rb @@ -2,6 +2,8 @@ require_relative "statisfy/configuration" require_relative "statisfy/counter" +require_relative "statisfy/aggregate" +require_relative "statisfy/monthly" module Statisfy class Error < StandardError; end diff --git a/lib/statisfy/aggregate.rb b/lib/statisfy/aggregate.rb new file mode 100644 index 0000000..d9dcf10 --- /dev/null +++ b/lib/statisfy/aggregate.rb @@ -0,0 +1,35 @@ +require_relative "counter" + +module Statisfy + module Aggregate + def self.included(klass) + klass.extend(ClassMethods) + klass.class_eval do + include Counter + end + end + + module ClassMethods + # + # Simply a shortcut for declaring an aggregation type counter + # + def aggregate(args = {}) + raise ArgumentError, "You must provide the value to aggregate" if args[:value].blank? + + count(args.merge(type: :aggregate)) + end + + # + # Average type counters ret + # + # @param scope: the scope of the counter (an Organisation or a Department) + # @param month: the month for which you want the value of the counter (optional) + # + def value(scope: nil, month: nil) + p "HEIN???" + month = month&.strftime("%Y-%m") if month.present? + average(scope:, month:) + end + end + end +end diff --git a/lib/statisfy/counter.rb b/lib/statisfy/counter.rb index 22f3e3d..ff9f6e1 100644 --- a/lib/statisfy/counter.rb +++ b/lib/statisfy/counter.rb @@ -1,11 +1,12 @@ require_relative "subscriber" +require_relative "monthly" module Statisfy module Counter def self.included(klass) klass.extend(ClassMethods) klass.class_eval do - include Subscriber + include Subscriber, Monthly attr_accessor :params, :subject end end @@ -32,10 +33,6 @@ def count(args = {}) class_eval(&Statisfy.configuration.append_to_counters) if Statisfy.configuration.append_to_counters.present? end - def aggregate(args = {}) - count(args.merge(type: :average)) - end - # # This method serves as a syntactic sugar # The below methods could be written directly in the class definition @@ -62,7 +59,7 @@ def apply_default_counter_options(args) # def value(scope: nil, month: nil) month = month&.strftime("%Y-%m") if month.present? - if const_get(:COUNTER_TYPE) == :average + if const_get(:COUNTER_TYPE) == :aggregate average(scope:, month:) else size(scope:, month:) @@ -118,38 +115,6 @@ def redis_client Statisfy.configuration.redis_client end - # - # Returns a hash of values grouped by month: - # { - # "01/2024" => 33.3, - # "02/2024" => 36.6, - # "03/2024" => 38.2, - # } - # - # @param scope: the scope of the counter (an Organisation or a Department) - # @param start_at: the date from which you want to start counting (optional) - # @param stop_at: the date at which you want to stop counting (optional) - # - def values_grouped_by_month(scope: nil, start_at: nil, stop_at: nil) - n_months = 24 - - if start_at.present? || scope&.created_at.present? - start_at ||= scope.created_at - n_months = (Time.zone.today.year + Time.zone.today.month) - (start_at.year + start_at.month) - end - - relevant_months = (0..n_months).map do |i| - (n_months - i).months.ago.beginning_of_month - end - - relevant_months - .filter { |month| stop_at.blank? || month < stop_at } - .to_h do |month| - [month.strftime("%m/%Y"), value(scope:, month:).round(2)] - end - end - # rubocop:enable Metrics/AbcSize - # # This allows to run a counter increment manually # It is useful when you want to backfill counters @@ -167,7 +132,6 @@ def initialize_with(resource, options = {}) # Returns the list of all the keys of this counter for a given scope (optional) # and a given month (optional) # - # rubocop:disable Metrics/AbcSize def all_keys(scope: nil, month: nil) redis_client.keys("*\"counter\":\"#{name.demodulize.underscore}\"*").filter do |json| key = JSON.parse(json) diff --git a/lib/statisfy/monthly.rb b/lib/statisfy/monthly.rb new file mode 100644 index 0000000..78e1460 --- /dev/null +++ b/lib/statisfy/monthly.rb @@ -0,0 +1,41 @@ +module Statisfy + module Monthly + def self.included(klass) + klass.extend(ClassMethods) + end + + module ClassMethods + # + # Returns a hash of values grouped by month: + # { + # "01/2024" => 33.3, + # "02/2024" => 36.6, + # "03/2024" => 38.2, + # } + # + # @param scope: the scope of the counter (an Organisation or a Department) + # @param start_at: the date from which you want to start counting (optional) + # @param stop_at: the date at which you want to stop counting (optional) + # + def values_grouped_by_month(scope: nil, start_at: nil, stop_at: nil) + n_months = 24 + + if start_at.present? || scope&.created_at.present? + start_at ||= scope.created_at + n_months = (Time.zone.today.year + Time.zone.today.month) - (start_at.year + start_at.month) + end + + relevant_months = (0..n_months).map do |i| + (n_months - i).months.ago.beginning_of_month + end + + relevant_months + .filter { |month| stop_at.blank? || month < stop_at } + .to_h do |month| + [month.strftime("%m/%Y"), value(scope:, month:).round(2)] + end + end + # rubocop:enable Metrics/AbcSize + end + end +end diff --git a/statisfy.gemspec b/statisfy.gemspec index 5f09695..a79db01 100644 --- a/statisfy.gemspec +++ b/statisfy.gemspec @@ -14,9 +14,9 @@ Gem::Specification.new do |s| s.license = "MIT" s.add_development_dependency "activerecord", "~> 7.0.4.3" s.add_development_dependency "activesupport", "~> 7.0.4.3" + s.add_development_dependency "pry", "~> 0.14.1" s.add_development_dependency "redis", "~> 4.8.1" s.add_development_dependency "redis-client", "~> 0.17.0" s.add_development_dependency "rubocop", "~> 1.49.0" s.add_development_dependency "sqlite3", "~> 1.6.9" - s.add_development_dependency "pry", "~> 0.14.1" end diff --git a/test/statisfy_test.rb b/test/statisfy_test.rb index 393221f..f48333f 100644 --- a/test/statisfy_test.rb +++ b/test/statisfy_test.rb @@ -204,7 +204,7 @@ class UserCounter test "aggregate option allows to aggregate instead of increment and get an average" do class SalaryPerUser - include Statisfy::Counter + include Statisfy::Aggregate aggregate every: :user_created, value: -> { user.salary } end