Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GSAF General Ledger
class GeneralLedgerDecorator < LittleDecorator
def division_colspan(division)
division_members(division).each_with_object([1]) do |member, num_columns|
num_columns << 1 if division_member_has_data?(division, member)
end.size
end
def division_member_has_data?(division, member)
data = record.get_division_member_data(division, member)
(data[:administration_fees].to_f + data[:origination_member_fees].to_f + data[:working_member_fees].to_f) > 0
end
def get_division_member_data(division, member)
currencify_hash(record.get_division_member_data(division, member))
end
def get_division_data(division)
currencify_hash(record.get_division_data(division))
end
def grand_totals
currencify_hash(record.grand_totals)
end
def company_totals
currencify_hash(record.company_totals)
end
private
def currencify_hash(hash)
hash.inject({}) do |new_hash, (key, value)|
new_hash[key] = number_to_currency(value); new_hash
end
end
end
class GeneralLedgerAuthorizer < ApplicationAuthorizer
def self.readable_by?(member)
member.security_group.admin
end
def readable_by?(member)
member.security_group.admin
end
end
class GeneralLedgersController < ApplicationController
before_action :authenticate_user!
before_action :check_tenant
authorize_actions_for GeneralLedger
# def new
# @general_ledger = GeneralLedger.new
# end
def index
@general_ledger = decorate(GeneralLedger.new(params, current_member))
end
end
%h1.page-header General Ledger
.row
.col-md-4
.row
= form_tag(general_ledgers_path, method: "get", class: "form-inline left-20px") do
= label_tag 'Start Date'
= date_field_tag "start_date", @general_ledger.start_date.nil? ? nil : @general_ledger.start_date.strftime('%F'), class: "form-control date", placeholder: "Start Date"
= label_tag 'End Date', nil, class: 'top-10px'
= date_field_tag "end_date", @general_ledger.end_date.nil? ? nil : @general_ledger.end_date.strftime('%F'), class: "form-control date", placeholder: "End Date"
= submit_tag "Search by Date", class: "btn btn-default top-10px bottom-10px"
%table.table.table-striped.table-bordered.mobile-table
%thead
%tr
%td{colspan: 2}
- @general_ledger.divisions.each do |division|
%td.info{colspan: "#{@general_ledger.division_colspan(division)}"}= division.name
%td
%tr
%th
%th
= "Total #{@general_ledger.company_name}"
- @general_ledger.divisions.each do |division|
- @general_ledger.division_members(division).each do |member|
- if @general_ledger.division_member_has_data?(division, member)
%th= member[:name]
%th= "#{division.name}"
%th TOTAL
- # To be refactored into partial or something
%tbody
%tr
%td Allocated Firm Administration Fees
%td= @general_ledger.company_totals[:administration_fees]
- @general_ledger.divisions.each do |division|
- @general_ledger.division_members(division).each do |member|
- if @general_ledger.division_member_has_data?(division, member)
%td= @general_ledger.get_division_member_data(division, member)[:administration_fees]
%td= @general_ledger.get_division_data(division)[:administration_fees]
%td
= @general_ledger.grand_totals[:administration_fees]
%tr
%td Allocated Originating Member Fees
%td= @general_ledger.company_totals[:originating_member_fees]
- @general_ledger.divisions.each do |division|
- @general_ledger.division_members(division).each do |member|
- if @general_ledger.division_member_has_data?(division, member)
%td= @general_ledger.get_division_member_data(division, member)[:originating_member_fees]
%td= @general_ledger.get_division_data(division)[:originating_member_fees]
%td
= @general_ledger.grand_totals[:originating_member_fees]
%tr
%td Allocated Working Member Fees
%td= @general_ledger.company_totals[:working_member_fees]
- @general_ledger.divisions.each do |division|
- @general_ledger.division_members(division).each do |member|
- if @general_ledger.division_member_has_data?(division, member)
%td= @general_ledger.get_division_member_data(division, member)[:working_member_fees]
%td= @general_ledger.get_division_data(division)[:working_member_fees]
%td
= @general_ledger.grand_totals[:working_member_fees]
resources :general_ledgers, only: :index
class GeneralLedger
include ActiveModel::Model
include Authority::Abilities
attr_reader :params, :current_member
def initialize(params, current_member)
@params = params.permit(:start_date, :end_date, :invoice_id, :credit_memo_id, :payment_id).to_h.with_indifferent_access
@current_member = current_member
end
def start_date
if params[:start_date].nil?
Date.current.last_month.beginning_of_month # Rails is so cool
elsif params[:start_date].present?
Date.parse(params[:start_date])
else
nil
end
end
def end_date
if params[:end_date].nil?
Date.current.last_month.end_of_month
elsif params[:end_date].present?
Date.parse(params[:end_date])
else
nil
end
end
def company
current_member.company
end
def company_name
company.name
end
def divisions
company.divisions
end
def division_members(division)
instance_variable_get("@division_members_#{division.name.parameterize(separator: "_")}") || begin
div_member_data = division.members.map do |member|
{ name: member.name, member_id: member.id, administration_fees: 0, originating_member_fees: calc_originating_member_fees(member), working_member_fees: calc_working_member_fees(member) }
end
instance_variable_set("@division_members_#{division.name.parameterize(separator: "_")}", div_member_data)
end
end
def get_division_member_data(division, member)
division_members(division).detect { |member_data| member_data[:member_id] == member[:member_id] }
end
def division_totals
@division_totals ||= begin
Division.all.map do |division|
{ name: division.name,
division_id: division.id,
administration_fees: division_members(division).reduce(0) { |sum, member_hash| sum + member_hash[:administration_fees] },
originating_member_fees: division_members(division).reduce(0) { |sum, member_hash| sum + member_hash[:originating_member_fees] },
working_member_fees: division_members(division).reduce(0) { |sum, member_hash| sum + member_hash[:working_member_fees] },
}
end
end
end
def get_division_data(division)
division_totals.detect { |division_data| division_data[:division_id] == division.id }
end
def company_totals
{ name: company_name,
administration_fees: calc_administration_fees,
originating_member_fees: 0,
working_member_fees: 0,
}
end
def grand_totals
{ name: company_name,
administration_fees: division_totals.reduce(0) { |sum, division_hash| sum + division_hash[:administration_fees] } + company_totals[:administration_fees],
originating_member_fees: division_totals.reduce(0) { |sum, division_hash| sum + division_hash[:originating_member_fees] } + company_totals[:originating_member_fees],
working_member_fees: division_totals.reduce(0) { |sum, division_hash| sum + division_hash[:working_member_fees] } + company_totals[:working_member_fees],
}
end
private
def validate_params
if has_date_params? && has_specific_id_params?
raise("You can only have a date range or specific id. Please pick one")
end
end
def calc_administration_fees
billed_fees(nil) * 0.15 #todo get from config
end
def calc_originating_member_fees(member)
billed_originating_fees(member) * 0.30 #todo get from config
end
def calc_working_member_fees(member)
billed_fees(member) * 0.55 #todo get from config
end
def billed_fees(member)
charges = Charge.billed.fees_only
charges = charges.where(member: member) if member
charges = charges.joins(:invoice).where("invoice_date >= ?", start_date) if start_date
charges = charges.joins(:invoice).where("invoice_date <= ?", end_date) if end_date
charges.sum(:bill_amount)
end
def billed_originating_fees(member)
#todo this won't capture charges that have no originating attorney
charges = Charge.joins(task: :project).billed.fees_only.where("projects.originating_member_id = ?", member.id)
charges = charges.joins(:invoice).where("invoice_date >= ?", start_date) if start_date
charges = charges.joins(:invoice).where("invoice_date <= ?", end_date) if end_date
charges.sum(:bill_amount)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment