acumatica-cli 0.26.0__tar.gz → 0.28.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.26.0 → acumatica_cli-0.28.0}/PKG-INFO +40 -56
  2. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/README.md +39 -55
  3. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/pyproject.toml +1 -1
  4. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/pyproject.toml.orig +1 -1
  5. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/bootstrap.py +2 -2
  6. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/bootstrap_project.xml +16 -2
  7. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/cli.py +63 -304
  8. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/config.py +35 -71
  9. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/inventory.py +3 -19
  10. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/seed.py +1 -1
  11. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/seed_catalog.yaml +8 -2
  12. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/README.md +6 -8
  13. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/20-accounts.yaml +0 -6
  14. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/env +6 -5
  15. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/overlays/README.md +7 -6
  16. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +3 -2
  17. acumatica_cli-0.26.0/src/acumatica_cli/matrix.py +0 -155
  18. acumatica_cli-0.26.0/src/acumatica_cli/templates/matrix +0 -9
  19. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/__init__.py +0 -0
  20. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
  21. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/client.py +0 -0
  22. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/extract.py +0 -0
  23. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/firstlogin.py +0 -0
  24. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/models.py +0 -0
  25. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/output.py +0 -0
  26. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/reconcile.py +0 -0
  27. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/run.py +0 -0
  28. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
  29. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/state.py +0 -0
  30. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/10-subaccounts.yaml +0 -0
  31. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/40-ledger.yaml +0 -0
  32. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/50-gl-preferences.yaml +0 -0
  33. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/60-ledger-company.yaml +0 -0
  34. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/baseline/90-uoms.yaml +0 -0
  35. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/bootstrap/company.yaml +0 -0
  36. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/bootstrap/credit-terms.yaml +0 -0
  37. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/bootstrap/features.yaml +0 -0
  38. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/bootstrap/segmented-key.yaml +0 -0
  39. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/05-numbering-sequences.yaml +0 -0
  40. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/10-reason-codes.yaml +0 -0
  41. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/20-in-preferences.yaml +0 -0
  42. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/30-availability-rules.yaml +0 -0
  43. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/40-posting-classes.yaml +0 -0
  44. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/50-warehouse.yaml +0 -0
  45. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/51-warehouse-locations.yaml +0 -0
  46. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/52-warehouse-defaults.yaml +0 -0
  47. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/53-tax-categories.yaml +0 -0
  48. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/54-item-classes.yaml +0 -0
  49. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/56-so-preferences.yaml +0 -0
  50. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/57-po-preferences.yaml +0 -0
  51. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/58-order-types.yaml +0 -0
  52. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/60-ar-preferences.yaml +0 -0
  53. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/61-ap-preferences.yaml +0 -0
  54. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/62-ca-preferences.yaml +0 -0
  55. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/63-cash-account.yaml +0 -0
  56. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/64-payment-methods.yaml +0 -0
  57. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/65-statement-cycles.yaml +0 -0
  58. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/70-vendor-classes.yaml +0 -0
  59. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/71-customer-classes.yaml +0 -0
  60. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/75-vendors.yaml +0 -0
  61. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/76-customers.yaml +0 -0
  62. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/80-stock-items-parts.yaml +0 -0
  63. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/82-stock-items-kits.yaml +0 -0
  64. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/85-kit-specifications.yaml +0 -0
  65. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/90-roles.yaml +0 -0
  66. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/master/91-users.yaml +0 -0
  67. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/setup/10-financial-year.yaml +0 -0
  68. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/setup/20-master-calendar.yaml +0 -0
  69. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/setup/30-open-periods.yaml +0 -0
  70. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/config/views/10-trial-balance.yaml +0 -0
  71. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/gitignore +0 -0
  72. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/overlays/default-24.200.001/scenario/30-build.yaml +0 -0
  73. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/scenario/10-seed-capital.yaml +0 -0
  74. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/scenario/20-buy.yaml +0 -0
  75. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/scenario/30-build.yaml +0 -0
  76. {acumatica_cli-0.26.0 → acumatica_cli-0.28.0}/src/acumatica_cli/templates/scenario/40-sell.yaml +0 -0
  77. {acumatica_cli-0.26.0 → acumatica_cli-0.28.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.26.0
3
+ Version: 0.28.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>
@@ -49,8 +49,8 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
49
49
  | Snapshot a site offline | `inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
50
50
  | Cross-check snapshot vs seed | `reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
51
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 |
52
+ | Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
53
+ | Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
54
54
 
55
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
56
 
@@ -65,11 +65,11 @@ Hosted sites skip SSH.
65
65
  uv tool install acumatica-cli
66
66
 
67
67
  acu config init --host erp.example.com my-erp
68
- cd my-erp # edit .env: set ACU_PASSWORD, ACU_TENANT
69
- # pin+where = matrix.yaml cell (default_api + base_url)
68
+ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
69
+ # ACU_BASE_URL is where; ACU_API_VERSION pins Default
70
70
  # start from a brand-new empty tenant
71
71
 
72
- acu config check # read-only preflight (incl. matrix.yaml)
72
+ acu config check # read-only preflight
73
73
  acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
74
74
  # or hosted: acu --tenant DEV bootstrap
75
75
  acu --tenant DEV apply config/ # seed config/{bootstrap,baseline,setup,master}/
@@ -99,7 +99,7 @@ acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
99
99
  ## CLI map
100
100
 
101
101
  ```text
102
- acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
102
+ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
103
103
  [--username U] [--password P] [--version] [--completion [SHELL]]
104
104
 
105
105
  ├── tenant tenant CRUD (ac.exe over SSH — control plane)
@@ -115,7 +115,7 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
115
115
  ├── apply [--dry-run] [FILES...] push YAML via REST (idempotent PUT upserts)
116
116
  ├── diff [FILES...] drift check vs the live tenant (exit 2 on drift)
117
117
  ├── run [--dry-run] [FILES...] execute transaction scenario YAML (exit 1 on any miss)
118
- ├── check [--all] [--yes] [--tenant L] cold lifecycle create→apply→run→diff; leave tenant (V47)
118
+ ├── check [--yes] [--tenant L] cold lifecycle create→apply→run→diff; leave tenant (V47)
119
119
  ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] [FILES...]
120
120
  │ capture derived state into state/ (not seed)
121
121
  ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
@@ -127,9 +127,9 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
127
127
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
128
128
 
129
129
  └── config configuration ops
130
- ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, matrix.yaml)
130
+ ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
131
131
  ├── show print the resolved config as a complete .env
132
- └── check [--strict] preflight: discovery, secrets, matrix, REST, endpoints, SSH
132
+ └── check preflight: discovery, secrets, REST, endpoints, SSH
133
133
  ```
134
134
 
135
135
  When you omit FILES:
@@ -202,13 +202,12 @@ There is no `--flavor`.
202
202
  | `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
203
203
  | `inventory/` | engagement: offline snapshot tables from `acu inventory` (not seed; not SEED_DIRS) |
204
204
  | `findings/` | engagement: `acu reconcile` cross-check output (never apply path) |
205
- | `matrix.yaml` | multi-host pin+where: cells `id`+`erp`+`default_api`+`base_url` (V27); `--cell` selects |
206
- | `.env` | secrets + optional where override (`ACU_*`); never Default API pin |
205
+ | `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
207
206
 
208
207
  Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
209
208
 
210
209
  Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
211
- Commit `matrix.yaml` with the seeds so every clone knows verified ERP line, Default API half, and REST where per cell.
210
+ Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
212
211
 
213
212
  Seed YAML is state: `apply` upserts it, `diff` proves it.
214
213
  `acu extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
@@ -239,8 +238,8 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
239
238
  | `default` | `Default/<api_version>` — tracks the resolved API version |
240
239
  | `Bootstrap/1.4.0` or `Default/25.200.001` | literal pin (ignores the resolved Default version) |
241
240
 
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`).
243
- `base_url` resolves as `--url`, else `ACU_BASE_URL`, else active cell `base_url`.
241
+ `api_version` resolves as `--api-version` flag, else `ACU_API_VERSION` in `.env`, else code default `25.200.001`.
242
+ `base_url` resolves as `--url`, else `ACU_BASE_URL` (required).
244
243
 
