Rejects pending expense entries by voiding them
Instead of deleting pending expense entries, marks them as voided by adding a #voided tag. This ensures an audit trail while excluding them from balances. Updates the Fava client to use 'params' for the delete request.
This commit is contained in:
parent
cfca10b782
commit
1362ada362
2 changed files with 39 additions and 7 deletions
|
|
@ -652,7 +652,7 @@ class FavaClient:
|
|||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
response = await client.delete(
|
||||
f"{self.base_url}/source_slice",
|
||||
json={
|
||||
params={
|
||||
"entry_hash": entry_hash,
|
||||
"sha256sum": sha256sum
|
||||
}
|
||||
|
|
|
|||
44
views_api.py
44
views_api.py
|
|
@ -2017,7 +2017,10 @@ async def api_reject_expense_entry(
|
|||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
) -> dict:
|
||||
"""
|
||||
Reject a pending expense entry by deleting it from the Beancount file (admin only).
|
||||
Reject a pending expense entry by marking it as voided (admin only).
|
||||
|
||||
Adds #voided tag for audit trail while keeping the '!' flag.
|
||||
Voided transactions are excluded from balances but preserved in the ledger.
|
||||
"""
|
||||
from lnbits.settings import settings as lnbits_settings
|
||||
from .fava_client import get_fava_client
|
||||
|
|
@ -2058,18 +2061,47 @@ async def api_reject_expense_entry(
|
|||
detail=f"Pending entry {entry_id} not found in Beancount ledger"
|
||||
)
|
||||
|
||||
# 3. Get the entry context for sha256sum
|
||||
# 3. Get the entry context (source text + sha256sum)
|
||||
context = await fava.get_entry_context(target_entry_hash)
|
||||
source = context.get("slice", "")
|
||||
sha256sum = context.get("sha256sum", "")
|
||||
|
||||
# 4. Delete the entry
|
||||
result = await fava.delete_entry(target_entry_hash, sha256sum)
|
||||
if not source:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail="Could not retrieve entry source from Fava"
|
||||
)
|
||||
|
||||
# 4. Add #voided tag (keep ! flag as per convention)
|
||||
date_str = target_entry.get("date", "")
|
||||
|
||||
# Add #voided tag if not already present
|
||||
if "#voided" not in source:
|
||||
# Find the transaction line and add #voided to the tags
|
||||
# Pattern: date ! "narration" #existing-tags
|
||||
lines = source.split('\n')
|
||||
for i, line in enumerate(lines):
|
||||
if date_str in line and '"' in line and '!' in line:
|
||||
# Add #voided tag to the transaction line
|
||||
if '#' in line:
|
||||
# Already has tags, append voided
|
||||
lines[i] = line.rstrip() + ' #voided'
|
||||
else:
|
||||
# No tags yet, add after narration
|
||||
lines[i] = line.rstrip() + ' #voided'
|
||||
break
|
||||
new_source = '\n'.join(lines)
|
||||
else:
|
||||
new_source = source
|
||||
|
||||
# 5. Update the entry via Fava API
|
||||
await fava.update_entry_source(target_entry_hash, new_source, sha256sum)
|
||||
|
||||
return {
|
||||
"message": f"Entry {entry_id} rejected and deleted successfully",
|
||||
"message": f"Entry {entry_id} rejected (marked as voided)",
|
||||
"entry_id": entry_id,
|
||||
"entry_hash": target_entry_hash,
|
||||
"date": target_entry.get("date", ""),
|
||||
"date": date_str,
|
||||
"description": target_entry.get("narration", "")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue