feat(inventory): local sharing — per-lot share terms, filter and printable catalog

The local half of the original Fase 2 (no network, no Offer entity yet):
- Lot sheet gains a 'do you share it?' choice (gift/swap first, sale last,
  never the default); declaring plenty of abundance reveals it with a nudge.
- Lot lines and list tiles badge shared batches; an 'I share' filter and
  a printable PDF catalog (paper bridge for fairs) round out the view.
- Catalog PDF embeds DejaVu (Latin-ext/Cyrillic/Greek); fonts are a
  per-locale resource like the OCR packs.
This commit is contained in:
vjrj 2026-07-09 22:19:55 +02:00
parent e3ec855630
commit ba87bf2719
20 changed files with 982 additions and 36 deletions

View file

@ -103,6 +103,20 @@ void main() {
expect(cubit.state.visibleItems.single.label, 'Tired');
});
test('sharing filter keeps only varieties with an offered lot', () async {
final sharedId = await repo.addQuickVariety(label: 'Shared');
await repo.addLot(varietyId: sharedId, offerStatus: OfferStatus.shared);
final privateId = await repo.addQuickVariety(label: 'Private');
await repo.addLot(varietyId: privateId);
await waitFor(cubit, (s) => s.hasShared && s.items.length == 2);
cubit.toggleSharingOnly();
expect(cubit.state.visibleItems.single.label, 'Shared');
cubit.toggleSharingOnly();
expect(cubit.state.visibleItems, hasLength(2));
});
test('clearFilters resets every filter but keeps the search query', () async {
await repo.addQuickVariety(label: 'Maize', category: 'Poaceae');
await waitFor(cubit, (s) => s.items.isNotEmpty);
@ -112,13 +126,15 @@ void main() {
..toggleCategory('Poaceae')
..toggleType(LotType.seed)
..toggleOrganicOnly()
..toggleNeedsReproductionOnly();
..toggleNeedsReproductionOnly()
..toggleSharingOnly();
cubit.clearFilters();
expect(cubit.state.categoryFilter, isEmpty);
expect(cubit.state.typeFilter, isEmpty);
expect(cubit.state.organicOnly, isFalse);
expect(cubit.state.needsReproductionOnly, isFalse);
expect(cubit.state.sharingOnly, isFalse);
expect(cubit.state.query, 'mai');
});