245
244
  Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the dataset pin.
246
245
 
@@ -266,75 +265,61 @@ Verify with `acu --version`.
266
265
 
267
266
  ## Configuration
268
267
 
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.
268
+ Secrets, REST where, and the Default contract pin live in one `.env` file (`ACU_*` vars).
269
+ Leftover `matrix.yaml` is ignored and never loaded.
273
270
 
274
271
  ```sh
275
- # ACU_BASE_URL optional when matrix.yaml cell carries base_url
276
- ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
272
+ ACU_BASE_URL=http://acu-dev1.vm.internal/AcumaticaERP # REST where (required)
273
+ ACU_API_VERSION=25.200.001 # Default contract half
274
+ ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
277
275
  # ACU_SSH omitted → defaults to Administrator@ + resolved base_url host
278
- # ACU_SSH= # hosted opt-out (blank key)
279
- ACU_USER=admin # optional, defaults to admin
280
- ACU_PASSWORD=... # required for live commands
276
+ # ACU_SSH= # hosted opt-out (blank key)
277
+ ACU_USER=admin # optional, defaults to admin
278
+ ACU_PASSWORD=... # required for live commands
281
279
  ```
282
280
 
283
- There is no `ACU_API_VERSION` env key (unknown `ACU_*` vars are ignored).
284
281
  Ad-hoc override: `acu --api-version 24.200.001 …` (version half only, never
285
282
  `Default/25.200.001` — a full path would nest as `/entity/Default/Default/...`).
286
283
 
287
- Committed `matrix.yaml` is the **sole data-repo pin+where registry** (1..N cells):
288
-
289
- ```yaml
290
- cells:
291
- - id: "default"
292
- erp: "26.101.0225" # claimed product line/build
293
- default_api: "25.200.001" # sources Instance.api_version when --api-version absent
294
- base_url: "http://acu-dev1.vm.internal/AcumaticaERP"
295
- ```
296
-
297
- `--cell <id>` selects a cell (omit means first cell).
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
-
300
- `acu config check` reports `ok matrix (cell=...; api_version from default_api=...; ...)`.
301
- Missing `matrix.yaml` only warns on `config check` unless you pass `--strict`.
284
+ `api_version` resolves as `--api-version`, else `ACU_API_VERSION`, else `25.200.001`.
285
+ `base_url` resolves as `--url`, else `ACU_BASE_URL`, else a hard error naming sources.
302
286
 
303
- `acu check` (lifecycle) **requires** matrix.
287
+ `acu config show` prints the resolved `.env` (password excluded; includes `ACU_API_VERSION`).
288
+ `acu check` (lifecycle) uses the same resolved instance.
304
289
 
305
- ### Multi-host matrix (V44)
290
+ ### Multi-host overlays (V44)
306
291
 
307
292
  One **trunk seed** in the data repo serves every host.
308
293
  Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
309
294
 
310
295
  | Piece | Role |
311
296
  | ----- | ---- |
312
- | Trunk seed | Canonical `config/` + `scenario/` (newest supported matrix) |
313
- | `matrix.yaml` cells | Each host: `id`+`erp`+`default_api`+`base_url`; `--cell` / `acu check --all` |
297
+ | Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
298
+ | `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
314
299
  | Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
315
300
  | OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
316
301
 
317
- **Overlays** live under `overlays/default-<default_api>/` (scaffolded by `acu config init`).
302
+ **Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
318
303
  No `--overlay` flag.
319
304
 
320
305
  **Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
321
306
  `acu run` replaces same-basename scenario files from the pin overlay.
322
307
 
323
- Pin = resolved `api_version` (matrix cell `default_api`).
308
+ Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
324
309
  Explicit path args disable auto-compose.
325
310
 
326
311
  ```sh
