diff options
| author | Zog | 2018-01-19 08:22:24 +0100 | 
|---|---|---|
| committer | Zog | 2018-02-02 14:31:32 +0100 | 
| commit | c13c94fe665fdbe2c434c8bfadd44a0988ecea60 (patch) | |
| tree | cbf70b0af9dd0bbbe4129384adcf5db39117fe33 /app/services | |
| parent | 9f30b2debe7ece403d9e588df9763c119436d967 (diff) | |
| download | chouette-core-c13c94fe665fdbe2c434c8bfadd44a0988ecea60.tar.bz2 | |
Refs #3542 @4h; First UI
Still missing:
- Pagination
- Filters
Diffstat (limited to 'app/services')
| -rw-r--r-- | app/services/referential_overview.rb | 218 | 
1 files changed, 218 insertions, 0 deletions
| diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb new file mode 100644 index 000000000..5b0e144db --- /dev/null +++ b/app/services/referential_overview.rb @@ -0,0 +1,218 @@ +class ReferentialOverview +  attr_reader :h + +  def initialize referential, h +    @referential = referential +    @page = 1 +    @h = h +  end + +  def lines +    @referential.metadatas_lines.includes(:company).page(@page).map{|l| Line.new(l, @referential, period.first, h)} +  end + +  def period +    @period ||= @referential.metadatas_period || [] +  end + +  def weeks +    @weeks = {} +    period.map do |d| +      @weeks[Week.key(d)] ||= Week.new(d, period.last, h) +    end +    @weeks.values +  end + +  class Line +    attr_reader :h +    attr_reader :referential_line + +    delegate :name, :number, :company, :color, :transport_mode, to: :referential_line + +    def initialize line, referential, start, h +      @referential_line = line +      @referential = referential +      @start = start +      @h = h +    end + +    def period +      @period ||= @referential.metadatas_period || [] +    end + +    def referential_periods +      @referential_periods ||= @referential.metadatas.include_lines([@referential_line.id]).map(&:periodes).flatten.sort{|p1, p2| p1.first <=> p2.first} +    end + +    def periods +      @periods ||= begin +        periods = referential_periods.flatten.map{|p| Period.new p, @start, h} +        periods = fill_periods periods +        periods = merge_periods periods +        periods +      end +    end + +    def fill_periods periods +      [].tap do |out| +        previous = OpenStruct.new(end: period.first - 1.day) +        (periods + [OpenStruct.new(start: period.last + 1.day)]).each do |p| +          if p.start > previous.end + 1.day +            out << Period.new((previous.end+1.day..p.start-1.day), @start, h).tap{|p| p.empty = true} +          end +          out << p if p.respond_to?(:end) +          previous = p +        end +      end +    end + +    def merge_periods periods +      [].tap do |out| +        current = periods.first +        periods[1..-1].each do |p| +          if p.start <= current.end +            current.end = p.end +          else +            out << current +            current = p +          end +        end +        out << current +      end +    end + +    def width +      period.count * Day::WIDTH +    end + +    def html_style +      { +        width: "#{width}px" +      }.map{|k, v| "#{k}: #{v}"}.join("; ") +    end + +    def html_class +      out = [] +      out +    end + +    class Period +      attr_accessor :empty +      attr_accessor :h + +      def initialize period, start, h +        @period = period +        @start = start +        @empty = false +        @h = h +      end + +      def start +        @period.first +      end + +      def end +        @period.last +      end + +      def end= val +        @period = (start..val) +      end + +      def width +        @period.count * Day::WIDTH +      end + +      def left +        (@period.first - @start).to_i * Day::WIDTH +      end + +      def html_style +        { +          width: "#{width}px", +          left: "#{left}px", +        }.map{|k, v| "#{k}: #{v}"}.join("; ") +      end + +      def empty? +        @empty +      end + +      def accepted? +        @period.count < 7 +      end + +      def title +        h.l(self.start, format: :short) + " - " + h.l(self.end, format: :short) +      end + +      def html_class +        out = [] +        out << "empty" if empty? +        out << "accepted" if accepted? +        out +      end +    end +  end + +  class Week +    attr_reader :h +    attr_reader :start_date +    attr_reader :end_date + +    def initialize start_date, boundary, h +      @start_date = start_date.to_date +      @end_date = [start_date.end_of_week, boundary].min.to_date +      @h = h +    end + +    def self.key date +      date.beginning_of_week.to_s +    end + +    def span +      h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b") +    end + +    def number +      h.l(@start_date, format: "%W") +    end + +    def period +      (@start_date..@end_date) +    end + +    def days +      period.map {|d| Day.new d, h } +    end +  end + +  class Day +    attr_reader :h + +    WIDTH=50 + +    def initialize date, h +      @date = date +      @h = h +    end + +    def html_style +      {width: "#{WIDTH}px"}.map{|k, v| "#{k}: #{v}"}.join("; ") +    end + +    def html_class +      out = [] +      out << "weekend" if [0, 6].include?(@date.wday) +      out +    end + +    def short_name +      h.l(@date, format: "%a") +    end + +    def number +      @date.day +    end +  end +end | 
