acumatica-cli 0.25.2__tar.gz → 0.26.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.
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/PKG-INFO +91 -28
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/README.md +90 -27
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/pyproject.toml +1 -1
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/pyproject.toml.orig +1 -1
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap.py +2 -2
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap_project.xml +35 -4
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/config.py +4 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/seed_catalog.yaml +15 -1
- acumatica_cli-0.26.0/src/acumatica_cli/templates/config/bootstrap/segmented-key.yaml +10 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/__init__.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/cli.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/client.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/extract.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/firstlogin.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/inventory.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/matrix.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/models.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/output.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/reconcile.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/run.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/seed.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/state.py +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/README.md +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/10-subaccounts.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/20-accounts.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/40-ledger.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/50-gl-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/60-ledger-company.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/90-uoms.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/company.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/credit-terms.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/features.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/05-numbering-sequences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/10-reason-codes.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/20-in-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/30-availability-rules.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/40-posting-classes.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/50-warehouse.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/51-warehouse-locations.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/52-warehouse-defaults.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/53-tax-categories.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/54-item-classes.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/56-so-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/57-po-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/58-order-types.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/60-ar-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/61-ap-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/62-ca-preferences.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/63-cash-account.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/64-payment-methods.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/65-statement-cycles.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/70-vendor-classes.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/71-customer-classes.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/75-vendors.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/76-customers.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/80-stock-items-parts.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/82-stock-items-kits.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/85-kit-specifications.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/90-roles.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/91-users.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/10-financial-year.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/20-master-calendar.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/30-open-periods.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/views/10-trial-balance.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/env +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/gitignore +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/matrix +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/README.md +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/default-24.200.001/scenario/30-build.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/10-seed-capital.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/20-buy.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/30-build.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/40-sell.yaml +0 -0
- {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/tenant.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: acumatica-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data
|
|
5
5
|
Author: Konstantin Borovik
|
|
6
6
|
Author-email: Konstantin Borovik <kb@lab5.ca>
|
|
@@ -32,6 +32,33 @@ Acumatica configuration normally lives in the web UI: wizards, screens, and manu
|
|
|
32
32
|
|
|
33
33
|
`acu` moves that configuration into YAML files in a git repo, so a tenant can be rebuilt from scratch, audited in a pull request, and checked for drift like any other infrastructure.
|
|
34
34
|
|
|
35
|
+
## What this tool is capable of
|
|
36
|
+
|
|
37
|
+
YAML in git is the source of truth; the live tenant is the target. `apply` is the only writer.
|
|
38
|
+
|
|
39
|
+
| You can | Command | Effect |
|
|
40
|
+
| ------- | ------- | ------ |
|
|
41
|
+
| Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
|
|
42
|
+
| Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
|
|
43
|
+
| Pull live config into YAML | `extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
|
|
44
|
+
| Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
|
|
45
|
+
| Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
|
|
46
|
+
| Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
|
|
47
|
+
| Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
|
|
48
|
+
| Prove a cold rebuild | `check` | create, then apply, then run, then diff on a fresh tenant |
|
|
49
|
+
| Snapshot a site offline | `inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
|
|
50
|
+
| Cross-check snapshot vs seed | `reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
|
|
51
|
+
| Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
|
|
52
|
+
| Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `matrix.yaml` tree |
|
|
53
|
+
| Preflight a target | `config check` | Discovery, secrets, matrix, REST, endpoints, SSH |
|
|
54
|
+
|
|
55
|
+
Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
|
|
56
|
+
|
|
57
|
+
REST is the data plane (`apply`, `diff`, `run`, `extract`, `state`, `bootstrap`, `schema`).
|
|
58
|
+
SSH is the control plane (`tenant *`).
|
|
59
|
+
|
|
60
|
+
Hosted sites skip SSH.
|
|
61
|
+
|
|
35
62
|
## Quick start
|
|
36
63
|
|
|
37
64
|
```sh
|
|
@@ -55,7 +82,8 @@ acu check --yes --tenant DEV # cold lifecycle create→apply→run
|
|
|
55
82
|
Bare `apply` / `diff` (no path args) also prefer `config/` when those trees exist.
|
|
56
83
|
See [docs/demo-seed.md](docs/demo-seed.md) for the entity map, once-guard, apply-order notes, NumberingSequence vs prefs `*NumberingID`, curated *Preferences field depth (V41), and Role/User + password seed rules.
|
|
57
84
|
|
|
58
|
-
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env
|
|
85
|
+
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
86
|
+
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
59
87
|
|
|
60
88
|
```sh
|
|
61
89
|
acu config init --host customer.acumatica.com my-erp
|
|
@@ -104,18 +132,35 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
104
132
|
└── check [--strict] preflight: discovery, secrets, matrix, REST, endpoints, SSH
|
|
105
133
|
```
|
|
106
134
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
`
|
|
110
|
-
|
|
135
|
+
When you omit FILES:
|
|
136
|
+
|
|
137
|
+
- `apply` / `diff` prefer `config/<name>/` if any seed child exists under `config/`.
|
|
138
|
+
Otherwise they walk root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
|
|
139
|
+
A path like `config/` expands those nested seed dirs in the same order.
|
|
140
|
+
- `run` defaults to `scenario/`.
|
|
141
|
+
- `state` defaults to `config/views/`; writes go to `state/` (`--out`).
|
|
142
|
+
|
|
143
|
+
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
144
|
+
`config/views` and `state` keep Period pinned — see [docs/demo-seed.md](docs/demo-seed.md#period-token-current_period-vs-pinned-views).
|
|
145
|
+
|
|
111
146
|
`extract` always writes under `config/{bootstrap,baseline,setup,master}/` (catalog-driven; never root SEED_DIRS).
|
|
112
|
-
|
|
113
|
-
`
|
|
114
|
-
|
|
147
|
+
|
|
148
|
+
`inventory` and `reconcile` are offline (no REST, SSH, or password).
|
|
149
|
+
`inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
150
|
+
|
|
151
|
+
`reconcile` compares `inventory/` to optional `config/` and writes `findings/` only.
|
|
152
|
+
It never writes seed.
|
|
153
|
+
|
|
154
|
+
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
155
|
+
It normalizes the join: pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code.
|
|
156
|
+
|
|
115
157
|
See [docs/demo-seed.md](docs/demo-seed.md).
|
|
158
|
+
|
|
116
159
|
`acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
|
|
117
|
-
|
|
118
|
-
|
|
160
|
+
|
|
161
|
+
Run `acu --help` for the full mental model (workflow, planes, exit codes, command map).
|
|
162
|
+
That is enough for an agent to learn the tool without extra docs.
|
|
163
|
+
|
|
119
164
|
Run `acu <command> --help` (or `-h`) for flags, examples, and prerequisites.
|
|
120
165
|
|
|
121
166
|
### Dual readers, one writer
|
|
@@ -133,13 +178,17 @@ Do not confuse them with each other or with `state`:
|
|
|
133
178
|
|
|
134
179
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
135
180
|
Binary `.adb` snapshots are rejected (XML only).
|
|
181
|
+
|
|
136
182
|
See [docs/ac-exe.md](docs/ac-exe.md) for export / SM203520 notes and [docs/demo-seed.md](docs/demo-seed.md) for the extract/state/inventory map.
|
|
137
183
|
|
|
138
184
|
## The data repo
|
|
139
185
|
|
|
140
186
|
Your configuration lives in its own git repo.
|
|
141
187
|
`acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
|
|
142
|
-
|
|
188
|
+
|
|
189
|
+
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
190
|
+
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
191
|
+
|
|
143
192
|
There is no `--flavor`.
|
|
144
193
|
|
|
145
194
|
| Path | What it holds |
|
|
@@ -163,9 +212,15 @@ Commit `matrix.yaml` with the seeds so every clone knows verified ERP line, Defa
|
|
|
163
212
|
|
|
164
213
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
165
214
|
`acu extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
166
|
-
|
|
215
|
+
|
|
216
|
+
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
217
|
+
The demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
|
|
218
|
+
|
|
167
219
|
Features synthesize to `config/bootstrap/features.yaml`.
|
|
168
|
-
Existing files skip unless `--force`; empty live sets skip
|
|
220
|
+
Existing files skip unless `--force`; empty live sets skip.
|
|
221
|
+
|
|
222
|
+
Row failures continue (exit 1 only if any row failed).
|
|
223
|
+
Drift stays with `diff`.
|
|
169
224
|
|
|
170
225
|
```sh
|
|
171
226
|
acu --tenant DEV extract --out . --force # refresh config/** from live tenant
|
|
@@ -186,6 +241,7 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
|
|
|
186
241
|
|
|
187
242
|
`api_version` resolves as `--api-version` flag, else active `matrix.yaml` cell `default_api`, else code default `25.200.001` (never `ACU_API_VERSION` in `.env`).
|
|
188
243
|
`base_url` resolves as `--url`, else `ACU_BASE_URL`, else active cell `base_url`.
|
|
244
|
+
|
|
189
245
|
Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the dataset pin.
|
|
190
246
|
|
|
191
247
|
## Installation
|
|
@@ -210,9 +266,10 @@ Verify with `acu --version`.
|
|
|
210
266
|
|
|
211
267
|
## Configuration
|
|
212
268
|
|
|
213
|
-
Secrets live in one `.env` file (`ACU_*` vars).
|
|
214
|
-
Default contract pin live in committed `matrix.yaml` (cell `base_url` +
|
|
215
|
-
|
|
269
|
+
Secrets live in one `.env` file (`ACU_*` vars).
|
|
270
|
+
Non-secret **where** and the Default contract pin live in committed `matrix.yaml` (cell `base_url` + `default_api`).
|
|
271
|
+
|
|
272
|
+
Optional `ACU_BASE_URL` overrides cell where for ad-hoc probes.
|
|
216
273
|
|
|
217
274
|
```sh
|
|
218
275
|
# ACU_BASE_URL optional when matrix.yaml cell carries base_url
|
|
@@ -238,16 +295,17 @@ cells:
|
|
|
238
295
|
```
|
|
239
296
|
|
|
240
297
|
`--cell <id>` selects a cell (omit means first cell).
|
|
241
|
-
When present, live commands source `api_version` from cell `default_api` and
|
|
242
|
-
|
|
298
|
+
When present, live commands source `api_version` from cell `default_api` and `base_url` from the cell when flag/env leave them unset.
|
|
299
|
+
|
|
243
300
|
`acu config check` reports `ok matrix (cell=...; api_version from default_api=...; ...)`.
|
|
244
301
|
Missing `matrix.yaml` only warns on `config check` unless you pass `--strict`.
|
|
302
|
+
|
|
245
303
|
`acu check` (lifecycle) **requires** matrix.
|
|
246
304
|
|
|
247
305
|
### Multi-host matrix (V44)
|
|
248
306
|
|
|
249
|
-
One **trunk seed** in the data repo serves every host.
|
|
250
|
-
**not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
|
|
307
|
+
One **trunk seed** in the data repo serves every host.
|
|
308
|
+
Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
|
|
251
309
|
|
|
252
310
|
| Piece | Role |
|
|
253
311
|
| ----- | ---- |
|
|
@@ -256,14 +314,14 @@ One **trunk seed** in the data repo serves every host. Version fan-out is
|
|
|
256
314
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
257
315
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
258
316
|
|
|
259
|
-
**Overlays** live under `overlays/default-<default_api>/` (scaffolded by
|
|
260
|
-
|
|
317
|
+
**Overlays** live under `overlays/default-<default_api>/` (scaffolded by `acu config init`).
|
|
318
|
+
No `--overlay` flag.
|
|
261
319
|
|
|
262
|
-
**Bare compose (pin auto):** when path args are omitted, `acu apply` /
|
|
263
|
-
`acu
|
|
264
|
-
|
|
265
|
-
resolved `api_version` (matrix cell `default_api`).
|
|
266
|
-
disable auto-compose.
|
|
320
|
+
**Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
|
|
321
|
+
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
322
|
+
|
|
323
|
+
Pin = resolved `api_version` (matrix cell `default_api`).
|
|
324
|
+
Explicit path args disable auto-compose.
|
|
267
325
|
|
|
268
326
|
```sh
|
|
269
327
|
# matrix cell default_api: 24.200.001 → uses overlays/default-24.200.001/
|
|
@@ -308,6 +366,7 @@ acu apply --dry-run # show what would be written, write nothing
|
|
|
308
366
|
|
|
309
367
|
Requires **GNU Make at least 3.82** — the Makefile uses `.ONESHELL`.
|
|
310
368
|
On macOS use Homebrew's `gmake` (`brew install make`); `/usr/bin/make` is 3.81 and fails the guard.
|
|
369
|
+
|
|
311
370
|
Elsewhere plain `make` is fine when it is GNU Make.
|
|
312
371
|
|
|
313
372
|
```sh
|
|
@@ -319,6 +378,7 @@ gmake check # offline gate: ruff, basedpyright strict, pytest
|
|
|
319
378
|
|
|
320
379
|
The default test suite is fully offline.
|
|
321
380
|
REST is faked with `httpx.MockTransport`, SSH with a monkeypatched `subprocess.run` — no live instance is needed.
|
|
381
|
+
|
|
322
382
|
`gmake check` must pass before every commit.
|
|
323
383
|
GitHub Actions runs the same gate on every push and pull request to `main`.
|
|
324
384
|
|
|
@@ -326,6 +386,7 @@ GitHub Actions runs the same gate on every push and pull request to `main`.
|
|
|
326
386
|
|
|
327
387
|
Human release notes live in root [`CHANGELOG.md`](CHANGELOG.md) (Keep a Changelog).
|
|
328
388
|
During development, append user-facing work under `## Unreleased` in `### Added` / `### Changed` / `### Fixed` as appropriate.
|
|
389
|
+
|
|
329
390
|
Empty Unreleased (no bullets) hard-fails the release — nothing to ship.
|
|
330
391
|
|
|
331
392
|
```sh
|
|
@@ -351,6 +412,7 @@ Configuration is one file: a decrypted `.env` at the repo root names the instanc
|
|
|
351
412
|
|
|
352
413
|
The tier is self-contained.
|
|
353
414
|
Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
|
|
415
|
+
|
|
354
416
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
355
417
|
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
356
418
|
|
|
@@ -364,6 +426,7 @@ gmake e2e FILE=test_scenario_lifecycle # scenario + state focus
|
|
|
364
426
|
|
|
365
427
|
This project is licensed under the PolyForm Noncommercial License 1.0.0.
|
|
366
428
|
Noncommercial use is free under that license.
|
|
429
|
+
|
|
367
430
|
Commercial use requires a separate license — contact [lab5.ca](https://lab5.ca).
|
|
368
431
|
|
|
369
432
|
See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
@@ -14,6 +14,33 @@ Acumatica configuration normally lives in the web UI: wizards, screens, and manu
|
|
|
14
14
|
|
|
15
15
|
`acu` moves that configuration into YAML files in a git repo, so a tenant can be rebuilt from scratch, audited in a pull request, and checked for drift like any other infrastructure.
|
|
16
16
|
|
|
17
|
+
## What this tool is capable of
|
|
18
|
+
|
|
19
|
+
YAML in git is the source of truth; the live tenant is the target. `apply` is the only writer.
|
|
20
|
+
|
|
21
|
+
| You can | Command | Effect |
|
|
22
|
+
| ------- | ------- | ------ |
|
|
23
|
+
| Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
|
|
24
|
+
| Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
|
|
25
|
+
| Pull live config into YAML | `extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
|
|
26
|
+
| Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
|
|
27
|
+
| Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
|
|
28
|
+
| Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
|
|
29
|
+
| Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
|
|
30
|
+
| Prove a cold rebuild | `check` | create, then apply, then run, then diff on a fresh tenant |
|
|
31
|
+
| Snapshot a site offline | `inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
|
|
32
|
+
| Cross-check snapshot vs seed | `reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
|
|
33
|
+
| Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
|
|
34
|
+
| Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `matrix.yaml` tree |
|
|
35
|
+
| Preflight a target | `config check` | Discovery, secrets, matrix, REST, endpoints, SSH |
|
|
36
|
+
|
|
37
|
+
Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
|
|
38
|
+
|
|
39
|
+
REST is the data plane (`apply`, `diff`, `run`, `extract`, `state`, `bootstrap`, `schema`).
|
|
40
|
+
SSH is the control plane (`tenant *`).
|
|
41
|
+
|
|
42
|
+
Hosted sites skip SSH.
|
|
43
|
+
|
|
17
44
|
## Quick start
|
|
18
45
|
|
|
19
46
|
```sh
|
|
@@ -37,7 +64,8 @@ acu check --yes --tenant DEV # cold lifecycle create→apply→run
|
|
|
37
64
|
Bare `apply` / `diff` (no path args) also prefer `config/` when those trees exist.
|
|
38
65
|
See [docs/demo-seed.md](docs/demo-seed.md) for the entity map, once-guard, apply-order notes, NumberingSequence vs prefs `*NumberingID`, curated *Preferences field depth (V41), and Role/User + password seed rules.
|
|
39
66
|
|
|
40
|
-
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env
|
|
67
|
+
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
68
|
+
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
41
69
|
|
|
42
70
|
```sh
|
|
43
71
|
acu config init --host customer.acumatica.com my-erp
|
|
@@ -86,18 +114,35 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
86
114
|
└── check [--strict] preflight: discovery, secrets, matrix, REST, endpoints, SSH
|
|
87
115
|
```
|
|
88
116
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
`
|
|
92
|
-
|
|
117
|
+
When you omit FILES:
|
|
118
|
+
|
|
119
|
+
- `apply` / `diff` prefer `config/<name>/` if any seed child exists under `config/`.
|
|
120
|
+
Otherwise they walk root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
|
|
121
|
+
A path like `config/` expands those nested seed dirs in the same order.
|
|
122
|
+
- `run` defaults to `scenario/`.
|
|
123
|
+
- `state` defaults to `config/views/`; writes go to `state/` (`--out`).
|
|
124
|
+
|
|
125
|
+
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
126
|
+
`config/views` and `state` keep Period pinned — see [docs/demo-seed.md](docs/demo-seed.md#period-token-current_period-vs-pinned-views).
|
|
127
|
+
|
|
93
128
|
`extract` always writes under `config/{bootstrap,baseline,setup,master}/` (catalog-driven; never root SEED_DIRS).
|
|
94
|
-
|
|
95
|
-
`
|
|
96
|
-
|
|
129
|
+
|
|
130
|
+
`inventory` and `reconcile` are offline (no REST, SSH, or password).
|
|
131
|
+
`inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
132
|
+
|
|
133
|
+
`reconcile` compares `inventory/` to optional `config/` and writes `findings/` only.
|
|
134
|
+
It never writes seed.
|
|
135
|
+
|
|
136
|
+
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
137
|
+
It normalizes the join: pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code.
|
|
138
|
+
|
|
97
139
|
See [docs/demo-seed.md](docs/demo-seed.md).
|
|
140
|
+
|
|
98
141
|
`acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
|
|
99
|
-
|
|
100
|
-
|
|
142
|
+
|
|
143
|
+
Run `acu --help` for the full mental model (workflow, planes, exit codes, command map).
|
|
144
|
+
That is enough for an agent to learn the tool without extra docs.
|
|
145
|
+
|
|
101
146
|
Run `acu <command> --help` (or `-h`) for flags, examples, and prerequisites.
|
|
102
147
|
|
|
103
148
|
### Dual readers, one writer
|
|
@@ -115,13 +160,17 @@ Do not confuse them with each other or with `state`:
|
|
|
115
160
|
|
|
116
161
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
117
162
|
Binary `.adb` snapshots are rejected (XML only).
|
|
163
|
+
|
|
118
164
|
See [docs/ac-exe.md](docs/ac-exe.md) for export / SM203520 notes and [docs/demo-seed.md](docs/demo-seed.md) for the extract/state/inventory map.
|
|
119
165
|
|
|
120
166
|
## The data repo
|
|
121
167
|
|
|
122
168
|
Your configuration lives in its own git repo.
|
|
123
169
|
`acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
|
|
124
|
-
|
|
170
|
+
|
|
171
|
+
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
172
|
+
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
173
|
+
|
|
125
174
|
There is no `--flavor`.
|
|
126
175
|
|
|
127
176
|
| Path | What it holds |
|
|
@@ -145,9 +194,15 @@ Commit `matrix.yaml` with the seeds so every clone knows verified ERP line, Defa
|
|
|
145
194
|
|
|
146
195
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
147
196
|
`acu extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
148
|
-
|
|
197
|
+
|
|
198
|
+
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
199
|
+
The demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
|
|
200
|
+
|
|
149
201
|
Features synthesize to `config/bootstrap/features.yaml`.
|
|
150
|
-
Existing files skip unless `--force`; empty live sets skip
|
|
202
|
+
Existing files skip unless `--force`; empty live sets skip.
|
|
203
|
+
|
|
204
|
+
Row failures continue (exit 1 only if any row failed).
|
|
205
|
+
Drift stays with `diff`.
|
|
151
206
|
|
|
152
207
|
```sh
|
|
153
208
|
acu --tenant DEV extract --out . --force # refresh config/** from live tenant
|
|
@@ -168,6 +223,7 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
|
|
|
168
223
|
|
|
169
224
|
`api_version` resolves as `--api-version` flag, else active `matrix.yaml` cell `default_api`, else code default `25.200.001` (never `ACU_API_VERSION` in `.env`).
|
|
170
225
|
`base_url` resolves as `--url`, else `ACU_BASE_URL`, else active cell `base_url`.
|
|
226
|
+
|
|
171
227
|
Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the dataset pin.
|
|
172
228
|
|
|
173
229
|
## Installation
|
|
@@ -192,9 +248,10 @@ Verify with `acu --version`.
|
|
|
192
248
|
|
|
193
249
|
## Configuration
|
|
194
250
|
|
|
195
|
-
Secrets live in one `.env` file (`ACU_*` vars).
|
|
196
|
-
Default contract pin live in committed `matrix.yaml` (cell `base_url` +
|
|
197
|
-
|
|
251
|
+
Secrets live in one `.env` file (`ACU_*` vars).
|
|
252
|
+
Non-secret **where** and the Default contract pin live in committed `matrix.yaml` (cell `base_url` + `default_api`).
|
|
253
|
+
|
|
254
|
+
Optional `ACU_BASE_URL` overrides cell where for ad-hoc probes.
|
|
198
255
|
|
|
199
256
|
```sh
|
|
200
257
|
# ACU_BASE_URL optional when matrix.yaml cell carries base_url
|
|
@@ -220,16 +277,17 @@ cells:
|
|
|
220
277
|
```
|
|
221
278
|
|
|
222
279
|
`--cell <id>` selects a cell (omit means first cell).
|
|
223
|
-
When present, live commands source `api_version` from cell `default_api` and
|
|
224
|
-
|
|
280
|
+
When present, live commands source `api_version` from cell `default_api` and `base_url` from the cell when flag/env leave them unset.
|
|
281
|
+
|
|
225
282
|
`acu config check` reports `ok matrix (cell=...; api_version from default_api=...; ...)`.
|
|
226
283
|
Missing `matrix.yaml` only warns on `config check` unless you pass `--strict`.
|
|
284
|
+
|
|
227
285
|
`acu check` (lifecycle) **requires** matrix.
|
|
228
286
|
|
|
229
287
|
### Multi-host matrix (V44)
|
|
230
288
|
|
|
231
|
-
One **trunk seed** in the data repo serves every host.
|
|
232
|
-
**not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
|
|
289
|
+
One **trunk seed** in the data repo serves every host.
|
|
290
|
+
Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
|
|
233
291
|
|
|
234
292
|
| Piece | Role |
|
|
235
293
|
| ----- | ---- |
|
|
@@ -238,14 +296,14 @@ One **trunk seed** in the data repo serves every host. Version fan-out is
|
|
|
238
296
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
239
297
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
240
298
|
|
|
241
|
-
**Overlays** live under `overlays/default-<default_api>/` (scaffolded by
|
|
242
|
-
|
|
299
|
+
**Overlays** live under `overlays/default-<default_api>/` (scaffolded by `acu config init`).
|
|
300
|
+
No `--overlay` flag.
|
|
243
301
|
|
|
244
|
-
**Bare compose (pin auto):** when path args are omitted, `acu apply` /
|
|
245
|
-
`acu
|
|
246
|
-
|
|
247
|
-
resolved `api_version` (matrix cell `default_api`).
|
|
248
|
-
disable auto-compose.
|
|
302
|
+
**Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
|
|
303
|
+
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
304
|
+
|
|
305
|
+
Pin = resolved `api_version` (matrix cell `default_api`).
|
|
306
|
+
Explicit path args disable auto-compose.
|
|
249
307
|
|
|
250
308
|
```sh
|
|
251
309
|
# matrix cell default_api: 24.200.001 → uses overlays/default-24.200.001/
|
|
@@ -290,6 +348,7 @@ acu apply --dry-run # show what would be written, write nothing
|
|
|
290
348
|
|
|
291
349
|
Requires **GNU Make at least 3.82** — the Makefile uses `.ONESHELL`.
|
|
292
350
|
On macOS use Homebrew's `gmake` (`brew install make`); `/usr/bin/make` is 3.81 and fails the guard.
|
|
351
|
+
|
|
293
352
|
Elsewhere plain `make` is fine when it is GNU Make.
|
|
294
353
|
|
|
295
354
|
```sh
|
|
@@ -301,6 +360,7 @@ gmake check # offline gate: ruff, basedpyright strict, pytest
|
|
|
301
360
|
|
|
302
361
|
The default test suite is fully offline.
|
|
303
362
|
REST is faked with `httpx.MockTransport`, SSH with a monkeypatched `subprocess.run` — no live instance is needed.
|
|
363
|
+
|
|
304
364
|
`gmake check` must pass before every commit.
|
|
305
365
|
GitHub Actions runs the same gate on every push and pull request to `main`.
|
|
306
366
|
|
|
@@ -308,6 +368,7 @@ GitHub Actions runs the same gate on every push and pull request to `main`.
|
|
|
308
368
|
|
|
309
369
|
Human release notes live in root [`CHANGELOG.md`](CHANGELOG.md) (Keep a Changelog).
|
|
310
370
|
During development, append user-facing work under `## Unreleased` in `### Added` / `### Changed` / `### Fixed` as appropriate.
|
|
371
|
+
|
|
311
372
|
Empty Unreleased (no bullets) hard-fails the release — nothing to ship.
|
|
312
373
|
|
|
313
374
|
```sh
|
|
@@ -333,6 +394,7 @@ Configuration is one file: a decrypted `.env` at the repo root names the instanc
|
|
|
333
394
|
|
|
334
395
|
The tier is self-contained.
|
|
335
396
|
Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
|
|
397
|
+
|
|
336
398
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
337
399
|
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
338
400
|
|
|
@@ -346,6 +408,7 @@ gmake e2e FILE=test_scenario_lifecycle # scenario + state focus
|
|
|
346
408
|
|
|
347
409
|
This project is licensed under the PolyForm Noncommercial License 1.0.0.
|
|
348
410
|
Noncommercial use is free under that license.
|
|
411
|
+
|
|
349
412
|
Commercial use requires a separate license — contact [lab5.ca](https://lab5.ca).
|
|
350
413
|
|
|
351
414
|
See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "acumatica-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.26.0"
|
|
4
4
|
description = "Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data"
|
|
5
5
|
authors = [{ name = "Konstantin Borovik", email = "kb@lab5.ca" }]
|
|
6
6
|
license = "PolyForm-Noncommercial-1.0.0"
|
|
@@ -9,7 +9,7 @@ cannot write CS100000 at all (T3 verdict) — and whose Bootstrap contract
|
|
|
9
9
|
endpoint exposes the seeding surface (serialization verified T12).
|
|
10
10
|
|
|
11
11
|
Bootstrap endpoint contract is package SoT (V2/V21/T178): always the
|
|
12
|
-
packaged full company ``bootstrap_project.xml`` (``Bootstrap/1.
|
|
12
|
+
packaged full company ``bootstrap_project.xml`` (``Bootstrap/1.6.0``).
|
|
13
13
|
Data-repo ``config/bootstrap/project.xml`` or ``bootstrap/project.xml`` is
|
|
14
14
|
not a seed — present → hard error naming package SoT (no dual contract line).
|
|
15
15
|
|
|
@@ -68,7 +68,7 @@ def _bootstrap_file(root: Path, name: str) -> Path | None:
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def packaged_contract_xml() -> bytes:
|
|
71
|
-
"""The CLI-shipped full company Bootstrap contract (``Bootstrap/1.
|
|
71
|
+
"""The CLI-shipped full company Bootstrap contract (``Bootstrap/1.6.0``)."""
|
|
72
72
|
return (resources.files("acumatica_cli") / "bootstrap_project.xml").read_bytes()
|
|
73
73
|
|
|
74
74
|
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
(SPEC T81 single full-company line; T145 bumps 1.0.0 -> 1.1.0 for Role/User;
|
|
5
5
|
T150 bumps 1.1.0 -> 1.2.0 for NumberingSequence;
|
|
6
6
|
T154/T155 bumps 1.2.0 -> 1.3.0 for *Preferences field depth, gh #26 / V41;
|
|
7
|
-
T159 bumps 1.3.0 -> 1.4.0 for NumberingSequence view-name fix
|
|
7
|
+
T159 bumps 1.3.0 -> 1.4.0 for NumberingSequence view-name fix;
|
|
8
|
+
T204 bumps 1.4.0 -> 1.5.0 for SegmentedKey, gh #30 / V50;
|
|
9
|
+
T207 bumps 1.5.0 -> 1.6.0 for SegmentedKey Detail view (B28)).
|
|
8
10
|
|
|
9
11
|
package_zip() (bootstrap.py) prefers data-repo bootstrap/project.xml when
|
|
10
12
|
present; otherwise this packaged template is the fallback so config init,
|
|
@@ -33,7 +35,7 @@
|
|
|
33
35
|
GLPreferences, INPreferences, ReasonCode, AP/AR/SO/PO/CA Preferences,
|
|
34
36
|
AvailabilityCalculationRule, PostingClass, VendorClass, StatementCycle,
|
|
35
37
|
Warehouse, OrderType, CashAccount, Role, User (+ UserRole membership detail),
|
|
36
|
-
NumberingSequence.
|
|
38
|
+
NumberingSequence, SegmentedKey.
|
|
37
39
|
|
|
38
40
|
T145 Role/User (gh #24) - Default endpoint has no Role/User surface:
|
|
39
41
|
- Role SM201005 -> RoleAccess, PrimaryView Roles (PX.SM.Roles):
|
|
@@ -62,6 +64,17 @@
|
|
|
62
64
|
live aspx + NumberingMaint reflection = Header/Sequence. Bump 1.3.0
|
|
63
65
|
-> 1.4.0 (V21). Wrong maps made every PUT 422 on NewSymbol mask.
|
|
64
66
|
|
|
67
|
+
T204 SegmentedKey (gh #30 / V50) - Default endpoint has no CS202000
|
|
68
|
+
surface; DimensionMaint Segmented Keys:
|
|
69
|
+
- PrimaryView Header (DAC Dimension): key DimensionID.
|
|
70
|
+
- Grid DataMember Detail (DAC Segment): SegmentID + Length. Live aspx
|
|
71
|
+
CS202000 DataMember is Detail (singular), not Details — T159 class
|
|
72
|
+
(B28: Details maps silent 200, GET omits Length, mask stays 10).
|
|
73
|
+
- Flat entity (NumberingSequence idiom): DimensionID on Header,
|
|
74
|
+
SegmentID/Length on Detail. One segment row per DimensionID is the
|
|
75
|
+
demo shape; multi-segment keys are out of v1. Seed updates existing
|
|
76
|
+
DimensionID only (never insert). Length = ShortValue (PXDBShort).
|
|
77
|
+
|
|
65
78
|
T154/T155 prefs-field-depth (gh #26 / V41) - curated *Preferences
|
|
66
79
|
deepen from LAB5 inventory *Setup vs virgin ERP defaults. NOT full DAC.
|
|
67
80
|
Each added field has a seed/catalog reason (demo need or rebuild risk).
|
|
@@ -95,9 +108,9 @@
|
|
|
95
108
|
Features (CS100000) stays OUT of the endpoint - the plugin owns features.
|
|
96
109
|
Shape change requires a version bump (V21).
|
|
97
110
|
-->
|
|
98
|
-
<Customization level="" description="acu bootstrap: CustomizationPlugin enables features on publish; Bootstrap endpoint exposes full company surface (company + credit terms + financial currency + GL chain + module preferences + vendor class + statement cycle + warehouse + order type + cash account + role + user + membership + numbering sequence)" product-version="26.101">
|
|
111
|
+
<Customization level="" description="acu bootstrap: CustomizationPlugin enables features on publish; Bootstrap endpoint exposes full company surface (company + credit terms + financial currency + GL chain + module preferences + vendor class + statement cycle + warehouse + order type + cash account + role + user + membership + numbering sequence + segmented key)" product-version="26.101">
|
|
99
112
|
<EntityEndpoint>
|
|
100
|
-
<Endpoint xmlns="http://www.acumatica.com/entity/maintenance/5.31" name="Bootstrap" version="1.
|
|
113
|
+
<Endpoint xmlns="http://www.acumatica.com/entity/maintenance/5.31" name="Bootstrap" version="1.6.0" systemContractVersion="4">
|
|
101
114
|
<TopLevelEntity name="Company" screen="CS101500">
|
|
102
115
|
<Fields>
|
|
103
116
|
<Field name="AcctCD" type="StringValue" />
|
|
@@ -1092,6 +1105,24 @@
|
|
|
1092
1105
|
</Mapping>
|
|
1093
1106
|
</Mappings>
|
|
1094
1107
|
</TopLevelEntity>
|
|
1108
|
+
<TopLevelEntity name="SegmentedKey" screen="CS202000">
|
|
1109
|
+
<Fields>
|
|
1110
|
+
<Field name="DimensionID" type="StringValue" />
|
|
1111
|
+
<Field name="SegmentID" type="ShortValue" />
|
|
1112
|
+
<Field name="Length" type="ShortValue" />
|
|
1113
|
+
</Fields>
|
|
1114
|
+
<Mappings>
|
|
1115
|
+
<Mapping field="DimensionID">
|
|
1116
|
+
<To object="Header" field="DimensionID" />
|
|
1117
|
+
</Mapping>
|
|
1118
|
+
<Mapping field="SegmentID">
|
|
1119
|
+
<To object="Detail" field="SegmentID" />
|
|
1120
|
+
</Mapping>
|
|
1121
|
+
<Mapping field="Length">
|
|
1122
|
+
<To object="Detail" field="Length" />
|
|
1123
|
+
</Mapping>
|
|
1124
|
+
</Mappings>
|
|
1125
|
+
</TopLevelEntity>
|
|
1095
1126
|
</Endpoint>
|
|
1096
1127
|
</EntityEndpoint>
|
|
1097
1128
|
</Customization>
|
|
@@ -55,6 +55,10 @@ INIT_TEMPLATES = (
|
|
|
55
55
|
("README.md", "README.md"),
|
|
56
56
|
("config/bootstrap/company.yaml", "config/bootstrap/company.yaml"),
|
|
57
57
|
("config/bootstrap/credit-terms.yaml", "config/bootstrap/credit-terms.yaml"),
|
|
58
|
+
(
|
|
59
|
+
"config/bootstrap/segmented-key.yaml",
|
|
60
|
+
"config/bootstrap/segmented-key.yaml",
|
|
61
|
+
),
|
|
58
62
|
("config/bootstrap/features.yaml", "config/bootstrap/features.yaml"),
|
|
59
63
|
("config/baseline/10-subaccounts.yaml", "config/baseline/10-subaccounts.yaml"),
|
|
60
64
|
("config/baseline/20-accounts.yaml", "config/baseline/20-accounts.yaml"),
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# entity contract entity name (the GET source and the emitted `entity:`)
|
|
7
7
|
# endpoint omitted = the instance Default endpoint; the symbolic name
|
|
8
8
|
# `bootstrap` stays symbolic in emitted files and resolves to
|
|
9
|
-
# the packaged full company Bootstrap/1.
|
|
9
|
+
# the packaged full company Bootstrap/1.6.0 at HTTP/load time
|
|
10
10
|
# (package SoT - V20/V21/T178; data-repo project.xml forbidden)
|
|
11
11
|
# keys key fields: the emitted `key:`, the record sort order, and
|
|
12
12
|
# the B9 fallback's $select projection; the tuple must
|
|
@@ -68,6 +68,20 @@ entities:
|
|
|
68
68
|
- DiscType
|
|
69
69
|
- DiscPercent
|
|
70
70
|
|
|
71
|
+
# SegmentedKey (T205/gh #30 / V50): V22 bootstrap/ sorts before master
|
|
72
|
+
# StockItem / Vendor / Customer. Bootstrap only — Default has no CS202000
|
|
73
|
+
# surface. Update existing DimensionID only (never insert). Seed INVENTORY
|
|
74
|
+
# + BIZACCT one alphanumeric segment Length 30 (DAC max); ACCOUNT + INSITE
|
|
75
|
+
# stay Length 10 (SiteCD NVarChar(10)) so they stay out of this file.
|
|
76
|
+
|
|
77
|
+
- entity: SegmentedKey
|
|
78
|
+
endpoint: bootstrap
|
|
79
|
+
keys: [DimensionID]
|
|
80
|
+
file: config/bootstrap/segmented-key.yaml
|
|
81
|
+
include:
|
|
82
|
+
- SegmentID
|
|
83
|
+
- Length
|
|
84
|
+
|
|
71
85
|
# config/baseline/ - numbered prefixes encode the V22 reference chain:
|
|
72
86
|
# subaccounts < accounts < ledger < GL preferences < org-ledger link;
|
|
73
87
|
# units of measure. Multicurrency Currency is not in the LAB5 template
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/20-buy.yaml
RENAMED
|
File without changes
|
{acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/30-build.yaml
RENAMED
|
File without changes
|
{acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/40-sell.yaml
RENAMED
|
File without changes
|
|
File without changes
|