327
- # matrix cell default_api: 24.200.001 → uses overlays/default-24.200.001/
328
- acu --cell lab25 apply
329
- acu --cell lab25 run
330
- acu --cell lab25 diff
312
+ # ACU_API_VERSION=24.200.001 → uses overlays/default-24.200.001/
313
+ acu apply
314
+ acu run
315
+ acu diff
331
316
 
332
317
  # explicit path args (no auto) — later path wins same keys
333
318
  acu apply config/ overlays/default-24.200.001/
334
319
  acu diff config/ overlays/default-24.200.001/
335
320
 
336
- # cold lifecycle every cell (SSH + tenant required); tenants left for inspect
337
- acu check --all --yes --tenant LAB5
321
+ # cold lifecycle vs the resolved .env instance (SSH + tenant required)
322
+ acu check --yes --tenant LAB5
338
323
  ```
339
324
 
340
325
  Add a future half by creating `overlays/default-<new-half>/` with the
@@ -347,18 +332,17 @@ Sibling data-repo retirement of release branches:
347
332
  Worth knowing:
348
333
 
349
334
  - The `.env` file is found by walking up from the current directory, so any subdirectory of the data repo works.
350
- - Without a `.env`, global flags plus the process environment (and matrix cell where) supply the configuration.
335
+ - Without a `.env`, global flags plus the process environment supply the configuration.
351
336
  - When `ACU_SSH` is **absent**, acu defaults to `Administrator@` + the resolved base_url hostname.
352
337
  A **present blank** `ACU_SSH=` is the hosted opt-out.
353
338
  Only `acu tenant` / `acu check` require a non-empty value post-default.
354
- - `acu config show` prints the resolved `.env` (password excluded; never `ACU_API_VERSION`) and comments active cell id/erp/default_api/base_url plus api_version source when `matrix.yaml` is present.
339
+ - `acu config show` prints the resolved `.env` (password excluded).
355
340
  - Redirect it to turn resolved state into a working config: `acu config show > .env`.
356
341
 
357
342
  Verify before touching anything live:
358
343
 
359
344
  ```sh
360
- acu config check # discovery, secrets, matrix, REST, endpoints, SSH
361
- acu config check --strict # missing matrix.yaml becomes fail
345
+ acu config check # discovery, secrets, REST, endpoints, SSH
362
346
  acu apply --dry-run # show what would be written, write nothing
363
347
  ```
364
348
 
@@ -31,8 +31,8 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
31
31
  | Snapshot a site offline | `inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
32
32
  | Cross-check snapshot vs seed | `reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
33
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 |
34
+ | Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
35
+ | Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
36
36
 
37
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
38
 
@@ -47,11 +47,11 @@ Hosted sites skip SSH.
47
47
  uv tool install acumatica-cli
48
48
 
49
49
  acu config init --host erp.example.com my-erp
50
- cd my-erp # edit .env: set ACU_PASSWORD, ACU_TENANT
51
- # pin+where = matrix.yaml cell (default_api + base_url)
50
+ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
51
+ # ACU_BASE_URL is where; ACU_API_VERSION pins Default
52
52
  # start from a brand-new empty tenant
53
53
 
54
- acu config check # read-only preflight (incl. matrix.yaml)
54
+ acu config check # read-only preflight
55
55
  acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
56
56
  # or hosted: acu --tenant DEV bootstrap
57
57
  acu --tenant DEV apply config/ # seed config/{bootstrap,baseline,setup,master}/
@@ -81,7 +81,7 @@ acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
81
81
  ## CLI map
82
82
 
83
83
  ```text
84
- acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
84
+ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
85
85
  [--username U] [--password P] [--version] [--completion [SHELL]]
86
86
 
87
87
  ├── tenant tenant CRUD (ac.exe over SSH — control plane)
@@ -97,7 +97,7 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
97
97
  ├── apply [--dry-run] [FILES...] push YAML via REST (idempotent PUT upserts)
