fix(articles): Mengen-Stepper beim Set-Entfernen wieder aktivieren

Ein Set kann mehrfach bestellt sein (Oberartikel-Menge = Set-Anzahl),
daher bleibt der Mengen-Stepper beim Entfernen über den Oberartikel
erhalten. Die gewählte Set-Anzahl kaskadiert PROPORTIONAL auf die
Komponenten (Stückzahl je Set × entfernte Sets, geklemmt auf Restmenge)
— funktioniert für 1:1-Mengen wie für Komponenten mit Stückzahl je Set.
Einzelne Komponenten bleiben weiterhin nicht direkt entfernbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-06-23 16:04:58 +02:00
parent 4c6bef6897
commit 7e345bd71b

View File

@ -217,34 +217,51 @@ class _ArticleManagementRow extends StatelessWidget {
));
}
/// Entfernt das GANZE Set (Oberartikel + alle Komponenten) auf einmal —
/// „entweder Parent komplett oder gar nix". Kein Mengen-Stepper
/// (`maxQuantity: null` ⇒ jede Zeile komplett).
Future<void> _openSetRemoveDialog(BuildContext context) async {
/// Entfernt eine Anzahl Sets über den Oberartikel und kaskadiert auf seine
/// Komponenten. Der Mengen-Stepper bleibt erhalten — ein Set kann mehrfach
/// bestellt sein (Oberartikel-Menge = Set-Anzahl). Die Komponenten werden
/// **proportional** mitreduziert (Stückzahl je Set × entfernte Sets),
/// geklemmt auf die jeweilige Restmenge. Einzelne Komponenten bleiben
/// nicht direkt entfernbar — nur dieser Weg über den Oberartikel.
Future<void> _openSetRemoveDialog(
BuildContext context, {
required int remaining,
}) async {
final tourBloc = context.read<TourBloc>();
final actorCarId = _actorCarId(context);
final result = await showReasonPickerSheet(
context: context,
title: 'Grund für das Entfernen (ganzes Set)',
title: 'Grund für das Entfernen',
presets: ReasonCatalog.itemRemove,
confirmLabel: 'Set entfernen',
maxQuantity: null,
confirmLabel: 'Entfernen',
maxQuantity: remaining,
);
if (result == null) return;
// Oberartikel + jede Komponente komplett entfernen (quantity null).
final n = result.quantity ?? remaining;
final parentRequired = item.requiredQuantity;
// Oberartikel um n Sets reduzieren.
tourBloc.add(RemoveItem(
deliveryItemId: item.id,
reason: result.reason,
actorCarId: actorCarId,
quantity: null,
quantity: n,
saveReasonAsNote: true,
));
// Komponenten proportional mitreduzieren.
for (final c in components) {
final cRemaining = c.requiredQuantity - c.scanProgress.creditedQuantity;
if (cRemaining <= 0) continue;
final proportional = parentRequired > 0
? (c.requiredQuantity * n / parentRequired).round()
: cRemaining;
final removeQty = proportional.clamp(0, cRemaining);
if (removeQty <= 0) continue;
tourBloc.add(RemoveItem(
deliveryItemId: c.id,
reason: result.reason,
actorCarId: actorCarId,
quantity: null,
quantity: removeQty,
// Grund nur einmal (am Oberartikel) als Notiz festhalten.
saveReasonAsNote: false,
));
@ -435,7 +452,7 @@ class _ArticleManagementRow extends StatelessWidget {
),
onPressed: canCredit
? () => hasComponents
? _openSetRemoveDialog(context)
? _openSetRemoveDialog(context, remaining: remaining)
: _openCreditDialog(context, remaining: remaining)
: null,
icon: Icon(