jman <emacs-orgm...@city17.xyz> writes:

> --8<---------------cut here---------------start------------->8---
> #+PROPERTY: INVOICE_STATUS "TO_BE_SENT SENT TO_BE_PAID PAID"
>
> | Invoice Date     | Invoice # | Amount | Status     |
> |------------------+-----------+--------+------------|
> | [2025-03-02 Sun] | CL161     |     10 | TO_BE_SENT |
>
> --8<---------------cut here---------------end--------------->8---
>
> Is there a way to edit a cell cycling these values? A bit like I can
> cycle values in `org-todo-keywords` with S-left/S-right

I see you've already coded up a solution that does what you want, cycle
through a custom sequence in a table cell. That's neat, and I can think
of all sorts of uses for it.

For this particular use case, though, have you considered a different
approach, using entries and column view? That is:

- Make an entry for each invoice with your data as entry properties
  (you'll want to define a capture template for this)
- Define a column view for the properties
- Use column view (C-c C-x C-c) to get a tabular view
- With point on a status cell, press `n' or S-right to cycle to next
  status in the sequence, and `p' or S-left to cycle back

I prefer a separate entry for each invoice, since entries can hold
arbitrary additional information (links, itemized costs, reminders), but
their properties can always be viewed as a table and extracted to a
table.

With your example, a minimal setup could be:

--8<---------------cut here---------------start------------->8---

* Invoices
  :PROPERTIES:
  :COLUMNS:  %DATE(Invoice Date) %NO(Invoice #) %AMOUNT(Amount) %STATUS(Status)
  :Status_ALL: "TO_BE_SENT" "SENT" "TO_BE_PAID" "PAID"
  :END:

** Invoice CL161
   :PROPERTIES:
   :Date: [2025-03-02 Sun]
   :No: CL161
   :Amount:   10
   :Status:   TO_BE_SENT
   :END:

   More notes on the invoice here

--8<---------------cut here---------------end--------------->8---

You can also cycle through the statuses with point on the property in
the entry itself.

For a nice table that you can manipulate and print, you can add a
columnview dynamic block. For instance, place these begin/end lines
under the Invoices headline above and update the block manually by
pressing C-c with point on the BEGIN line:

  #+BEGIN: columnview :id local :match "LEVEL=2"
  #+END:

However, you cannot use the generated table in the dynamic block to
cycle through statuses and update the underlying entry.

An alternative to defining a STATUS property at all would be to define the
statuses as local TODO keywords, which gives you a quick way to look up
all unsent or unpaid invoices via the agenda view without having to
write match syntax.

Yours,
Christian

Reply via email to