Guest User

Untitled

a guest
Feb 19th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. #! /usr/bin/env ruby
  2.  
  3. # Usage: ruby bill_generator.rb data.yml 2008-1-1 2008-12-31
  4.  
  5. # Params: data file, begin date, end date
  6. # begin and end date is in the format yyyy-mm-dd
  7.  
  8. # Sample data.yml file entries
  9. # Date format is [yyyy, mm, dd]
  10. #
  11. # # Paid every two weeks
  12. # Income1:
  13. # amount: 1000
  14. # start: [2008, 1, 18]
  15. # repeat: daily
  16. # freq: 14
  17. #
  18. # # Paid twice a month on the 15th and the last day
  19. # Income2:
  20. # amount: 1000
  21. # start: [ [2008, 1, 15], [2008, 1, -1] ]
  22. # repeat: monthly
  23. # freq: 1
  24. #
  25. # # Weekly food expense
  26. # Food:
  27. # amount: -100
  28. # start: [2008, 1, 6]
  29. # repeat: weekly
  30. # freq: 1
  31. #
  32. # # Quarterly bill
  33. # Water:
  34. # amount: -100
  35. # start: [2008, 1, 20]
  36. # repeat: monthly
  37. # freq: 3
  38. #
  39. # # Monthly bill
  40. # Home:
  41. # amount: -1000
  42. # start: [2008, 1, 1]
  43. # repeat: monthly
  44. # freq: 1
  45.  
  46. # v0.1
  47.  
  48. # TODO: Date parser for better dates in the yaml file
  49. # TODO: Extract bill class out into separate file
  50. # TODO: Use command line params lib
  51.  
  52. require 'yaml'
  53. require 'date'
  54.  
  55. class Bill
  56.  
  57. def initialize(name, params)
  58. @name = name
  59. @amount = params['amount']
  60. @start_dates = params['start']
  61. @repeat = params['repeat']
  62. @freq = params['freq'].to_i
  63. end
  64.  
  65. attr_accessor :name, :amount
  66.  
  67. def due?(current_date)
  68. due = false
  69. if @start_dates[0].is_a? Array
  70. @start_dates.each do |start_date|
  71. # No need to check others if it matches
  72. next if due == true
  73. due = check_for_repeat_type(current_date, start_date)
  74. end
  75. else
  76. due = check_for_repeat_type(current_date, @start_dates)
  77. end
  78. due
  79. end
  80.  
  81. private
  82.  
  83. def check_for_repeat_type(current_date, start_date)
  84. case @repeat
  85. when "daily"
  86. compare_daily(current_date, start_date)
  87. when "weekly"
  88. compare_daily(current_date, start_date, @freq * 7)
  89. when "monthly"
  90. compare_monthly(current_date, start_date)
  91. when "yearly"
  92. compare_yearly(current_date, start_date)
  93. else
  94. raise ArgumentError, "Invalid repeat option. Must be one of daily, weekly, monthly, or yearly"
  95. end
  96. end
  97.  
  98. def compare_daily(current_date, start_date, freq = @freq)
  99. # Custom freq allows us to convert weekly to daily
  100. start_date = convert_date(start_date)
  101. ((current_date - start_date) % freq) == 0
  102. end
  103.  
  104. def compare_monthly(current_date, start_date)
  105. # Check for end of month comparison
  106. if start_date[2].to_i == -1
  107. start_date = convert_date(start_date)
  108. ((current_date.month - start_date.month) % @freq == 0) && current_date.day == end_of_month_day(current_date)
  109. else
  110. start_date = convert_date(start_date)
  111. ((current_date.month - start_date.month) % @freq == 0) && current_date.day == start_date.day
  112. end
  113. end
  114.  
  115. def compare_yearly(current_date, start_date)
  116. ((current_date.year - start_date.year) % @freq == 0) && current_date.month == start_date.month && current_date.day == start_date.day
  117. end
  118.  
  119. # Accepts format of [year, month, day]
  120. def convert_date(date)
  121. Date.new(*date)
  122. end
  123.  
  124. def end_of_month_day(current_date)
  125. Date.new(current_date.year, current_date.month, -1).day
  126. end
  127. end
  128.  
  129. # Begin script
  130.  
  131. file = ARGV[0]
  132. date_start = Date.parse(ARGV[1].to_s)
  133. date_end = Date.parse(ARGV[2].to_s)
  134.  
  135. bills = YAML.load_file(file)
  136.  
  137. (date_start..date_end).each do |date|
  138. bills.each do |name, info|
  139. bill = Bill.new(name, info)
  140. puts "#{bill.name}, #{date.to_s.strip}, #{bill.amount}" if bill.due? date
  141. end
  142. end
Add Comment
Please, Sign In to add comment