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.
Files changed (77) hide show
  1. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/PKG-INFO +91 -28
  2. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/README.md +90 -27
  3. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/pyproject.toml +1 -1
  4. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/pyproject.toml.orig +1 -1
  5. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap.py +2 -2
  6. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap_project.xml +35 -4
  7. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/config.py +4 -0
  8. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/seed_catalog.yaml +15 -1
  9. acumatica_cli-0.26.0/src/acumatica_cli/templates/config/bootstrap/segmented-key.yaml +10 -0
  10. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/__init__.py +0 -0
  11. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
  12. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/cli.py +0 -0
  13. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/client.py +0 -0
  14. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/extract.py +0 -0
  15. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/firstlogin.py +0 -0
  16. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/inventory.py +0 -0
  17. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/matrix.py +0 -0
  18. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/models.py +0 -0
  19. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/output.py +0 -0
  20. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/reconcile.py +0 -0
  21. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/run.py +0 -0
  22. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/seed.py +0 -0
  23. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
  24. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/state.py +0 -0
  25. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/README.md +0 -0
  26. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/10-subaccounts.yaml +0 -0
  27. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/20-accounts.yaml +0 -0
  28. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/40-ledger.yaml +0 -0
  29. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/50-gl-preferences.yaml +0 -0
  30. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/60-ledger-company.yaml +0 -0
  31. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/baseline/90-uoms.yaml +0 -0
  32. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/company.yaml +0 -0
  33. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/credit-terms.yaml +0 -0
  34. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/bootstrap/features.yaml +0 -0
  35. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/05-numbering-sequences.yaml +0 -0
  36. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/10-reason-codes.yaml +0 -0
  37. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/20-in-preferences.yaml +0 -0
  38. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/30-availability-rules.yaml +0 -0
  39. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/40-posting-classes.yaml +0 -0
  40. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/50-warehouse.yaml +0 -0
  41. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/51-warehouse-locations.yaml +0 -0
  42. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/52-warehouse-defaults.yaml +0 -0
  43. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/53-tax-categories.yaml +0 -0
  44. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/54-item-classes.yaml +0 -0
  45. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/56-so-preferences.yaml +0 -0
  46. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/57-po-preferences.yaml +0 -0
  47. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/58-order-types.yaml +0 -0
  48. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/60-ar-preferences.yaml +0 -0
  49. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/61-ap-preferences.yaml +0 -0
  50. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/62-ca-preferences.yaml +0 -0
  51. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/63-cash-account.yaml +0 -0
  52. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/64-payment-methods.yaml +0 -0
  53. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/65-statement-cycles.yaml +0 -0
  54. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/70-vendor-classes.yaml +0 -0
  55. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/71-customer-classes.yaml +0 -0
  56. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/75-vendors.yaml +0 -0
  57. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/76-customers.yaml +0 -0
  58. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/80-stock-items-parts.yaml +0 -0
  59. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/82-stock-items-kits.yaml +0 -0
  60. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/85-kit-specifications.yaml +0 -0
  61. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/90-roles.yaml +0 -0
  62. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/master/91-users.yaml +0 -0
  63. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/10-financial-year.yaml +0 -0
  64. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/20-master-calendar.yaml +0 -0
  65. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/setup/30-open-periods.yaml +0 -0
  66. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/config/views/10-trial-balance.yaml +0 -0
  67. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/env +0 -0
  68. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/gitignore +0 -0
  69. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/matrix +0 -0
  70. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/README.md +0 -0
  71. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +0 -0
  72. {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
  73. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/10-seed-capital.yaml +0 -0
  74. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/20-buy.yaml +0 -0
  75. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/30-build.yaml +0 -0
  76. {acumatica_cli-0.25.2 → acumatica_cli-0.26.0}/src/acumatica_cli/templates/scenario/40-sell.yaml +0 -0
  77. {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.25.2
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` (scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes).
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
- `apply` and `diff` without FILES prefer `config/<name>/` when any seed child exists under `config/`; otherwise root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
108
- A path like `config/` expands nested seed dirs in that fixed order.
109
- `run` without FILES defaults to `scenario/`. Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and once.present params; `config/views` / `state` keep Period pinned (see [docs/demo-seed.md](docs/demo-seed.md#period-token-current_period-vs-pinned-views)).
110
- `state` without FILES defaults to `config/views/`; writes go to `state/` (`--out`).
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
- `inventory` is offline (no REST/SSH/password): SM203520 Settings XML ZIP or `ac.exe export xml` folder writes to `inventory/`.
113
- `reconcile` is offline: compare `inventory/` to optional `config/` and write `findings/` only (never writes seed).
114
- Optional `snapshot_map.yaml` (data-repo root or package defaults) maps DAC tables to catalog entities and normalizes join (pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code).
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
- Run `acu --help` for the full mental model (workflow, planes, exit codes,
118
- command map) enough for an agent to learn the tool without extra docs.
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
- The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`); `config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
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
- Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split); the demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
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; row failures continue (exit 1 only if any row failed — drift stays with `diff`).
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). Non-secret **where** and the
214
- Default contract pin live in committed `matrix.yaml` (cell `base_url` +
215
- `default_api`). Optional `ACU_BASE_URL` overrides cell where for ad-hoc probes.
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
- `base_url` from the cell when flag/env leave them unset.
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. Version fan-out is
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
- `acu config init`). No `--overlay` flag.
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 diff` append overlay config seed dirs when present; `acu run` replaces
264
- same-basename scenario files from the pin overlay. Pin =
265
- resolved `api_version` (matrix cell `default_api`). Explicit path args
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` (scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes).
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
- `apply` and `diff` without FILES prefer `config/<name>/` when any seed child exists under `config/`; otherwise root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
90
- A path like `config/` expands nested seed dirs in that fixed order.
91
- `run` without FILES defaults to `scenario/`. Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and once.present params; `config/views` / `state` keep Period pinned (see [docs/demo-seed.md](docs/demo-seed.md#period-token-current_period-vs-pinned-views)).
92
- `state` without FILES defaults to `config/views/`; writes go to `state/` (`--out`).
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
- `inventory` is offline (no REST/SSH/password): SM203520 Settings XML ZIP or `ac.exe export xml` folder writes to `inventory/`.
95
- `reconcile` is offline: compare `inventory/` to optional `config/` and write `findings/` only (never writes seed).
96
- Optional `snapshot_map.yaml` (data-repo root or package defaults) maps DAC tables to catalog entities and normalizes join (pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code).
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
- Run `acu --help` for the full mental model (workflow, planes, exit codes,
100
- command map) enough for an agent to learn the tool without extra docs.
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
- The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`); `config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
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
- Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split); the demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
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; row failures continue (exit 1 only if any row failed — drift stays with `diff`).
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). Non-secret **where** and the
196
- Default contract pin live in committed `matrix.yaml` (cell `base_url` +
197
- `default_api`). Optional `ACU_BASE_URL` overrides cell where for ad-hoc probes.
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
- `base_url` from the cell when flag/env leave them unset.
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. Version fan-out is
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
- `acu config init`). No `--overlay` flag.
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 diff` append overlay config seed dirs when present; `acu run` replaces
246
- same-basename scenario files from the pin overlay. Pin =
247
- resolved `api_version` (matrix cell `default_api`). Explicit path args
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.25.2"
3
+ version = "0.26.0"
4
4
  description = "Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data"
5
5
  license = "PolyForm-Noncommercial-1.0.0"
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acumatica-cli"
3
- version = "0.25.2"
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.4.0``).
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.4.0``)."""
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.4.0" systemContractVersion="4">
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.4.0 at HTTP/load time
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
@@ -0,0 +1,10 @@
1
+ entity: SegmentedKey
2
+ key: DimensionID
3
+ endpoint: bootstrap
4
+ records:
5
+ - DimensionID: BIZACCT
6
+ SegmentID: 1
7
+ Length: 30
8
+ - DimensionID: INVENTORY
9
+ SegmentID: 1
10
+ Length: 30