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
|
|
@ -78,6 +78,7 @@ class TranslationsPt extends Translations with BaseTranslations<AppLocale, Trans
|
|||
@override late final _Translations$wot$pt wot = _Translations$wot$pt._(_root);
|
||||
@override late final _Translations$notifications$pt notifications = _Translations$notifications$pt._(_root);
|
||||
@override late final _Translations$plantare$pt plantare = _Translations$plantare$pt._(_root);
|
||||
@override late final _Translations$sale$pt sale = _Translations$sale$pt._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
|
|
@ -160,6 +161,7 @@ class _Translations$menu$pt extends Translations$menu$en {
|
|||
@override String get wishlist => 'Lista de desejos';
|
||||
@override String get following => 'A seguir';
|
||||
@override String get plantares => 'Plantares';
|
||||
@override String get sales => 'Vendas';
|
||||
@override String get settings => 'Definições';
|
||||
}
|
||||
|
||||
|
|
@ -838,6 +840,31 @@ class _Translations$plantare$pt extends Translations$plantare$en {
|
|||
@override String get removeConfirm => 'Remover este compromisso?';
|
||||
}
|
||||
|
||||
// Path: sale
|
||||
class _Translations$sale$pt extends Translations$sale$en {
|
||||
_Translations$sale$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsPt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Vendas';
|
||||
@override String get help => 'Regista semente vendida ou comprada — dinheiro, Ğ1 ou qualquer moeda. Um modelo separado do presente e do Plantare. Nunca se cobra comissão pelas sementes.';
|
||||
@override String get add => 'Registar venda';
|
||||
@override String get empty => 'Ainda não há vendas. Anota aqui o que vendes ou compras.';
|
||||
@override String get iSold => 'Vendi';
|
||||
@override String get iBought => 'Comprei';
|
||||
@override String get direction => 'Vendes ou compras?';
|
||||
@override String get counterparty => 'Com quem?';
|
||||
@override String get counterpartyHint => 'Uma pessoa ou um coletivo (opcional)';
|
||||
@override String get amount => 'Montante';
|
||||
@override String get currency => 'Moeda';
|
||||
@override String get currencyHint => '€, Ğ1, horas… (opcional)';
|
||||
@override String get note => 'Nota (opcional)';
|
||||
@override String get save => 'Guardar';
|
||||
@override String get delete => 'Remover';
|
||||
@override String get removeConfirm => 'Remover esta venda?';
|
||||
}
|
||||
|
||||
// Path: intro.slides
|
||||
class _Translations$intro$slides$pt extends Translations$intro$slides$en {
|
||||
_Translations$intro$slides$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
|
@ -1207,6 +1234,7 @@ extension on TranslationsPt {
|
|||
'menu.wishlist' => 'Lista de desejos',
|
||||
'menu.following' => 'A seguir',
|
||||
'menu.plantares' => 'Plantares',
|
||||
'menu.sales' => 'Vendas',
|
||||
'menu.settings' => 'Definições',
|
||||
'settings.language' => 'Idioma',
|
||||
'settings.systemLanguage' => 'Idioma do sistema',
|
||||
|
|
@ -1617,6 +1645,22 @@ extension on TranslationsPt {
|
|||
'plantare.openSection' => 'Pendentes',
|
||||
'plantare.settledSection' => 'Feitos',
|
||||
'plantare.removeConfirm' => 'Remover este compromisso?',
|
||||
'sale.title' => 'Vendas',
|
||||
'sale.help' => 'Regista semente vendida ou comprada — dinheiro, Ğ1 ou qualquer moeda. Um modelo separado do presente e do Plantare. Nunca se cobra comissão pelas sementes.',
|
||||
'sale.add' => 'Registar venda',
|
||||
'sale.empty' => 'Ainda não há vendas. Anota aqui o que vendes ou compras.',
|
||||
'sale.iSold' => 'Vendi',
|
||||
'sale.iBought' => 'Comprei',
|
||||
'sale.direction' => 'Vendes ou compras?',
|
||||
'sale.counterparty' => 'Com quem?',
|
||||
'sale.counterpartyHint' => 'Uma pessoa ou um coletivo (opcional)',
|
||||
'sale.amount' => 'Montante',
|
||||
'sale.currency' => 'Moeda',
|
||||
'sale.currencyHint' => '€, Ğ1, horas… (opcional)',
|
||||
'sale.note' => 'Nota (opcional)',
|
||||
'sale.save' => 'Guardar',
|
||||
'sale.delete' => 'Remover',
|
||||
'sale.removeConfirm' => 'Remover esta venda?',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue