Skip to content

Commit

Permalink
Revert "WIP - fixing centers and center_meeting_days once and for all"
Browse files Browse the repository at this point in the history
This reverts commit 03ea9d8.

since this is WIP, moving it to a separate branch "fixing-centers"
  • Loading branch information
Siddharth Sharma committed Feb 4, 2012
1 parent 03ea9d8 commit 3aeaaf2
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 214 deletions.
145 changes: 77 additions & 68 deletions app/models/center.rb
Expand Up @@ -2,8 +2,14 @@ class Center
include DataMapper::Resource
include DateParser

attr_accessor :meeting_day_change_date

before :save, :convert_blank_to_nil
after :save, :handle_meeting_date_change
before :save, :set_meeting_change_date
before :create, :set_meeting_change_date
before :valid?, :convert_blank_to_nil
before :valid?, :handle_meeting_days


DAYS = [:none, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]

Expand All @@ -13,7 +19,7 @@ class Center
property :address, Text, :lazy => true
property :contact_number, String, :length => 40, :lazy => true
property :landmark, String, :length => 100, :lazy => true
property :meeting_day, Enum.send('[]', *DAYS), :nullable => true, :default => :none, :index => true # DEPRECATED
property :meeting_day, Enum.send('[]', *DAYS), :nullable => false, :default => :none, :index => true
property :meeting_time_hours, Integer, :length => 2, :index => true
property :meeting_time_minutes, Integer, :length => 2, :index => true
property :meeting_calendar, Text # this is a comma separated list of dates and takes precedence over everything else.
Expand All @@ -38,6 +44,8 @@ class Center
validates_with_method :meeting_time_hours, :method => :hours_valid?
validates_with_method :meeting_time_minutes, :method => :minutes_valid?

# validates_with_method :creation_date_ok

def self.from_csv(row, headers)
hour, minute = row[headers[:center_meeting_time_in_24h_format]].split(":")
branch = Branch.first(:name => row[headers[:branch]].strip)
Expand All @@ -62,23 +70,12 @@ def self.meeting_days
DAYS
end

def get_meeting_dates(to = SEP_DATE,from = creation_date)
# DEPRECATED - Please use Center#meeting_dates. get_meeting_dates is non-idiomatic ruby
meeting_dates(to, from)
end


# get a list of meeting dates between from and to if to is a Date. Else gets "to" meeting dates if to is an integer
#
# a center must take the responsibility that center_meeting_days never overlap.
# to can be a date or a number
def meeting_dates(to = nil,from = nil)
debugger
# sometimes loans from another center might be moved to this center. they can be created before this centers creation date
# therefore, we refer to the loan history table first and if there are no rows there, we refer to the creation date for the 'from' date if none is specified
min_max_dates = LoanHistory.all(:center_id => self.id).aggregate(:date.min, :date.max)
from ||= (min_max_dates[0] || self.creation_date)
to ||= (min_max_dates[1] || SEP_DATE)
# first refer to the meeting_calendar
def get_meeting_dates(to = Date.new(2100,12,31),from = creation_date)
# to can be a date or a number
# first find the date_Vectors for all center_meeting_days as a hash {:valid_from => DateVector}
unless self.meeting_calendar.blank?
ds = self.meeting_calendar.split(/[\s,]/).reject(&:blank?).map{|d| Date.parse(d) rescue nil}.compact.select{|d| d >= from}.sort
if to
Expand All @@ -87,8 +84,6 @@ def meeting_dates(to = nil,from = nil)
end
return ds
end

# then check the date vectors
select = to.class == Date ? {:valid_from.lte => to} : {}
dvs = center_meeting_days.all(select).map{|cmd| [cmd.valid_from, cmd.date_vector]}.to_hash

Expand Down Expand Up @@ -127,7 +122,7 @@ def self.catalog(user=nil)
result = {}
branch_names = {}

if (user or Nothing).staff_member
if user.staff_member
staff_member = user.staff_member
[staff_member.centers.branches, staff_member.branches].flatten.each{|b| branch_names[b.id] = b.name }
centers = [staff_member.centers, staff_member.branches.centers].flatten
Expand All @@ -145,8 +140,7 @@ def self.catalog(user=nil)
end



# returns the meeting day for a given date

def meeting_day_for(date)
@meeting_days ||= self.center_meeting_days(:order => [:valid_from])
if @meeting_days.length==0
Expand All @@ -161,34 +155,43 @@ def meeting_day_for(date)
end

def next_meeting_date_from(date)
# first refer to the LoanHistory. Sometimes, some funky loans might be in here and we don't want to depend on center meeting dates in
# the first instance
r_date = (LoanHistory.first(:center_id => self.id, :date.gt => date, :order => [:date], :limit => 1) or Nothing).date
return r_date if r_date
#oops...no loans in this center. use center_meeting_dates
debugger
self.meeting_dates(1, date)[0]
unless r_date
number = get_meeting_date(date, :next)
if meeting_day != :none and (date + number - get_meeting_date(date + number, :previous)).cweek == (date + number).cweek
r_date = (date + number + get_meeting_date(date + number, :next)).holiday_bump
else
r_date = (date + number).holiday_bump
end
end
r_date

end

def previous_meeting_date_from(date)
#likewise for this (see comment above)
r_date = (LoanHistory.first(:center_id => self.id, :date.lte => date, :order => [:date.desc], :limit => 1) or Nothing).date
return r_date if r_date
#oops...no loans in this center. use center_meeting_dates
self.meeting_dates(date)[-1]
unless r_date
number = get_meeting_date(date, :previous)
if meeting_day != :none and (date - number - get_meeting_date(date - number, :previous)).cweek == (date - number).cweek
r_date = (date - number - get_meeting_date(date - number, :previous)).holiday_bump
else
r_date = (date - number).holiday_bump
end
end
r_date

end


def meeting_day?(date)
Center.meeting_days.include?(date)
LoanHistory.all(:date => date).aggregate(:center_id).include?(self.id)
end

def meeting_time
meeting_time_hours.two_digits + ':' + meeting_time_minutes.two_digits rescue "00:00"
end

def self.paying_today(user, date = Date.today, branch_id = nil)
# returns a list of centers paying today
selection = {:date => date}.merge(branch_id ? {:branch_id => branch_id} : {})
center_ids = LoanHistory.all(selection).aggregate(:center_id)
centers = center_ids.blank? ? [] : Center.all(:id => center_ids)
Expand Down Expand Up @@ -216,7 +219,6 @@ def location
end

def self.meeting_today(date=Date.today, user=nil)
# this makes no sense
user = User.first
center_ids = LoanHistory.all(:date => date).aggregate(:center_id)
# restrict branch manager and center managers to their own branches
Expand All @@ -227,9 +229,6 @@ def self.meeting_today(date=Date.today, user=nil)
Center.all(:id => center_ids)
end


private

def hours_valid?
return true if (0..23).include? meeting_time_hours.to_i
[false, "Hours of the meeting time should be within 0-23"]
Expand All @@ -240,9 +239,14 @@ def minutes_valid?
end
def manager_is_an_active_staff_member?
return true if manager and manager.active
[false, "Cannot set #{self.manager.name} as center manager because this staff member is not currently not active"]
[false, "Receiving staff member is currently not active"]
end

def creation_date_ok
return true if clients.map{|c| c.loans}.count == 0
return true if creation_date <= loans.aggregate(:applied_on.min)
return [false, "Creation date cannot be after the first loan application date"]
end

def handle_meeting_date_change
# no need to do all this if meeting date was not changed
Expand Down Expand Up @@ -280,39 +284,44 @@ def handle_meeting_date_change
return true
end

def handle_meeting_days
# this function creates the first center meeting day for the center when only a meeting day is specified.
# we will soon deprecate the meeting_day field and work only with center_meeting_days
if center_meeting_days.blank?
unless meeting_day == :none
cmd = CenterMeetingDay.new(:valid_from => nil, :valid_upto => nil, :center_id => self.id, :meeting_day => (meeting_day || :none))
self.center_meeting_days << cmd
def set_meeting_change_date
if self.new?
self.meeting_day_change_date = self.creation_date
else
# Check if meeting date was changed.
if self.dirty_attributes.map{|x| x.first.name}.include?(:meeting_day)
if self.meeting_day_change_date.class==String and not self.meeting_day_change_date.blank?
self.meeting_day_change_date = parse_date(self.meeting_day_change_date)
else
# if meeting_day was indeed changed and no meeting_change_date is foudn then set it as today's date
self.meeting_day_change_date ||= Date.today
end
else
# If meeting_day was not changed then set meeting_day_change_date as nil.
self.meeting_day_change_date = nil
end
end

