mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
* Add tax treatment metrics to reports, forms, and models - Implement `build_gains_by_tax_treatment` for grouping gains by tax treatment - Update investment performance view with tax treatment breakdown - Add tax treatment field to crypto and investments forms - Introduce `realized_gain_loss` calculation in the Trade model - Group investment subtypes by region for improved dropdown organization * Optimize investment performance report by reducing N+1 queries - Eager-load associations in `build_gains_by_tax_treatment` to minimize database queries - Preload holdings for realized gain/loss calculations in trades - Refactor views to standardize "no data" placeholder using translations - Adjust styling in tax treatment breakdown for improved layout * Enhance investment performance translations and optimize holdings lookup logic - Update `holdings_count` and `sells_count` translations to handle pluralization - Refactor views to use pluralized translation keys with count interpolation - Optimize preloaded holdings lookup in `Trade` to ensure deterministic selection using `select` and `max_by` * Refine preloaded holdings logic in `Trade` model - Treat empty preloaded holdings as authoritative to prevent unnecessary DB queries - Add explicit fallback behavior for database query when holdings are not preloaded --------- Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
49 lines
1.5 KiB
Ruby
49 lines
1.5 KiB
Ruby
module ReportsHelper
|
|
# Returns CSS classes for tax treatment badge styling
|
|
def tax_treatment_badge_classes(treatment)
|
|
case treatment.to_sym
|
|
when :tax_exempt
|
|
"bg-green-500/10 text-green-600 theme-dark:text-green-400"
|
|
when :tax_deferred
|
|
"bg-blue-500/10 text-blue-600 theme-dark:text-blue-400"
|
|
when :tax_advantaged
|
|
"bg-purple-500/10 text-purple-600 theme-dark:text-purple-400"
|
|
else
|
|
"bg-gray-500/10 text-secondary"
|
|
end
|
|
end
|
|
|
|
# Generate SVG polyline points for a sparkline chart
|
|
# Returns empty string if fewer than 2 data points (can't draw a line with 1 point)
|
|
def sparkline_points(values, width: 60, height: 16)
|
|
return "" if values.nil? || values.length < 2 || values.all? { |v| v.nil? || v.zero? }
|
|
|
|
nums = values.map(&:to_f)
|
|
max_val = nums.max
|
|
min_val = nums.min
|
|
range = max_val - min_val
|
|
range = 1.0 if range.zero?
|
|
|
|
points = nums.each_with_index.map do |val, i|
|
|
x = (i.to_f / [ nums.length - 1, 1 ].max) * width
|
|
y = height - ((val - min_val) / range * (height - 2)) - 1
|
|
"#{x.round(1)},#{y.round(1)}"
|
|
end
|
|
|
|
points.join(" ")
|
|
end
|
|
|
|
# Calculate cumulative net values from trends data
|
|
def cumulative_net_values(trends)
|
|
return [] if trends.nil?
|
|
|
|
running = 0
|
|
trends.map { |t| running += t[:net].to_i; running }
|
|
end
|
|
|
|
# Check if trends data has enough points for sparklines (need at least 2)
|
|
def has_sparkline_data?(trends_data)
|
|
trends_data&.length.to_i >= 2
|
|
end
|
|
end
|