feat(sales): local sales/purchase ledger (any currency)
A sale is a distinct model from a gift or a Plantare (reproduction
commitment): a recorded seed sale or purchase with an optional price in
ANY currency — €, Ğ1, time, or none yet. Mirrors the Plantare feature.
- schema v10: Sales table (SyncColumns), guarded createTable migration,
schema dump + generated schema_v10 for the migration round-trip test
- enum SaleDirection { iSold, iBought }
- VarietyRepository: create/watch/watchForVariety/delete + backup
export/exportForSync/import (LWW-by-HLC, tombstones)
- InventorySnapshot.sales + JSON codec encode/decode (round-trips amount,
currency, counterparty)
- UI: SalesScreen (/sales), sale sheet, drawer entry, variety-detail
action beside 'add Plantare'; money hides a trailing .0
- i18n sale block + menu.sales in en/es/pt/ast
- tests: sales repo test (5) incl. Ğ1/price-less/backup round-trip;
Sales screen added to the small-screen overflow guard
Also harden the overflow guard: swallow the headless engine's image
resource service PNG-decode errors (unrelated to layout) while still
failing on real RenderFlex overflows, so home/about stop reporting
false failures.
This commit is contained in:
parent
de6938d5d7
commit
6de039d518
27 changed files with 6156 additions and 23 deletions
|
|
@ -23,6 +23,7 @@ part 'database.g.dart';
|
|||
Attachments,
|
||||
ExternalLinks,
|
||||
Plantares,
|
||||
Sales,
|
||||
],
|
||||
)
|
||||
class AppDatabase extends _$AppDatabase {
|
||||
|
|
@ -30,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 = 9;
|
||||
static const int currentSchemaVersion = 10;
|
||||
|
||||
@override
|
||||
int get schemaVersion => currentSchemaVersion;
|
||||
|
|
@ -146,6 +147,12 @@ class AppDatabase extends _$AppDatabase {
|
|||
await m.createTable(plantares);
|
||||
}
|
||||
}
|
||||
// v10: Sales — recorded seed sales (separate from gift/Plantare). Guarded.
|
||||
if (from < 10) {
|
||||
if (!await _hasTable('sales')) {
|
||||
await m.createTable(sales);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -101,3 +101,8 @@ enum PlantareDirection {
|
|||
/// Lifecycle of a Plantare. Framed as a promise, not a debt (data-model §2.7):
|
||||
/// `forgiven` (not "defaulted") when it's let go.
|
||||
enum PlantareStatus { open, returned, forgiven }
|
||||
|
||||
/// Direction of a recorded seed Sale, seen from this app's owner. A sale is a
|
||||
/// SEPARATE model from a gift or a Plantare — seed for money (any currency:
|
||||
/// €, Ğ1, a local/time currency…). No commission is ever taken on seeds.
|
||||
enum SaleDirection { iSold, iBought }
|
||||
|
|
|
|||
|
|
@ -212,6 +212,34 @@ class Plantares extends Table with SyncColumns {
|
|||
TextColumn get note => text().nullable()();
|
||||
}
|
||||
|
||||
/// A recorded seed Sale — seed for money (data-model §2.8/sharing-model §6). A
|
||||
/// SEPARATE model from a gift or a Plantare: a completed exchange with a price
|
||||
/// in ANY currency (€, Ğ1, a local/time currency). Local-first ledger; the
|
||||
/// cross-party/receipt form is a later social-layer concern.
|
||||
class Sales extends Table with SyncColumns {
|
||||
/// The seed sold/bought. Nullable so a sale can be jotted before it's linked
|
||||
/// to a catalogued variety.
|
||||
TextColumn get varietyId => text().nullable()(); // → Variety
|
||||
|
||||
/// Whether I sold or I bought.
|
||||
TextColumn get direction => textEnum<SaleDirection>()();
|
||||
|
||||
/// The other party as a human name (v1).
|
||||
TextColumn get counterparty => text().nullable()();
|
||||
|
||||
/// Price paid. Nullable — a barter-ish "sale" recorded before a figure is set.
|
||||
RealColumn get amount => real().nullable()();
|
||||
|
||||
/// The currency, free text: "€", "Ğ1", "horas", a local currency name. Never
|
||||
/// assumed — the seed world uses many (sharing-model §6).
|
||||
TextColumn get currency => text().nullable()();
|
||||
|
||||
/// When the sale happened (ms since epoch).
|
||||
IntColumn get soldOn => integer()();
|
||||
|
||||
TextColumn get note => text().nullable()();
|
||||
}
|
||||
|
||||
/// Any pasted URL (Wikipedia, forum…). Polymorphic parent.
|
||||
class ExternalLinks extends Table with SyncColumns {
|
||||
TextColumn get parentType => textEnum<ParentType>()();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue