usawa

Signed, immutable accounting.
Log | Files | Refs | Submodules | LICENSE

commit b08e50e439a155777010ee58f9d0a9f3f4583b10
parent e3badb6790fe44c9ed978a71e6417f95e6ed9c1a
Author: lash <dev@holbrook.no>
Date:   Tue, 31 Mar 2026 16:06:40 -0600

Merge branch 'carlos/set_entry_date' into dev-0.2.0

Diffstat:
Mdummy/usawa/gui/controllers/entry_controller.py | 16+++++++++-------
Mdummy/usawa/gui/core/models.py | 3++-
Mdummy/usawa/gui/views/create_entry_view.py | 2+-
Mdummy/usawa/gui/views/entry_list_view.py | 6+++++-
Mdummy/usawa/storage/entry_mapper.py | 12++++++------
Mdummy/usawa/storage/ledger_repository.py | 4++--
6 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/dummy/usawa/gui/controllers/entry_controller.py b/dummy/usawa/gui/controllers/entry_controller.py @@ -17,15 +17,19 @@ class EntryController: def collect_entry_data(self, view) -> Optional[LedgerEntry]: """Collect data from the view and create an entry""" - tx_date_str = view.date_entry.get_text().strip() tx_time_str = view.time_entry.get_text().strip() - try: if tx_time_str: - tx_date = datetime.strptime( - f"{tx_date_str} {tx_time_str}", "%Y-%m-%d %H:%M:%S" - ) + for fmt in ("%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M"): + try: + tx_date = datetime.strptime(f"{tx_date_str} {tx_time_str}", fmt) + break + except ValueError: + continue + else: + logg.error("Invalid time format, use H:MM or H:MM:SS") + return None else: tx_date = datetime.strptime(tx_date_str, "%Y-%m-%d").date() except ValueError: @@ -44,13 +48,11 @@ class EntryController: dest_type=view.get_dest_type(), dest_path=view.dest_path_entry.get_text().strip(), ) - is_valid, error_msg = entry.validate() if not is_valid: logg.error(f"Validation failed: {error_msg}") return None return entry - except ValueError as e: logg.error(f"Failed to collect entry data: {e}") return None diff --git a/dummy/usawa/gui/core/models.py b/dummy/usawa/gui/core/models.py @@ -6,7 +6,7 @@ from pathlib import Path @dataclass class LedgerEntry: - """DTO for ledger entry input, converted to usawa.Entry before adding to ledger.""" + """DTO for ledger entry input, converted to usawa.Entry""" # Basic details external_reference: Optional[str] = None @@ -14,6 +14,7 @@ class LedgerEntry: # Transaction details amount: float = 0.0 + precision: int = 0 source_unit: str = "" source_type: str = "" source_path: str = "general" diff --git a/dummy/usawa/gui/views/create_entry_view.py b/dummy/usawa/gui/views/create_entry_view.py @@ -166,7 +166,7 @@ class CreateEntryView(Gtk.Box): section_box.append(time_label) self.time_entry = Gtk.Entry() - self.time_entry.set_placeholder_text("HH:MM:SS") + self.time_entry.set_placeholder_text("H:MM or H:MM:SS") section_box.append(self.time_entry) # Amount diff --git a/dummy/usawa/gui/views/entry_list_view.py b/dummy/usawa/gui/views/entry_list_view.py @@ -612,6 +612,10 @@ class EntryListView(Gtk.Box): def _make_entry_item(self, entry) -> EntryItem: signers_raw = entry.signer_pubkeys signers_display = ", ".join([f"{k[:8]}...{k[-6:]}" for k in signers_raw]) + + raw = entry.amount / (10**entry.precision) + amount_display = f"{entry.source_unit} {raw:.{entry.precision}f}" + return EntryItem( serial=entry.serial, parent_digest=entry.parent_digest, @@ -620,7 +624,7 @@ class EntryListView(Gtk.Box): tx_date_rg=entry.date_registered, description=entry.description, auth_state="trusted", - amount=entry.amount, + amount=amount_display, source_path=entry.source_path, source_type=entry.source_type, source_unit=entry.source_unit, diff --git a/dummy/usawa/storage/entry_mapper.py b/dummy/usawa/storage/entry_mapper.py @@ -2,6 +2,7 @@ import logging from datetime import datetime, date from usawa.entry import Entry, EntryPart +from usawa.ledger import Ledger from usawa.unit import UnitIndex from ..gui.core.models import LedgerEntry from usawa import Entry, EntryPart @@ -72,11 +73,14 @@ class EntryMapper: return entry @staticmethod - def to_domain_entry(storage_entry) -> LedgerEntry: + def to_domain_entry(ledger: Ledger, storage_entry: Entry) -> LedgerEntry: """ Convert Entry (storage) to LedgerEntry (domain) """ + base = ledger.uidx.base + precision = ledger.uidx.detail[base] + source_unit = "" source_type = "" source_path = "" @@ -91,28 +95,23 @@ class EntryMapper: source_type = debit_part.typ source_path = debit_part.account amount = abs(float(debit_part.amount)) - is_debit = debit_part.isdebit else: source_unit = source_type = source_path = "" amount = 0.0 - is_debit = None if storage_entry.credit: credit_part = storage_entry.credit[0] dest_unit = credit_part.unit dest_type = credit_part.typ dest_path = credit_part.account - is_credit = credit_part.isdebit else: dest_unit = dest_type = dest_path = "" - is_credit = None parent_digest = parent_digest = storage_entry.parent.hex() tx_date = storage_entry.dt date_registered = storage_entry.dtreg - transaction_ref = str(storage_entry.ref) if storage_entry.ref else None external_ref = None signer_pubkeys = list(storage_entry.sigs.keys()) @@ -121,6 +120,7 @@ class EntryMapper: external_reference=external_ref, description=storage_entry.description, amount=amount, + precision=precision, source_unit=source_unit, source_type=source_type, source_path=source_path, diff --git a/dummy/usawa/storage/ledger_repository.py b/dummy/usawa/storage/ledger_repository.py @@ -156,9 +156,9 @@ class LedgerRepository: def get_all_entries(self) -> List[LedgerEntry]: """Get all entries""" try: - store, _, _ = self._init_store() + store, ledger, _ = self._init_store() return [ - EntryMapper.to_domain_entry(storage_entry) + EntryMapper.to_domain_entry(ledger=ledger, storage_entry=storage_entry) for _, storage_entry in store.ledger.entries.items() ] except Exception as e: