Skip to content

Instantly share code, notes, and snippets.

@trico
Created March 16, 2018 10:10
Show Gist options
  • Save trico/ed94879893485e365922bbbb972979d2 to your computer and use it in GitHub Desktop.
Save trico/ed94879893485e365922bbbb972979d2 to your computer and use it in GitHub Desktop.
module CampaignBlock::ReportManager
class ReportIncrementalBudget
attr_accessor :year, :month, :report
def self.default_year
Date.current.year
end
def self.default_month
Date.current.month
end
def self.find_or_create(year = default_year, month = default_month)
report = Report.find_by(slug: slug, analytic_year: year, analytic_month: month)
report = Report.create!(slug: slug, name: "budget #{year} #{month}", analytic_year: year, analytic_month: month) if report.nil?
report
end
def self.slug
'campaign_block_incremental_budget'
end
def self.generate(year = default_year, month = default_month)
new(year, month).generate
end
def initialize(year, month)
@year = year
@month = month
end
def generate
return unless generable?
self.report = find_or_create(year, month)
remove_details_not_protected
generate_details_not_protected
report.reload
report.generate
rescue StandardError => e
report.update!(status: 'error') if report
raise e
end
private
def remove_details_not_protected
report.report_details.
where.not(id: protected_report_detail_ids).
destroy_all
end
def generate_details_not_protected
CampaignBlock.generable_for_budget_and_dates(from: date, to: date).each do |block|
klass = "CampaignBlock::ReportManager::ReportIncrementalBudget#{block.slug.capitalize}".constantize
klass.new(block, report).generate_details!
end
end
def generable?
date = Date.new(year, month, 1)
date >= Date.current.beginning_of_month
end
def protected_campaign_block_ids
date = Date.new(year, month, 1)
CampaignBlock.generable_for_budget_and_dates(from: date, to: date).join(&:ids)
campaign_block_ids = []
campaign_block_ids << CampaignBlock.not_customs_not_scheduled_or_delivered_between(from: date, to: date).map(&:id)
campaign_block_ids << CampaignBlock.customs_delivered_between(from: date, to: date.end_of_month).map(&:id)
campaign_block_ids.flatten!
end
def protected_report_details
from = Date.new(year, month, 1)
to = Date.current.beginning_of_month
if from > to
campaign_blocks = CampaignBlock.generable_for_budget_and_dates(from: from, to: to)
report.report_details.by_camapign_blocks(campaign_blocks)
report_details = report.report_details. select do |report_detail|
block_data = report_detail.configuration['campaign_block_data']
block_data && sent_campaign_block_ids.include?(block_data['campaign_block_id'])
end
report_detail_ids = report_details.map(&:id)
end
report_detail_ids
end
end
end
# ....
class CampaignBlock
def can_generate_budget_detail?
!steps.empty? && fulfilled? && type != 'CampaignBlock::CouponReminder'
end
# se puede mejorar, pasando a sql la consulta
def self.budget_generable_for_dates(from:, to:)
not_customs_not_scheduled_or_delivered_between(from: from, to: to) + customs_delivered_between(from: from, to: to)
end
# se puede mejorar, pasando a sql la consulta
def self.not_customs_not_scheduled_or_delivered_between(from:, to:)
where.not(type: 'CampaignBlock::Custom').
select { |block| !block.scheduled_between?(from, to) || !block.history_by_dates(from, to).nil? }.
end
# se puede mejorar, pasando a sql la consulta
def self.customs_delivered_between(from:, to:)
where(type: 'CampaignBlock::Custom').
select { |block| block.sent_between?(from, to) }
end
end
# ....
class ReportIncrementalBudgetX
def generate_details!
if block.can_generate_budget_detail?
# ...
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment