Complete export->import cycle

Add the transaction ID to the export of transactions and enable the
import of SplitTransactions. The ID should function as a stable
transaction identifier.
Fix tag import on transactions.
Fix rules import of date for DBs that need datetime.date format.
This commit is contained in:
Luís Murta 2023-05-16 20:09:22 +01:00
parent 42d84b02f4
commit 6574165f8f
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
2 changed files with 46 additions and 12 deletions

View File

@ -138,6 +138,7 @@ class Transaction(Base, Serializable):
} }
return dict( return dict(
id=self.id,
date=self.date.isoformat(), date=self.date.isoformat(),
description=self.description, description=self.description,
amount=str(self.amount), amount=str(self.amount),
@ -172,9 +173,9 @@ class Transaction(Base, Serializable):
tags: set[TransactionTag] = set() tags: set[TransactionTag] = set()
if map["tags"]: if map["tags"]:
tags = set(t["tag"] for t in map["tags"]) tags = set(TransactionTag(t["tag"]) for t in map["tags"])
return cls( result = cls(
dt.date.fromisoformat(map["date"]), dt.date.fromisoformat(map["date"]),
map["description"], map["description"],
map["amount"], map["amount"],
@ -184,6 +185,10 @@ class Transaction(Base, Serializable):
map["note"], map["note"],
) )
if map["id"]:
result.id = map["id"]
return result
def __lt__(self, other: Transaction): def __lt__(self, other: Transaction):
return self.date < other.date return self.date < other.date
@ -227,11 +232,15 @@ class SplitTransaction(Transaction):
__mapper_args__ = {"polymorphic_identity": "split", "polymorphic_load": "inline"} __mapper_args__ = {"polymorphic_identity": "split", "polymorphic_load": "inline"}
def serialize(self) -> Mapping[str, Any]: def serialize(self) -> Mapping[str, Any]:
raise AttributeError map = cast(MutableMapping[str, Any], super().serialize())
map["original"] = self.original
return map
@classmethod @classmethod
def deserialize(cls, map: Mapping[str, Any]) -> Self: def deserialize(cls, map: Mapping[str, Any]) -> Self:
raise AttributeError transaction = cls._deserialize(map)
transaction.original = map["original"]
return transaction
class CategoryGroup(Base, Serializable): class CategoryGroup(Base, Serializable):
@ -263,8 +272,8 @@ class Category(Base, Serializable, repr=False):
for rule in self.rules: for rule in self.rules:
rules.append( rules.append(
{ {
"start": rule.start, "start": rule.start.isoformat() if rule.start else None,
"end": rule.end, "end": rule.end.isoformat() if rule.end else None,
"description": rule.description, "description": rule.description,
"regex": rule.regex, "regex": rule.regex,
"bank": rule.bank, "bank": rule.bank,
@ -290,10 +299,24 @@ class Category(Base, Serializable, repr=False):
@classmethod @classmethod
def deserialize(cls, map: Mapping[str, Any]) -> Self: def deserialize(cls, map: Mapping[str, Any]) -> Self:
rules: list[CategoryRule] = []
for rule in map["rules"]:
rules.append(
CategoryRule(
dt.date.fromisoformat(rule["start"]) if rule["start"] else None,
dt.date.fromisoformat(rule["end"]) if rule["end"] else None,
rule["description"],
rule["regex"],
rule["bank"],
rule["min"],
rule["max"],
)
)
return cls( return cls(
map["name"], map["name"],
map["group"], map["group"],
list(CategoryRule(**r) for r in map["rules"]), rules,
CategorySchedule(**map["schedule"]) if map["schedule"] else None, CategorySchedule(**map["schedule"]) if map["schedule"] else None,
) )
@ -379,10 +402,21 @@ class Tag(Base, Serializable):
@classmethod @classmethod
def deserialize(cls, map: Mapping[str, Any]) -> Self: def deserialize(cls, map: Mapping[str, Any]) -> Self:
return cls( rules: list[TagRule] = []
map["name"], for rule in map["rules"]:
list(TagRule(**r) for r in map["rules"]), rules.append(
) TagRule(
dt.date.fromisoformat(rule["start"]) if rule["start"] else None,
dt.date.fromisoformat(rule["end"]) if rule["end"] else None,
rule["description"],
rule["regex"],
rule["bank"],
rule["min"],
rule["max"],
)
)
return cls(map["name"], rules)
class TransactionTag(Base, unsafe_hash=True): class TransactionTag(Base, unsafe_hash=True):

View File

@ -35,6 +35,7 @@ params = [
(transactions.bank, BankTransaction), (transactions.bank, BankTransaction),
(transactions.money, Transaction), (transactions.money, Transaction),
(transactions.money, MoneyTransaction), (transactions.money, MoneyTransaction),
(transactions.split, SplitTransaction),
([banks.checking, banks.cc], Bank), ([banks.checking, banks.cc], Bank),
([categories.category_null, categories.category1, categories.category2], Category), ([categories.category_null, categories.category1, categories.category2], Category),
( (
@ -50,7 +51,6 @@ params = [
] ]
not_serializable = [ not_serializable = [
(transactions.split, SplitTransaction),
(transactions.simple_transformed, TransactionCategory), (transactions.simple_transformed, TransactionCategory),
(transactions.tagged, TransactionTag), (transactions.tagged, TransactionTag),
(transactions.noted, Note), (transactions.noted, Note),