Method

book.replayJournal

Replay a GnuCash .log journal onto the open book: create, update or delete transactions by GUID.

Replays a GnuCash .log journal onto the open book: each record creates, updates or deletes a transaction by GUID. Use it to recover work from a journal after a crash, by replaying the journal of the book you lost onto the last saved file. created, updated and deleted list the GUIDs touched; notFound lists records whose transaction was not there to update or delete.

Replaying is journaled like any other change, and it changes transactions only, not accounts: records that need an account the book lacks are refused unless skipInvalid is true, which skips them and lists them in skippedRecords. The file is read on the server, so path is relative to where it runs.

Examples

The journal of an open book is the journal field of book.info. A path that does not exist fails with io-error, and nothing is changed:

Example: with a copy of the reports/test-data example book open as book.gnucash.

JSON-RPC

Request:

{"jsonrpc":"2.0","id":1,"method":"book.replayJournal","params":{"path":"missing.log"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": 1008,
    "message": "…",
    "data": {
      "path": "…",
      "help": "error/io-error"
    }
  }
}

Command line

red-ale exec --book book.gnucash book.replayJournal '{"path":"missing.log"}'

It fails with exit status 2, printing on standard error:

{
  "error": {
    "code": 1008,
    "message": "…",
    "data": {
      "path": "…",
      "help": "error/io-error"
    }
  }
}

MCP tool call

Tool call:

{"name":"book.replayJournal","arguments":{"path":"missing.log"}}

Result:

{
  "isError": true,
  "structuredContent": {
    "error": {
      "code": 1008,
      "name": "io-error",
      "message": "…",
      "data": {
        "path": "…",
        "help": "error/io-error"
      }
    }
  }
}

A transaction posted and then lost, because the book was closed without saving, comes back from the journal. The journal is named by the local time it was opened at, here book.gnucash.20240701120000.log:

Example: with a new, empty book open as book.gnucash, at 2024-07-01T12:00:00Z.

JSON-RPC

Request:

{"jsonrpc":"2.0","id":1,"method":"account.create","params":{"name":"Checking","type":"BANK","commodity":"USD"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "…"
}

Request:

{"jsonrpc":"2.0","id":2,"method":"account.create","params":{"name":"Rent","type":"EXPENSE","commodity":"USD"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": "…"
}

Request:

{"jsonrpc":"2.0","id":3,"method":"book.save","params":{}}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": "…"
}

Request:

{"jsonrpc":"2.0","id":4,"method":"transaction.post","params":{"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}}

Response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "guid": "…",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":5,"method":"book.close","params":{"discard":true}}

Response:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": "…"
}

Request:

{"jsonrpc":"2.0","id":6,"method":"book.open","params":{"path":"book.gnucash"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "counts": {
      "transactions": 0,
      "…": "…"
    },
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":7,"method":"book.replayJournal","params":{"path":"book.gnucash.20240701120000.log"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "created": [
      "…"
    ],
    "updated": [],
    "deleted": [],
    "notFound": [],
    "…": "…"
  }
}

Command line

red-ale exec --book book.gnucash --script - <<'EOF'
account.create {"name":"Checking","type":"BANK","commodity":"USD"}
account.create {"name":"Rent","type":"EXPENSE","commodity":"USD"}
book.save {}
transaction.post {"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}
book.close {"discard":true}
book.open {"path":"book.gnucash"}
book.replayJournal {"path":"book.gnucash.20240701120000.log"}
EOF

It prints:

[
  "…",
  "…",
  "…",
  {
    "guid": "…",
    "…": "…"
  },
  "…",
  {
    "counts": {
      "transactions": 0,
      "…": "…"
    },
    "…": "…"
  },
  {
    "created": [
      "…"
    ],
    "updated": [],
    "deleted": [],
    "notFound": [],
    "…": "…"
  }
]

MCP tool call

Tool call:

{"name":"account.create","arguments":{"name":"Checking","type":"BANK","commodity":"USD"}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "\"…\""
    }
  ]
}

Tool call:

{"name":"account.create","arguments":{"name":"Rent","type":"EXPENSE","commodity":"USD"}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "\"…\""
    }
  ]
}

Tool call:

{"name":"book.save","arguments":{}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "\"…\""
    }
  ]
}

Tool call:

{"name":"transaction.post","arguments":{"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}}

Result:

{
  "structuredContent": {
    "guid": "…",
    "…": "…"
  }
}

Tool call:

{"name":"book.close","arguments":{"discard":true}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "\"…\""
    }
  ]
}

Tool call:

{"name":"book.open","arguments":{"path":"book.gnucash"}}

Result:

{
  "structuredContent": {
    "counts": {
      "transactions": 0,
      "…": "…"
    },
    "…": "…"
  }
}

Tool call:

{"name":"book.replayJournal","arguments":{"path":"book.gnucash.20240701120000.log"}}

Result:

{
  "structuredContent": {
    "created": [
      "…"
    ],
    "updated": [],
    "deleted": [],
    "notFound": [],
    "…": "…"
  }
}

Effect: write, on the Book.

Params

Params of book.replayJournal.

  • path (string, required): The journal: a <book>.<timestamp>.log file.
  • skipInvalid (boolean): Skip records that cannot be applied (for example an unbalanced transaction) instead of refusing the replay.

Result

What book.replayJournal did.

  • records (integer (uint), required): Records read.
  • created (array of Guid, required): Transactions created.
  • updated (array of Guid, required): Transactions updated.
  • deleted (array of Guid, required): Transactions deleted.
  • notFound (array of Guid, required): Deletions of transactions the book does not have.
  • skippedRecords (array of string, required): Records skipped, with why.
  • skippedLines (array of string, required): Lines that could not be read, as line N: reason.