kctl-accurate 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kctl_accurate-0.2.0/.gitignore +33 -0
- kctl_accurate-0.2.0/CLAUDE.md +42 -0
- kctl_accurate-0.2.0/PKG-INFO +18 -0
- kctl_accurate-0.2.0/README.md +79 -0
- kctl_accurate-0.2.0/pyproject.toml +51 -0
- kctl_accurate-0.2.0/skills/accurate-admin/SKILL.md +173 -0
- kctl_accurate-0.2.0/src/kctl_accurate/__init__.py +3 -0
- kctl_accurate-0.2.0/src/kctl_accurate/__main__.py +5 -0
- kctl_accurate-0.2.0/src/kctl_accurate/cli.py +102 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/__init__.py +1 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/auth.py +58 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/config_cmd.py +196 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/dashboard.py +90 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/db.py +89 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/discover.py +103 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/doctor_cmd.py +149 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/export.py +126 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/extract.py +201 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/modules.py +245 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/reports.py +513 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/statements.py +208 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/tax.py +210 -0
- kctl_accurate-0.2.0/src/kctl_accurate/commands/validate.py +329 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/__init__.py +1 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/callbacks.py +38 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/client.py +114 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/columns.py +178 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/config.py +144 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/exceptions.py +70 -0
- kctl_accurate-0.2.0/src/kctl_accurate/core/streaming.py +183 -0
- kctl_accurate-0.2.0/tests/__init__.py +0 -0
- kctl_accurate-0.2.0/tests/conftest.py +79 -0
- kctl_accurate-0.2.0/tests/unit/__init__.py +0 -0
- kctl_accurate-0.2.0/tests/unit/test_cli_help.py +25 -0
- kctl_accurate-0.2.0/tests/unit/test_cli_version.py +20 -0
- kctl_accurate-0.2.0/tests/unit/test_client.py +107 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_auth.py +89 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_config.py +132 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_dashboard.py +117 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_db.py +132 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_doctor.py +83 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_extract.py +121 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_modules.py +242 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_reports.py +259 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_statements.py +119 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_tax.py +114 -0
- kctl_accurate-0.2.0/tests/unit/test_cmd_validate.py +181 -0
- kctl_accurate-0.2.0/tests/unit/test_columns.py +65 -0
- kctl_accurate-0.2.0/tests/unit/test_config.py +128 -0
- kctl_accurate-0.2.0/tests/unit/test_exceptions.py +88 -0
- kctl_accurate-0.2.0/tests/unit/test_streaming.py +201 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.eggs/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# IDE
|
|
15
|
+
.idea/
|
|
16
|
+
.vscode/
|
|
17
|
+
*.swp
|
|
18
|
+
*.swo
|
|
19
|
+
|
|
20
|
+
# Testing
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.coverage
|
|
23
|
+
htmlcov/
|
|
24
|
+
.mypy_cache/
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Environment
|
|
32
|
+
.env
|
|
33
|
+
.env.local
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# CLAUDE.md - kctl-accurate
|
|
2
|
+
|
|
3
|
+
Kodemeio CLI for the Accurate Online API.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync --all-packages
|
|
9
|
+
uv run --project ../.. pytest packages/kctl-accurate/tests/ -v
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Architecture
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
src/kctl_accurate/
|
|
16
|
+
├── cli.py # Typer app + @app.callback for global flags
|
|
17
|
+
├── core/
|
|
18
|
+
│ ├── config.py # SERVICE_KEY=accurate, ServiceConfig, resolve_connection
|
|
19
|
+
│ ├── client.py # AccurateClientWrapper translates SDK exceptions
|
|
20
|
+
│ ├── exceptions.py # SDK→KctlError translator (drives exit codes)
|
|
21
|
+
│ └── callbacks.py # AppContext(AppContextBase), lazy client
|
|
22
|
+
└── commands/
|
|
23
|
+
├── config_cmd.py # init/list/show/use/add/remove/set/test
|
|
24
|
+
├── auth.py # token-info/refresh/logout
|
|
25
|
+
└── doctor_cmd.py # ConfigCheck + TokenCheck + DbListCheck
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Key constraints
|
|
29
|
+
|
|
30
|
+
- SERVICE_KEY: `"accurate"` — config at `profiles.<name>.accurate.*`
|
|
31
|
+
- Depends on `kctl-lib>=0.4.0` (workspace) and `kodemeio-accurate>=0.4.0,<1.0.0` (PyPI)
|
|
32
|
+
- All SDK exceptions translated at the wrapper boundary in `core/client.py`
|
|
33
|
+
- Secrets always masked in any non-debug output (per `~/.claude/rules/security.md`)
|
|
34
|
+
- Exit-code contract enforced by `KctlError` subclass (see `core/exceptions.py`)
|
|
35
|
+
- One profile = one tenant. Multi-tenant via multiple profiles, not multi-target invocation.
|
|
36
|
+
|
|
37
|
+
## What's next
|
|
38
|
+
|
|
39
|
+
- Phase 2: 23 module command groups (`customers list`, `invoices get`, etc.) generated from `core/columns.py:MODULE_REGISTRY`
|
|
40
|
+
- Phase 3: `extract`, `export`, `indo` (e-Faktur + 3 validators + 3 statement extractors)
|
|
41
|
+
|
|
42
|
+
See `kodemeio-accurate/docs/superpowers/specs/2026-04-30-kctl-accurate-design.md` for the full design.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kctl-accurate
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Kodemeio Accurate Online CLI — general-purpose ops on the Accurate API
|
|
5
|
+
Requires-Python: >=3.12
|
|
6
|
+
Requires-Dist: kctl-lib>=0.4.0
|
|
7
|
+
Requires-Dist: kodemeio-accurate<1.0.0,>=0.4.0
|
|
8
|
+
Requires-Dist: pydantic>=2.10.0
|
|
9
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
10
|
+
Requires-Dist: rich>=13.9.0
|
|
11
|
+
Requires-Dist: typer>=0.15.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: mypy>=1.14.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest-httpx>=0.35.0; extra == 'dev'
|
|
16
|
+
Requires-Dist: pytest>=8.3.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: ruff>=0.9.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# kctl-accurate
|
|
2
|
+
|
|
3
|
+
General-purpose CLI for the Accurate Online API. Part of the Kodemeio kctl-* family.
|
|
4
|
+
|
|
5
|
+
> **v0.1.0a1 (alpha)** — Phase 1 walking skeleton: config + auth + doctor only.
|
|
6
|
+
> Module commands (customers, invoices, etc.) ship in 0.1.0 (Phase 2).
|
|
7
|
+
> Extract / Indo commands ship in 0.2.0 (Phase 3).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv tool install kctl-accurate
|
|
13
|
+
# or, from the kodemeio-platform monorepo:
|
|
14
|
+
uv sync --all-packages
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Interactive: prompts for token, secret, db_id; verifies; saves.
|
|
21
|
+
kctl-accurate config init
|
|
22
|
+
|
|
23
|
+
# Verify creds against the live API
|
|
24
|
+
kctl-accurate config test
|
|
25
|
+
|
|
26
|
+
# Show current token info
|
|
27
|
+
kctl-accurate auth token-info
|
|
28
|
+
|
|
29
|
+
# Diagnose
|
|
30
|
+
kctl-accurate doctor
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Profiles
|
|
34
|
+
|
|
35
|
+
Multi-tenant via the kctl-* shared config at `~/.config/kodemeio/config.yaml`:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
profiles:
|
|
39
|
+
tpp:
|
|
40
|
+
accurate:
|
|
41
|
+
api_token: aut.xxxxx
|
|
42
|
+
signature_secret: ${KCTL_ACCURATE_TPP_SECRET} # env-var indirection works
|
|
43
|
+
db_id: 12345
|
|
44
|
+
host: https://public.accurate.id
|
|
45
|
+
db_alias: PT TPP Indonesia
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use a profile per command: `kctl-accurate -p tpp auth token-info`.
|
|
49
|
+
|
|
50
|
+
## Global flags
|
|
51
|
+
|
|
52
|
+
| flag | purpose |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `-p, --profile NAME` | Override active profile |
|
|
55
|
+
| `--api-token TOKEN` | Override profile's api_token |
|
|
56
|
+
| `--signature-secret S` | Override profile's signature_secret |
|
|
57
|
+
| `--db-id N` | Override profile's db_id |
|
|
58
|
+
| `--host URL` | Override profile's host |
|
|
59
|
+
| `--json` | JSON output |
|
|
60
|
+
| `-q, --quiet` | Suppress progress/info |
|
|
61
|
+
| `-V, --version` | Print version + exit |
|
|
62
|
+
|
|
63
|
+
## Exit codes
|
|
64
|
+
|
|
65
|
+
| code | meaning |
|
|
66
|
+
|---|---|
|
|
67
|
+
| 0 | success |
|
|
68
|
+
| 1 | command-level failure |
|
|
69
|
+
| 2 | config error (missing creds, bad profile) |
|
|
70
|
+
| 3 | network/API error (5xx, host unreachable) |
|
|
71
|
+
| 4 | auth error (401/403, signature/token) |
|
|
72
|
+
| 5 | rate-limit exhaustion (429 after retries) |
|
|
73
|
+
|
|
74
|
+
> Note: kctl-lib 0.4.0's `handle_cli_error` currently exits 1 for all KctlError subclasses. The differentiated exit codes above are the *intent* carried by the subclass — they will activate when kctl-lib adds per-subclass exit-code routing or when per-command `_run()` overrides are added.
|
|
75
|
+
|
|
76
|
+
## Related
|
|
77
|
+
|
|
78
|
+
- [`kodemeio-accurate`](https://pypi.org/project/kodemeio-accurate/) — the Python SDK powering this CLI
|
|
79
|
+
- `accurate-sync` — the migration writer (Accurate → Odoo); separate tool, separate scope
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "kctl-accurate"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Kodemeio Accurate Online CLI — general-purpose ops on the Accurate API"
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"kctl-lib>=0.4.0",
|
|
12
|
+
"kodemeio-accurate>=0.4.0,<1.0.0",
|
|
13
|
+
"typer>=0.15.0",
|
|
14
|
+
"rich>=13.9.0",
|
|
15
|
+
"pydantic>=2.10.0",
|
|
16
|
+
"pyyaml>=6.0.2",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
dev = [
|
|
21
|
+
"pytest>=8.3.0",
|
|
22
|
+
"pytest-httpx>=0.35.0",
|
|
23
|
+
"pytest-cov>=6.0.0",
|
|
24
|
+
"ruff>=0.9.0",
|
|
25
|
+
"mypy>=1.14.0",
|
|
26
|
+
"types-PyYAML>=6.0.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
kctl-accurate = "kctl_accurate.cli:_run"
|
|
31
|
+
|
|
32
|
+
[project.entry-points."kctl_accurate.plugins"]
|
|
33
|
+
|
|
34
|
+
[tool.uv.sources]
|
|
35
|
+
kctl-lib = { workspace = true }
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.wheel]
|
|
38
|
+
packages = ["src/kctl_accurate"]
|
|
39
|
+
|
|
40
|
+
[tool.ruff]
|
|
41
|
+
target-version = "py312"
|
|
42
|
+
line-length = 120
|
|
43
|
+
|
|
44
|
+
[tool.mypy]
|
|
45
|
+
python_version = "3.12"
|
|
46
|
+
strict = true
|
|
47
|
+
ignore_missing_imports = true
|
|
48
|
+
|
|
49
|
+
[[tool.mypy.overrides]]
|
|
50
|
+
module = ["kctl_lib", "kctl_lib.*", "accurate_sdk", "accurate_sdk.*"]
|
|
51
|
+
follow_imports = "silent"
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: accurate-admin
|
|
3
|
+
description: >
|
|
4
|
+
Accurate Online accounting administration via kctl-accurate CLI (10+ groups, ~30 commands + 23 module groups).
|
|
5
|
+
MUST use for ANY kctl-accurate operation.
|
|
6
|
+
Triggers on: "accurate", "accounting", "auth", "config", "customers", "dashboard", "db", "doctor",
|
|
7
|
+
"efaktur", "export", "extract", "glaccounts", "invoices", "items", "kctl-accurate", "migrate",
|
|
8
|
+
"module", "nsfp", "pph", "profile", "statements", "tax", "validate", "vendors".
|
|
9
|
+
Auto-generated: 2026-05-03
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# accurate-admin -- kctl-accurate CLI Reference
|
|
13
|
+
|
|
14
|
+
> Auto-generated from `kctl-accurate` command registry. Do not edit manually.
|
|
15
|
+
> To regenerate: `kctl-accurate skill generate`
|
|
16
|
+
> To add custom content: edit `SKILL.extra.md` in the same directory.
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
**CLI:** `kctl-accurate`
|
|
21
|
+
**Command groups:** 10 core + 23 module groups
|
|
22
|
+
**Total commands:** ~30 core + ~69 module (list/get/count per module)
|
|
23
|
+
**Install:** `cd packages/kctl-accurate && uv tool install --editable .`
|
|
24
|
+
|
|
25
|
+
## Global Options
|
|
26
|
+
|
|
27
|
+
| Flag | Description |
|
|
28
|
+
|------|-------------|
|
|
29
|
+
| `--json` | Output as JSON |
|
|
30
|
+
| `--quiet`, `-q` | Suppress info messages |
|
|
31
|
+
| `--profile`, `-p` | Config profile name |
|
|
32
|
+
| `--api-token` | Override Accurate API token |
|
|
33
|
+
| `--signature-secret` | Override HMAC-SHA256 secret |
|
|
34
|
+
| `--db-id` | Override Accurate company db_id |
|
|
35
|
+
| `--host` | Override Accurate host |
|
|
36
|
+
| `--version`, `-V` | Show version |
|
|
37
|
+
|
|
38
|
+
## Command Reference
|
|
39
|
+
|
|
40
|
+
### `kctl-accurate auth`
|
|
41
|
+
|
|
42
|
+
Accurate auth operations: token-info, refresh, logout.
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| `auth token-info` | Show current API token info: user, database, host. |
|
|
47
|
+
| `auth refresh` | Refresh the current API session token. |
|
|
48
|
+
| `auth logout` | Invalidate the current API session. |
|
|
49
|
+
|
|
50
|
+
### `kctl-accurate config`
|
|
51
|
+
|
|
52
|
+
Manage CLI configuration and profiles.
|
|
53
|
+
|
|
54
|
+
| Command | Description |
|
|
55
|
+
|---------|-------------|
|
|
56
|
+
| `config init` | Initialize CLI configuration. |
|
|
57
|
+
| `config show` | Show configuration (keys masked). |
|
|
58
|
+
| `config add` | Add a new profile. |
|
|
59
|
+
| `config use` | Switch default profile. |
|
|
60
|
+
| `config remove` | Remove a profile. |
|
|
61
|
+
| `config set` | Set a config value. |
|
|
62
|
+
| `config test` | Test API connection. |
|
|
63
|
+
|
|
64
|
+
### `kctl-accurate dashboard`
|
|
65
|
+
|
|
66
|
+
Show a dashboard overview: user info, DB info, and module record counts
|
|
67
|
+
(customers, vendors, items, sales-invoices, purchase-invoices).
|
|
68
|
+
|
|
69
|
+
### `kctl-accurate db`
|
|
70
|
+
|
|
71
|
+
Accurate database/company operations.
|
|
72
|
+
|
|
73
|
+
| Command | Description |
|
|
74
|
+
|---------|-------------|
|
|
75
|
+
| `db list-companies` | List all Accurate companies accessible with this token. |
|
|
76
|
+
| `db open <db_id>` | Open a database session and print session info. |
|
|
77
|
+
| `db info` | Show current profile's database info (user, DB ID, alias, host). |
|
|
78
|
+
|
|
79
|
+
### `kctl-accurate extract`
|
|
80
|
+
|
|
81
|
+
Bulk-extract Accurate Online data to JSON files on disk.
|
|
82
|
+
|
|
83
|
+
| Command | Description |
|
|
84
|
+
|---------|-------------|
|
|
85
|
+
| `extract run --out-dir <path> [--modules] [--no-detail] [--resume]` | Extract data (master + transaction modules) to JSON files. |
|
|
86
|
+
| `extract resume --out-dir <path>` | Resume a previous extraction run, skipping already-fetched files. |
|
|
87
|
+
|
|
88
|
+
### `kctl-accurate export`
|
|
89
|
+
|
|
90
|
+
Convert Accurate Online JSON extracts to Odoo-importable CSV files.
|
|
91
|
+
|
|
92
|
+
| Command | Description |
|
|
93
|
+
|---------|-------------|
|
|
94
|
+
| `export csv --json-dir <path> --out-dir <path> [--modules]` | Convert JSON extracts to Odoo-importable CSV files. |
|
|
95
|
+
|
|
96
|
+
### `kctl-accurate tax`
|
|
97
|
+
|
|
98
|
+
e-Faktur (DJP) commands -- list and export faktur pajak data.
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|---------|-------------|
|
|
102
|
+
| `tax efaktur-list [--since] [--period] [--out]` | List faktur pajak records for a date range or calendar period. |
|
|
103
|
+
| `tax efaktur-export-csv --out <path> [--period] [--since]` | Export faktur pajak records to a file (.csv, .jsonl, .json). |
|
|
104
|
+
|
|
105
|
+
### `kctl-accurate validate`
|
|
106
|
+
|
|
107
|
+
Pre/post-migration data quality checks.
|
|
108
|
+
|
|
109
|
+
| Command | Description |
|
|
110
|
+
|---------|-------------|
|
|
111
|
+
| `validate nsfp` | Check for duplicate NSFP numbers across open AR/AP invoices. |
|
|
112
|
+
| `validate pph --accurate-totals <file> --odoo-totals <file>` | Check PPh withholding consistency (post-migration). |
|
|
113
|
+
| `validate ar-ap --accurate-balances <file> --odoo-balances <file>` | Check AR/AP open-balance parity (post-migration). |
|
|
114
|
+
|
|
115
|
+
### `kctl-accurate statements`
|
|
116
|
+
|
|
117
|
+
Financial statement extraction (opening BS, YTD BS, YTD P&L).
|
|
118
|
+
|
|
119
|
+
| Command | Description |
|
|
120
|
+
|---------|-------------|
|
|
121
|
+
| `statements opening-bs --as-of <date> [--out]` | Extract opening Balance Sheet at a specific historical date. |
|
|
122
|
+
| `statements ytd-bs [--out]` | Extract year-to-date Balance Sheet (current account balances). |
|
|
123
|
+
| `statements ytd-pl [--out]` | Extract year-to-date Profit & Loss (current account balances). |
|
|
124
|
+
|
|
125
|
+
### `kctl-accurate doctor`
|
|
126
|
+
|
|
127
|
+
Run diagnostic checks: config, token validity, DB access.
|
|
128
|
+
|
|
129
|
+
### Module Groups (23 auto-generated)
|
|
130
|
+
|
|
131
|
+
Each module group provides `list`, `get`, and `count` subcommands driven by the `MODULE_REGISTRY`.
|
|
132
|
+
|
|
133
|
+
**Master data:** customers, vendors, items, glaccounts, warehouses, currencies, employees, units, taxes, payment-terms
|
|
134
|
+
|
|
135
|
+
**Sales:** sales-orders, sales-invoices, sales-receipts, delivery-orders
|
|
136
|
+
|
|
137
|
+
**Purchase:** purchase-orders, purchase-invoices, purchase-payments, receive-items
|
|
138
|
+
|
|
139
|
+
**Finance:** journal-vouchers, expenses, bank-transfers, other-deposits, other-payments
|
|
140
|
+
|
|
141
|
+
**Examples:**
|
|
142
|
+
```bash
|
|
143
|
+
kctl-accurate customers list -p idtpp
|
|
144
|
+
kctl-accurate sales-invoices get 12345 -p idtpp
|
|
145
|
+
kctl-accurate items count -p idtpp
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
Shared config: `~/.config/kodemeio/config.yaml`
|
|
151
|
+
Service key: `accurate`
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
kctl-accurate config init # Interactive setup
|
|
155
|
+
kctl-accurate config show # Show current config
|
|
156
|
+
kctl-accurate config test # Verify API connection
|
|
157
|
+
kctl-accurate doctor run # Full diagnostics
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Examples:**
|
|
161
|
+
```bash
|
|
162
|
+
# Extract all modules to JSON
|
|
163
|
+
kctl-accurate extract run --out-dir ./dump -p idtpp
|
|
164
|
+
|
|
165
|
+
# Convert extracted JSON to Odoo CSV
|
|
166
|
+
kctl-accurate export csv --json-dir ./dump --out-dir ./csv -p idtpp
|
|
167
|
+
|
|
168
|
+
# List e-Faktur records for April 2026
|
|
169
|
+
kctl-accurate tax efaktur-list --period 2026-04 -p idtpp
|
|
170
|
+
|
|
171
|
+
# Pre-migration NSFP duplicate check
|
|
172
|
+
kctl-accurate validate nsfp -p idtpp
|
|
173
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Main CLI entry point for kctl-accurate."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from kctl_lib import KctlError, handle_cli_error
|
|
9
|
+
|
|
10
|
+
from kctl_accurate import __version__
|
|
11
|
+
from kctl_accurate.commands.auth import app as auth_app
|
|
12
|
+
from kctl_accurate.commands.config_cmd import app as config_app
|
|
13
|
+
from kctl_accurate.commands.dashboard import app as dashboard_app
|
|
14
|
+
from kctl_accurate.commands.db import app as db_app
|
|
15
|
+
from kctl_accurate.commands.discover import app as discover_app
|
|
16
|
+
from kctl_accurate.commands.doctor_cmd import app as doctor_app
|
|
17
|
+
from kctl_accurate.commands.export import app as export_app
|
|
18
|
+
from kctl_accurate.commands.extract import app as extract_app
|
|
19
|
+
from kctl_accurate.commands.modules import build_module_app
|
|
20
|
+
from kctl_accurate.commands.reports import app as reports_app
|
|
21
|
+
from kctl_accurate.commands.statements import app as statements_app
|
|
22
|
+
from kctl_accurate.commands.tax import app as tax_app
|
|
23
|
+
from kctl_accurate.commands.validate import app as validate_app
|
|
24
|
+
from kctl_accurate.core.callbacks import AppContext
|
|
25
|
+
from kctl_accurate.core.columns import MODULE_REGISTRY
|
|
26
|
+
from kctl_lib.self_update import notify_if_outdated
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def version_callback(value: bool) -> None:
|
|
30
|
+
if value:
|
|
31
|
+
typer.echo(f"kctl-accurate {__version__}")
|
|
32
|
+
raise typer.Exit()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
app = typer.Typer(
|
|
36
|
+
name="kctl-accurate",
|
|
37
|
+
help="Kodemeio Accurate Online CLI — general-purpose ops on the Accurate API.",
|
|
38
|
+
no_args_is_help=True,
|
|
39
|
+
rich_markup_mode="rich",
|
|
40
|
+
pretty_exceptions_enable=False,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
app.add_typer(auth_app, name="auth")
|
|
44
|
+
app.add_typer(config_app, name="config")
|
|
45
|
+
app.add_typer(discover_app, name="discover")
|
|
46
|
+
app.add_typer(doctor_app, name="doctor")
|
|
47
|
+
app.add_typer(db_app, name="db")
|
|
48
|
+
app.add_typer(dashboard_app, name="dashboard")
|
|
49
|
+
app.add_typer(extract_app, name="extract")
|
|
50
|
+
app.add_typer(export_app, name="export")
|
|
51
|
+
app.add_typer(tax_app, name="tax")
|
|
52
|
+
app.add_typer(validate_app, name="validate")
|
|
53
|
+
app.add_typer(reports_app, name="reports")
|
|
54
|
+
app.add_typer(statements_app, name="statements")
|
|
55
|
+
|
|
56
|
+
# ── Module groups ─────────────────────────────────────────────────────────────
|
|
57
|
+
for _cli_name, _spec in MODULE_REGISTRY.items():
|
|
58
|
+
app.add_typer(build_module_app(_spec), name=_cli_name)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@app.callback()
|
|
62
|
+
def main(
|
|
63
|
+
ctx: typer.Context,
|
|
64
|
+
json_output: Annotated[bool, typer.Option("--json", help="Output as JSON")] = False,
|
|
65
|
+
quiet: Annotated[bool, typer.Option("--quiet", "-q", help="Suppress info messages")] = False,
|
|
66
|
+
profile: Annotated[str | None, typer.Option("--profile", "-p", help="Config profile name")] = None,
|
|
67
|
+
api_token: Annotated[str | None, typer.Option("--api-token", help="Override Accurate API token")] = None,
|
|
68
|
+
signature_secret: Annotated[
|
|
69
|
+
str | None,
|
|
70
|
+
typer.Option("--signature-secret", help="Override HMAC-SHA256 secret"),
|
|
71
|
+
] = None,
|
|
72
|
+
db_id: Annotated[int | None, typer.Option("--db-id", help="Override Accurate company db_id")] = None,
|
|
73
|
+
host: Annotated[str | None, typer.Option("--host", help="Override Accurate host")] = None,
|
|
74
|
+
version: Annotated[
|
|
75
|
+
bool,
|
|
76
|
+
typer.Option("--version", "-V", callback=version_callback, is_eager=True, help="Show version"),
|
|
77
|
+
] = False,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Kodemeio Accurate Online CLI."""
|
|
80
|
+
ctx.ensure_object(dict)
|
|
81
|
+
ctx.obj = AppContext(
|
|
82
|
+
json_mode=json_output,
|
|
83
|
+
quiet=quiet,
|
|
84
|
+
profile=profile,
|
|
85
|
+
api_token_override=api_token,
|
|
86
|
+
signature_secret_override=signature_secret,
|
|
87
|
+
db_id_override=db_id,
|
|
88
|
+
host_override=host,
|
|
89
|
+
)
|
|
90
|
+
notify_if_outdated(ctx.obj.output, "kctl-accurate", __version__)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _run() -> None:
|
|
94
|
+
"""Entry point with error handling."""
|
|
95
|
+
try:
|
|
96
|
+
app()
|
|
97
|
+
except KctlError as e:
|
|
98
|
+
handle_cli_error(e)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
_run()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""kctl-accurate command groups."""
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""kctl-accurate auth — Accurate Online auth ops."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from kctl_accurate.core.callbacks import AppContext
|
|
10
|
+
|
|
11
|
+
app = typer.Typer(help="Accurate auth operations: token-info, refresh, logout.")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@app.command("token-info")
|
|
15
|
+
def token_info(ctx: typer.Context) -> None:
|
|
16
|
+
"""Show current API token info: user, database, host."""
|
|
17
|
+
actx: AppContext = ctx.obj
|
|
18
|
+
out = actx.output
|
|
19
|
+
info = actx.client.token_info()
|
|
20
|
+
|
|
21
|
+
if actx.json_mode:
|
|
22
|
+
print(json.dumps(info, indent=2, ensure_ascii=False))
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
d = info.get("d", {})
|
|
26
|
+
user = d.get("user") or {}
|
|
27
|
+
db = d.get("database") or {}
|
|
28
|
+
|
|
29
|
+
out.header("Accurate Token Info")
|
|
30
|
+
out.kv("User", user.get("name", "[dim]—[/dim]"))
|
|
31
|
+
out.kv("Email", user.get("email", "[dim]—[/dim]"))
|
|
32
|
+
out.kv("DB ID", str(db.get("id", "[dim]—[/dim]")))
|
|
33
|
+
out.kv("DB Alias", db.get("alias", "[dim]—[/dim]"))
|
|
34
|
+
out.kv("Host", db.get("host", "[dim]—[/dim]"))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@app.command()
|
|
38
|
+
def refresh(ctx: typer.Context) -> None:
|
|
39
|
+
"""Refresh the current API session token."""
|
|
40
|
+
actx: AppContext = ctx.obj
|
|
41
|
+
out = actx.output
|
|
42
|
+
result = actx.client.refresh_token()
|
|
43
|
+
if actx.json_mode:
|
|
44
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
45
|
+
return
|
|
46
|
+
out.success("Token refreshed")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@app.command()
|
|
50
|
+
def logout(ctx: typer.Context) -> None:
|
|
51
|
+
"""Invalidate the current API session."""
|
|
52
|
+
actx: AppContext = ctx.obj
|
|
53
|
+
out = actx.output
|
|
54
|
+
result = actx.client.logout()
|
|
55
|
+
if actx.json_mode:
|
|
56
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
57
|
+
return
|
|
58
|
+
out.success("Logged out")
|