end

# def get_meeting_date(date, direction)
# DEPRECATED. Commenting out right now so that we can restore it if it is being referenced from somewhere
# TODO remove this from the codebase if nothing borks by 2012-02-28
# number = 1
# if direction == :next
# nwday = (date + number).wday
# while (meet_day = Center.meeting_days.index(meeting_day_for(date + number)) and meet_day > 0 and nwday != meet_day)
# number += 1
# nwday = (date + number).wday
# nwday = 7 if nwday == 0
# end
# else
# nwday = (date - number).wday
# while (meet_day = Center.meeting_days.index(meeting_day_for(date - number)) and meet_day > 0 and nwday != meet_day)
# number += 1
# nwday = (date - number).wday
# nwday = 7 if nwday == 0
# end
# end
# return number
# end
def get_meeting_date(date, direction)
number = 1
if direction == :next
nwday = (date + number).wday
while (meet_day = Center.meeting_days.index(meeting_day_for(date + number)) and meet_day > 0 and nwday != meet_day)
number += 1
nwday = (date + number).wday
nwday = 7 if nwday == 0
end
else
nwday = (date - number).wday
while (meet_day = Center.meeting_days.index(meeting_day_for(date - number)) and meet_day > 0 and nwday != meet_day)
number += 1
nwday = (date - number).wday
nwday = 7 if nwday == 0
end
end
return number
end

def convert_blank_to_nil
self.attributes.each{|k, v|
Expand Down
3 changes: 1 addition & 2 deletions app/models/center_meeting_day.rb
Expand Up @@ -98,9 +98,8 @@ def to_s


def valid_from_is_lesser_than_valid_upto
return true if self.valid_from.blank? and self.valid_upto.blank? # neither is set
self.valid_from = Date.parse(self.valid_from) unless self.valid_from.is_a? Date
self.valid_upto = (self.valid_upto.blank? ? SEP_DATE : Date.parse(self.valid_upto)) if self.valid_upto.class == String
self.valid_upto = (self.valid_upto.blank? ? Date.new(2100,12,31) : Date.parse(self.valid_upto)) if self.valid_upto.class == String

if self.valid_from and self.valid_upto
return [false, "Valid from date cannot be before than valid upto date"] if self.valid_from > self.valid_upto
Expand Down
3 changes: 3 additions & 0 deletions app/models/loan.rb
Expand Up @@ -1248,7 +1248,10 @@ def calculate_history
actual_outstanding_principal = outstanding ? actual[:balance].round(2) : 0
actual_outstanding_total = outstanding ? actual[:total_balance].round(2) : 0
actual_outstanding_interest = outstanding ? (actual_outstanding_total - actual_outstanding_principal) : 0
<<<<<<< HEAD

=======
>>>>>>> e8b0fb3120ed49f25dac950f47aa21be9b15129f
_apo = [0,total_principal_paid.round(2) - total_principal_due.round(2)].max # advance principal outstanding at the start
_api = [0,total_interest_paid.round(2) - total_interest_due.round(2)].max
advance_principal_outstanding = outstanding ? _apo : 0
Expand Down
3 changes: 0 additions & 3 deletions config/constants.rb
Expand Up @@ -122,6 +122,3 @@
# in order to avoid overrunning the SQL max packet size, we split the cacher update into chunks
# 2500 should be good for the standard SQL max_packet_size of 16MB
CHUNK_SIZE = 2500


SEP_DATE = Date.new(2100,12,31) # SEP = Someone Else's Problem http://en.wikipedia.org/wiki/Somebody_Else's_Problem i.e. a date so far in the future as to represent infinity
2 changes: 1 addition & 1 deletion spec/factories.rb
Expand Up @@ -582,7 +582,7 @@
name 'home'
title 'Home page'
route '/'
type BookmarkTypes.first
type Types.first
share_with User::ROLES.first

association :user
Expand Down

0 comments on commit 3aeaaf2

Please sign in to comment.