feat(offers): asking price on lots, published with sale offers (schema v11)
The data model always meant sale offers to carry an informational price (data-model §2.8, sharing-model §4.4); with offer state collapsed onto the Lot, the price lives there. Null amount on a sell lot = 'to be agreed' — the NIP-99 event simply omits the price tag. - schema v11: Lots.price_amount/price_currency, guarded migration, schema dump + generated schema_v11 for the round-trip test - ShareableLot/VarietyLot carry the price (sell-only in shareableLots); addLot/updateLot persist it and clear it when the lot leaves sale - OffersCubit.publishLots forwards it (outbox flush picks it up free) - lot sheet: price + currency inputs revealed only on 'For sale', with the €/Ğ1/hours quick-picks extracted to a shared CurrencyQuickPicks widget (reused by the sale sheet) - backup JSON round-trips the new columns - i18n share.price/priceHint in en/es/pt/ast
This commit is contained in:
parent
89addb1ed7
commit
cfa1053842
25 changed files with 4690 additions and 31 deletions
|
|
@ -31,7 +31,7 @@ class AppDatabase extends _$AppDatabase {
|
|||
|
||||
/// Current schema version; also stamped into interchange exports so an
|
||||
/// importer knows which app generation wrote the file (data-model §7).
|
||||
static const int currentSchemaVersion = 10;
|
||||
static const int currentSchemaVersion = 11;
|
||||
|
||||
@override
|
||||
int get schemaVersion => currentSchemaVersion;
|
||||
|
|
@ -153,6 +153,16 @@ class AppDatabase extends _$AppDatabase {
|
|||
await m.createTable(sales);
|
||||
}
|
||||
}
|
||||
// v11: asking price on Lots — published with "sell" market offers.
|
||||
// Guarded (see the v7 note above).
|
||||
if (from < 11) {
|
||||
if (!await _hasColumn('lots', 'price_amount')) {
|
||||
await m.addColumn(lots, lots.priceAmount);
|
||||
}
|
||||
if (!await _hasColumn('lots', 'price_currency')) {
|
||||
await m.addColumn(lots, lots.priceCurrency);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -3266,6 +3266,28 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
|
|||
).withConverter<PreservationFormat?>(
|
||||
$LotsTable.$converterpreservationFormatn,
|
||||
);
|
||||
static const VerificationMeta _priceAmountMeta = const VerificationMeta(
|
||||
'priceAmount',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<double> priceAmount = GeneratedColumn<double>(
|
||||
'price_amount',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.double,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _priceCurrencyMeta = const VerificationMeta(
|
||||
'priceCurrency',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<String> priceCurrency = GeneratedColumn<String>(
|
||||
'price_currency',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
id,
|
||||
|
|
@ -3289,6 +3311,8 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
|
|||
originPlace,
|
||||
abundance,
|
||||
preservationFormat,
|
||||
priceAmount,
|
||||
priceCurrency,
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
|
|
@ -3429,6 +3453,24 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('price_amount')) {
|
||||
context.handle(
|
||||
_priceAmountMeta,
|
||||
priceAmount.isAcceptableOrUnknown(
|
||||
data['price_amount']!,
|
||||
_priceAmountMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('price_currency')) {
|
||||
context.handle(
|
||||
_priceCurrencyMeta,
|
||||
priceCurrency.isAcceptableOrUnknown(
|
||||
data['price_currency']!,
|
||||
_priceCurrencyMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -3532,6 +3574,14 @@ class $LotsTable extends Lots with TableInfo<$LotsTable, Lot> {
|
|||
data['${effectivePrefix}preservation_format'],
|
||||
),
|
||||
),
|
||||
priceAmount: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.double,
|
||||
data['${effectivePrefix}price_amount'],
|
||||
),
|
||||
priceCurrency: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}price_currency'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -3600,6 +3650,17 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
/// How the (seed) lot is physically conserved — see [PreservationFormat].
|
||||
/// Distinct from [storageLocation]. Optional.
|
||||
final PreservationFormat? preservationFormat;
|
||||
|
||||
/// Asking price when [offerStatus] is `sell` (data-model §2.8 puts price on
|
||||
/// the Offer; with offer state collapsed onto the Lot, it lives here and is
|
||||
/// published with the market offer). Informational only — money changes
|
||||
/// hands off-platform, never in-app. Null amount on a sell lot means
|
||||
/// "price to be agreed" (the offer publishes without a price).
|
||||
final double? priceAmount;
|
||||
|
||||
/// Free-text currency, like [Sales.currency]: "€", "Ğ1", a local/time
|
||||
/// currency. Never assumed (sharing-model §6).
|
||||
final String? priceCurrency;
|
||||
const Lot({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
|
|
@ -3622,6 +3683,8 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
this.originPlace,
|
||||
this.abundance,
|
||||
this.preservationFormat,
|
||||
this.priceAmount,
|
||||
this.priceCurrency,
|
||||
});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
|
|
@ -3683,6 +3746,12 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
$LotsTable.$converterpreservationFormatn.toSql(preservationFormat),
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || priceAmount != null) {
|
||||
map['price_amount'] = Variable<double>(priceAmount);
|
||||
}
|
||||
if (!nullToAbsent || priceCurrency != null) {
|
||||
map['price_currency'] = Variable<String>(priceCurrency);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
@ -3733,6 +3802,12 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
preservationFormat: preservationFormat == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(preservationFormat),
|
||||
priceAmount: priceAmount == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(priceAmount),
|
||||
priceCurrency: priceCurrency == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(priceCurrency),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -3773,6 +3848,8 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
preservationFormat: $LotsTable.$converterpreservationFormatn.fromJson(
|
||||
serializer.fromJson<String?>(json['preservationFormat']),
|
||||
),
|
||||
priceAmount: serializer.fromJson<double?>(json['priceAmount']),
|
||||
priceCurrency: serializer.fromJson<String?>(json['priceCurrency']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
|
@ -3808,6 +3885,8 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
'preservationFormat': serializer.toJson<String?>(
|
||||
$LotsTable.$converterpreservationFormatn.toJson(preservationFormat),
|
||||
),
|
||||
'priceAmount': serializer.toJson<double?>(priceAmount),
|
||||
'priceCurrency': serializer.toJson<String?>(priceCurrency),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -3833,6 +3912,8 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
Value<String?> originPlace = const Value.absent(),
|
||||
Value<Abundance?> abundance = const Value.absent(),
|
||||
Value<PreservationFormat?> preservationFormat = const Value.absent(),
|
||||
Value<double?> priceAmount = const Value.absent(),
|
||||
Value<String?> priceCurrency = const Value.absent(),
|
||||
}) => Lot(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
|
|
@ -3863,6 +3944,10 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
preservationFormat: preservationFormat.present
|
||||
? preservationFormat.value
|
||||
: this.preservationFormat,
|
||||
priceAmount: priceAmount.present ? priceAmount.value : this.priceAmount,
|
||||
priceCurrency: priceCurrency.present
|
||||
? priceCurrency.value
|
||||
: this.priceCurrency,
|
||||
);
|
||||
Lot copyWithCompanion(LotsCompanion data) {
|
||||
return Lot(
|
||||
|
|
@ -3915,6 +4000,12 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
preservationFormat: data.preservationFormat.present
|
||||
? data.preservationFormat.value
|
||||
: this.preservationFormat,
|
||||
priceAmount: data.priceAmount.present
|
||||
? data.priceAmount.value
|
||||
: this.priceAmount,
|
||||
priceCurrency: data.priceCurrency.present
|
||||
? data.priceCurrency.value
|
||||
: this.priceCurrency,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -3941,7 +4032,9 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
..write('originName: $originName, ')
|
||||
..write('originPlace: $originPlace, ')
|
||||
..write('abundance: $abundance, ')
|
||||
..write('preservationFormat: $preservationFormat')
|
||||
..write('preservationFormat: $preservationFormat, ')
|
||||
..write('priceAmount: $priceAmount, ')
|
||||
..write('priceCurrency: $priceCurrency')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
|
@ -3969,6 +4062,8 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
originPlace,
|
||||
abundance,
|
||||
preservationFormat,
|
||||
priceAmount,
|
||||
priceCurrency,
|
||||
]);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
|
|
@ -3994,7 +4089,9 @@ class Lot extends DataClass implements Insertable<Lot> {
|
|||
other.originName == this.originName &&
|
||||
other.originPlace == this.originPlace &&
|
||||
other.abundance == this.abundance &&
|
||||
other.preservationFormat == this.preservationFormat);
|
||||
other.preservationFormat == this.preservationFormat &&
|
||||
other.priceAmount == this.priceAmount &&
|
||||
other.priceCurrency == this.priceCurrency);
|
||||
}
|
||||
|
||||
class LotsCompanion extends UpdateCompanion<Lot> {
|
||||
|
|
@ -4019,6 +4116,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
final Value<String?> originPlace;
|
||||
final Value<Abundance?> abundance;
|
||||
final Value<PreservationFormat?> preservationFormat;
|
||||
final Value<double?> priceAmount;
|
||||
final Value<String?> priceCurrency;
|
||||
final Value<int> rowid;
|
||||
const LotsCompanion({
|
||||
this.id = const Value.absent(),
|
||||
|
|
@ -4042,6 +4141,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
this.originPlace = const Value.absent(),
|
||||
this.abundance = const Value.absent(),
|
||||
this.preservationFormat = const Value.absent(),
|
||||
this.priceAmount = const Value.absent(),
|
||||
this.priceCurrency = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
});
|
||||
LotsCompanion.insert({
|
||||
|
|
@ -4066,6 +4167,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
this.originPlace = const Value.absent(),
|
||||
this.abundance = const Value.absent(),
|
||||
this.preservationFormat = const Value.absent(),
|
||||
this.priceAmount = const Value.absent(),
|
||||
this.priceCurrency = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
}) : id = Value(id),
|
||||
createdAt = Value(createdAt),
|
||||
|
|
@ -4094,6 +4197,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
Expression<String>? originPlace,
|
||||
Expression<String>? abundance,
|
||||
Expression<String>? preservationFormat,
|
||||
Expression<double>? priceAmount,
|
||||
Expression<String>? priceCurrency,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
|
|
@ -4118,6 +4223,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
if (originPlace != null) 'origin_place': originPlace,
|
||||
if (abundance != null) 'abundance': abundance,
|
||||
if (preservationFormat != null) 'preservation_format': preservationFormat,
|
||||
if (priceAmount != null) 'price_amount': priceAmount,
|
||||
if (priceCurrency != null) 'price_currency': priceCurrency,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
|
|
@ -4144,6 +4251,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
Value<String?>? originPlace,
|
||||
Value<Abundance?>? abundance,
|
||||
Value<PreservationFormat?>? preservationFormat,
|
||||
Value<double?>? priceAmount,
|
||||
Value<String?>? priceCurrency,
|
||||
Value<int>? rowid,
|
||||
}) {
|
||||
return LotsCompanion(
|
||||
|
|
@ -4168,6 +4277,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
originPlace: originPlace ?? this.originPlace,
|
||||
abundance: abundance ?? this.abundance,
|
||||
preservationFormat: preservationFormat ?? this.preservationFormat,
|
||||
priceAmount: priceAmount ?? this.priceAmount,
|
||||
priceCurrency: priceCurrency ?? this.priceCurrency,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
|
|
@ -4250,6 +4361,12 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (priceAmount.present) {
|
||||
map['price_amount'] = Variable<double>(priceAmount.value);
|
||||
}
|
||||
if (priceCurrency.present) {
|
||||
map['price_currency'] = Variable<String>(priceCurrency.value);
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
}
|
||||
|
|
@ -4280,6 +4397,8 @@ class LotsCompanion extends UpdateCompanion<Lot> {
|
|||
..write('originPlace: $originPlace, ')
|
||||
..write('abundance: $abundance, ')
|
||||
..write('preservationFormat: $preservationFormat, ')
|
||||
..write('priceAmount: $priceAmount, ')
|
||||
..write('priceCurrency: $priceCurrency, ')
|
||||
..write('rowid: $rowid')
|
||||
..write(')'))
|
||||
.toString();
|
||||
|
|
@ -11663,6 +11782,8 @@ typedef $$LotsTableCreateCompanionBuilder =
|
|||
Value<String?> originPlace,
|
||||
Value<Abundance?> abundance,
|
||||
Value<PreservationFormat?> preservationFormat,
|
||||
Value<double?> priceAmount,
|
||||
Value<String?> priceCurrency,
|
||||
Value<int> rowid,
|
||||
});
|
||||
typedef $$LotsTableUpdateCompanionBuilder =
|
||||
|
|
@ -11688,6 +11809,8 @@ typedef $$LotsTableUpdateCompanionBuilder =
|
|||
Value<String?> originPlace,
|
||||
Value<Abundance?> abundance,
|
||||
Value<PreservationFormat?> preservationFormat,
|
||||
Value<double?> priceAmount,
|
||||
Value<String?> priceCurrency,
|
||||
Value<int> rowid,
|
||||
});
|
||||
|
||||
|
|
@ -11812,6 +11935,16 @@ class $$LotsTableFilterComposer extends Composer<_$AppDatabase, $LotsTable> {
|
|||
column: $table.preservationFormat,
|
||||
builder: (column) => ColumnWithTypeConverterFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<double> get priceAmount => $composableBuilder(
|
||||
column: $table.priceAmount,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get priceCurrency => $composableBuilder(
|
||||
column: $table.priceCurrency,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
}
|
||||
|
||||
class $$LotsTableOrderingComposer extends Composer<_$AppDatabase, $LotsTable> {
|
||||
|
|
@ -11926,6 +12059,16 @@ class $$LotsTableOrderingComposer extends Composer<_$AppDatabase, $LotsTable> {
|
|||
column: $table.preservationFormat,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<double> get priceAmount => $composableBuilder(
|
||||
column: $table.priceAmount,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get priceCurrency => $composableBuilder(
|
||||
column: $table.priceCurrency,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
}
|
||||
|
||||
class $$LotsTableAnnotationComposer
|
||||
|
|
@ -12030,6 +12173,16 @@ class $$LotsTableAnnotationComposer
|
|||
column: $table.preservationFormat,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<double> get priceAmount => $composableBuilder(
|
||||
column: $table.priceAmount,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<String> get priceCurrency => $composableBuilder(
|
||||
column: $table.priceCurrency,
|
||||
builder: (column) => column,
|
||||
);
|
||||
}
|
||||
|
||||
class $$LotsTableTableManager
|
||||
|
|
@ -12082,6 +12235,8 @@ class $$LotsTableTableManager
|
|||
Value<Abundance?> abundance = const Value.absent(),
|
||||
Value<PreservationFormat?> preservationFormat =
|
||||
const Value.absent(),
|
||||
Value<double?> priceAmount = const Value.absent(),
|
||||
Value<String?> priceCurrency = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => LotsCompanion(
|
||||
id: id,
|
||||
|
|
@ -12105,6 +12260,8 @@ class $$LotsTableTableManager
|
|||
originPlace: originPlace,
|
||||
abundance: abundance,
|
||||
preservationFormat: preservationFormat,
|
||||
priceAmount: priceAmount,
|
||||
priceCurrency: priceCurrency,
|
||||
rowid: rowid,
|
||||
),
|
||||
createCompanionCallback:
|
||||
|
|
@ -12131,6 +12288,8 @@ class $$LotsTableTableManager
|
|||
Value<Abundance?> abundance = const Value.absent(),
|
||||
Value<PreservationFormat?> preservationFormat =
|
||||
const Value.absent(),
|
||||
Value<double?> priceAmount = const Value.absent(),
|
||||
Value<String?> priceCurrency = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => LotsCompanion.insert(
|
||||
id: id,
|
||||
|
|
@ -12154,6 +12313,8 @@ class $$LotsTableTableManager
|
|||
originPlace: originPlace,
|
||||
abundance: abundance,
|
||||
preservationFormat: preservationFormat,
|
||||
priceAmount: priceAmount,
|
||||
priceCurrency: priceCurrency,
|
||||
rowid: rowid,
|
||||
),
|
||||
withReferenceMapper: (p0) => p0
|
||||
|
|
|
|||
|
|
@ -109,6 +109,17 @@ class Lots extends Table with SyncColumns {
|
|||
/// Distinct from [storageLocation]. Optional.
|
||||
TextColumn get preservationFormat =>
|
||||
textEnum<PreservationFormat>().nullable()();
|
||||
|
||||
/// Asking price when [offerStatus] is `sell` (data-model §2.8 puts price on
|
||||
/// the Offer; with offer state collapsed onto the Lot, it lives here and is
|
||||
/// published with the market offer). Informational only — money changes
|
||||
/// hands off-platform, never in-app. Null amount on a sell lot means
|
||||
/// "price to be agreed" (the offer publishes without a price).
|
||||
RealColumn get priceAmount => real().nullable()();
|
||||
|
||||
/// Free-text currency, like [Sales.currency]: "€", "Ğ1", a local/time
|
||||
/// currency. Never assumed (sharing-model §6).
|
||||
TextColumn get priceCurrency => text().nullable()();
|
||||
}
|
||||
|
||||
/// Optional germination history for a Lot; percent is derived in code.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue