datex-studio-cli 0.4.14__tar.gz → 0.4.15__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.
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/PKG-INFO +1 -1
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/pyproject.toml +1 -1
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/__init__.py +1 -1
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/crm.py +344 -7
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/dynamics/client.py +10 -1
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/.gitignore +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/README.md +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/report-creator.skill +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/scripts/analyze_corpus.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/scripts/generate_rdlx_schema.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/__main__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/cli.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/api.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/auth.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/branch.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/cascade.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/config.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/configuration.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/datasource.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/devops.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/document.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/endpoint.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/env.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/explore.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/function.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/init.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/marketplace.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/_common.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/api.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/create.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/data.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/pack.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/ng/preview.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/odata.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/organization.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/proxy.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/reference.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/release_notes.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/repo.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/add_cmds.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/api.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/batch.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/create.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/data.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/dataset.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/edit.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/folder.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/preview.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/report/schema_cmds.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/reset.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/schema.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/servicepack.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/source.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/studio.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/telemetry.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/commands/user.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/context.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/app_config.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/client.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/endpoints.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/metadata_models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/api/reference_graph.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/datex_tenant.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/decorators.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/msal_client.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/tenants.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/auth/token_cache.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/cache.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/flow_generator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/flow_models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/generator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/parsers.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/resolver.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/type_def_parser.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/validator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/designer/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/designer/flow_models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/designer/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/designer/parsers.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/devops/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/devops/client.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/devops/helpers.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/devops/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/dynamics/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/dynamics/metadata_cache.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/footprint/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/footprint/client.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/footprint/edmx_parser.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/footprint/metadata.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/function/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/function/generator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/function/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/function/validator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/graph.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/onboarding.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/csv_fmt.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/formatter.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/json_fmt.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/redaction.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/output/yaml_fmt.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/release_notes.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/responses.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/config.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/identity.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/recorder.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/scrubber.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/telemetry/sender.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/models/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/folder.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/manifest.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/mocks.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/preview.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/ng/scaffold.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/py.typed +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/datasource_binding.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/engine.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/field_parser.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/folder.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/manifest.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/models.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/preview.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/preview_arjs.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/schema.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/svg_renderer.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/templates/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/validate_arjs.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/validator.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/report/wrapper.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/click_options.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/clipboard.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/config.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/errors.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/filtering.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/image.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/paths.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/resolvers.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/responses.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/restricted.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/sorting.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/update_check.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/utils/versioning.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/__init__.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/app.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/design.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/proxy_app.py +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/404/index.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/404.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_buildManifest.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_ssgManifest.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/538-84e2e111415f1fda.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-ea1be7001c230704.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-a5e129c2d223432c.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/app/design/page-21ba66a3dd3b03f0.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/app/layout-2cc6eac09e476c91.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/app/page-20c358395882cdac.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/main-app-b69998d8941231d8.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/design/capture/index.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/design/capture/index.txt +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/design/index.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/design/index.txt +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/index.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/index.txt +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/render-cli.js +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/report-preview.html +0 -0
- {datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/web/static/report-validate.html +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: datex-studio-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.15
|
|
4
4
|
Summary: CLI for Datex Studio low-code platform, designed for LLM-based AI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/datex/datex-studio-cli
|
|
6
6
|
Project-URL: Documentation, https://github.com/datex/datex-studio-cli
|
|
@@ -525,6 +525,33 @@ _DESCRIPTION_WRAPPER = (
|
|
|
525
525
|
|
|
526
526
|
_ENTITLEMENT_ACTIVE_STATE = 1
|
|
527
527
|
|
|
528
|
+
_ANNOTATION_ENTITY_SET = "annotations"
|
|
529
|
+
_PORTAL_COMMENT_ENTITY_SET = "adx_portalcomments"
|
|
530
|
+
|
|
531
|
+
# The CRM rich-text editor's own markup. Notes and portal comments authored in
|
|
532
|
+
# the UI all carry it, so a CLI-authored one renders like its neighbours rather
|
|
533
|
+
# than as an unstyled string.
|
|
534
|
+
_CK_WRAPPER = (
|
|
535
|
+
'<div class="ck-content" data-wrapper="true" dir="ltr" '
|
|
536
|
+
'style="--ck-image-style-spacing: 1.5em; --ck-inline-image-style-spacing: '
|
|
537
|
+
"calc(var(--ck-image-style-spacing) / 2); font-family: Segoe UI; "
|
|
538
|
+
'font-size: 11pt;">{body}</div>'
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
# Activity-party roles. 8 (regarding) and 9 (owner) are added by the platform.
|
|
542
|
+
_PARTY_SENDER = 1
|
|
543
|
+
_PARTY_RECIPIENT = 2
|
|
544
|
+
|
|
545
|
+
# adx_portalcommentdirectioncode.
|
|
546
|
+
_COMMENT_DIRECTION_OUTGOING = 2
|
|
547
|
+
|
|
548
|
+
# Marking the comment sent is a second step. An activity is created in the Open
|
|
549
|
+
# state, `statecode` is not writable on create, and "Sent" belongs to Completed
|
|
550
|
+
# — so setting it in the create body fails the whole request with
|
|
551
|
+
# "2 is not a valid status code for state code adx_portalcommentState.Open".
|
|
552
|
+
_COMMENT_STATE_COMPLETED = 1
|
|
553
|
+
_COMMENT_STATUS_SENT = 2
|
|
554
|
+
|
|
528
555
|
|
|
529
556
|
def _is_guid(value: str) -> bool:
|
|
530
557
|
"""Whether a value is a bare GUID rather than a name to look up."""
|
|
@@ -549,6 +576,55 @@ def _wrap_description_html(text: str) -> str:
|
|
|
549
576
|
)
|
|
550
577
|
|
|
551
578
|
|
|
579
|
+
def _wrap_note_html(text: str) -> str:
|
|
580
|
+
"""Convert plain text to the CRM editor's HTML for a note or comment body.
|
|
581
|
+
|
|
582
|
+
Blank-line-separated paragraphs become ``<p style="margin: 0;">`` siblings
|
|
583
|
+
inside one wrapper div; single newlines become ``<br>``. Quotes are left as
|
|
584
|
+
typed — see :func:`_wrap_description_html` for why.
|
|
585
|
+
"""
|
|
586
|
+
from html import escape
|
|
587
|
+
|
|
588
|
+
paragraphs = [p for p in re.split(r"\n\s*\n", text.strip()) if p.strip()]
|
|
589
|
+
body = "".join(
|
|
590
|
+
f'<p style="margin: 0;">{escape(p.strip(), quote=False).replace(chr(10), "<br>")}</p>'
|
|
591
|
+
for p in paragraphs
|
|
592
|
+
)
|
|
593
|
+
return _CK_WRAPPER.format(body=body)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
def _read_body(text: str | None, text_file: "Path | None", flag: str) -> str:
|
|
597
|
+
"""Take the body from an argument or a file, and insist it is not blank."""
|
|
598
|
+
from dxs.utils.errors import ValidationError
|
|
599
|
+
|
|
600
|
+
if text is not None and text_file is not None:
|
|
601
|
+
raise ValidationError(
|
|
602
|
+
message=f"Pass either {flag} text or --text-file, not both",
|
|
603
|
+
code="DXS-CRM-CASE-BODY",
|
|
604
|
+
suggestions=["The body has one source; the other would be silently dropped"],
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
body = text_file.read_text(encoding="utf-8") if text_file else text
|
|
608
|
+
if body is None or not body.strip():
|
|
609
|
+
raise ValidationError(
|
|
610
|
+
message="The body cannot be empty",
|
|
611
|
+
code="DXS-CRM-CASE-BODY",
|
|
612
|
+
suggestions=["Pass the text as an argument, or read it from --text-file"],
|
|
613
|
+
)
|
|
614
|
+
return body
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def _resolve_case_for_write(client: "DynamicsClient", ticket_number: str) -> dict[str, Any]:
|
|
618
|
+
"""Resolve a ticket number to the one incident a write may land on.
|
|
619
|
+
|
|
620
|
+
``resolve_ticket`` raises when a ticket number matches several cases, which
|
|
621
|
+
is what we want here: appending to an arbitrary one of them would be worse
|
|
622
|
+
than failing.
|
|
623
|
+
"""
|
|
624
|
+
incident = client.resolve_ticket(ticket_number)
|
|
625
|
+
return client.get_incident(incident["incidentid"])
|
|
626
|
+
|
|
627
|
+
|
|
552
628
|
def _resolve_account(client: "DynamicsClient", value: str) -> tuple[str, str]:
|
|
553
629
|
"""Resolve an account name or GUID to (account_id, account_name)."""
|
|
554
630
|
from dxs.utils.errors import ValidationError
|
|
@@ -752,7 +828,8 @@ def crm() -> None:
|
|
|
752
828
|
"""Dynamics CRM / Dataverse commands.
|
|
753
829
|
|
|
754
830
|
Query support cases, accounts, and activities - or run raw OData against
|
|
755
|
-
any Dataverse entity. Read-only apart from 'case create' and
|
|
831
|
+
any Dataverse entity. Read-only apart from 'case create/note/comment' and
|
|
832
|
+
'commit-ref'.
|
|
756
833
|
|
|
757
834
|
\b
|
|
758
835
|
Setup (one-time):
|
|
@@ -761,7 +838,7 @@ def crm() -> None:
|
|
|
761
838
|
|
|
762
839
|
\b
|
|
763
840
|
Pick a command:
|
|
764
|
-
case Support cases
|
|
841
|
+
case Support cases: search, get, create, note, comment, types
|
|
765
842
|
account Accounts (companies): list, search, contacts, entitlements
|
|
766
843
|
activity Portal comments & emails - by date range or ticket
|
|
767
844
|
metadata Discover entities, fields, and relationships
|
|
@@ -800,11 +877,19 @@ def case() -> None:
|
|
|
800
877
|
|
|
801
878
|
\b
|
|
802
879
|
Subcommands:
|
|
803
|
-
search
|
|
804
|
-
get
|
|
805
|
-
create
|
|
806
|
-
|
|
807
|
-
|
|
880
|
+
search Find cases by text, account, status, date, or type
|
|
881
|
+
get Fetch cases by ticket number (+ activity / notes)
|
|
882
|
+
create Open a new case
|
|
883
|
+
note Add an internal note (staff-only)
|
|
884
|
+
comment Reply to the customer (they see it on the portal)
|
|
885
|
+
query Custom OData over incidents (full field control)
|
|
886
|
+
types List case-type picklist values
|
|
887
|
+
|
|
888
|
+
\b
|
|
889
|
+
note vs comment - the difference is who reads it:
|
|
890
|
+
note -> annotation, internal to staff
|
|
891
|
+
comment -> portal comment, visible to the customer
|
|
892
|
+
Writes support --dry-run; 'comment' also confirms before posting.
|
|
808
893
|
|
|
809
894
|
\b
|
|
810
895
|
Ticket numbers are NOT unique - 'get' returns a list; check
|
|
@@ -1328,6 +1413,258 @@ def case_create(
|
|
|
1328
1413
|
ctx.output(single(item=item, semantic_key="case", created=True))
|
|
1329
1414
|
|
|
1330
1415
|
|
|
1416
|
+
@case.command("note")
|
|
1417
|
+
@click.argument("ticket_number")
|
|
1418
|
+
@click.argument("text", required=False, default=None)
|
|
1419
|
+
@click.option(
|
|
1420
|
+
"--text-file",
|
|
1421
|
+
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
1422
|
+
default=None,
|
|
1423
|
+
help="Read the note body from a file instead of the command line.",
|
|
1424
|
+
)
|
|
1425
|
+
@click.option("--subject", default=None, help="Optional note subject (usually left blank).")
|
|
1426
|
+
@click.option(
|
|
1427
|
+
"--dry-run",
|
|
1428
|
+
is_flag=True,
|
|
1429
|
+
default=False,
|
|
1430
|
+
help="Show the note that would be created, without creating it.",
|
|
1431
|
+
)
|
|
1432
|
+
@click.pass_obj
|
|
1433
|
+
@require_auth
|
|
1434
|
+
@restrict_in_restricted_mode("writes to Dynamics CRM records")
|
|
1435
|
+
def case_note(
|
|
1436
|
+
ctx: "DxsContext",
|
|
1437
|
+
ticket_number: str,
|
|
1438
|
+
text: str | None,
|
|
1439
|
+
text_file: Path | None,
|
|
1440
|
+
subject: str | None,
|
|
1441
|
+
dry_run: bool,
|
|
1442
|
+
) -> None:
|
|
1443
|
+
"""Add an internal note to a case.
|
|
1444
|
+
|
|
1445
|
+
Writes an annotation — what the CRM Notes tab shows and what
|
|
1446
|
+
'dxs crm case get --include-notes' reads back. It is internal to staff:
|
|
1447
|
+
the customer does not see it on the support portal. To reply to the
|
|
1448
|
+
customer, use 'dxs crm case comment' instead.
|
|
1449
|
+
|
|
1450
|
+
\b
|
|
1451
|
+
Arguments:
|
|
1452
|
+
TICKET_NUMBER Case ticket number (e.g. C260303_0017)
|
|
1453
|
+
TEXT The note body (or use --text-file)
|
|
1454
|
+
|
|
1455
|
+
\b
|
|
1456
|
+
Examples:
|
|
1457
|
+
dxs crm case note C260303_0017 "Root cause is the material swap rule."
|
|
1458
|
+
dxs crm case note C260303_0017 --text-file findings.md
|
|
1459
|
+
dxs crm case note C260303_0017 "Checked the logs" --dry-run
|
|
1460
|
+
|
|
1461
|
+
\b
|
|
1462
|
+
Ticket numbers are not unique. If this one matches more than one case the
|
|
1463
|
+
command fails rather than picking one — pull the case list with
|
|
1464
|
+
'dxs crm case get <ticket>' and note the right one by GUID.
|
|
1465
|
+
"""
|
|
1466
|
+
body = _read_body(text, text_file, "the note")
|
|
1467
|
+
|
|
1468
|
+
client = DynamicsClient()
|
|
1469
|
+
|
|
1470
|
+
ctx.log(f"Resolving case {ticket_number}...")
|
|
1471
|
+
incident = _resolve_case_for_write(client, ticket_number)
|
|
1472
|
+
incident_id = incident["incidentid"]
|
|
1473
|
+
|
|
1474
|
+
payload: dict[str, Any] = {
|
|
1475
|
+
"notetext": _wrap_note_html(body),
|
|
1476
|
+
"isdocument": False,
|
|
1477
|
+
"objectid_incident@odata.bind": f"/incidents({incident_id})",
|
|
1478
|
+
}
|
|
1479
|
+
if subject:
|
|
1480
|
+
payload["subject"] = subject
|
|
1481
|
+
|
|
1482
|
+
item: dict[str, Any] = {
|
|
1483
|
+
"ticketnumber": incident.get("ticketnumber"),
|
|
1484
|
+
"case_title": incident.get("title"),
|
|
1485
|
+
"incident_id": incident_id,
|
|
1486
|
+
"visibility": "internal",
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
if dry_run:
|
|
1490
|
+
ctx.output(single(item={**item, "dry_run": True, "record": payload}, semantic_key="note"))
|
|
1491
|
+
return
|
|
1492
|
+
|
|
1493
|
+
ctx.log(f"Adding note to {incident.get('ticketnumber')}...")
|
|
1494
|
+
note_id = client.create(f"/{_ANNOTATION_ENTITY_SET}", payload)
|
|
1495
|
+
|
|
1496
|
+
ctx.output(single(item={**item, "note_id": note_id, "created": True}, semantic_key="note"))
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
@case.command("comment")
|
|
1500
|
+
@click.argument("ticket_number")
|
|
1501
|
+
@click.argument("text", required=False, default=None)
|
|
1502
|
+
@click.option(
|
|
1503
|
+
"--text-file",
|
|
1504
|
+
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
1505
|
+
default=None,
|
|
1506
|
+
help="Read the comment body from a file instead of the command line.",
|
|
1507
|
+
)
|
|
1508
|
+
@click.option(
|
|
1509
|
+
"--to",
|
|
1510
|
+
"to_contact",
|
|
1511
|
+
default=None,
|
|
1512
|
+
help="Recipient contact - name, email or GUID. Defaults to the case's primary contact.",
|
|
1513
|
+
)
|
|
1514
|
+
@click.option("--yes", is_flag=True, default=False, help="Skip the confirmation prompt.")
|
|
1515
|
+
@click.option(
|
|
1516
|
+
"--dry-run",
|
|
1517
|
+
is_flag=True,
|
|
1518
|
+
default=False,
|
|
1519
|
+
help="Show the comment that would be posted, without posting it.",
|
|
1520
|
+
)
|
|
1521
|
+
@click.pass_obj
|
|
1522
|
+
@require_auth
|
|
1523
|
+
@restrict_in_restricted_mode("writes to Dynamics CRM records")
|
|
1524
|
+
def case_comment(
|
|
1525
|
+
ctx: "DxsContext",
|
|
1526
|
+
ticket_number: str,
|
|
1527
|
+
text: str | None,
|
|
1528
|
+
text_file: Path | None,
|
|
1529
|
+
to_contact: str | None,
|
|
1530
|
+
yes: bool,
|
|
1531
|
+
dry_run: bool,
|
|
1532
|
+
) -> None:
|
|
1533
|
+
"""Reply to the customer on a case (visible to them).
|
|
1534
|
+
|
|
1535
|
+
Posts an outgoing portal comment — what the customer reads and replies to
|
|
1536
|
+
on the support portal, and what 'dxs crm activity portalcomment' lists.
|
|
1537
|
+
This is customer-facing, so it confirms before posting unless --yes is
|
|
1538
|
+
given. For a staff-only note, use 'dxs crm case note' instead.
|
|
1539
|
+
|
|
1540
|
+
\b
|
|
1541
|
+
Arguments:
|
|
1542
|
+
TICKET_NUMBER Case ticket number (e.g. C260303_0017)
|
|
1543
|
+
TEXT The comment body (or use --text-file)
|
|
1544
|
+
|
|
1545
|
+
\b
|
|
1546
|
+
Examples:
|
|
1547
|
+
dxs crm case comment C260303_0017 "We've identified the cause."
|
|
1548
|
+
dxs crm case comment C260303_0017 --text-file reply.md --dry-run
|
|
1549
|
+
dxs crm case comment C260303_0017 "Fixed in 2.4" --to kelly@example.com --yes
|
|
1550
|
+
|
|
1551
|
+
\b
|
|
1552
|
+
The recipient defaults to the case's primary contact. Run --dry-run first
|
|
1553
|
+
to see who that resolves to.
|
|
1554
|
+
"""
|
|
1555
|
+
from dxs.utils.errors import ApiError, DxsError, ValidationError
|
|
1556
|
+
|
|
1557
|
+
body = _read_body(text, text_file, "the comment")
|
|
1558
|
+
|
|
1559
|
+
client = DynamicsClient()
|
|
1560
|
+
|
|
1561
|
+
ctx.log(f"Resolving case {ticket_number}...")
|
|
1562
|
+
incident = _resolve_case_for_write(client, ticket_number)
|
|
1563
|
+
incident_id = incident["incidentid"]
|
|
1564
|
+
|
|
1565
|
+
account_name = incident.get("_customerid_value@OData.Community.Display.V1.FormattedValue") or ""
|
|
1566
|
+
contact_id: str | None
|
|
1567
|
+
if to_contact:
|
|
1568
|
+
account_id = incident.get("_customerid_value")
|
|
1569
|
+
if not account_id:
|
|
1570
|
+
raise ValidationError(
|
|
1571
|
+
message=f"Case {ticket_number} has no customer account to look up contacts in",
|
|
1572
|
+
code="DXS-CRM-CASE-RECIPIENT",
|
|
1573
|
+
suggestions=["Pass --to as a contact GUID"],
|
|
1574
|
+
)
|
|
1575
|
+
contact_id, contact_name = _resolve_contact(client, account_id, account_name, to_contact)
|
|
1576
|
+
else:
|
|
1577
|
+
contact_id = incident.get("_primarycontactid_value")
|
|
1578
|
+
contact_name = (
|
|
1579
|
+
incident.get("_primarycontactid_value@OData.Community.Display.V1.FormattedValue") or ""
|
|
1580
|
+
)
|
|
1581
|
+
if not contact_id:
|
|
1582
|
+
raise ValidationError(
|
|
1583
|
+
message=f"Case {ticket_number} has no primary contact to reply to",
|
|
1584
|
+
code="DXS-CRM-CASE-RECIPIENT",
|
|
1585
|
+
suggestions=[
|
|
1586
|
+
"Name the recipient explicitly: --to <name|email>",
|
|
1587
|
+
f"List the account's contacts: dxs crm account contacts '{account_name}'",
|
|
1588
|
+
],
|
|
1589
|
+
)
|
|
1590
|
+
|
|
1591
|
+
sender_id = client.whoami()
|
|
1592
|
+
|
|
1593
|
+
payload: dict[str, Any] = {
|
|
1594
|
+
"description": _wrap_note_html(body),
|
|
1595
|
+
"adx_portalcommentdirectioncode": _COMMENT_DIRECTION_OUTGOING,
|
|
1596
|
+
"regardingobjectid_incident_adx_portalcomment@odata.bind": f"/incidents({incident_id})",
|
|
1597
|
+
"adx_portalcomment_activity_parties": [
|
|
1598
|
+
{
|
|
1599
|
+
"partyid_systemuser@odata.bind": f"/systemusers({sender_id})",
|
|
1600
|
+
"participationtypemask": _PARTY_SENDER,
|
|
1601
|
+
},
|
|
1602
|
+
{
|
|
1603
|
+
"partyid_contact@odata.bind": f"/contacts({contact_id})",
|
|
1604
|
+
"participationtypemask": _PARTY_RECIPIENT,
|
|
1605
|
+
},
|
|
1606
|
+
],
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
item: dict[str, Any] = {
|
|
1610
|
+
"ticketnumber": incident.get("ticketnumber"),
|
|
1611
|
+
"case_title": incident.get("title"),
|
|
1612
|
+
"incident_id": incident_id,
|
|
1613
|
+
"recipient": {"id": contact_id, "name": contact_name},
|
|
1614
|
+
"account": account_name,
|
|
1615
|
+
"visibility": "customer",
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
if dry_run:
|
|
1619
|
+
ctx.output(
|
|
1620
|
+
single(item={**item, "dry_run": True, "record": payload}, semantic_key="comment")
|
|
1621
|
+
)
|
|
1622
|
+
return
|
|
1623
|
+
|
|
1624
|
+
if not yes:
|
|
1625
|
+
# click.echo, not ctx.log: the preview is part of the prompt, and being
|
|
1626
|
+
# asked to approve a customer-facing message without seeing it — which
|
|
1627
|
+
# is what --quiet would otherwise do — is worse than not being asked.
|
|
1628
|
+
preview = [
|
|
1629
|
+
"This posts a reply the customer will see on the support portal.",
|
|
1630
|
+
f" Case: {incident.get('ticketnumber')} ({account_name})",
|
|
1631
|
+
f" Recipient: {contact_name}",
|
|
1632
|
+
"",
|
|
1633
|
+
*(f" | {line}" for line in body.strip().splitlines()),
|
|
1634
|
+
"",
|
|
1635
|
+
]
|
|
1636
|
+
click.echo("\n".join(preview), err=True)
|
|
1637
|
+
click.confirm("Post this comment to the customer?", abort=True, err=True)
|
|
1638
|
+
|
|
1639
|
+
ctx.log(f"Posting comment on {incident.get('ticketnumber')}...")
|
|
1640
|
+
comment_id = client.create(f"/{_PORTAL_COMMENT_ENTITY_SET}", payload)
|
|
1641
|
+
|
|
1642
|
+
# Second step, not decoration: a comment left Open is a draft the customer
|
|
1643
|
+
# never sees, so a failure here is reported as a failure to send.
|
|
1644
|
+
try:
|
|
1645
|
+
client.patch(
|
|
1646
|
+
f"/{_PORTAL_COMMENT_ENTITY_SET}({comment_id})",
|
|
1647
|
+
{"statecode": _COMMENT_STATE_COMPLETED, "statuscode": _COMMENT_STATUS_SENT},
|
|
1648
|
+
)
|
|
1649
|
+
except DxsError as exc:
|
|
1650
|
+
raise ApiError(
|
|
1651
|
+
message=(
|
|
1652
|
+
f"Comment saved as a draft on {incident.get('ticketnumber')} but could not "
|
|
1653
|
+
f"be marked sent - the customer will not see it ({exc.message})"
|
|
1654
|
+
),
|
|
1655
|
+
code="DXS-CRM-COMMENT-UNSENT",
|
|
1656
|
+
details={"comment_id": comment_id, "incident_id": incident_id},
|
|
1657
|
+
suggestions=[
|
|
1658
|
+
"Mark it sent in CRM, or delete the draft and retry: "
|
|
1659
|
+
f'dxs crm odata adx_portalcomments -f "activityid eq {comment_id}"',
|
|
1660
|
+
],
|
|
1661
|
+
) from exc
|
|
1662
|
+
|
|
1663
|
+
ctx.output(
|
|
1664
|
+
single(item={**item, "comment_id": comment_id, "created": True}, semantic_key="comment")
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
|
|
1331
1668
|
@case.command("get")
|
|
1332
1669
|
@click.argument("ticket_number")
|
|
1333
1670
|
@click.option(
|
|
@@ -896,7 +896,7 @@ class DynamicsClient:
|
|
|
896
896
|
INCIDENT_SELECT = (
|
|
897
897
|
"incidentid,ticketnumber,title,description,"
|
|
898
898
|
"statecode,statuscode,createdon,modifiedon,"
|
|
899
|
-
"_customerid_value,_ownerid_value,"
|
|
899
|
+
"_customerid_value,_ownerid_value,_primarycontactid_value,"
|
|
900
900
|
"casetypecode,prioritycode,severitycode,daa_immediatebusinessimpact,"
|
|
901
901
|
"isescalated,escalatedon,resolveby,responseby,"
|
|
902
902
|
"adx_resolution,adx_resolutiondate"
|
|
@@ -915,6 +915,15 @@ class DynamicsClient:
|
|
|
915
915
|
)
|
|
916
916
|
return ",".join(expand_parts)
|
|
917
917
|
|
|
918
|
+
def whoami(self) -> str:
|
|
919
|
+
"""Return the calling user's systemuserid.
|
|
920
|
+
|
|
921
|
+
Needed to name the sender on an outgoing activity: the platform sets
|
|
922
|
+
``ownerid`` on its own, but the sender activity party has to be built
|
|
923
|
+
explicitly.
|
|
924
|
+
"""
|
|
925
|
+
return cast(str, self.get("/WhoAmI")["UserId"])
|
|
926
|
+
|
|
918
927
|
def list_contacts_for_account(self, account_id: str) -> dict[str, Any]:
|
|
919
928
|
"""List the active contacts belonging to an account.
|
|
920
929
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/flow_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datex_studio_cli-0.4.14 → datex_studio_cli-0.4.15}/src/dxs/core/datasource/type_def_parser.py
RENAMED
|
File without changes
|
|
File without changes
|