mirror of
https://github.com/we-promise/sure.git
synced 2026-06-05 18:59:04 +00:00
feat: Allow creating a budget up to 2 years ahead
This commit is contained in:
@@ -29,13 +29,14 @@ class Budget < ApplicationRecord
|
||||
end
|
||||
|
||||
def budget_date_valid?(date, family:)
|
||||
if family.uses_custom_month_start?
|
||||
budget_start = family.custom_month_start_for(date)
|
||||
budget_start >= oldest_valid_budget_date(family) && budget_start <= family.custom_month_end_for(Date.current)
|
||||
budget_start = if family.uses_custom_month_start?
|
||||
family.custom_month_start_for(date)
|
||||
else
|
||||
beginning_of_month = date.beginning_of_month
|
||||
beginning_of_month >= oldest_valid_budget_date(family) && beginning_of_month <= Date.current.end_of_month
|
||||
date.beginning_of_month
|
||||
end
|
||||
|
||||
budget_start >= oldest_valid_budget_date(family) &&
|
||||
budget_start <= latest_valid_budget_start_date(family)
|
||||
end
|
||||
|
||||
def find_or_bootstrap(family, start_date:)
|
||||
@@ -70,6 +71,14 @@ class Budget < ApplicationRecord
|
||||
oldest_entry_date = family.oldest_entry_date.beginning_of_month
|
||||
[ two_years_ago, oldest_entry_date ].min
|
||||
end
|
||||
|
||||
def latest_valid_budget_start_date(family)
|
||||
if family.uses_custom_month_start?
|
||||
family.current_custom_month_period.start_date + 2.years
|
||||
else
|
||||
Date.current.beginning_of_month + 2.years
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def period
|
||||
@@ -151,8 +160,6 @@ class Budget < ApplicationRecord
|
||||
end
|
||||
|
||||
def next_budget_param
|
||||
return nil if current?
|
||||
|
||||
next_date = start_date + 1.month
|
||||
return nil unless self.class.budget_date_valid?(next_date, family: family)
|
||||
|
||||
|
||||
@@ -58,8 +58,35 @@ class BudgetTest < ActiveSupport::TestCase
|
||||
refute Budget.budget_date_valid?(3.years.ago.beginning_of_month, family: @family)
|
||||
end
|
||||
|
||||
test "budget_date_valid? does not allow future dates beyond current month" do
|
||||
refute Budget.budget_date_valid?(2.months.from_now, family: @family)
|
||||
test "budget_date_valid? allows future dates up to 2 years ahead" do
|
||||
travel_to Date.current.beginning_of_month do
|
||||
assert Budget.budget_date_valid?(Date.current.beginning_of_month + 1.month, family: @family)
|
||||
assert Budget.budget_date_valid?(Date.current.beginning_of_month + 2.years, family: @family)
|
||||
end
|
||||
end
|
||||
|
||||
test "budget_date_valid? does not allow future dates beyond 2 years ahead" do
|
||||
travel_to Date.current.beginning_of_month do
|
||||
refute Budget.budget_date_valid?(Date.current.beginning_of_month + 2.years + 1.month, family: @family)
|
||||
end
|
||||
end
|
||||
|
||||
test "budget_date_valid? for custom month start allows dates up to 2 years ahead" do
|
||||
@family.update!(month_start_day: 15)
|
||||
|
||||
travel_to Date.current.beginning_of_month do
|
||||
cap_start = @family.current_custom_month_period.start_date + 2.years
|
||||
assert Budget.budget_date_valid?(cap_start, family: @family)
|
||||
end
|
||||
end
|
||||
|
||||
test "budget_date_valid? for custom month start does not allow dates beyond 2 years ahead" do
|
||||
@family.update!(month_start_day: 15)
|
||||
|
||||
travel_to Date.current.beginning_of_month do
|
||||
beyond_cap = @family.current_custom_month_period.start_date + 2.years + 1.month
|
||||
refute Budget.budget_date_valid?(beyond_cap, family: @family)
|
||||
end
|
||||
end
|
||||
|
||||
test "previous_budget_param returns nil when date is too old" do
|
||||
@@ -75,6 +102,49 @@ class BudgetTest < ActiveSupport::TestCase
|
||||
assert_nil budget.previous_budget_param
|
||||
end
|
||||
|
||||
test "next_budget_param returns next month when current month budget is selected" do
|
||||
travel_to Date.current.beginning_of_month do
|
||||
budget = Budget.create!(
|
||||
family: @family,
|
||||
start_date: Date.current.beginning_of_month,
|
||||
end_date: Date.current.end_of_month,
|
||||
currency: "USD"
|
||||
)
|
||||
|
||||
assert_equal Budget.date_to_param(Date.current.beginning_of_month + 1.month), budget.next_budget_param
|
||||
end
|
||||
end
|
||||
|
||||
test "next_budget_param returns nil at future cap" do
|
||||
travel_to Date.current.beginning_of_month do
|
||||
cap_start = Date.current.beginning_of_month + 2.years
|
||||
budget = Budget.create!(
|
||||
family: @family,
|
||||
start_date: cap_start,
|
||||
end_date: cap_start.end_of_month,
|
||||
currency: "USD"
|
||||
)
|
||||
|
||||
assert_nil budget.next_budget_param
|
||||
end
|
||||
end
|
||||
|
||||
test "next_budget_param returns nil at future cap for custom month start" do
|
||||
@family.update!(month_start_day: 15)
|
||||
|
||||
travel_to Date.current.beginning_of_month do
|
||||
cap_start = @family.current_custom_month_period.start_date + 2.years
|
||||
budget = Budget.create!(
|
||||
family: @family,
|
||||
start_date: cap_start,
|
||||
end_date: cap_start + 1.month - 1.day,
|
||||
currency: "USD"
|
||||
)
|
||||
|
||||
assert_nil budget.next_budget_param
|
||||
end
|
||||
end
|
||||
|
||||
test "actual_spending nets refunds against expenses in same category" do
|
||||
family = families(:dylan_family)
|
||||
budget = Budget.find_or_bootstrap(family, start_date: Date.current.beginning_of_month)
|
||||
|
||||
Reference in New Issue
Block a user