feat: support manual dividend ledger entries

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-09 02:04:02 +00:00
committed by GitHub
co-authored by genichin
parent 9d2c2aea5f
commit ccde81b7a0
6 changed files with 281 additions and 12 deletions
+25 -2
View File
@@ -148,6 +148,7 @@ ManualLedgerAction = Literal[
"SELL",
"WITHDRAW",
"PROFIT",
"DIVIDEND",
"REVERSAL",
]
@@ -161,9 +162,11 @@ class ManualLedgerRequest(BaseModel):
price: Decimal | None = Field(default=None, gt=0)
fee: Decimal = Field(default=Decimal("0"), ge=0)
tax: Decimal = Field(default=Decimal("0"), ge=0)
executed_at: date | None = None
target_ledger_entry_id: int | None = None
note: str = ""
confirm_daemon_managed_manual_write: bool = False
confirm_duplicate: bool = False
confirmation_evidence: str | None = None
@model_validator(mode="after")
@@ -172,6 +175,9 @@ class ManualLedgerRequest(BaseModel):
trade_actions = {"BUY", "SELL"}
provided_fields = self.model_fields_set
fee_or_tax_provided = "fee" in provided_fields or "tax" in provided_fields
fee_provided = "fee" in provided_fields
executed_at_provided = "executed_at" in provided_fields
confirm_duplicate_provided = "confirm_duplicate" in provided_fields and self.confirm_duplicate
if self.action in amount_actions:
if self.amount is None:
raise ValueError("amount is required for this action")
@@ -180,17 +186,33 @@ class ManualLedgerRequest(BaseModel):
or self.price is not None
or self.target_ledger_entry_id is not None
or fee_or_tax_provided
or executed_at_provided
or confirm_duplicate_provided
):
raise ValueError("unexpected numeric/target field for amount action")
elif self.action == "DIVIDEND":
if self.amount is None:
raise ValueError("amount is required for this action")
if self.executed_at is None:
raise ValueError("executed_at is required for DIVIDEND")
if self.quantity is not None or self.price is not None or self.target_ledger_entry_id is not None or fee_provided:
raise ValueError("unexpected numeric/target field for DIVIDEND")
elif self.action in trade_actions:
if self.quantity is None or self.price is None:
raise ValueError("quantity and price are required for BUY/SELL")
if self.amount is not None or self.target_ledger_entry_id is not None:
if self.amount is not None or self.target_ledger_entry_id is not None or executed_at_provided or confirm_duplicate_provided:
raise ValueError("unexpected amount/target field for BUY/SELL")
elif self.action == "REVERSAL":
if self.target_ledger_entry_id is None:
raise ValueError("target_ledger_entry_id is required for REVERSAL")
if self.amount is not None or self.quantity is not None or self.price is not None or fee_or_tax_provided:
if (
self.amount is not None
or self.quantity is not None
or self.price is not None
or fee_or_tax_provided
or executed_at_provided
or confirm_duplicate_provided
):
raise ValueError("unexpected numeric field for REVERSAL")
return self
@@ -204,6 +226,7 @@ class ManualLedgerResponse(BaseModel):
price: float = 0.0
fee: float = 0.0
tax: float = 0.0
executed_at: datetime | None = None
note: str = ""
recorded_at: datetime | None = None
cash_balance_after: float = 0.0