- # encoding: utf-8
- class MemberReport
- include ActionView::Helpers::NumberHelper
- attr_reader :region_id, :start_date, :end_date,
- :total, :total_members, :total_trials
- KEYS = [
- :start,
- :entering, :entering_switching,
- :resigning, :resigning_switching,
- :trend_absolute, :trend_relative,
- :end,
- ]
- # - <internal group name>: <array of ContactRole#id>
- CONTACT_ROLES = {
- personal_members: [5],
- company_members: [1],
- company_representatives: [2],
- personal_trial_members: [5],
- company_trial_members: [1],
- company_trial_representatives: [2],
- }
- # - <internal group name>: <array of MembershopStateGroup#id>
- MEMBERSHIP_STATE_GROUPS = {
- personal_trial_members: [3],
- company_trial_members: [4],
- company_trial_representatives: [4],
- }
- CONTACT_ROLES.keys.each do |group|
- # For all groups, calculation is the same
- define_method \"calc_#{group}\" do
- calc_trend(stats(group))
- end
- # For all groups, the results are accessed through an attr_reader
- define_method \"#{group}\" do
- self.instance_variable_get(\"@#{group}\")
- end
- end
- def initialize(region_id, start_date=Date.today, end_date=Date.today, calc_on_init=true)
- @region_id = region_id
- @start_date = start_date
- @end_date = end_date
- calculcate if calc_on_init
- end
- def calculcate
- CONTACT_ROLES.keys.each do |group|
- instance_eval(\"@#{group} = calc_#{group}\")
- end
- member_groups = [
- personal_members, company_members, company_representatives
- ]
- trial_groups = [
- personal_trial_members, company_trial_members, company_trial_representatives
- ]
- @total = calc_total(member_groups + trial_groups)
- @total_members = calc_total(member_groups)
- @total_trials = calc_total(trial_groups)
- self
- end
- # Calculations
- def calc_total(groups=[])
- result = {}
- groups.each do |group|
- KEYS.each do |key|
- result[key] ||= 0
- result[key] += group[key].to_i
- end
- end
- calc_trend(result)
- result
- end
- def member_count(group, date_from, date_to=nil, type=nil, switching=false)
- return 0 unless group && CONTACT_ROLES[group]
- date_to ||= date_from
- contact_ids = ContactAffiliation.main
- .where(region_id: @region_id)
- .where(company_id: nil)
- .between(date_from, date_to)
- contact_ids = contact_ids.entering_within(date_from, date_to) if type == :entering
- contact_ids = contact_ids.resigning_within(date_from, date_to) if type == :resigning
- contact_ids = contact_ids.collect(&:contact_id).uniq
- if switching
- relevant_date_relation = \'resign_date <=\' if type == :entering
- relevant_date_relation ||= \'entry_date >=\'
- contact_ids = ContactAffiliation.main
- .where(\'region_id != ?\', @region_id)
- .where(contact_id: contact_ids)
- .where(
- \"#{relevant_date_relation} ?\",
- date_from
- )
- .collect(&:contact_id).uniq
- end
- contacts_with_roles =
- ContactRoleAffiliation.all
- .where(contact_id: contact_ids)
- .where(contact_role_id: CONTACT_ROLES[group])
- .between(date_from, date_to)
- if group.to_s.include?(\'trial\')
- trial_member_count(contacts_with_roles, date_from, date_to)
- else
- contacts_with_roles.count
- end
- end
- def trial_member_count(contacts_with_roles, date_from, date_to=nil)
- date_to ||= date_from
- Membership.all
- .between(date_from, date_to)
- .for_contacts(contacts_with_roles.pluck(:id))
- .count
- end
- private
- # Helpers
- def trend_relative(start_value=0, end_value=0)
- start_value = start_value.to_f
- end_value = end_value.to_f
- if start_value == end_value
- \"±0\"
- else
- (
- end_value > start_value ? \'+\' : \'\'
- ) + number_to_percentage( ((end_value / start_value)-1)*100 )
- end
- end
- def trend_absolute(start_value=0, end_value=0)
- if start_value == end_value
- \"±0\"
- else
- (
- end_value > start_value ? \'+\' : \'\'
- ) + (end_value - start_value).to_s
- end
- end
- def calc_trend(hash={})
- hash[:trend_relative] = trend_relative(hash[:start], hash[:end])
- hash[:trend_absolute] = trend_absolute(hash[:start], hash[:end])
- hash
- end
- def stats(group)
- return {} unless group
- {
- start:
- member_count(group, @start_date),
- entering:
- member_count(group, @start_date, @end_date, :entering),
- entering_switching:
- member_count(group, @start_date, @end_date, :entering, true),
- resigning:
- member_count(group, @start_date, @end_date, :resigning),
- resigning_switching:
- member_count(group, @start_date, @end_date, :resigning, true),
- end:
- member_count(group, @end_date),
- }
- end
- end
Undefined
By: Guest | Date: Feb 25 2015 12:28 | Format: None | Expires: never | Size: 5.13 KB | Hits: 918
Latest pastes
1 hours ago
11 hours ago
1 days ago
2 days ago
2 days ago