Skip to content

Release/4.5.0#324

Open
lukas-staab wants to merge 17 commits into
mainfrom
release/4.5.0
Open

Release/4.5.0#324
lukas-staab wants to merge 17 commits into
mainfrom
release/4.5.0

Conversation

@lukas-staab

Copy link
Copy Markdown
Member

Checklist for @DieMichii

  • Languaging
  • automated Testing
  • Documentation
  • Version bump (composer) and Version Tag
  • Changelog written

Changelog:

FIXME

lukas-staab and others added 17 commits June 27, 2026 09:23
The settings-import migration still invoked the old
settings:import-from-legacy-config name; update it to match the command
namespace reorg.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remove the @alpinejs/sort plugin and its registration; sortable budget
items now use Livewire's native wire:sort instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… and cloning

Graduate the budget-plan feature from the dev-only feature branch to a
full release (4.5.0):

- Replace the draft/final BudgetPlanState enum with a spatie
  model-states workflow (Draft → Resolved → Approved → Published →
  Completed) and gate transitions through the policy.
- Add a derived BudgetItemKind (group/budget/mount) and "mount" items
  that stand in for the income/expense side of another plan, with
  cycle-safe effective-value rollups and reachability checks.
- Add Support\Budget helpers: TitleNumberer for auto Titelnummern and
  BudgetPlanCloner for copy-from-existing with per-mount copy/drop.
- New plan-create and plan-view Livewire pages; rework plan-edit and the
  index; drop the old controller-rendered view.
- Rework fiscal-year create/edit: overlap validation, authorization,
  next-year suggestion and a compact range label.
- Move routes from web-dev.php into web.php, add the nav entry, schema
  (referenced_plan_id, nullable description) and German strings.
- Fix BudgetPlanFactory missing Published state import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update ConvertLegacyBudgetPlans for the new model/state structure and
add coverage for the legacy conversion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add legacy:verify-booking-migration, a read-only reconciliation that
cross-references the booking table against both the old (haushaltstitel)
and new (budget_item) title tables. For every booked title it shows the
old/new identity side by side and flags titles that are missing on the
new side or resolve to a non-bookable group/mount.

The footer prints grand totals and a fingerprint over the per-title
booking sums: capture it before and after the upgrade to confirm the
booking table was preserved (or trigger a rollback if it changed). Only
ground truth while both real tables exist, i.e. before the table->view
swap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e guards

Make the new BudgetItem the canonical title for accounting, leaving the
legacy haushaltstitel tables and the booking FK in place (the table->view
swap follows separately).

- Wire BudgetItem::bookings() (was a stub) to the booking table by
  titel_id, which equals budget_item.id for converted leaf items, and add
  isBookable()/hasBookings() helpers. Bookability is derived (a plain
  budget leaf, never a group or mount), no stored column.
- Re-point Booking::budgetItem, ProjectPost::budgetItem and
  TaxBudget::budgetTitle (renamed from legacyBudgetTitle) at BudgetItem;
  update consumers (DatevExport, the legacy transaction + show-project
  views, edit-project tax posts) to short_name/name/budget_type.
- Guard plan-edit delete/convertToGroup/convertToMount against items that
  already have bookings, so a booked leaf can't become non-bookable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the legacy-plan conversion logic out of the ConvertLegacyBudgetPlans
console command into a reusable App\Support\Budget\BudgetPlanConverter, so
it can also be invoked outside the console (the upcoming table->view swap
migration runs it). The command becomes a thin wrapper that handles the
dry-run transaction and console output via a logger callback. Behaviour is
unchanged (same preserved ids, same fingerprint); the conversion-helper
test now exercises the service directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turn haushaltsplan/haushaltsgruppen/haushaltstitel into read-only VIEWS over
the new budget_plan/budget_item structure, so the legacy PHP app keeps reading
live data while the new budget plan becomes the single source of truth.

Migration (self-contained): converts any existing legacy data into the new
tables (idempotent, preserves leaf ids), re-points the booking/projektposten/
tax_budget foreign keys from haushaltstitel/haushaltsplan to budget_item/
budget_plan (widening the int columns to match), drops the legacy tables and
recreates them as views. FK constraint names are discovered from
information_schema (they vary by environment), and all raw SQL is table-prefix
aware. Plans without a fiscal year have no legacy von/bis, so the haushaltsplan
view excludes them. NOT data-reversible — roll back from a backup, using
legacy:verify-booking-migration's fingerprint to confirm the booking table.

Writers are disabled, since the legacy tables can no longer be written:
- legacy HHP import (HHPHandler::saveNewHHP) now refuses with a clear message.
- TaxBudget::addToPlan is reworked to create budget_items (and its relations
  point at the new models); its test moves to the new structure.

Demo seeding moves off the SQL dump for the budget data: the legacy budget
inserts are removed from stufis-demo-data.sql and replaced by DemoBudgetSeeder,
which builds the plans/groups/titles in the new structure (preserving leaf and
plan ids so the dump's bookings/posts still resolve) and runs before the dump.
The year-shift is shared via DemoDataSeeder::yearShiftDelta. Project tests that
built legacy fixtures now build the new structure. composer prepare-test gains
--drop-views so the persistent test DB can be refreshed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mark legacy:budget-group-shift, legacy:budget-id-shift,
legacy:budget-id-batch-shift and legacy:delete-hhp as deprecated / slated for
deletion: their targets (haushaltsplan/gruppen/titel) are now read-only views,
so they can no longer write. Left runnable for now, but each carries a
@deprecated docblock, a [DEPRECATED] description and a runtime warning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The tax_budget foreign keys now point at the new tables, so give them clear
English names: titel_id -> budget_id (budget_item), hhp_id -> plan_id
(budget_plan). The rename happens in the swap migration (and reverses in
down()); cascade it through the TaxBudget model (fillable, relations,
addToPlan) and its callers (edit-project tax posts, AddToPlanTest).

booking.titel_id and projektposten.titel_id are left as-is: the legacy PHP app
reads those column names directly via raw SQL in several places, so renaming
them would mean churn in legacy code that is slated for deletion anyway.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring the legacy HHP "Umsatzsteuer-Titel hinzufügen" feature into the new
budget plan editor as an addTaxTitles() action, and improve it:

- Authorized via the plan-update policy and gated by the global tax.active
  setting (button only shown when active), mirroring the legacy gate.
- Tax rates are now configurable via a new tax.rates setting (default 7/19)
  instead of being hard-coded; rates are normalised (deduped, positives only,
  sorted) and a title is generated per rate.
- addToPlan() returns how many titles were newly added, so the action gives
  real feedback ("n added" vs "already present") via a toast, and refreshes
  the tree. Still fully idempotent.

The legacy button keeps working too — it calls the same reworked addToPlan,
which now writes the new budget_item structure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion

Preload entire item tree with relations and compute effective values bottom-up to reduce redundant database queries and improve rendering efficiency.
…e tax title deletion handling

Introduce a function to add plain budget items at the root level and update tests accordingly. Fix foreign key constraint issues during tax title deletion by ensuring tax-budget rows are removed in a transaction. Adjust UI and translations to accommodate the new budget item functionality.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant