Skip to content

Add planned builds (reserve part stock for future project builds) - #1567

Open
kernchen-brc wants to merge 2 commits into
Part-DB:masterfrom
kernchen-brc:master
Open

kernchen-brc wants to merge 2 commits into
Part-DB:masterfrom
kernchen-brc:master

Conversation

@kernchen-brc

Copy link
Copy Markdown
Contributor

Summary

Adds planned builds: a way to reserve the parts a project needs for a future build, without removing them from the inventory yet. Reserved stock is excluded from what can be withdrawn, moved or used by other builds, until the plan is built or cancelled.

Stock is now tracked as Total = Available + Reserved per lot and per part. This is shown on the part page, can be shown as table columns (Reserved, Available) and is part of the API (reserved_amount, available_amount on part lots).

How it works

  • Plan: new "Plan build" tab next to "Build" on a project. The form pre-fills the reservation per lot (and lets you change it), like the build form does. Planning never touches any amount.
  • Planning always works. If there is not enough stock, only what is available is reserved (partial reservation). Parts without any stock lot are listed as well, with nothing reserved.
  • Build: withdraws what the project needs, optionally adds the builds to the build part, and marks the plan Built. The withdrawal is derived from the current stock, so a plan that fell short while planning can be built after the part was restocked. If there still is not enough stock, the build is refused (and the Build button is disabled with the list of missing parts).
  • Built plans are kept as a record: who planned and who built it and when (existing event log), and a snapshot of the parts and lots that were used (planned_projects.built_parts).
  • Cancel: releases the reservations.
  • UI: "Planned builds" list and detail pages (sortable parts list, status, build/cancel/delete), a "Missing parts" report, and a sidebar entry under Projects that updates automatically.

Changes to existing behaviour

  • Withdraw, move and the normal project build now check against the available amount instead of the total amount.
  • Parts, part lots and BOM entries that have active reservations can not be deleted or merged. This shows a message (no server error) in the part delete, bulk delete, merge and lot-removal flows. Deleting a project with active planned builds is blocked as well.
  • Manually withdrawing/moving more than the available amount shows a message instead of an error.
  • parts.edit now also sets the new parts_stock.reserve/release permissions.

Database / permissions

  • Migration Version20260929120000 creates planned_projects and part_lot_reservations (MySQL, SQLite, PostgreSQL).
  • Migration Version20260929130000 copies existing projects permissions to the new planned_projects permission, and parts_stock.withdraw/add to the new parts_stock.reserve/release, so existing installs and admins see the feature right away. The permission presets for new installs are updated too.
  • New permissions: group planned_projects (read/edit/create/delete/show_history/revert_element/import), parts_stock.reserve, parts_stock.release.

Other

  • The new entities are registered in LogTargetType, ElementTypes, EntityURLGenerator, the log filter and the cache invalidation listener, so logging, history links and the sidebar work.
  • Documentation: docs/usage/planned_builds.md. English translations are added to messages.en.xlf / validators.en.xlf (other languages are left to Crowdin).

Testing

  • composer phpstan (level 5), lint:twig, lint:yaml and doctrine:schema:validate --skip-sync pass. The migrations run from scratch on SQLite; I did not run them on MySQL or PostgreSQL.
  • New tests: planning helper (planning, building, restocking after planning, sorting, shortfalls), planning request, PlannedProject entity, sidebar tree builder, and a functional controller test (parts without lots are listed, sorting, building keeps the plan, active reservations block part deletion and manual withdrawal). PartLot/withdraw tests are extended, and the new pages are added to the availability tests.
  • Manually checked in the Docker container: planning with a part without lots, sorting, building after restocking.

Notes for reviewers

  • Reservations only exist while a plan is planned; building or cancelling releases them. History of a built plan lives in the built_parts snapshot, so it does not block deleting parts, lots or projects and does not slow down the stock calculations.
  • SQLite does not enforce foreign keys by default in Part-DB, so cleanup relies on the ORM cascades, not on ON DELETE CASCADE.
  • If two planned builds could both be completed from the same free stock, each shows as buildable on its own; whichever is built first uses the stock.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.46067% with 165 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.26%. Comparing base (23208b1) to head (f1ee2ea).

Files with missing lines Patch % Lines
src/Controller/PlannedProjectController.php 61.65% 51 Missing ⚠️
...rc/Helpers/Projects/BuildPlannedProjectRequest.php 29.03% 22 Missing ⚠️
...c/Services/ProjectSystem/ProjectPlanningHelper.php 91.66% 18 Missing ⚠️
...c/Controller/AdminPages/ProjectAdminController.php 0.00% 10 Missing ⚠️
src/DataTables/PlannedProjectsDataTable.php 88.46% 9 Missing ⚠️
src/Helpers/Projects/PlanProjectRequest.php 88.88% 7 Missing ⚠️
src/Form/ProjectSystem/BuildPlannedProjectType.php 81.81% 6 Missing ⚠️
src/Services/Parts/PartsTableActionHandler.php 0.00% 6 Missing ⚠️
src/Controller/PartController.php 72.22% 5 Missing ⚠️
src/Entity/ProjectSystem/PartLotReservation.php 68.75% 5 Missing ⚠️
... and 10 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1567      +/-   ##
============================================
+ Coverage     62.97%   63.26%   +0.28%     
- Complexity    10071    10358     +287     
============================================
  Files           748      762      +14     
  Lines         32315    33194     +879     
============================================
+ Hits          20351    20999     +648     
- Misses        11964    12195     +231     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
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