feat(labels): choose copies per label, prefilled from container count

Each label in the print sheet gets an editable copy count, suggested from
the lot's latest condition-check container count (3 jars → 3 labels), and
falling back to 1. Type or step the count; the total updates live and Save
is disabled at zero. On save each seed expands into that many identical
labels.

- SeedLabelEntry.suggestedCopies; labelRows reads the latest container count
- label print sheet: per-row −/number/+ stepper, live total, expand on save
- tests: repository suggestedCopies + print-sheet copy chooser
This commit is contained in:
vjrj 2026-07-10 20:12:36 +02:00
parent 63f48db5c2
commit d36fd05741
4 changed files with 298 additions and 4 deletions

View file

@ -134,6 +134,7 @@ class SeedLabelEntry extends Equatable {
this.quantity,
this.originName,
this.originPlace,
this.suggestedCopies = 1,
});
final String varietyLabel;
@ -147,6 +148,11 @@ class SeedLabelEntry extends Equatable {
final String? originName;
final String? originPlace;
/// How many copies of this label to suggest the latest condition check's
/// container count (e.g. 3 jars 3 labels), or 1 when unknown. Always 1;
/// the print sheet prefills it and lets the keeper edit.
final int suggestedCopies;
@override
List<Object?> get props => [
varietyLabel,
@ -157,6 +163,7 @@ class SeedLabelEntry extends Equatable {
quantity,
originName,
originPlace,
suggestedCopies,
];
}
@ -1325,6 +1332,28 @@ class VarietyRepository {
(lotsByVariety[l.varietyId] ??= <Lot>[]).add(l);
}
// Suggest one label per stored container: the latest condition check's
// container count (3 jars 3 labels). `.first` is the most recent because
// we order by check date descending.
final containersByLot = <String, int>{};
if (lots.isNotEmpty) {
final checks =
await (_db.select(_db.conditionChecks)
..where(
(c) =>
c.lotId.isIn(lots.map((l) => l.id).toList()) &
c.isDeleted.equals(false),
)
..orderBy([(c) => OrderingTerm.desc(c.checkedOn)]))
.get();
for (final c in checks) {
final count = c.containerCount;
if (count != null && count > 0) {
containersByLot.putIfAbsent(c.lotId, () => count);
}
}
}
SeedLabelEntry entryFor(Variety v, Lot? l) {
final hasQuantity =
l != null &&
@ -1346,6 +1375,7 @@ class VarietyRepository {
: null,
originName: l?.originName,
originPlace: l?.originPlace,
suggestedCopies: l == null ? 1 : (containersByLot[l.id] ?? 1),
);
}