usawa

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

entry_service.py (2036B)


      1 import logging
      2 from datetime import datetime
      3 import uuid
      4 
      5 from .models import LedgerEntry
      6 from usawa.storage.ledger_repository import LedgerRepository
      7 
      8 logg = logging.getLogger("core.entry_service")
      9 
     10 
     11 class EntryService:
     12 
     13     def __init__(self, repository: LedgerRepository):
     14         self.repository = repository
     15 
     16     def save_entry(self, entry: LedgerEntry) -> tuple[bool, str]:
     17         entry.date_registered = datetime.now()
     18         entry.transaction_ref = str(uuid.uuid4())
     19 
     20         is_valid, error_msg = entry.validate()
     21         if not is_valid:
     22             logg.error(f"Entry validation failed: {error_msg}")
     23             return False, error_msg
     24 
     25         try:
     26             self.repository.save(entry)
     27         except (FileExistsError, ValueError, IOError, Exception) as e:
     28             error_msg = self._error_message_for(e)
     29             logg.error(
     30                 f"Save failed: {e}",
     31                 exc_info=not isinstance(e, (FileExistsError, ValueError, IOError)),
     32             )
     33             return False, error_msg
     34 
     35         logg.info("Entry saved successfully")
     36         return True, ""
     37 
     38     def _error_message_for(self, e: Exception) -> str:
     39         if isinstance(e, FileExistsError):
     40             return (
     41                 "Some file information for this entry is already recorded in the ledger"
     42             )
     43         if isinstance(e, ValueError):
     44             return f"Invalid entry data: {e}"
     45         if isinstance(e, IOError):
     46             return f"File error: {e}"
     47         return f"Failed to save entry: {e}"
     48 
     49     def get_all_entries(self):
     50         return self.repository.get_all_entries()
     51 
     52     def get_asset_bytes(self, digest: bytes) -> bytes:
     53         return self.repository.get_asset_bytes(digest=digest)
     54 
     55     def export_all_entries_to_xml(self, output_path: str) -> tuple[bool, str]:
     56         return self.repository.export_all_entries_to_xml(output_path=output_path)
     57 
     58     def export_entry_to_xml(self, serial: int, output_path: str) -> tuple[bool, str]:
     59         return self.repository.export_entry_to_xml(serial, output_path)