Created
February 25, 2014 16:10
-
-
Save eLafo/9211985 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainGraph | |
include ActiveModel::Validations | |
attr_reader :company, :starts_at, :ends_at | |
#attr_reader :graph_window_at, :period_search, :project_periods, :onthebench, :billable_by_period, :unbillable_by_period, | |
# :free_by_period, :billable, :unbillable, :free, :graph_form | |
validate :validate_graph | |
#def initialize(weeks_number, graph_form, company) | |
# @weeks_number = weeks_number | |
# @graph_form = graph_form | |
# @company = company | |
#end | |
def initialize(company, starts_at = Date.today.at_beginning_of_week, ends_at = Date.today.at_end_of_week) | |
@company = company | |
@starts_at = starts_at | |
@ends_at = ends_at | |
end | |
def participates_by_resource | |
company.projects.inject([]) do |res, project| | |
res << [project, build_participates_info(project.participates)] | |
end | |
end | |
def build_participates_info(participates) | |
dates_from_participates(participates).inject([]) do |res, pair_of_dates| | |
res << [pair_of_dates, participates.select{|p| p.begin_date <= pair_of_dates.first && p.end_date >= pair_of_dates.last}] | |
end | |
end | |
def dates_from_participates(participates) | |
h = participates.inject({starts_at: [], ends_at: []}) do |res, participate| | |
res[:starts_at] << [participate.begin_date, starts_at].max if participate.begin_date <= ends_at | |
res[:ends_at] << [participate.end_date, ends_at].min if participate.end_date >= starts_at | |
res | |
end | |
h[:starts_at].uniq! | |
h[:ends_at].uniq! | |
(h[:starts_at] + h[:ends_at]).sort.each_cons(2) | |
#.uniq.sort.each_cons(2) | |
end | |
def show_main_line_graph | |
if @graph_form | |
@graph_window_at = Date.strptime(@graph_form[:central_date], '%Y-%m-%d') | |
if @graph_form[:action] == 'prev' | |
@graph_window_at = @graph_window_at - 1.weeks | |
else | |
@graph_window_at = @graph_window_at + 1.weeks | |
end | |
else | |
@graph_window_at = Date.today.beginning_of_week | |
end | |
graph_window_to = @graph_window_at + @weeks_number.weeks | |
@period_search = "From #{@graph_window_at.strftime('%d/%m/%Y')} to #{graph_window_to.strftime('%d/%m/%Y')}" | |
@project_periods= [] | |
periods = [] | |
rangeold = nil | |
#return resources participating in a project in a specified time | |
participates = @company.participates.joins(project: :client). | |
order('projects.billable desc, clients.name, projects.name'). | |
containing_date(@graph_window_at, graph_window_to) | |
# select distinct projects | |
projects = participates.group(:project_id) | |
projects.each do |project| | |
# selects participates of that project id and sets graph_window_at if begin_date is older, sets graph_window_to if begin_date is newer | |
participates_by_project = participates.with_project_id(project.project_id).each do |participate| | |
participate.end_date = participate.end_date + 1.days | |
participate.begin_date = @graph_window_at if participate.begin_date < @graph_window_at | |
participate.end_date = graph_window_to if participate.end_date > graph_window_to | |
end | |
#splits every date and search between this dates how many resources the company has | |
participate_days = participates_by_project.map { |x| [x.begin_date, x.end_date] }.flatten.uniq.sort | |
participate_days.each do |range| | |
if rangeold | |
participate = @company.participates.with_project_id(project.project_id). | |
where('participates.begin_date <= DATE(?) and DATE(?) <= participates.end_date', rangeold, rangeold) | |
periods.push(Period.new(participate, rangeold, range)) unless participate.blank? | |
end | |
rangeold=range | |
end | |
@project_periods.push(ProjectPeriod.new(project, periods)) | |
periods = [] | |
rangeold = nil | |
end | |
end | |
# show bar charts under the lines chart | |
def show_percentajes_bar_chart | |
@billable = [] | |
@unbillable = [] | |
@free = [] | |
@onthebench = [] | |
@weeks_number.times do |weeknumber| | |
begin_date = @graph_window_at + weeknumber.weeks | |
end_date = begin_date + 1.week | |
participates_by_project = @company.participates.containing_date(begin_date, end_date).each do |participate| | |
participate.end_date = participate.end_date + 1.days | |
participate.begin_date = begin_date if participate.begin_date < begin_date | |
participate.end_date = end_date if participate.end_date > end_date | |
end | |
participate_days = participates_by_project.map { |x| [x.begin_date, x.end_date] }.flatten.uniq.sort | |
arr = [] | |
dateold = nil | |
participate_days.each do |date_index| | |
if dateold | |
workingpeople = @company.participates. | |
where('participates.begin_date <= DATE(?) and DATE(?) <= participates.end_date', dateold, dateold) | |
working = workingpeople.inject(0) { |sum, e| sum.to_f + e.dedication_percent.to_f } / 100.0 | |
notworking = @company.resources.active(dateold, date_index).where.not(id: workingpeople.pluck(:resource_id).uniq) | |
@onthebench.push(Period.new(notworking, dateold, date_index)) | |
total_resources = @company.resources.active(dateold, date_index).count | |
billable = @company.participates. | |
where('participates.billable=1 and participates.begin_date <= DATE(?) and DATE(?) <= participates.end_date', dateold, dateold). | |
joins(:project).where(projects: {billable: 1}). | |
inject(0) { |sum, e| sum.to_f + e.dedication_percent.to_f } / 100.0 | |
arr.push(Utilization.new(dateold, date_index, total_resources, billable, working)) | |
end | |
dateold = date_index | |
end | |
@billable.push(arr.count > 0 ? arr.inject(0) { |sum, e| sum += e.billable }/arr.count : 0) | |
@unbillable.push(arr.count > 0 ? arr.inject(0) { |sum, e| sum += e.unbillable }/arr.count : 0) | |
@free.push(arr.count > 0 ? arr.inject(0) { |sum, e| sum += e.free }/arr.count : 0) | |
end | |
end | |
def show_semicircle_chart | |
# for the semicircle chart | |
total_sum_billable = @billable.inject(0) { |sum, e| sum += e } | |
total_sum_unbillable = @unbillable.inject(0) { |sum, e| sum += e } | |
total_sum_free = @free.inject(0) { |sum, e| sum += e } | |
@billable_by_period = 0.0 | |
@unbillable_by_period = 0.0 | |
@free_by_period = 0.0 | |
@billable_by_period = total_sum_billable/@billable.count if total_sum_billable > 0.0 | |
@unbillable_by_period = total_sum_unbillable/@unbillable.count if total_sum_unbillable>0.0 | |
@free_by_period = total_sum_free/@free.count if total_sum_free>0.0 | |
end | |
def validate_graph | |
if @company.resources.blank? | |
errors.add(:resources, 'You need at least one resource, you can create one') | |
end | |
if @company.clients.blank? | |
errors.add(:clients, 'You need at least one client, you can create one') | |
end | |
if @company.projects.blank? && @company.clients.present? | |
errors.add(:projects, 'You need at least one project, you can create one') | |
end | |
if @company.projects.present? && @company.resources.present? && @company.participates.blank? | |
errors.add(:participates, 'You need at least one participate, you can create one') | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment