Skip to content

Commit 8eac11a

Browse files
jakeschepisclaude
andcommitted
feat: add credit notes, tracking, journals, purchase orders, budgets, overpayments, prepayments, quotes, and tax rates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 302c35d commit 8eac11a

31 files changed

Lines changed: 2485 additions & 100 deletions

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
This release closes the full Xero Accounting API gap, adding credit notes, tracking categories, manual journals, purchase orders, budgets, overpayments, prepayments, quotes, tax rates, and five new financial reports.
11+
12+
### Added
13+
- `xero credit-notes` — list (auto-paginated), get, create, apply against invoice (`--credit-note-id`, `--invoice-id`, `--amount`)
14+
- `xero tracking` — list, get, create tracking categories; `option add` to add category options
15+
- `xero journals` — list (auto-paginated), get, create manual journals
16+
- `xero journal-ledger` — list journal ledger entries with offset-based pagination (read-only audit trail)
17+
- `xero po` — list (auto-paginated), get, create purchase orders
18+
- `xero budgets` — list and get budgets (read-only; created in Xero UI)
19+
- `xero overpayments` — list (auto-paginated), apply against invoice
20+
- `xero prepayments` — list (auto-paginated), apply against invoice
21+
- `xero quotes` — list (auto-paginated), get, create, convert to invoice
22+
- `xero tax-rates list` — list tax rates (reference data)
23+
- `xero reports cash-flow` — Cash Flow Summary report
24+
- `xero reports budget-variance` — Budget Variance report (`--budget-id` required)
25+
- `xero reports account-transactions` — Account Transactions report (`--account-code` required)
26+
- `xero reports executive-summary` — Executive Summary report
27+
- `xero reports bank-summary` — Bank Summary report
28+
- `--tracking-category` and `--tracking-option` flags on `xero reports profit-loss` for segment filtering
29+
1030
## [0.2.0] - 2026-02-20
1131

1232
This release introduces the Cloudflare Worker auth proxy, which removes the Xero `client_secret` from the CLI binary entirely. Authentication is now gated through the Zeus Electron app — users cannot run `xero auth login` directly without being authorised through Zeus first.

README.md

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,108 @@ xero payments get <id> # Get a payment
112112
xero payments create # Apply a payment to an invoice
113113
```
114114

115+
### Credit Notes
116+
117+
```bash
118+
xero credit-notes list # List credit notes
119+
xero credit-notes get <id> # Get a credit note by ID
120+
xero credit-notes create # Create a credit note
121+
xero credit-notes apply # Apply a credit note against an invoice
122+
```
123+
124+
Flags: `--status`, `--type`, `--page`, `--org`, `--all-orgs`
125+
126+
### Tracking Categories
127+
128+
```bash
129+
xero tracking list # List tracking categories
130+
xero tracking get <id> # Get a tracking category
131+
xero tracking create # Create a tracking category
132+
xero tracking option add <id> # Add an option to a category
133+
```
134+
135+
### Manual Journals
136+
137+
```bash
138+
xero journals list # List manual journals
139+
xero journals get <id> # Get a manual journal
140+
xero journals create # Create a manual journal
141+
```
142+
143+
Flags: `--from`, `--to`, `--page`
144+
145+
### Journal Ledger
146+
147+
```bash
148+
xero journal-ledger list # List journal ledger entries (audit trail)
149+
```
150+
151+
Flags: `--from`, `--to`, `--offset` (0 = fetch all)
152+
153+
### Purchase Orders
154+
155+
```bash
156+
xero po list # List purchase orders
157+
xero po get <id> # Get a purchase order
158+
xero po create # Create a purchase order
159+
```
160+
161+
Flags: `--status`, `--page`, `--org`, `--all-orgs`
162+
163+
### Budgets
164+
165+
```bash
166+
xero budgets list # List budgets
167+
xero budgets get <id> # Get a budget by ID
168+
```
169+
170+
### Overpayments & Prepayments
171+
172+
```bash
173+
xero overpayments list # List overpayments
174+
xero overpayments apply # Apply an overpayment against an invoice
175+
xero prepayments list # List prepayments
176+
xero prepayments apply # Apply a prepayment against an invoice
177+
```
178+
179+
Flags: `--page`, `--org`, `--all-orgs`
180+
181+
### Quotes
182+
183+
```bash
184+
xero quotes list # List quotes
185+
xero quotes get <id> # Get a quote by ID
186+
xero quotes create # Create a quote
187+
xero quotes convert <id> # Convert a quote to an invoice
188+
```
189+
190+
Flags: `--status`, `--page`, `--org`, `--all-orgs`
191+
192+
### Tax Rates
193+
194+
```bash
195+
xero tax-rates list # List tax rates (reference data)
196+
```
197+
115198
### Reports
116199

117200
```bash
118-
xero reports profit-loss # Profit & Loss
119-
xero reports balance-sheet # Balance Sheet
120-
xero reports trial-balance # Trial Balance
121-
xero reports aged-receivables # Aged Receivables
122-
xero reports aged-payables # Aged Payables
201+
xero reports profit-loss # Profit & Loss
202+
xero reports balance-sheet # Balance Sheet
203+
xero reports trial-balance # Trial Balance
204+
xero reports aged-receivables # Aged Receivables
205+
xero reports aged-payables # Aged Payables
206+
xero reports cash-flow # Cash Flow Summary
207+
xero reports budget-variance # Budget Variance
208+
xero reports account-transactions # Account Transactions
209+
xero reports executive-summary # Executive Summary
210+
xero reports bank-summary # Bank Summary
123211
```
124212

125213
Flags: `--from`, `--to`, `--org`, `--all-orgs`
126214

215+
The `profit-loss` report also supports `--tracking-category` and `--tracking-option` to filter by tracking segment.
216+
127217
### Bank
128218

129219
```bash

internal/cli/commands/auth.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,3 @@ func newAuthRefreshCmd(format *string) *cobra.Command {
114114
},
115115
}
116116
}
117-

internal/cli/commands/budgets.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package commands
2+
3+
import (
4+
"github.com/jakeschepis/zeus-cli/pkg/output"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
// NewBudgetsCmd returns the budgets command group.
9+
func NewBudgetsCmd(format *string, org *string) *cobra.Command {
10+
cmd := &cobra.Command{
11+
Use: "budgets",
12+
Short: "View Xero budgets",
13+
}
14+
cmd.AddCommand(
15+
newBudgetsListCmd(format, org),
16+
newBudgetsGetCmd(format, org),
17+
)
18+
return cmd
19+
}
20+
21+
func newBudgetsListCmd(format *string, org *string) *cobra.Command {
22+
return &cobra.Command{
23+
Use: "list",
24+
Short: "List budgets",
25+
RunE: func(cmd *cobra.Command, args []string) error {
26+
client, _, err := getClientForOrg(*org)
27+
if err != nil {
28+
return err
29+
}
30+
budgets, err := client.ListBudgets()
31+
if err != nil {
32+
return err
33+
}
34+
return output.Print(budgets, output.Format(*format))
35+
},
36+
}
37+
}
38+
39+
func newBudgetsGetCmd(format *string, org *string) *cobra.Command {
40+
return &cobra.Command{
41+
Use: "get <budget-id>",
42+
Short: "Get a budget by ID",
43+
Args: cobra.ExactArgs(1),
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
client, _, err := getClientForOrg(*org)
46+
if err != nil {
47+
return err
48+
}
49+
budget, err := client.GetBudget(args[0])
50+
if err != nil {
51+
return err
52+
}
53+
return output.Print(budget, output.Format(*format))
54+
},
55+
}
56+
}

internal/cli/commands/contacts.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ func newContactsListCmd(format *string, org *string) *cobra.Command {
5252

5353
func newContactsGetCmd(format *string, org *string) *cobra.Command {
5454
return &cobra.Command{
55-
Use: "get <contact-id>",
55+
Use: "get <contact-id>",
5656
Short: "Get a single contact by ID",
57-
Args: cobra.ExactArgs(1),
57+
Args: cobra.ExactArgs(1),
5858
RunE: func(cmd *cobra.Command, args []string) error {
5959
client, _, err := getClientForOrg(*org)
6060
if err != nil {
@@ -109,16 +109,16 @@ func newContactsCreateCmd(format *string, org *string) *cobra.Command {
109109
cmd.Flags().StringVar(&taxNumber, "tax-number", "", "Tax/VAT number")
110110
cmd.Flags().BoolVar(&isCustomer, "customer", false, "Mark as a customer")
111111
cmd.Flags().BoolVar(&isSupplier, "supplier", false, "Mark as a supplier")
112-
cmd.MarkFlagRequired("name")
112+
_ = cmd.MarkFlagRequired("name")
113113
return cmd
114114
}
115115

116116
func newContactsUpdateCmd(format *string, org *string) *cobra.Command {
117117
var name, firstName, lastName, email, accountNum string
118118
cmd := &cobra.Command{
119-
Use: "update <contact-id>",
119+
Use: "update <contact-id>",
120120
Short: "Update an existing contact",
121-
Args: cobra.ExactArgs(1),
121+
Args: cobra.ExactArgs(1),
122122
RunE: func(cmd *cobra.Command, args []string) error {
123123
input := xero.ContactCreateInput{
124124
Name: name,

0 commit comments

Comments
 (0)