Files
sure/app/controllers/retirement/adjustments_controller.rb
Guillem Arias 26bb333c34 feat(retirement): PR2 CRUD for sources, statements, adjustments, bucket
Functional data-entry surface on the (still preview) /retirement page.
The polished combined-page UI is PR4; this ships plain forms + lists so
a preview user can populate a plan end to end.

- RetirementScoped concern: tier-1 preview gate + tier-2 family
  killswitch + per-owner plan bootstrap (Goal::Retirement.for_owner
  find-or-creates, so children always have a parent). RetirementController
  now uses it.
- Nested controllers under Retirement::: PensionSources (full CRUD),
  Statements (new/create + soft-delete destroy — append-only audit),
  Adjustments (full CRUD), Buckets (replace-all account selection,
  same-family filtered). All scoped to the current user's own plan, so
  cross-user access is impossible by construction.
- Routes nested under `resource :retirement` via `scope module:`.
- Views: show page rewritten into management sections (sources,
  adjustments, bucket checkboxes, statement journal) + plain
  styled_form_with forms. Money carries privacy-sensitive.
- Goal gains a target_amount_required? hook (true); Goal::Retirement
  overrides it false — the forecast owns the target (PR3), so a plan
  can exist before any target is set.
- EN locale for the new surface. 111 controller+model tests green.

Note: delete uses Turbo confirm for now; PR4 swaps in the skinned
DS::Dialog per the design.
2026-05-29 10:49:18 +02:00

52 lines
1.2 KiB
Ruby

class Retirement::AdjustmentsController < ApplicationController
include RetirementScoped
before_action :set_adjustment, only: %i[edit update destroy]
def new
@adjustment = @plan.adjustments.new(
from_age: 65, ordinal: next_ordinal,
currency: Current.family.primary_currency_code
)
end
def create
@adjustment = @plan.adjustments.new(adjustment_params)
if @adjustment.save
redirect_to retirement_path, notice: t(".created")
else
render :new, status: :unprocessable_entity
end
end
def edit; end
def update
if @adjustment.update(adjustment_params)
redirect_to retirement_path, notice: t(".updated")
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@adjustment.destroy!
redirect_to retirement_path, notice: t(".deleted")
end
private
def set_adjustment
@adjustment = @plan.adjustments.find(params[:id])
end
def next_ordinal
(@plan.adjustments.maximum(:ordinal) || -1) + 1
end
def adjustment_params
params.require(:goal_retirement_adjustment).permit(
:label, :from_age, :to_age, :amount_today, :currency, :icon, :ordinal
)
end
end