98
98
  ├── diff [FILES...] drift check vs the live tenant (exit 2 on drift)
99
99
  ├── run [--dry-run] [FILES...] execute transaction scenario YAML (exit 1 on any miss)
100
- ├── check [--all] [--yes] [--tenant L] cold lifecycle create→apply→run→diff; leave tenant (V47)
100
+ ├── check [--yes] [--tenant L] cold lifecycle create→apply→run→diff; leave tenant (V47)
101
101
  ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] [FILES...]
102
102
  │ capture derived state into state/ (not seed)
103
103
  ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
@@ -109,9 +109,9 @@ acu [--cell ID] [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
109
109
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
110
110
 
111
111
  └── config configuration ops
112
- ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, matrix.yaml)
112
+ ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
113
113
  ├── show print the resolved config as a complete .env
114
- └── check [--strict] preflight: discovery, secrets, matrix, REST, endpoints, SSH
114
+ └── check preflight: discovery, secrets, REST, endpoints, SSH
115
115
  ```
116
116
 
117
117
  When you omit FILES:
@@ -184,13 +184,12 @@ There is no `--flavor`.
184
184
  | `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
185
185
  | `inventory/` | engagement: offline snapshot tables from `acu inventory` (not seed; not SEED_DIRS) |
186
186
  | `findings/` | engagement: `acu reconcile` cross-check output (never apply path) |
187
- | `matrix.yaml` | multi-host pin+where: cells `id`+`erp`+`default_api`+`base_url` (V27); `--cell` selects |
188
- | `.env` | secrets + optional where override (`ACU_*`); never Default API pin |
187
+ | `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
189
188
 
190
189
  Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
191
190
 
192
191
  Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
193
- Commit `matrix.yaml` with the seeds so every clone knows verified ERP line, Default API half, and REST where per cell.
192
+ Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
194
193
 
195
194
  Seed YAML is state: `apply` upserts it, `diff` proves it.
196
195
  `acu extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
@@ -221,8 +220,8 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
221
220
  | `default` | `Default/<api_version>` — tracks the resolved API version |
222
221
  | `Bootstrap/1.4.0` or `Default/25.200.001` | literal pin (ignores the resolved Default version) |
223
222
 
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`).
225
- `base_url` resolves as `--url`, else `ACU_BASE_URL`, else active cell `base_url`.
223
+ `api_version` resolves as `--api-version` flag, else `ACU_API_VERSION` in `.env`, else code default `25.200.001`.
224
+ `base_url` resolves as `--url`, else `ACU_BASE_URL` (required).
226
225
 
227
226
  Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the dataset pin.
228
227
 
@@ -248,75 +247,61 @@ Verify with `acu --version`.
248
247
 
249
248
  ## Configuration
250
249
 
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.
250
+ Secrets, REST where, and the Default contract pin live in one `.env` file (`ACU_*` vars).
251
+ Leftover `matrix.yaml` is ignored and never loaded.
255
252
 
256
253
  ```sh
257
- # ACU_BASE_URL optional when matrix.yaml cell carries base_url
258
- ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
254
+ ACU_BASE_URL=http://acu-dev1.vm.internal/AcumaticaERP # REST where (required)
255
+ ACU_API_VERSION=25.200.001 # Default contract half
256
+ ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
259
257
  # ACU_SSH omitted → defaults to Administrator@ + resolved base_url host
260
- # ACU_SSH= # hosted opt-out (blank key)
261
- ACU_USER=admin # optional, defaults to admin
262
- ACU_PASSWORD=... # required for live commands
258
+ # ACU_SSH= # hosted opt-out (blank key)
259
+ ACU_USER=admin # optional, defaults to admin
260
+ ACU_PASSWORD=... # required for live commands
263
261
  ```
264
262
 
265
- There is no `ACU_API_VERSION` env key (unknown `ACU_*` vars are ignored).
266
263
  Ad-hoc override: `acu --api-version 24.200.001 …` (version half only, never
267
264
  `Default/25.200.001` — a full path would nest as `/entity/Default/Default/...`).
268
265
 
269
- Committed `matrix.yaml` is the **sole data-repo pin+where registry** (1..N cells):
270
-
271
- ```yaml
272
- cells:
273
- - id: "default"
274
- erp: "26.101.0225" # claimed product line/build
275
- default_api: "25.200.001" # sources Instance.api_version when --api-version absent
276
- base_url: "http://acu-dev1.vm.internal/AcumaticaERP"
277
- ```
278
-
279
- `--cell <id>` selects a cell (omit means first cell).
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
-
282
- `acu config check` reports `ok matrix (cell=...; api_version from default_api=...; ...)`.
283
- Missing `matrix.yaml` only warns on `config check` unless you pass `--strict`.
266
+ `api_version` resolves as `--api-version`, else `ACU_API_VERSION`, else `25.200.001`.
267
+ `base_url` resolves as `--url`, else `ACU_BASE_URL`, else a hard error naming sources.
284
268
 
285
- `acu check` (lifecycle) **requires** matrix.
269
+ `acu config show` prints the resolved `.env` (password excluded; includes `ACU_API_VERSION`).
270
+ `acu check` (lifecycle) uses the same resolved instance.
286
271
 
287
- ### Multi-host matrix (V44)
272
+ ### Multi-host overlays (V44)
288
273
 
289
274
  One **trunk seed** in the data repo serves every host.
290
275
  Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`, …).
291
276
 
292
277
  | Piece | Role |
293
278
  | ----- | ---- |
294
- | Trunk seed | Canonical `config/` + `scenario/` (newest supported matrix) |
295
- | `matrix.yaml` cells | Each host: `id`+`erp`+`default_api`+`base_url`; `--cell` / `acu check --all` |
279
+ | Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
280
+ | `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
296
281
  | Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
297
282
  | OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
298
283
 
299
- **Overlays** live under `overlays/default-<default_api>/` (scaffolded by `acu config init`).
284
+ **Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
300
285
  No `--overlay` flag.
301
286
 
302
287
  **Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
303
288
  `acu run` replaces same-basename scenario files from the pin overlay.
304
289
 
305
- Pin = resolved `api_version` (matrix cell `default_api`).
290
+ Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
306
291
  Explicit path args disable auto-compose.
307
292
 
308
293
  ```sh
309
- # matrix cell default_api: 24.200.001 → uses overlays/default-24.200.001/
310
- acu --cell lab25 apply
311
- acu --cell lab25 run
312
- acu --cell lab25 diff
294
+ # ACU_API_VERSION=24.200.001 → uses overlays/default-24.200.001/
295
+ acu apply
296
+ acu run
297
+ acu diff
313
298
 
314
299
  # explicit path args (no auto) — later path wins same keys
315
300
  acu apply config/ overlays/default-24.200.001/
316
301
  acu diff config/ overlays/default-24.200.001/
317
302
 
318
- # cold lifecycle every cell (SSH + tenant required); tenants left for inspect
319
- acu check --all --yes --tenant LAB5
303
+ # cold lifecycle vs the resolved .env instance (SSH + tenant required)
304
+ acu check --yes --tenant LAB5
320
305
  ```
321
306
 
322
307
  Add a future half by creating `overlays/default-<new-half>/` with the
@@ -329,18 +314,17 @@ Sibling data-repo retirement of release branches:
329
314
  Worth knowing:
330
315
 
331
316
  - The `.env` file is found by walking up from the current directory, so any subdirectory of the data repo works.
332
- - Without a `.env`, global flags plus the process environment (and matrix cell where) supply the configuration.
317
+ - Without a `.env`, global flags plus the process environment supply the configuration.
333
318
  - When `ACU_SSH` is **absent**, acu defaults to `Administrator@` + the resolved base_url hostname.
334
319
  A **present blank** `ACU_SSH=` is the hosted opt-out.
335
320
  Only `acu tenant` / `acu check` require a non-empty value post-default.
336
- - `acu config show` prints the resolved `.env` (password excluded; never `ACU_API_VERSION`) and comments active cell id/erp/default_api/base_url plus api_version source when `matrix.yaml` is present.
321
+ - `acu config show` prints the resolved `.env` (password excluded).
337
322
  - Redirect it to turn resolved state into a working config: `acu config show > .env`.
338
323
 
339
324
  Verify before touching anything live:
340
325
 
341
326
  ```sh
