feat(labels): print seed labels with QR from an inventory selection

Add multi-select to the inventory and a "Print labels" flow that renders a
PDF sheet of labels (small stickers or large cards), each carrying the seed's
common name, variety, scientific name, year/origin and a tanemaki://seed QR
that holds the seed's data offline (future scan-to-import).

- SeedLabelCodec: compact, versioned tanemaki://seed URI (encode/decode)
- LabelSheetService: pure-Dart PDF grid (pdf + barcode + DejaVu), RTL-aware
- VarietyRepository.labelRows: one row per lot, locale-picked common name
- InventoryCubit selection mode; contextual app bar + label print sheet
- i18n en/es/pt (printLabels.*)

Tests: codec, PDF service (both formats + RTL), labelRows, selection cubit,
inventory widget selection.
This commit is contained in:
vjrj 2026-07-10 19:14:04 +02:00
parent 432acded29
commit efb369eb81
19 changed files with 1465 additions and 116 deletions

View file

@ -258,6 +258,23 @@
"catalogSaved": "Catálogo guardado",
"cancelled": "Cancelado"
},
"printLabels": {
"action": "Imprimir etiquetas",
"title": "Imprimir etiquetas",
"selectHint": "Escolhe as sementes para imprimir as etiquetas",
"selectAll": "Selecionar tudo",
"selected": "{n} selecionadas",
"none": "Seleciona sementes primeiro",
"format": "Tamanho da etiqueta",
"formatStickers": "Autocolantes pequenos",
"formatStickersHint": "Muitas etiquetas pequenas por folha — para colar em envelopes",
"formatCards": "Cartões grandes",
"formatCardsHint": "Menos etiquetas, maiores — para frascos e caixas",
"count": "{n} etiquetas",
"save": "Guardar etiquetas",
"saved": "Etiquetas guardadas",
"cancelled": "Cancelado"
},
"cropCalendar": {
"add": "Calendário de cultivo",
"title": "Calendário de cultivo",