mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-23 07:09:39 +02:00
Fix time period key conflicts (#1944)
This commit is contained in:
parent
4c4a4026c4
commit
e907b073ed
6 changed files with 37 additions and 39 deletions
|
@ -2,7 +2,7 @@ class PagesController < ApplicationController
|
||||||
skip_before_action :authenticate_user!, only: %i[early_access]
|
skip_before_action :authenticate_user!, only: %i[early_access]
|
||||||
|
|
||||||
def dashboard
|
def dashboard
|
||||||
@period = Period.from_key(params[:period], fallback: true)
|
@period = params[:period] ? Period.from_key(params[:period]) : Period.last_30_days
|
||||||
@balance_sheet = Current.family.balance_sheet
|
@balance_sheet = Current.family.balance_sheet
|
||||||
@accounts = Current.family.accounts.active.with_attached_logo
|
@accounts = Current.family.accounts.active.with_attached_logo
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class Budget < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def period
|
def period
|
||||||
Period.new(start_date: start_date, end_date: end_date)
|
Period.custom(start_date: start_date, end_date: end_date)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
class Period
|
class Period
|
||||||
include ActiveModel::Validations, Comparable
|
include ActiveModel::Validations, Comparable
|
||||||
|
|
||||||
attr_reader :start_date, :end_date
|
class InvalidKeyError < StandardError; end
|
||||||
|
|
||||||
validates :start_date, :end_date, presence: true
|
attr_reader :key, :start_date, :end_date
|
||||||
|
|
||||||
|
validates :start_date, :end_date, presence: true, if: -> { PERIODS[key].nil? }
|
||||||
|
validates :key, presence: true, if: -> { start_date.nil? || end_date.nil? }
|
||||||
validate :must_be_valid_date_range
|
validate :must_be_valid_date_range
|
||||||
|
|
||||||
PERIODS = {
|
PERIODS = {
|
||||||
|
@ -64,18 +67,18 @@ class Period
|
||||||
}
|
}
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def default
|
def from_key(key)
|
||||||
from_key("last_30_days")
|
unless PERIODS.key?(key)
|
||||||
|
raise InvalidKeyError, "Invalid period key: #{key}"
|
||||||
|
end
|
||||||
|
|
||||||
|
start_date, end_date = PERIODS[key].fetch(:date_range)
|
||||||
|
|
||||||
|
new(key: key, start_date: start_date, end_date: end_date)
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_key(key, fallback: false)
|
def custom(start_date:, end_date:)
|
||||||
if PERIODS[key].present?
|
new(start_date: start_date, end_date: end_date)
|
||||||
start_date, end_date = PERIODS[key].fetch(:date_range)
|
|
||||||
new(start_date: start_date, end_date: end_date)
|
|
||||||
else
|
|
||||||
return default if fallback
|
|
||||||
raise ArgumentError, "Invalid period key: #{key}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def all
|
def all
|
||||||
|
@ -85,12 +88,12 @@ class Period
|
||||||
|
|
||||||
PERIODS.each do |key, period|
|
PERIODS.each do |key, period|
|
||||||
define_singleton_method(key) do
|
define_singleton_method(key) do
|
||||||
start_date, end_date = period.fetch(:date_range)
|
from_key(key)
|
||||||
new(start_date: start_date, end_date: end_date)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(start_date:, end_date:, date_format: "%b %d, %Y")
|
def initialize(start_date: nil, end_date: nil, key: nil, date_format: "%b %d, %Y")
|
||||||
|
@key = key
|
||||||
@start_date = start_date
|
@start_date = start_date
|
||||||
@end_date = end_date
|
@end_date = end_date
|
||||||
@date_format = date_format
|
@date_format = date_format
|
||||||
|
@ -121,37 +124,33 @@ class Period
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def key
|
|
||||||
PERIODS.find { |_, period| period.fetch(:date_range) == [ start_date, end_date ] }&.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def label
|
def label
|
||||||
if known?
|
if key_metadata
|
||||||
PERIODS[key].fetch(:label)
|
key_metadata.fetch(:label)
|
||||||
else
|
else
|
||||||
"Custom Period"
|
"Custom Period"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def label_short
|
def label_short
|
||||||
if known?
|
if key_metadata
|
||||||
PERIODS[key].fetch(:label_short)
|
key_metadata.fetch(:label_short)
|
||||||
else
|
else
|
||||||
"CP"
|
"Custom"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def comparison_label
|
def comparison_label
|
||||||
if known?
|
if key_metadata
|
||||||
PERIODS[key].fetch(:comparison_label)
|
key_metadata.fetch(:comparison_label)
|
||||||
else
|
else
|
||||||
"#{start_date.strftime(@date_format)} to #{end_date.strftime(@date_format)}"
|
"#{start_date.strftime(@date_format)} to #{end_date.strftime(@date_format)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def known?
|
def key_metadata
|
||||||
key.present?
|
@key_metadata ||= PERIODS[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
def must_be_valid_date_range
|
def must_be_valid_date_range
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<% period = Period.from_key(params[:period], fallback: true) %>
|
<% period = params[:period] ? Period.from_key(params[:period]) : Period.last_30_days %>
|
||||||
<% series = @account.balance_series(period: period) %>
|
<% series = @account.balance_series(period: period) %>
|
||||||
<% trend = series.trend %>
|
<% trend = series.trend %>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<%# locals: (account:, title: nil, tooltip: nil, **args) %>
|
<%# locals: (account:, title: nil, tooltip: nil, **args) %>
|
||||||
|
|
||||||
<% period = Period.from_key(params[:period], fallback: true) %>
|
<% period = params[:period] ? Period.from_key(params[:period]) : Period.last_30_days %>
|
||||||
<% default_value_title = account.asset? ? t(".balance") : t(".owed") %>
|
<% default_value_title = account.asset? ? t(".balance") : t(".owed") %>
|
||||||
|
|
||||||
<div id="<%= dom_id(account, :chart) %>" class="bg-white shadow-xs rounded-xl border border-alpha-black-25 rounded-lg space-y-2">
|
<div id="<%= dom_id(account, :chart) %>" class="bg-white shadow-xs rounded-xl border border-alpha-black-25 rounded-lg space-y-2">
|
||||||
|
|
|
@ -18,20 +18,19 @@ class PeriodTest < ActiveSupport::TestCase
|
||||||
assert_includes error.message, "Start date must be before end date"
|
assert_includes error.message, "Start date must be before end date"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "can create custom period" do
|
||||||
|
period = Period.new(start_date: Date.current - 15.days, end_date: Date.current)
|
||||||
|
assert_equal "Custom Period", period.label
|
||||||
|
end
|
||||||
|
|
||||||
test "from_key returns period for valid key" do
|
test "from_key returns period for valid key" do
|
||||||
period = Period.from_key("last_30_days")
|
period = Period.from_key("last_30_days")
|
||||||
assert_equal 30.days.ago.to_date, period.start_date
|
assert_equal 30.days.ago.to_date, period.start_date
|
||||||
assert_equal Date.current, period.end_date
|
assert_equal Date.current, period.end_date
|
||||||
end
|
end
|
||||||
|
|
||||||
test "from_key with invalid key and fallback returns default period" do
|
|
||||||
period = Period.from_key("invalid_key", fallback: true)
|
|
||||||
assert_equal 30.days.ago.to_date, period.start_date
|
|
||||||
assert_equal Date.current, period.end_date
|
|
||||||
end
|
|
||||||
|
|
||||||
test "from_key with invalid key and no fallback raises error" do
|
test "from_key with invalid key and no fallback raises error" do
|
||||||
assert_raises ArgumentError do
|
error = assert_raises(Period::InvalidKeyError) do
|
||||||
Period.from_key("invalid_key")
|
Period.from_key("invalid_key")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue