acumatica-cli 0.10.2__tar.gz → 0.11.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 (68) hide show
  1. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/PKG-INFO +31 -7
  2. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/README.md +30 -6
  3. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/pyproject.toml +1 -1
  4. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/bootstrap.py +8 -8
  5. acumatica_cli-0.11.0/src/acumatica_cli/bootstrap_project.xml +789 -0
  6. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/cli.py +39 -13
  7. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/client.py +21 -2
  8. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/config.py +124 -21
  9. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/extract.py +4 -4
  10. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/extract_manifest.yaml +1 -1
  11. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/run.py +5 -5
  12. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/seed.py +5 -4
  13. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/README.md +49 -0
  14. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/baseline/20-accounts.yaml +238 -0
  15. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/baseline/60-ledger-company.yaml +27 -0
  16. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/baseline/90-uoms.yaml +17 -0
  17. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/bootstrap/company.yaml +15 -0
  18. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/bootstrap/features.yaml +26 -0
  19. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/10-reason-codes.yaml +49 -0
  20. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/20-in-preferences.yaml +34 -0
  21. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/30-availability-rules.yaml +16 -0
  22. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/40-posting-classes.yaml +44 -0
  23. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/50-warehouse.yaml +23 -0
  24. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/51-warehouse-locations.yaml +26 -0
  25. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/52-warehouse-defaults.yaml +13 -0
  26. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/53-tax-categories.yaml +14 -0
  27. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/54-item-classes.yaml +43 -0
  28. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/56-so-preferences.yaml +21 -0
  29. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/57-po-preferences.yaml +21 -0
  30. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/58-order-types.yaml +21 -0
  31. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/60-ar-preferences.yaml +15 -0
  32. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/61-ap-preferences.yaml +14 -0
  33. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/62-ca-preferences.yaml +18 -0
  34. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/63-cash-account.yaml +23 -0
  35. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/64-payment-methods.yaml +27 -0
  36. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/65-statement-cycles.yaml +23 -0
  37. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/70-vendor-classes.yaml +38 -0
  38. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/71-customer-classes.yaml +28 -0
  39. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/75-vendors.yaml +73 -0
  40. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/76-customers.yaml +54 -0
  41. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/80-stock-items-parts.yaml +63 -0
  42. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/82-stock-items-kits.yaml +37 -0
  43. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/master/85-kit-specifications.yaml +94 -0
  44. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/scenario/buy-sell.yaml +235 -0
  45. acumatica_cli-0.11.0/src/acumatica_cli/templates/distribution/setup/30-open-periods.yaml +33 -0
  46. acumatica_cli-0.10.2/src/acumatica_cli/bootstrap_project.xml +0 -238
  47. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/__init__.py +0 -0
  48. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
  49. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/firstlogin.py +0 -0
  50. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/models.py +0 -0
  51. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/output.py +0 -0
  52. {acumatica_cli-0.10.2 → acumatica_cli-0.11.0}/src/acumatica_cli/target.py +0 -0
  53. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/10-subaccounts.yaml +0 -0
  54. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/20-accounts.yaml +0 -0
  55. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/40-ledger.yaml +0 -0
  56. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/50-gl-preferences.yaml +0 -0
  57. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/60-ledger-company.yaml +0 -0
  58. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/baseline/90-uoms.yaml +0 -0
  59. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/bootstrap/company.yaml +0 -0
  60. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/bootstrap/credit-terms.yaml +0 -0
  61. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/bootstrap/features.yaml +0 -0
  62. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/env +0 -0
  63. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/gitignore +0 -0
  64. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/setup/10-financial-year.yaml +0 -0
  65. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/setup/20-master-calendar.yaml +0 -0
  66. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/setup/30-open-periods.yaml +0 -0
  67. {acumatica_cli-0.10.2/src/acumatica_cli/templates → acumatica_cli-0.11.0/src/acumatica_cli/templates/finance}/target +0 -0
  68. {acumatica_cli-0.10.2 → acumatica_cli-0.11.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.10.2
3
+ Version: 0.11.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>
@@ -16,7 +16,7 @@ Project-URL: Homepage, https://lab5.ca
16
16
  Project-URL: Repository, https://github.com/kborovik/acumatica-cli
17
17
  Description-Content-Type: text/markdown
18
18
 
19
- # Acumatica GitOps (Config-as-Code)
19
+ # Acumatica ERP - GitOps CLI
20
20
 
21
21
  **`acu`** configures Acumatica ERP from YAML files in a git repo (GitOps).
22
22
 
@@ -43,10 +43,20 @@ cd my-erp # edit .env: set ACU_PASSWORD
43
43
 
44
44
  acu config check # read-only preflight (incl. target.yaml)
45
45
  acu tenant create --id 3 --login DEV # create the tenant + bootstrap it (needs SSH)
46
- acu --tenant DEV apply # seed bootstrap/, baseline/, setup/
46
+ acu --tenant DEV apply # seed bootstrap/, baseline/, setup/ (, master/)
47
47
  acu --tenant DEV diff # prove zero drift (exit 2 on drift)
48
48
  ```
49
49
 
50
+ **Distribution demo seed** (inventory, warehouse, items, vendors/customers, golden scenario):
51
+
52
+ ```sh
53
+ acu config init --flavor distribution --host erp.example.com my-dist
54
+ cd my-dist # edit .env; start from an empty tenant
55
+ acu config check && acu bootstrap && acu apply && acu run scenario/ && acu diff
56
+ ```
57
+
58
+ See [docs/distribution.md](docs/distribution.md) for the entity map and apply-order notes.
59
+
50
60
  **Hosted Acumatica (no SSH):** the tenant already exists; leave `ACU_SSH` blank.
51
61
 
52
62
  ```sh
@@ -81,25 +91,29 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
81
91
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
82
92
 
83
93
  └── config configuration ops
84
- ├── init [--host HOST] [DIR] scaffold a data repo (.env, target.yaml, example YAML)
94
+ ├── init [--host HOST] [--flavor distribution] [DIR]
95
+ │ scaffold a data repo (.env, target.yaml, example YAML)
85
96
  ├── show print the resolved config as a complete .env
86
97
  └── check [--strict] preflight: discovery, secrets, target, REST, endpoints, SSH
87
98
  ```
88
99
 
89
- `apply` and `diff` called without FILES default to the scaffolded directories, in order: `bootstrap/`, then `baseline/`, then `setup/`.
100
+ `apply` and `diff` called without FILES default to existing scaffolded directories, in order: `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
90
101
  `run` called without FILES defaults to `scenario/`.
91
102
  `acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
92
103
  Run `acu <command> --help` for details on any command.
93
104
 
94
105
  ## The data repo
95
106
 
96
- Your configuration lives in its own git repo. `acu config init` scaffolds everything except `scenario/`, which you author by hand:
107
+ Your configuration lives in its own git repo.
108
+ `acu config init` scaffolds finance-minimal seeds (Bootstrap `project.xml` at `Bootstrap/1.0.0`, no `master/`).
109
+ `acu config init --flavor distribution` adds the full demo set (same contract identity, expanded COA, `master/`, golden `scenario/`, README).
97
110
 
98
111
  | Path | What it holds |
99
112
  | ------------- | -------------------------------------------------------------------------- |
100
113
  | `bootstrap/` | what makes a virgin tenant configurable: features, company, credit terms |
101
114
  | `baseline/` | reference data: subaccounts, chart of accounts, ledger, units of measure |
102
115
  | `setup/` | one-time actions: financial year, master calendar, open periods |
116
+ | `master/` | distribution masters (prefs, warehouse, items, vendors, customers); flavor only |
103
117
  | `scenario/` | transaction scenarios for `acu run`: purchase, build, sell flows |
104
118
  | `target.yaml` | committed verified matrix: `erp` + `default_api` (what, not where) |
105
119
  | `.env` | where to apply and who signs in, every key an `ACU_*` variable |
@@ -121,7 +135,7 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
121
135
  | omitted | `Default/<ACU_API_VERSION>` for Default-only entities |
122
136
  | `bootstrap` | active `Bootstrap/<ver>` from `bootstrap/project.xml` or the packaged contract |
123
137
  | `default` | `Default/<ACU_API_VERSION>` — tracks the operator API version |
124
- | `Bootstrap/1.9.0` or `Default/25.200.001` | literal pin (ignores `ACU_API_VERSION` for Default) |
138
+ | `Bootstrap/1.0.0` or `Default/25.200.001` | literal pin (ignores `ACU_API_VERSION` for Default) |
125
139
 
126
140
  Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the configured API generation.
127
141
 
@@ -258,6 +272,16 @@ gmake check # offline gate: ruff, basedpyright strict, pytest
258
272
  The default test suite is fully offline.
259
273
  REST is faked with `httpx.MockTransport`, SSH with a monkeypatched `subprocess.run` — no live instance is needed.
260
274
  `gmake check` must pass before every commit.
275
+ GitHub Actions runs the same gate on every push and pull request to `main`.
276
+
277
+ ### Release
278
+
279
+ ```sh
280
+ gmake release patch # or minor | major
281
+ ```
282
+
283
+ Local release runs `gmake check`, bumps the version, commits, tags `v<version>`, and pushes.
284
+ GitHub Actions re-runs the check on the tag, then publishes the GitHub release and PyPI package only if that check passes.
261
285
 
262
286
  ### Live end-to-end tier
263
287
 
@@ -1,4 +1,4 @@
1
- # Acumatica GitOps (Config-as-Code)
1
+ # Acumatica ERP - GitOps CLI
2
2
 
3
3
  **`acu`** configures Acumatica ERP from YAML files in a git repo (GitOps).
4
4
 
@@ -25,10 +25,20 @@ cd my-erp # edit .env: set ACU_PASSWORD
25
25
 
26
26
  acu config check # read-only preflight (incl. target.yaml)
27
27
  acu tenant create --id 3 --login DEV # create the tenant + bootstrap it (needs SSH)
28
- acu --tenant DEV apply # seed bootstrap/, baseline/, setup/
28
+ acu --tenant DEV apply # seed bootstrap/, baseline/, setup/ (, master/)
29
29
  acu --tenant DEV diff # prove zero drift (exit 2 on drift)
30
30
  ```
31
31
 
32
+ **Distribution demo seed** (inventory, warehouse, items, vendors/customers, golden scenario):
33
+
34
+ ```sh
35
+ acu config init --flavor distribution --host erp.example.com my-dist
36
+ cd my-dist # edit .env; start from an empty tenant
37
+ acu config check && acu bootstrap && acu apply && acu run scenario/ && acu diff
38
+ ```
39
+
40
+ See [docs/distribution.md](docs/distribution.md) for the entity map and apply-order notes.
41
+
32
42
  **Hosted Acumatica (no SSH):** the tenant already exists; leave `ACU_SSH` blank.
33
43
 
34
44
  ```sh
@@ -63,25 +73,29 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
63
73
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
64
74
 
65
75
  └── config configuration ops
66
- ├── init [--host HOST] [DIR] scaffold a data repo (.env, target.yaml, example YAML)
76
+ ├── init [--host HOST] [--flavor distribution] [DIR]
77
+ │ scaffold a data repo (.env, target.yaml, example YAML)
67
78
  ├── show print the resolved config as a complete .env
68
79
  └── check [--strict] preflight: discovery, secrets, target, REST, endpoints, SSH
69
80
  ```
70
81
 
71
- `apply` and `diff` called without FILES default to the scaffolded directories, in order: `bootstrap/`, then `baseline/`, then `setup/`.
82
+ `apply` and `diff` called without FILES default to existing scaffolded directories, in order: `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
72
83
  `run` called without FILES defaults to `scenario/`.
73
84
  `acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
74
85
  Run `acu <command> --help` for details on any command.
75
86
 
76
87
  ## The data repo
77
88
 
78
- Your configuration lives in its own git repo. `acu config init` scaffolds everything except `scenario/`, which you author by hand:
89
+ Your configuration lives in its own git repo.
90
+ `acu config init` scaffolds finance-minimal seeds (Bootstrap `project.xml` at `Bootstrap/1.0.0`, no `master/`).
91
+ `acu config init --flavor distribution` adds the full demo set (same contract identity, expanded COA, `master/`, golden `scenario/`, README).
79
92
 
80
93
  | Path | What it holds |
81
94
  | ------------- | -------------------------------------------------------------------------- |
82
95
  | `bootstrap/` | what makes a virgin tenant configurable: features, company, credit terms |
83
96
  | `baseline/` | reference data: subaccounts, chart of accounts, ledger, units of measure |
84
97
  | `setup/` | one-time actions: financial year, master calendar, open periods |
98
+ | `master/` | distribution masters (prefs, warehouse, items, vendors, customers); flavor only |
85
99
  | `scenario/` | transaction scenarios for `acu run`: purchase, build, sell flows |
86
100
  | `target.yaml` | committed verified matrix: `erp` + `default_api` (what, not where) |
87
101
  | `.env` | where to apply and who signs in, every key an `ACU_*` variable |
@@ -103,7 +117,7 @@ Dual-served entities (on both Bootstrap and Default) need an explicit `endpoint:
103
117
  | omitted | `Default/<ACU_API_VERSION>` for Default-only entities |
104
118
  | `bootstrap` | active `Bootstrap/<ver>` from `bootstrap/project.xml` or the packaged contract |
105
119
  | `default` | `Default/<ACU_API_VERSION>` — tracks the operator API version |
106
- | `Bootstrap/1.9.0` or `Default/25.200.001` | literal pin (ignores `ACU_API_VERSION` for Default) |
120
+ | `Bootstrap/1.0.0` or `Default/25.200.001` | literal pin (ignores `ACU_API_VERSION` for Default) |
107
121
 
108
122
  Prefer symbolic `default` over a pinned `Default/25.200.001` so the seed tree travels with the configured API generation.
109
123
 
@@ -240,6 +254,16 @@ gmake check # offline gate: ruff, basedpyright strict, pytest
240
254
  The default test suite is fully offline.
241
255
  REST is faked with `httpx.MockTransport`, SSH with a monkeypatched `subprocess.run` — no live instance is needed.
242
256
  `gmake check` must pass before every commit.
257
+ GitHub Actions runs the same gate on every push and pull request to `main`.
258
+
259
+ ### Release
260
+
261
+ ```sh
262
+ gmake release patch # or minor | major
263
+ ```
264
+
265
+ Local release runs `gmake check`, bumps the version, commits, tags `v<version>`, and pushes.
266
+ GitHub Actions re-runs the check on the tag, then publishes the GitHub release and PyPI package only if that check passes.
243
267
 
244
268
  ### Live end-to-end tier
245
269
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acumatica-cli"
3
- version = "0.10.2"
3
+ version = "0.11.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"
@@ -8,10 +8,10 @@ virgin tenant, so bootstrap = publish a package whose CustomizationPlugin
8
8
  cannot write CS100000 at all (T3 verdict) — and whose Bootstrap contract
9
9
  endpoint exposes the seeding surface (serialization verified T12).
10
10
 
11
- Contract ownership is hybrid (T69/V2): the data repo's
12
- ``bootstrap/project.xml`` is preferred when present (full company surface);
13
- else the packaged minimal ``bootstrap_project.xml`` covers config-init +
14
- the GL chain so PyPI-only and offline virgin paths still bootstrap.
11
+ Contract ownership is hybrid (T69/V2/T81): the data repo's
12
+ ``bootstrap/project.xml`` is preferred when present; else the packaged
13
+ full company ``bootstrap_project.xml`` (``Bootstrap/1.0.0``) so PyPI-only
14
+ and offline virgin paths still bootstrap the full surface.
15
15
 
16
16
  Customization publishes are tenant-scoped, so the package must be published
17
17
  per tenant; publish() is idempotent on content — the skip gate compares the
@@ -60,7 +60,7 @@ FEATURES_SENTINEL = "/*ACU_FEATURES*/"
60
60
 
61
61
 
62
62
  def packaged_contract_xml() -> bytes:
63
- """The CLI-shipped minimal Bootstrap contract (config-init surface)."""
63
+ """The CLI-shipped full company Bootstrap contract (``Bootstrap/1.0.0``)."""
64
64
  return (resources.files("acumatica_cli") / "bootstrap_project.xml").read_bytes()
65
65
 
66
66
 
@@ -69,7 +69,7 @@ def load_contract_xml(root: Path | None = None) -> bytes:
69
69
 
70
70
  ``root`` is the data-repo discovery root (the dir holding ``.env``).
71
71
  Absent root or absent ``bootstrap/project.xml`` falls back to the
72
- packaged minimal contract (V2, same absence pattern as features.yaml).
72
+ packaged full company contract (V2/T81, same absence pattern as features.yaml).
73
73
  """
74
74
  if root is not None:
75
75
  path = root / "bootstrap" / "project.xml"
@@ -136,9 +136,9 @@ def package_zip(
136
136
  ``Enabled`` set at the ACU_FEATURES sentinel — the one point where the
137
137
  data repo's feature list enters the package (V2).
138
138
 
139
- Contract XML (V2/T69): ``contract`` when given; else
139
+ Contract XML (V2/T69/T81): ``contract`` when given; else
140
140
  ``bootstrap/project.xml`` under ``root`` when present; else the
141
- packaged minimal template.
141
+ packaged full company template.
142
142
  """
143
143
  pkg = resources.files("acumatica_cli")
144
144
  if contract is None: