Warenwirtschaft: AP-50 — Lagerort löschbar (Buchungen übernehmen) + Köln als Default
Kundenentscheid 26.08.: „Waldbröl" gibt es nicht mehr, alles wird Köln; die Standort-Funktion bleibt für künftige Standorte. - LocationController::destroy überschrieben: ein belegter Lagerort lässt sich löschen, indem seine Buchungen (Wareneingänge, Produktionen, Ausschuss) transaktional auf einen Ziel-Lagerort übernommen werden. Ohne Ziel-Lagerort bleibt die Sperre bestehen; unbelegte Orte werden direkt gelöscht. - Lagerort-Liste: Ziel-Auswahl („→ Köln" vorbelegt) im Lösch-Formular. - Wareneingang: Köln als Standard-Lagerort vorbelegt (wie in der Produktion). Außerdem AP-49-Folgeanpassung: Test-Helper hängt die Kategorie „Kosmetikrohstoffe" an, damit Lieferanten im gefilterten INCI-Formular erscheinen; Lagerort-Sperr-Test prüft die neue Meldung. Suite 322 grün. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4eb36486b0
commit
e08c8dec40
6 changed files with 142 additions and 4 deletions
|
|
@ -4,9 +4,60 @@ namespace App\Http\Controllers\Admin\Inventory;
|
|||
|
||||
use App\Http\Requests\Inventory\StoreLocationRequest;
|
||||
use App\Models\Location;
|
||||
use App\Models\Production;
|
||||
use App\Models\StockDisposal;
|
||||
use App\Models\StockEntry;
|
||||
use App\Services\DeletionGuard;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LocationController extends SettingCrudController
|
||||
{
|
||||
/**
|
||||
* AP-50 (Kundenentscheid 26.08.2026): Ein belegter Lagerort (z. B. „Waldbröl")
|
||||
* lässt sich löschen, indem seine Buchungen (Wareneingänge, Produktionen,
|
||||
* Ausschuss) auf einen Ziel-Lagerort (z. B. Köln) übernommen werden. Ohne
|
||||
* Referenzen wird direkt gelöscht; die Standard-Sperre bleibt bestehen, solange
|
||||
* kein Ziel-Lagerort gewählt ist.
|
||||
*/
|
||||
public function destroy(): RedirectResponse
|
||||
{
|
||||
/** @var Location $location */
|
||||
$location = $this->routeModel();
|
||||
$reassignTo = (int) request()->input('reassign_to', 0);
|
||||
|
||||
$guard = app(DeletionGuard::class);
|
||||
$blockers = $guard->blockersFor($location);
|
||||
|
||||
if ($blockers !== []) {
|
||||
$target = $reassignTo > 0 && $reassignTo !== $location->id
|
||||
? Location::query()->find($reassignTo)
|
||||
: null;
|
||||
|
||||
if (! $target) {
|
||||
\Session::flash('alert-error', __('Lagerort ist noch belegt — bitte einen Ziel-Lagerort zum Übernehmen der Buchungen wählen.'));
|
||||
|
||||
return redirect()->route($this->redirectRoute());
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($location, $target) {
|
||||
StockEntry::query()->where('location_id', $location->id)->update(['location_id' => $target->id]);
|
||||
Production::query()->where('location_id', $location->id)->update(['location_id' => $target->id]);
|
||||
StockDisposal::query()->where('location_id', $location->id)->update(['location_id' => $target->id]);
|
||||
$location->delete();
|
||||
});
|
||||
|
||||
\Session::flash('alert-success', __('Lagerort gelöscht — Buchungen auf „:target" übernommen.', ['target' => $target->name]));
|
||||
|
||||
return redirect()->route($this->redirectRoute());
|
||||
}
|
||||
|
||||
$location->delete();
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route($this->redirectRoute());
|
||||
}
|
||||
|
||||
protected function modelClass(): string
|
||||
{
|
||||
return Location::class;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ class StockEntryController extends Controller
|
|||
$model = new StockEntry([
|
||||
'ordered_at' => now()->toDateString(),
|
||||
'entry_type' => 'ingredient',
|
||||
// AP-50: Köln als Standard-Lagerort vorbelegen (wie in der Produktion).
|
||||
'location_id' => Location::query()->where('name', 'like', '%öln%')->value('id')
|
||||
?? Location::query()->where('active', true)->orderBy('name')->value('id'),
|
||||
]);
|
||||
|
||||
$ingredientId = (int) $request->query('ingredient_id');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue