# frozen_string_literal: true # # Copyright (c) 2018-present, Blue Marble Payroll, LLC # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # module Differential module Calculator # This class is responsible for building an entire report. Usage: # - Instantiate a Reader. # - Instantiate a Report. # - Feed in dataset(s) into the Reader to generate Record objects. # - Feed in Record objects, generated by a Reader, by calling Report#add. # The Report object will keep running sums and deltas of all added records. class Report include HasTotals def sorted_groups groups.sort_by { |group| group.id.value } end def groups groups_by_id.values end def add(record, side) raise ArgumentError, 'record is required' unless record raise ArgumentError, 'side is required' unless side totals.add(record.value, side) upsert_group(record, side) self end private def upsert_group(record, side) group_id_key = record.group_id.value group_id = record.group_id # Create a new group if one does not exist groups_by_id[group_id_key] = Group.new(group_id) unless groups_by_id.key?(group_id_key) groups_by_id[group_id_key].add(record, side) nil end def groups_by_id @groups_by_id ||= {} end end end end