342
- acu config check # discovery, secrets, matrix, REST, endpoints, SSH
343
- acu config check --strict # missing matrix.yaml becomes fail
327
+ acu config check # discovery, secrets, REST, endpoints, SSH
344
328
  acu apply --dry-run # show what would be written, write nothing
345
329
  ```
346
330
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acumatica-cli"
3
- version = "0.26.0"
3
+ version = "0.28.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.26.0"
3
+ version = "0.28.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.6.0``).
12
+ packaged full company ``bootstrap_project.xml`` (``Bootstrap/1.7.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.6.0``)."""
71
+ """The CLI-shipped full company Bootstrap contract (``Bootstrap/1.7.0``)."""
72
72
  return (resources.files("acumatica_cli") / "bootstrap_project.xml").read_bytes()
73
73
 
74
74
 
@@ -6,7 +6,9 @@
6
6
  T154/T155 bumps 1.2.0 -> 1.3.0 for *Preferences field depth, gh #26 / V41;
7
7
  T159 bumps 1.3.0 -> 1.4.0 for NumberingSequence view-name fix;
8
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)).
9
+ T207 bumps 1.5.0 -> 1.6.0 for SegmentedKey Detail view (B28);
10
+ gh #34 bumps 1.6.0 -> 1.7.0 for Company DecPlQty + WeightUOM/VolumeUOM
11
+ (CS101500 commonsetup; kit BOM milligram-scale KG needs qty precision 3).
10
12
 
11
13
  package_zip() (bootstrap.py) prefers data-repo bootstrap/project.xml when
12
14
  present; otherwise this packaged template is the fallback so config init,
@@ -110,7 +112,7 @@
110
112
  -->
111
113
  <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">
112
114
  <EntityEndpoint>
113
- <Endpoint xmlns="http://www.acumatica.com/entity/maintenance/5.31" name="Bootstrap" version="1.6.0" systemContractVersion="4">
115
+ <Endpoint xmlns="http://www.acumatica.com/entity/maintenance/5.31" name="Bootstrap" version="1.7.0" systemContractVersion="4">
114
116
  <TopLevelEntity name="Company" screen="CS101500">
115
117
  <Fields>
116
118
  <Field name="AcctCD" type="StringValue" />
@@ -118,6 +120,9 @@
118
120
  <Field name="OrganizationType" type="StringValue" />
119
121
  <Field name="BaseCuryID" type="StringValue" />
120
122
  <Field name="CountryID" type="StringValue" />
123
+ <Field name="DecPlQty" type="ShortValue" />
124
+ <Field name="WeightUOM" type="StringValue" />
125
+ <Field name="VolumeUOM" type="StringValue" />
121
126
  </Fields>
122
127
  <Mappings>
123
128
  <Mapping field="AcctCD">
@@ -135,6 +140,15 @@
135
140
  <Mapping field="CountryID">
136
141
  <To object="AddressDummy" field="CountryID" />
137
142
  </Mapping>
143
+ <Mapping field="DecPlQty">
144
+ <To object="commonsetup" field="DecPlQty" />
145
+ </Mapping>
146
+ <Mapping field="WeightUOM">
147
+ <To object="commonsetup" field="WeightUOM" />
148
+ </Mapping>
149
+ <Mapping field="VolumeUOM">
150
+ <To object="commonsetup" field="VolumeUOM" />
151
+ </Mapping>
138
152
  </Mappings>
139
153
  </TopLevelEntity>
140
154
  <TopLevelEntity name="CreditTerms" screen="CS206500">