feat(inventory): month/year harvest date picker (schema v3)

Replace the free-text harvest year with a themed month/year picker:
a tappable field opens a green-styled dialog with month and year grids
(navigable, paginated years), month optional. Lots now read e.g.
"September 2021" or just "Year 2021".

- schema v3: add nullable Lot.harvest_month (1..12) + migration + tests
- repo/cubit propagate harvestMonth; localized month names (en/es) via slang
This commit is contained in:
vjrj 2026-07-08 12:09:38 +02:00
parent 9e5c82184b
commit 5d4053157f
17 changed files with 3799 additions and 57 deletions

View file

@ -2631,6 +2631,17 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
type: DriftSqlType.int,
requiredDuringInsert: false,
);
static const VerificationMeta _harvestMonthMeta = const VerificationMeta(
'harvestMonth',
);
@override
late final GeneratedColumn<int> harvestMonth = GeneratedColumn<int>(
'harvest_month',
aliasedName,
true,
type: DriftSqlType.int,
requiredDuringInsert: false,
);
static const VerificationMeta _quantityKindMeta = const VerificationMeta(
'quantityKind',
);
@ -2707,6 +2718,7 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
varietyId,
type,
harvestYear,
harvestMonth,
quantityKind,
quantityPrecise,
quantityLabel,
@ -2787,6 +2799,15 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
),
);
}
if (data.containsKey('harvest_month')) {
context.handle(
_harvestMonthMeta,
harvestMonth.isAcceptableOrUnknown(
data['harvest_month']!,
_harvestMonthMeta,
),
);
}
if (data.containsKey('quantity_kind')) {
context.handle(
_quantityKindMeta,
@ -2876,6 +2897,10 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
DriftSqlType.int,
data['${effectivePrefix}harvest_year'],
),
harvestMonth: attachedDatabase.typeMapping.read(
DriftSqlType.int,
data['${effectivePrefix}harvest_month'],
),
quantityKind: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}quantity_kind'],
@ -2926,6 +2951,7 @@ class Lot extends DataClass implements Insertable<Lot> {
final String varietyId;
final LotType type;
final int? harvestYear;
final int? harvestMonth;
final String? quantityKind;
final double? quantityPrecise;
final String? quantityLabel;
@ -2942,6 +2968,7 @@ class Lot extends DataClass implements Insertable<Lot> {
required this.varietyId,
required this.type,
this.harvestYear,
this.harvestMonth,
this.quantityKind,
this.quantityPrecise,
this.quantityLabel,
@ -2965,6 +2992,9 @@ class Lot extends DataClass implements Insertable<Lot> {
if (!nullToAbsent || harvestYear != null) {
map['harvest_year'] = Variable<int>(harvestYear);
}
if (!nullToAbsent || harvestMonth != null) {
map['harvest_month'] = Variable<int>(harvestMonth);
}
if (!nullToAbsent || quantityKind != null) {
map['quantity_kind'] = Variable<String>(quantityKind);
}
@ -3001,6 +3031,9 @@ class Lot extends DataClass implements Insertable<Lot> {
harvestYear: harvestYear == null && nullToAbsent
? const Value.absent()
: Value(harvestYear),
harvestMonth: harvestMonth == null && nullToAbsent
? const Value.absent()
: Value(harvestMonth),
quantityKind: quantityKind == null && nullToAbsent
? const Value.absent()
: Value(quantityKind),
@ -3037,6 +3070,7 @@ class Lot extends DataClass implements Insertable<Lot> {
serializer.fromJson<String>(json['type']),
),
harvestYear: serializer.fromJson<int?>(json['harvestYear']),
harvestMonth: serializer.fromJson<int?>(json['harvestMonth']),
quantityKind: serializer.fromJson<String?>(json['quantityKind']),
quantityPrecise: serializer.fromJson<double?>(json['quantityPrecise']),
quantityLabel: serializer.fromJson<String?>(json['quantityLabel']),
@ -3060,6 +3094,7 @@ class Lot extends DataClass implements Insertable<Lot> {
'varietyId': serializer.toJson<String>(varietyId),
'type': serializer.toJson<String>($LotsTable.$convertertype.toJson(type)),
'harvestYear': serializer.toJson<int?>(harvestYear),
'harvestMonth': serializer.toJson<int?>(harvestMonth),
'quantityKind': serializer.toJson<String?>(quantityKind),
'quantityPrecise': serializer.toJson<double?>(quantityPrecise),
'quantityLabel': serializer.toJson<String?>(quantityLabel),
@ -3081,6 +3116,7 @@ class Lot extends DataClass implements Insertable<Lot> {
String? varietyId,
LotType? type,
Value<int?> harvestYear = const Value.absent(),
Value<int?> harvestMonth = const Value.absent(),
Value<String?> quantityKind = const Value.absent(),
Value<double?> quantityPrecise = const Value.absent(),
Value<String?> quantityLabel = const Value.absent(),
@ -3097,6 +3133,7 @@ class Lot extends DataClass implements Insertable<Lot> {
varietyId: varietyId ?? this.varietyId,
type: type ?? this.type,
harvestYear: harvestYear.present ? harvestYear.value : this.harvestYear,
harvestMonth: harvestMonth.present ? harvestMonth.value : this.harvestMonth,
quantityKind: quantityKind.present ? quantityKind.value : this.quantityKind,
quantityPrecise: quantityPrecise.present
? quantityPrecise.value
@ -3127,6 +3164,9 @@ class Lot extends DataClass implements Insertable<Lot> {
harvestYear: data.harvestYear.present
? data.harvestYear.value
: this.harvestYear,
harvestMonth: data.harvestMonth.present
? data.harvestMonth.value
: this.harvestMonth,
quantityKind: data.quantityKind.present
? data.quantityKind.value
: this.quantityKind,
@ -3160,6 +3200,7 @@ class Lot extends DataClass implements Insertable<Lot> {
..write('varietyId: $varietyId, ')
..write('type: $type, ')
..write('harvestYear: $harvestYear, ')
..write('harvestMonth: $harvestMonth, ')
..write('quantityKind: $quantityKind, ')
..write('quantityPrecise: $quantityPrecise, ')
..write('quantityLabel: $quantityLabel, ')
@ -3181,6 +3222,7 @@ class Lot extends DataClass implements Insertable<Lot> {
varietyId,
type,
harvestYear,
harvestMonth,
quantityKind,
quantityPrecise,
quantityLabel,
@ -3201,6 +3243,7 @@ class Lot extends DataClass implements Insertable<Lot> {
other.varietyId == this.varietyId &&
other.type == this.type &&
other.harvestYear == this.harvestYear &&
other.harvestMonth == this.harvestMonth &&
other.quantityKind == this.quantityKind &&
other.quantityPrecise == this.quantityPrecise &&
other.quantityLabel == this.quantityLabel &&
@ -3219,6 +3262,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
final Value<String> varietyId;
final Value<LotType> type;
final Value<int?> harvestYear;
final Value<int?> harvestMonth;
final Value<String?> quantityKind;
final Value<double?> quantityPrecise;
final Value<String?> quantityLabel;
@ -3236,6 +3280,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
this.varietyId = const Value.absent(),
this.type = const Value.absent(),
this.harvestYear = const Value.absent(),
this.harvestMonth = const Value.absent(),
this.quantityKind = const Value.absent(),
this.quantityPrecise = const Value.absent(),
this.quantityLabel = const Value.absent(),
@ -3254,6 +3299,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
required String varietyId,
this.type = const Value.absent(),
this.harvestYear = const Value.absent(),
this.harvestMonth = const Value.absent(),
this.quantityKind = const Value.absent(),
this.quantityPrecise = const Value.absent(),
this.quantityLabel = const Value.absent(),
@ -3276,6 +3322,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
Expression<String>? varietyId,
Expression<String>? type,
Expression<int>? harvestYear,
Expression<int>? harvestMonth,
Expression<String>? quantityKind,
Expression<double>? quantityPrecise,
Expression<String>? quantityLabel,
@ -3294,6 +3341,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
if (varietyId != null) 'variety_id': varietyId,
if (type != null) 'type': type,
if (harvestYear != null) 'harvest_year': harvestYear,
if (harvestMonth != null) 'harvest_month': harvestMonth,
if (quantityKind != null) 'quantity_kind': quantityKind,
if (quantityPrecise != null) 'quantity_precise': quantityPrecise,
if (quantityLabel != null) 'quantity_label': quantityLabel,
@ -3314,6 +3362,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
Value<String>? varietyId,
Value<LotType>? type,
Value<int?>? harvestYear,
Value<int?>? harvestMonth,
Value<String?>? quantityKind,
Value<double?>? quantityPrecise,
Value<String?>? quantityLabel,
@ -3332,6 +3381,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
varietyId: varietyId ?? this.varietyId,
type: type ?? this.type,
harvestYear: harvestYear ?? this.harvestYear,
harvestMonth: harvestMonth ?? this.harvestMonth,
quantityKind: quantityKind ?? this.quantityKind,
quantityPrecise: quantityPrecise ?? this.quantityPrecise,
quantityLabel: quantityLabel ?? this.quantityLabel,
@ -3374,6 +3424,9 @@ class LotsCompanion extends UpdateCompanion<Lot> {
if (harvestYear.present) {
map['harvest_year'] = Variable<int>(harvestYear.value);
}
if (harvestMonth.present) {
map['harvest_month'] = Variable<int>(harvestMonth.value);
}
if (quantityKind.present) {
map['quantity_kind'] = Variable<String>(quantityKind.value);
}
@ -3412,6 +3465,7 @@ class LotsCompanion extends UpdateCompanion<Lot> {
..write('varietyId: $varietyId, ')
..write('type: $type, ')
..write('harvestYear: $harvestYear, ')
..write('harvestMonth: $harvestMonth, ')
..write('quantityKind: $quantityKind, ')
..write('quantityPrecise: $quantityPrecise, ')
..write('quantityLabel: $quantityLabel, ')
@ -8188,6 +8242,7 @@ typedef $$LotsTableCreateCompanionBuilder =
required String varietyId,
Value<LotType> type,
Value<int?> harvestYear,
Value<int?> harvestMonth,
Value<String?> quantityKind,
Value<double?> quantityPrecise,
Value<String?> quantityLabel,
@ -8207,6 +8262,7 @@ typedef $$LotsTableUpdateCompanionBuilder =
Value<String> varietyId,
Value<LotType> type,
Value<int?> harvestYear,
Value<int?> harvestMonth,
Value<String?> quantityKind,
Value<double?> quantityPrecise,
Value<String?> quantityLabel,
@ -8270,6 +8326,11 @@ class $$LotsTableFilterComposer extends Composer<_$AppDatabase, $LotsTable> {
builder: (column) => ColumnFilters(column),
);
ColumnFilters<int> get harvestMonth => $composableBuilder(
column: $table.harvestMonth,
builder: (column) => ColumnFilters(column),
);
ColumnFilters<String> get quantityKind => $composableBuilder(
column: $table.quantityKind,
builder: (column) => ColumnFilters(column),
@ -8355,6 +8416,11 @@ class $$LotsTableOrderingComposer extends Composer<_$AppDatabase, $LotsTable> {
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<int> get harvestMonth => $composableBuilder(
column: $table.harvestMonth,
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<String> get quantityKind => $composableBuilder(
column: $table.quantityKind,
builder: (column) => ColumnOrderings(column),
@ -8428,6 +8494,11 @@ class $$LotsTableAnnotationComposer
builder: (column) => column,
);
GeneratedColumn<int> get harvestMonth => $composableBuilder(
column: $table.harvestMonth,
builder: (column) => column,
);
GeneratedColumn<String> get quantityKind => $composableBuilder(
column: $table.quantityKind,
builder: (column) => column,
@ -8497,6 +8568,7 @@ class $$LotsTableTableManager
Value<String> varietyId = const Value.absent(),
Value<LotType> type = const Value.absent(),
Value<int?> harvestYear = const Value.absent(),
Value<int?> harvestMonth = const Value.absent(),
Value<String?> quantityKind = const Value.absent(),
Value<double?> quantityPrecise = const Value.absent(),
Value<String?> quantityLabel = const Value.absent(),
@ -8514,6 +8586,7 @@ class $$LotsTableTableManager
varietyId: varietyId,
type: type,
harvestYear: harvestYear,
harvestMonth: harvestMonth,
quantityKind: quantityKind,
quantityPrecise: quantityPrecise,
quantityLabel: quantityLabel,
@ -8533,6 +8606,7 @@ class $$LotsTableTableManager
required String varietyId,
Value<LotType> type = const Value.absent(),
Value<int?> harvestYear = const Value.absent(),
Value<int?> harvestMonth = const Value.absent(),
Value<String?> quantityKind = const Value.absent(),
Value<double?> quantityPrecise = const Value.absent(),
Value<String?> quantityLabel = const Value.absent(),
@ -8550,6 +8624,7 @@ class $$LotsTableTableManager
varietyId: varietyId,
type: type,
harvestYear: harvestYear,
harvestMonth: harvestMonth,
quantityKind: quantityKind,
quantityPrecise: quantityPrecise,
quantityLabel: quantityLabel,